├── examples ├── ESP8266 │ └── ESP8266.ino └── w5500 │ └── w5500.ino ├── library.properties ├── readme.md └── src ├── aliIotLink.cpp ├── aliIotLink.h └── modules ├── Crypto ├── AES.h ├── AES128.cpp ├── AES192.cpp ├── AES256.cpp ├── AESCommon.cpp ├── AESEsp32.cpp ├── AuthenticatedCipher.cpp ├── AuthenticatedCipher.h ├── BLAKE2b.cpp ├── BLAKE2b.h ├── BLAKE2s.cpp ├── BLAKE2s.h ├── BigNumberUtil.cpp ├── BigNumberUtil.h ├── BlockCipher.cpp ├── BlockCipher.h ├── CTR.cpp ├── CTR.h ├── ChaCha.cpp ├── ChaCha.h ├── ChaChaPoly.cpp ├── ChaChaPoly.h ├── Cipher.cpp ├── Cipher.h ├── Crypto.cpp ├── Crypto.h ├── Curve25519.cpp ├── Curve25519.h ├── EAX.cpp ├── EAX.h ├── Ed25519.cpp ├── Ed25519.h ├── GCM.cpp ├── GCM.h ├── GF128.cpp ├── GF128.h ├── GHASH.cpp ├── GHASH.h ├── Hash.cpp ├── Hash.h ├── KeccakCore.cpp ├── KeccakCore.h ├── NoiseSource.cpp ├── NoiseSource.h ├── OMAC.cpp ├── OMAC.h ├── P521.cpp ├── P521.h ├── Poly1305.cpp ├── Poly1305.h ├── RNG.cpp ├── RNG.h ├── SHA256.cpp ├── SHA256.h ├── SHA3.cpp ├── SHA3.h ├── SHA512.cpp ├── SHA512.h ├── SHAKE.cpp ├── SHAKE.h ├── XOF.cpp ├── XOF.h ├── XTS.cpp ├── XTS.h ├── examples │ ├── TestAES │ │ └── TestAES.ino │ ├── TestAESSmall │ │ └── TestAESSmall.ino │ ├── TestAESTiny │ │ └── TestAESTiny.ino │ ├── TestBLAKE2b │ │ └── TestBLAKE2b.ino │ ├── TestBLAKE2s │ │ └── TestBLAKE2s.ino │ ├── TestBigNumberUtil │ │ └── TestBigNumberUtil.ino │ ├── TestCTR │ │ └── TestCTR.ino │ ├── TestChaCha │ │ └── TestChaCha.ino │ ├── TestChaChaPoly │ │ └── TestChaChaPoly.ino │ ├── TestCurve25519 │ │ └── TestCurve25519.ino │ ├── TestCurve25519Math │ │ └── TestCurve25519Math.ino │ ├── TestEAX │ │ └── TestEAX.ino │ ├── TestEd25519 │ │ └── TestEd25519.ino │ ├── TestGCM │ │ └── TestGCM.ino │ ├── TestGHASH │ │ └── TestGHASH.ino │ ├── TestP521 │ │ └── TestP521.ino │ ├── TestP521Math │ │ └── TestP521Math.ino │ ├── TestPoly1305 │ │ └── TestPoly1305.ino │ ├── TestRNG │ │ └── TestRNG.ino │ ├── TestSHA256 │ │ └── TestSHA256.ino │ ├── TestSHA3_256 │ │ └── TestSHA3_256.ino │ ├── TestSHA3_512 │ │ └── TestSHA3_512.ino │ ├── TestSHA512 │ │ └── TestSHA512.ino │ ├── TestSHAKE128 │ │ └── TestSHAKE128.ino │ ├── TestSHAKE256 │ │ └── TestSHAKE256.ino │ └── TestXTS │ │ └── TestXTS.ino ├── keywords.txt ├── library.json └── utility │ ├── EndianUtil.h │ ├── LimbUtil.h │ ├── ProgMemUtil.h │ └── RotateUtil.h └── mqtt ├── PubSubClient.cpp └── PubSubClient.h /examples/ESP8266/ESP8266.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | const char* ssid = "WIFI-SSID"; 5 | const char* password = "12345678"; 6 | 7 | static const char ProductKey[] PROGMEM = "a1BllGqYfBO"; 8 | static const char DeviceName[] PROGMEM = "QNfNlOW1l9uTY2V0Dw2E"; 9 | static const char DeviceSecret[] PROGMEM = "jIM4j0tphyiXhx4yVzuv2BcF1bz916Oo"; 10 | 11 | static const char postTopic[] PROGMEM = ""; //上报消息topic 12 | static const char setTopic[] PROGMEM = ""; //服务器消息topic 13 | 14 | WiFiClient espClient; //实例化 wifi网络 15 | PubSubClient client(espClient); //将网络传入MQTT 16 | AliIotLink aliLink(client); //将mqtt传入服务 17 | 18 | //回调函数 19 | void Callbacks(char* topic, byte* payload, unsigned int length) 20 | { 21 | //回调功能演示,将监听到的消息直接打印到串口 22 | Serial.print(topic); 23 | Serial.print(":"); 24 | for (int i = 0; i < length; i++) 25 | { 26 | Serial.print((char)payload[i]); 27 | } 28 | Serial.println(); 29 | } 30 | 31 | void setup() 32 | { 33 | 34 | Serial.begin(115200); 35 | WiFi.mode(WIFI_STA); //配置为客户端模式 36 | WiFi.begin(ssid, password); //初始化并且链接wifi 37 | 38 | while (WiFi.status() != WL_CONNECTED) //等待wifi连接 39 | { 40 | delay(500); 41 | Serial.print("."); 42 | } 43 | 44 | aliLink.subTopic(FPSTR(setTopic)); //订阅服务器下行消息 45 | 46 | aliLink.setCallback(Callbacks); //注册下发消息回调函数 47 | aliLink.begin(FPSTR(DeviceName),FPSTR(ProductKey),FPSTR(DeviceSecret)); //完成初始化配置 三元素(DeviceName,ProductKey,DeviceSecret) 48 | } 49 | void loop() 50 | { 51 | if (aliLink.state() != 0) // 显示连接错误码,实际项目不需要 52 | { 53 | Serial.println(aliLink.state()); 54 | } 55 | aliLink.loop(); //循环维持心跳与消息触发,应尽可能多的执行 56 | } 57 | -------------------------------------------------------------------------------- /examples/w5500/w5500.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | //W5500 链接阿里云 5 | 6 | byte mac[] = {0x00, 0xED, 0xBA, 0xFE, 0xFE, 0xED }; //MAC地址 7 | 8 | 9 | static const char ProductKey[] PROGMEM = "a1BllGqYfBO"; 10 | static const char DeviceName[] PROGMEM = "QNfNlOW1l9uTY2V0Dw2E"; 11 | static const char DeviceSecret[] PROGMEM = "jIM4j0tphyiXhx4yVzuv2BcF1bz916Oo"; 12 | 13 | static const char postTopic[] PROGMEM = ""; //上报消息topic 14 | static const char setTopic[] PROGMEM = ""; //服务器消息topic 15 | 16 | EthernetClient ethClient; //实例化以太网 17 | PubSubClient client(ethClient); //将网络传入MQTT 18 | AliIotLink aliLink(client); //将mqtt传入服务 19 | 20 | 21 | //回调函数 22 | void Callbacks(char* topic, byte* payload, unsigned int length) 23 | { 24 | //回调功能演示,将监听到的消息直接打印到串口 25 | Serial.print(topic); 26 | Serial.print(":"); 27 | for (int i = 0; i < length; i++) 28 | { 29 | Serial.print((char)payload[i]); 30 | } 31 | Serial.println(); 32 | } 33 | 34 | void setup() 35 | { 36 | Serial.begin(115200); 37 | Ethernet.begin(mac); //初始化以太网 38 | 39 | 40 | aliLink.subTopic(FPSTR(setTopic)); //订阅服务器下行消息 41 | aliLink.setCallback(Callbacks); //注册下发消息回调函数 42 | aliLink.begin(FPSTR(DeviceName),FPSTR(ProductKey),FPSTR(DeviceSecret)); //完成初始化配置 三元素(DeviceName,ProductKey,DeviceSecret) 43 | } 44 | void loop() 45 | { 46 | 47 | if (aliLink.state() != 0) // 显示连接错误码,实际项目不需要 48 | { 49 | Serial.println(aliLink.state()); 50 | } 51 | aliLink.loop(); //循环维持心跳与消息触发,应尽可能多的执行 52 | 53 | } 54 | 55 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=aliIotLink 2 | version=0.0.1 3 | author=MiNiQiang 4 | maintainer=MiNiQiang 5 | sentence= 6 | paragraph=Support Arduino, ESP8266, ESP8285, ESP32. 7 | category=Communication 8 | url=https://github.com/MINI-Qiang/aliIotLink 9 | architectures=* 10 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## 阿里云物联网平台的 arduino连接工具包 2 | * 目前实现了订阅消息与平台推送消息的回调 3 | * 只能发布QoS 0消息,可以订阅QoS 0或QoS 1 4 | * 目前已支持 arduino UNO ,MEGA2560 (基于W5100,W5500),esp8266,esp8285,esp32 (wifi) 5 | * 基于[Arduino_Core_STM32](https://github.com/stm32duino/Arduino_Core_STM32) ,可扩展支持STM32系列处理器 F0~F4等 6 | -------------------------------------------------------------------------------- /src/aliIotLink.cpp: -------------------------------------------------------------------------------- 1 | #include "aliIotLink.h" 2 | SHA256 sha256; 3 | 4 | AliIotLink::AliIotLink(PubSubClient& client) 5 | { 6 | _client = &client; 7 | } 8 | void AliIotLink::begin() 9 | { 10 | //randomSeed(analogRead(A0)); //获取IO随机值【非安全的伪随机】作为种子 11 | //delayMicroseconds(random(0,10000)); //延迟随机时间 12 | 13 | generateClientId(); 14 | readUrl(); 15 | readUser(); 16 | readPasswd(); 17 | _client->setServer(_URL.c_str(),_port); //写入服务器名称与端口号 18 | 19 | } 20 | 21 | 22 | void AliIotLink::begin(String __DeviceName,String __ProductKey,String __DeviceSecret) 23 | { 24 | _Id = __DeviceName; 25 | _DeviceName = __DeviceName; 26 | _ProductKey = __ProductKey; 27 | _DeviceSecret = __DeviceSecret; 28 | //randomSeed(analogRead(A0)); 29 | //delayMicroseconds(random(0,10000)); 30 | generateClientId(); 31 | readUrl(); 32 | readUser(); 33 | readPasswd(); 34 | _client->setServer(_URL.c_str(),_port); //写入服务器名称与端口号 35 | } 36 | 37 | void AliIotLink::writeUrl(String __ServerUrl) // 设置登录网址 38 | { 39 | //_ServerUrl = __ServerUrl; 40 | } 41 | //服务器端口设置 42 | void AliIotLink::writePort(uint16_t __port) 43 | { 44 | _port = __port; 45 | } 46 | //硬件设备名称 47 | void AliIotLink::writeID(String __Id) 48 | { 49 | _Id = __Id; 50 | } 51 | // 设置设备硬件标签名称【阿里云提供】 52 | void AliIotLink::writeDeviceName(String __DeviceName) 53 | { 54 | _DeviceName = __DeviceName; 55 | } 56 | //【阿里云提供】 57 | void AliIotLink::writeProductKey(String __ProductKey) 58 | { 59 | _ProductKey = __ProductKey; 60 | } 61 | //【阿里云提供】 62 | void AliIotLink::writeDeviceSecret(String __DeviceSecret) 63 | { 64 | _DeviceSecret = __DeviceSecret; 65 | } 66 | 67 | void AliIotLink::generateClientId() 68 | { 69 | //ID+参数+随机数+结尾符号 70 | randomSeed(micros()); 71 | Times =random(0, 65535); 72 | _ClientId = _Id + "|securemode=3,signmethod=hmacsha256,timestamp=" + Times +"|"; 73 | 74 | } 75 | 76 | //获取合成好的登录用的ClientId 77 | String AliIotLink::readClientId() 78 | { 79 | return _ClientId; 80 | } 81 | 82 | 83 | //合成访问网址 84 | String AliIotLink::readUrl() 85 | { 86 | 87 | _URL = _ProductKey + "." + "iot-as-mqtt.cn-shanghai.aliyuncs.com"; 88 | return _URL; 89 | } 90 | 91 | //合成访问用户名 92 | String AliIotLink::readUser() 93 | { 94 | _Username = _DeviceName + "&" + _ProductKey ; 95 | return _Username; 96 | } 97 | 98 | 99 | //合成访问密码 100 | String AliIotLink::readPasswd() 101 | { 102 | String _Passwd = "clientId" + _Id + "deviceName" + _DeviceName +"productKey"+_ProductKey + "timestamp" + Times; 103 | _PasswdHash = ""; 104 | 105 | byte hashData[64]; 106 | 107 | HMAC(_DeviceSecret.c_str(), 32, _Passwd.c_str(), _Passwd.length(), hashData); 108 | 109 | for (int i = 0; i < 32; i++) //hash 固定长度 110 | { 111 | _PasswdHash = _PasswdHash + "0123456789ABCDEF"[hashData[i] >> 4]; 112 | _PasswdHash = _PasswdHash + "0123456789ABCDEF"[hashData[i] & 0xf]; 113 | } 114 | 115 | //return _PasswdHash; //返回HASH密文 116 | } 117 | 118 | 119 | 120 | //===================mqtt部分===================== 121 | 122 | bool AliIotLink::connect() 123 | { 124 | 125 | 126 | return _client->connect(_ClientId.c_str(),_Username.c_str(),_PasswdHash.c_str()); //像服务器传递 ClientId,用户名,密码 127 | 128 | 129 | } 130 | 131 | //重连 132 | void AliIotLink::reconnect() 133 | { 134 | 135 | while(!_client->connected()) //检查网络网络是否不正常,断开的网络会锁定重试 136 | { 137 | 138 | if (connect()) //重连并判断是否成功 139 | { 140 | 141 | //成功 142 | for(byte a = 0;aconnected()) 163 | { 164 | reconnect(); 165 | } 166 | _client->loop(); 167 | } 168 | 169 | 170 | int AliIotLink::state() //错误消息返回 171 | { 172 | return _client->state(); 173 | } 174 | 175 | 176 | 177 | //回调函数 178 | void AliIotLink::setCallback(MQTT_CALLBACK_SIGNATURE) 179 | { 180 | _client->setCallback(callback); 181 | //SerialUSB.println(callback); 182 | } 183 | //监听Topic 184 | void AliIotLink::subscribe(const char* topic) 185 | { 186 | _client->subscribe(topic); 187 | } 188 | //推送消息 189 | void AliIotLink::publish(const char* topic, const char* payload) 190 | { 191 | _client->publish(topic,payload); 192 | } 193 | 194 | 195 | //登记topic 196 | void AliIotLink::subTopic(String topic) 197 | { 198 | TopicName[TopicNum] = topic; 199 | TopicNum++; 200 | if(TopicNum > MQTT_Topic_Quantity) 201 | { 202 | TopicNum = MQTT_Topic_Quantity; 203 | } 204 | } 205 | 206 | void AliIotLink::HMAC( char const *key, byte KeySize, char const *data, byte dataSize, byte *hashData) 207 | { 208 | uint8_t result[32]; 209 | sha256.resetHMAC(key, KeySize); //传入KEY,和key长度 210 | sha256.update(data, dataSize);// 传输 hash明文 211 | sha256.finalizeHMAC(key, KeySize, result, sizeof(result)); // 计算 212 | for (byte a = 0; a < sizeof(result); a++) //传出签名 213 | { 214 | *(hashData + a) = result[a]; 215 | } 216 | } -------------------------------------------------------------------------------- /src/aliIotLink.h: -------------------------------------------------------------------------------- 1 | #ifndef aliIotLink_H 2 | #define aliIotLink_H 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #define MQTT_Topic_Quantity 2 11 | #define in3_5 10 12 | 13 | 14 | class AliIotLink 15 | { 16 | public: 17 | AliIotLink(PubSubClient& client); 18 | void begin(); 19 | void begin(String __DeviceName,String __ProductKey,String __DeviceSecret); 20 | void writeUrl(String __ServerUrl); // 设置登录网址 21 | void writePort(uint16_t __port); //服务器端口 22 | void writeID(String __Id); //设备ID 23 | void writeDeviceName(String __DeviceName); // 设置设备名称 24 | void writeProductKey(String __ProductKey); 25 | void writeDeviceSecret(String __DeviceSecret); 26 | 27 | void generateClientId(); //获取登录的设备ID 28 | 29 | 30 | 31 | bool connect(); //链接服务器 32 | void subTopic(String topic); //配置订阅topic 33 | void publish(const char* topic, const char * payload); //推送消息 34 | void setCallback(MQTT_CALLBACK_SIGNATURE);//注册回调函数 35 | void reconnect(); 36 | void loop(); //心跳维持与重连 37 | int state(); //错误消息返回 38 | 39 | private: 40 | //私有函数 41 | 42 | void HMAC(char const *key, byte KeySize, char const *data, byte dataSize, byte *hashData); 43 | 44 | void subscribe(const char* topic); //监听Topic 45 | String readClientId(); //获取登录的设备ID 46 | String readUrl(); 47 | String readUser(); 48 | String readPasswd(); 49 | //登录用四元素 50 | 51 | //私有对象 52 | PubSubClient* _client; //mqtt接口 53 | //私有变量 54 | String TopicName[MQTT_Topic_Quantity]; 55 | //String _ServerUrl = "iot-as-mqtt.cn-shanghai.aliyuncs.com"; 56 | String _Id; 57 | //String _ClientIdSuffix = "|securemode=3,signmethod=hmacsha256,timestamp="; 58 | 59 | uint16_t _port = 1883; 60 | uint16_t Times; 61 | uint8_t TopicNum =0; //topic计数器 62 | // 63 | String _URL; 64 | String _ClientId; 65 | String _Username; 66 | String _PasswdHash; 67 | //三元素 68 | String _DeviceName; 69 | String _ProductKey; 70 | String _DeviceSecret; 71 | }; 72 | 73 | 74 | 75 | 76 | #endif -------------------------------------------------------------------------------- /src/modules/Crypto/AES.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015,2018 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_AES_h 24 | #define CRYPTO_AES_h 25 | 26 | #include "BlockCipher.h" 27 | 28 | // Determine which AES implementation to export to applications. 29 | #if defined(ESP32) 30 | #define CRYPTO_AES_ESP32 1 31 | #else 32 | #define CRYPTO_AES_DEFAULT 1 33 | #endif 34 | 35 | #if defined(CRYPTO_AES_DEFAULT) || defined(CRYPTO_DOC) 36 | 37 | class AESTiny128; 38 | class AESTiny256; 39 | class AESSmall128; 40 | class AESSmall256; 41 | 42 | class AESCommon : public BlockCipher 43 | { 44 | public: 45 | virtual ~AESCommon(); 46 | 47 | size_t blockSize() const; 48 | 49 | void encryptBlock(uint8_t *output, const uint8_t *input); 50 | void decryptBlock(uint8_t *output, const uint8_t *input); 51 | 52 | void clear(); 53 | 54 | protected: 55 | AESCommon(); 56 | 57 | /** @cond aes_internal */ 58 | uint8_t rounds; 59 | uint8_t *schedule; 60 | 61 | static void subBytesAndShiftRows(uint8_t *output, const uint8_t *input); 62 | static void inverseShiftRowsAndSubBytes(uint8_t *output, const uint8_t *input); 63 | static void mixColumn(uint8_t *output, uint8_t *input); 64 | static void inverseMixColumn(uint8_t *output, const uint8_t *input); 65 | static void keyScheduleCore(uint8_t *output, const uint8_t *input, uint8_t iteration); 66 | static void applySbox(uint8_t *output, const uint8_t *input); 67 | /** @endcond */ 68 | 69 | friend class AESTiny128; 70 | friend class AESTiny256; 71 | friend class AESSmall128; 72 | friend class AESSmall256; 73 | }; 74 | 75 | class AES128 : public AESCommon 76 | { 77 | public: 78 | AES128(); 79 | virtual ~AES128(); 80 | 81 | size_t keySize() const; 82 | 83 | bool setKey(const uint8_t *key, size_t len); 84 | 85 | private: 86 | uint8_t sched[176]; 87 | }; 88 | 89 | class AES192 : public AESCommon 90 | { 91 | public: 92 | AES192(); 93 | virtual ~AES192(); 94 | 95 | size_t keySize() const; 96 | 97 | bool setKey(const uint8_t *key, size_t len); 98 | 99 | private: 100 | uint8_t sched[208]; 101 | }; 102 | 103 | class AES256 : public AESCommon 104 | { 105 | public: 106 | AES256(); 107 | virtual ~AES256(); 108 | 109 | size_t keySize() const; 110 | 111 | bool setKey(const uint8_t *key, size_t len); 112 | 113 | private: 114 | uint8_t sched[240]; 115 | }; 116 | 117 | class AESTiny256 : public BlockCipher 118 | { 119 | public: 120 | AESTiny256(); 121 | virtual ~AESTiny256(); 122 | 123 | size_t blockSize() const; 124 | size_t keySize() const; 125 | 126 | bool setKey(const uint8_t *key, size_t len); 127 | 128 | void encryptBlock(uint8_t *output, const uint8_t *input); 129 | void decryptBlock(uint8_t *output, const uint8_t *input); 130 | 131 | void clear(); 132 | 133 | private: 134 | uint8_t schedule[32]; 135 | }; 136 | 137 | class AESSmall256 : public AESTiny256 138 | { 139 | public: 140 | AESSmall256(); 141 | virtual ~AESSmall256(); 142 | 143 | bool setKey(const uint8_t *key, size_t len); 144 | 145 | void decryptBlock(uint8_t *output, const uint8_t *input); 146 | 147 | void clear(); 148 | 149 | private: 150 | uint8_t reverse[32]; 151 | }; 152 | 153 | class AESTiny128 : public BlockCipher 154 | { 155 | public: 156 | AESTiny128(); 157 | virtual ~AESTiny128(); 158 | 159 | size_t blockSize() const; 160 | size_t keySize() const; 161 | 162 | bool setKey(const uint8_t *key, size_t len); 163 | 164 | void encryptBlock(uint8_t *output, const uint8_t *input); 165 | void decryptBlock(uint8_t *output, const uint8_t *input); 166 | 167 | void clear(); 168 | 169 | private: 170 | uint8_t schedule[16]; 171 | }; 172 | 173 | class AESSmall128 : public AESTiny128 174 | { 175 | public: 176 | AESSmall128(); 177 | virtual ~AESSmall128(); 178 | 179 | bool setKey(const uint8_t *key, size_t len); 180 | 181 | void decryptBlock(uint8_t *output, const uint8_t *input); 182 | 183 | void clear(); 184 | 185 | private: 186 | uint8_t reverse[16]; 187 | }; 188 | 189 | #endif // CRYPTO_AES_DEFAULT 190 | 191 | #if defined(CRYPTO_AES_ESP32) 192 | 193 | // "hwcrypto/aes.h" includes "rom/aes.h" which defines global enums for 194 | // AES128, AES192, and AES256. The enum definitions interfere with the 195 | // definition of the same-named classes below. The #define's and #undef's 196 | // here work around the problem by defining the enums to different names. 197 | #define AES128 AES128_enum 198 | #define AES192 AES192_enum 199 | #define AES256 AES256_enum 200 | #include "hwcrypto/aes.h" 201 | #undef AES128 202 | #undef AES192 203 | #undef AES256 204 | 205 | class AESCommon : public BlockCipher 206 | { 207 | public: 208 | virtual ~AESCommon(); 209 | 210 | size_t blockSize() const; 211 | size_t keySize() const; 212 | 213 | bool setKey(const uint8_t *key, size_t len); 214 | 215 | void encryptBlock(uint8_t *output, const uint8_t *input); 216 | void decryptBlock(uint8_t *output, const uint8_t *input); 217 | 218 | void clear(); 219 | 220 | protected: 221 | AESCommon(uint8_t keySize); 222 | 223 | private: 224 | esp_aes_context ctx; 225 | }; 226 | 227 | class AES128 : public AESCommon 228 | { 229 | public: 230 | AES128() : AESCommon(16) {} 231 | virtual ~AES128(); 232 | }; 233 | 234 | class AES192 : public AESCommon 235 | { 236 | public: 237 | AES192() : AESCommon(24) {} 238 | virtual ~AES192(); 239 | }; 240 | 241 | class AES256 : public AESCommon 242 | { 243 | public: 244 | AES256() : AESCommon(32) {} 245 | virtual ~AES256(); 246 | }; 247 | 248 | // The ESP32 AES context is so small that it already qualifies as "tiny". 249 | typedef AES128 AESTiny128; 250 | typedef AES256 AESTiny256; 251 | typedef AES128 AESSmall128; 252 | typedef AES256 AESSmall256; 253 | 254 | #endif // CRYPTO_AES_ESP32 255 | 256 | #endif 257 | -------------------------------------------------------------------------------- /src/modules/Crypto/AES192.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "AES.h" 24 | #include "Crypto.h" 25 | #include 26 | 27 | #if defined(CRYPTO_AES_DEFAULT) || defined(CRYPTO_DOC) 28 | 29 | /** 30 | * \class AES192 AES.h 31 | * \brief AES block cipher with 192-bit keys. 32 | * 33 | * \sa AES128, AES256 34 | */ 35 | 36 | /** 37 | * \brief Constructs an AES 192-bit block cipher with no initial key. 38 | * 39 | * This constructor must be followed by a call to setKey() before the 40 | * block cipher can be used for encryption or decryption. 41 | */ 42 | AES192::AES192() 43 | { 44 | rounds = 12; 45 | schedule = sched; 46 | } 47 | 48 | AES192::~AES192() 49 | { 50 | clean(sched); 51 | } 52 | 53 | /** 54 | * \brief Size of a 192-bit AES key in bytes. 55 | * \return Always returns 24. 56 | */ 57 | size_t AES192::keySize() const 58 | { 59 | return 24; 60 | } 61 | 62 | bool AES192::setKey(const uint8_t *key, size_t len) 63 | { 64 | if (len != 24) 65 | return false; 66 | 67 | // Copy the key itself into the first 24 bytes of the schedule. 68 | uint8_t *schedule = sched; 69 | memcpy(schedule, key, 24); 70 | 71 | // Expand the key schedule until we have 208 bytes of expanded key. 72 | uint8_t iteration = 1; 73 | uint8_t n = 24; 74 | uint8_t w = 6; 75 | while (n < 208) { 76 | if (w == 6) { 77 | // Every 24 bytes (6 words) we need to apply the key schedule core. 78 | keyScheduleCore(schedule + 24, schedule + 20, iteration); 79 | schedule[24] ^= schedule[0]; 80 | schedule[25] ^= schedule[1]; 81 | schedule[26] ^= schedule[2]; 82 | schedule[27] ^= schedule[3]; 83 | ++iteration; 84 | w = 0; 85 | } else { 86 | // Otherwise just XOR the word with the one 24 bytes previous. 87 | schedule[24] = schedule[20] ^ schedule[0]; 88 | schedule[25] = schedule[21] ^ schedule[1]; 89 | schedule[26] = schedule[22] ^ schedule[2]; 90 | schedule[27] = schedule[23] ^ schedule[3]; 91 | } 92 | 93 | // Advance to the next word in the schedule. 94 | schedule += 4; 95 | n += 4; 96 | ++w; 97 | } 98 | 99 | return true; 100 | } 101 | 102 | #endif // CRYPTO_AES_DEFAULT 103 | -------------------------------------------------------------------------------- /src/modules/Crypto/AESEsp32.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "AES.h" 24 | #include "Crypto.h" 25 | #include 26 | 27 | // AES implementation for ESP32 using the hardware crypto module. 28 | 29 | #if defined(CRYPTO_AES_ESP32) 30 | 31 | AESCommon::AESCommon(uint8_t keySize) 32 | { 33 | ctx.key_bytes = keySize; 34 | } 35 | 36 | AESCommon::~AESCommon() 37 | { 38 | clean(ctx.key, sizeof(ctx.key)); 39 | } 40 | 41 | size_t AESCommon::blockSize() const 42 | { 43 | return 16; 44 | } 45 | 46 | size_t AESCommon::keySize() const 47 | { 48 | return ctx.key_bytes; 49 | } 50 | 51 | bool AESCommon::setKey(const uint8_t *key, size_t len) 52 | { 53 | if (len == ctx.key_bytes) { 54 | // Do the effect of esp_aes_setkey() which is just a memcpy(). 55 | memcpy(ctx.key, key, len); 56 | return true; 57 | } 58 | return false; 59 | } 60 | 61 | void AESCommon::encryptBlock(uint8_t *output, const uint8_t *input) 62 | { 63 | esp_aes_encrypt(&ctx, input, output); 64 | } 65 | 66 | void AESCommon::decryptBlock(uint8_t *output, const uint8_t *input) 67 | { 68 | esp_aes_decrypt(&ctx, input, output); 69 | } 70 | 71 | void AESCommon::clear() 72 | { 73 | clean(ctx.key, sizeof(ctx.key)); 74 | } 75 | 76 | AES128::~AES128() 77 | { 78 | } 79 | 80 | AES192::~AES192() 81 | { 82 | } 83 | 84 | AES256::~AES256() 85 | { 86 | } 87 | 88 | #endif // CRYPTO_AES_ESP32 89 | -------------------------------------------------------------------------------- /src/modules/Crypto/AuthenticatedCipher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "AuthenticatedCipher.h" 24 | 25 | /** 26 | * \class AuthenticatedCipher AuthenticatedCipher.h 27 | * \brief Abstract base class for authenticated ciphers. 28 | * 29 | * This class abstracts the details of algorithms that provide Authenticated 30 | * Encryption with Associated Data (AEAD). Such algorithms combine 31 | * encryption with message authentication to provide a single primitive. 32 | * 33 | * Authenticated ciphers have four parameters: the secret key, an 34 | * initialization vector (called a "nonce" in the literature), the 35 | * plaintext, and some associated data which is to be authenticated 36 | * with the plaintext but not encrypted. Associated data might be 37 | * sequence numbers, IP addresses, protocol versions, or other information 38 | * that is not secret but is important and unique to the session. 39 | * 40 | * Subclasses encrypt the plaintext content and output the ciphertext. 41 | * Once all plaintext has been processed, the caller should invoke 42 | * computeTag() to obtain the authentication tag to transmit with 43 | * the ciphertext. When the ciphertext is later decrypted, the checkTag() 44 | * function can be used to check that the data is authentic. 45 | * 46 | * Reference: RFC 5116 47 | * 48 | * \sa Cipher 49 | */ 50 | 51 | /** 52 | * \brief Constructs a new authenticated cipher. 53 | */ 54 | AuthenticatedCipher::AuthenticatedCipher() 55 | { 56 | } 57 | 58 | /** 59 | * \brief Destroys this authenticated cipher. 60 | */ 61 | AuthenticatedCipher::~AuthenticatedCipher() 62 | { 63 | } 64 | 65 | /** 66 | * \fn size_t AuthenticatedCipher::tagSize() const 67 | * \brief Returns the size of the authentication tag. 68 | * 69 | * \return The size of the authentication tag in bytes. 70 | * 71 | * By default this function should return the largest tag size supported 72 | * by the authenticated cipher. 73 | * 74 | * \sa computeTag() 75 | */ 76 | 77 | /** 78 | * \fn void AuthenticatedCipher::addAuthData(const void *data, size_t len) 79 | * \brief Adds extra data that will be authenticated but not encrypted. 80 | * 81 | * \param data The extra data to be authenticated. 82 | * \param len The number of bytes of extra data to be authenticated. 83 | * 84 | * This function must be called before the first call to encrypt() or 85 | * decrypt(). That is, it is assumed that all extra data for authentication 86 | * is available before the first payload data block and that it will be 87 | * prepended to the payload for authentication. If the subclass needs to 88 | * process the extra data after the payload, then it is responsible for saving 89 | * \a data away until it is needed during computeTag() or checkTag(). 90 | * 91 | * This function can be called multiple times with separate extra data 92 | * blocks for authentication. All such data will be concatenated into a 93 | * single block for authentication purposes. 94 | */ 95 | 96 | /** 97 | * \fn void AuthenticatedCipher::computeTag(void *tag, size_t len) 98 | * \brief Finalizes the encryption process and computes the authentication tag. 99 | * 100 | * \param tag Points to the buffer to write the tag to. 101 | * \param len The length of the tag, which may be less than tagSize() to 102 | * truncate the tag to the first \a len bytes. 103 | * 104 | * \sa checkTag() 105 | */ 106 | 107 | /** 108 | * \fn bool AuthenticatedCipher::checkTag(const void *tag, size_t len) 109 | * \brief Finalizes the decryption process and checks the authentication tag. 110 | * 111 | * \param tag The tag value from the incoming ciphertext to be checked. 112 | * \param len The length of the tag value in bytes, which may be less 113 | * than tagSize(). 114 | * 115 | * \return Returns true if the \a tag is identical to the first \a len 116 | * bytes of the authentication tag that was calculated during the 117 | * decryption process. Returns false otherwise. 118 | * 119 | * This function must be called after the final block of ciphertext is 120 | * passed to decrypt() to determine if the data could be authenticated. 121 | * 122 | * \note Authenticated cipher modes usually require that if the tag could 123 | * not be verified, then all of the data that was previously decrypted 124 | * must be discarded. It is unwise to use the decrypted data for 125 | * any purpose before it can be verified. Callers are responsible for 126 | * ensuring that any data returned via previous calls to decrypt() is 127 | * discarded if checkTag() returns false. 128 | * 129 | * \sa computeTag() 130 | */ 131 | -------------------------------------------------------------------------------- /src/modules/Crypto/AuthenticatedCipher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_AUTHENTICATEDCIPHER_h 24 | #define CRYPTO_AUTHENTICATEDCIPHER_h 25 | 26 | #include "Cipher.h" 27 | 28 | class AuthenticatedCipher : public Cipher 29 | { 30 | public: 31 | AuthenticatedCipher(); 32 | virtual ~AuthenticatedCipher(); 33 | 34 | virtual size_t tagSize() const = 0; 35 | 36 | virtual void addAuthData(const void *data, size_t len) = 0; 37 | 38 | virtual void computeTag(void *tag, size_t len) = 0; 39 | virtual bool checkTag(const void *tag, size_t len) = 0; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/modules/Crypto/BLAKE2b.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_BLAKE2B_H 24 | #define CRYPTO_BLAKE2B_H 25 | 26 | #include "Hash.h" 27 | 28 | class BLAKE2b : public Hash 29 | { 30 | public: 31 | BLAKE2b(); 32 | virtual ~BLAKE2b(); 33 | 34 | size_t hashSize() const; 35 | size_t blockSize() const; 36 | 37 | void reset(); 38 | void reset(uint8_t outputLength); 39 | void reset(const void *key, size_t keyLen, uint8_t outputLength = 64); 40 | 41 | void update(const void *data, size_t len); 42 | void finalize(void *hash, size_t len); 43 | 44 | void clear(); 45 | 46 | void resetHMAC(const void *key, size_t keyLen); 47 | void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen); 48 | 49 | private: 50 | struct { 51 | uint64_t h[8]; 52 | uint64_t m[16]; 53 | uint64_t lengthLow; 54 | uint64_t lengthHigh; 55 | uint8_t chunkSize; 56 | } state; 57 | 58 | void processChunk(uint64_t f0); 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/modules/Crypto/BLAKE2s.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_BLAKE2S_H 24 | #define CRYPTO_BLAKE2S_H 25 | 26 | #include "Hash.h" 27 | 28 | class BLAKE2s : public Hash 29 | { 30 | public: 31 | BLAKE2s(); 32 | virtual ~BLAKE2s(); 33 | 34 | size_t hashSize() const; 35 | size_t blockSize() const; 36 | 37 | void reset(); 38 | void reset(uint8_t outputLength); 39 | void reset(const void *key, size_t keyLen, uint8_t outputLength = 32); 40 | 41 | void update(const void *data, size_t len); 42 | void finalize(void *hash, size_t len); 43 | 44 | void clear(); 45 | 46 | void resetHMAC(const void *key, size_t keyLen); 47 | void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen); 48 | 49 | private: 50 | struct { 51 | uint32_t h[8]; 52 | uint32_t m[16]; 53 | uint64_t length; 54 | uint8_t chunkSize; 55 | } state; 56 | 57 | void processChunk(uint32_t f0); 58 | }; 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/modules/Crypto/BigNumberUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_BIGNUMBERUTIL_h 24 | #define CRYPTO_BIGNUMBERUTIL_h 25 | 26 | #include 27 | #include 28 | 29 | // Define exactly one of these to 1 to set the size of the basic limb type. 30 | #if defined(__AVR__) || defined(ESP8266) 31 | // 16-bit limbs seem to give the best performance on 8-bit AVR micros. 32 | // They also seem to give better performance on ESP8266 as well. 33 | #define BIGNUMBER_LIMB_8BIT 0 34 | #define BIGNUMBER_LIMB_16BIT 1 35 | #define BIGNUMBER_LIMB_32BIT 0 36 | #define BIGNUMBER_LIMB_64BIT 0 37 | #elif defined(__GNUC__) && __WORDSIZE == 64 38 | // 64-bit system with 128-bit double limbs. 39 | #define BIGNUMBER_LIMB_8BIT 0 40 | #define BIGNUMBER_LIMB_16BIT 0 41 | #define BIGNUMBER_LIMB_32BIT 0 42 | #define BIGNUMBER_LIMB_64BIT 1 43 | #else 44 | // On all other platforms, assume 32-bit is best. 45 | #define BIGNUMBER_LIMB_8BIT 0 46 | #define BIGNUMBER_LIMB_16BIT 0 47 | #define BIGNUMBER_LIMB_32BIT 1 48 | #define BIGNUMBER_LIMB_64BIT 0 49 | #endif 50 | 51 | // Define the limb types to use on this platform. 52 | #if BIGNUMBER_LIMB_8BIT 53 | typedef uint8_t limb_t; 54 | typedef int8_t slimb_t; 55 | typedef uint16_t dlimb_t; 56 | #elif BIGNUMBER_LIMB_16BIT 57 | typedef uint16_t limb_t; 58 | typedef int16_t slimb_t; 59 | typedef uint32_t dlimb_t; 60 | #elif BIGNUMBER_LIMB_32BIT 61 | typedef uint32_t limb_t; 62 | typedef int32_t slimb_t; 63 | typedef uint64_t dlimb_t; 64 | #elif BIGNUMBER_LIMB_64BIT 65 | typedef uint64_t limb_t; 66 | typedef int64_t slimb_t; 67 | typedef unsigned __int128 dlimb_t; 68 | #else 69 | #error "limb_t must be 8, 16, 32, or 64 bits in size" 70 | #endif 71 | 72 | class BigNumberUtil 73 | { 74 | public: 75 | static void unpackLE(limb_t *limbs, size_t count, 76 | const uint8_t *bytes, size_t len); 77 | static void unpackBE(limb_t *limbs, size_t count, 78 | const uint8_t *bytes, size_t len); 79 | static void packLE(uint8_t *bytes, size_t len, 80 | const limb_t *limbs, size_t count); 81 | static void packBE(uint8_t *bytes, size_t len, 82 | const limb_t *limbs, size_t count); 83 | 84 | static limb_t add(limb_t *result, const limb_t *x, 85 | const limb_t *y, size_t size); 86 | static limb_t sub(limb_t *result, const limb_t *x, 87 | const limb_t *y, size_t size); 88 | static void mul(limb_t *result, const limb_t *x, size_t xcount, 89 | const limb_t *y, size_t ycount); 90 | static void reduceQuick(limb_t *result, const limb_t *x, 91 | const limb_t *y, size_t size); 92 | 93 | static limb_t add_P(limb_t *result, const limb_t *x, 94 | const limb_t *y, size_t size); 95 | static limb_t sub_P(limb_t *result, const limb_t *x, 96 | const limb_t *y, size_t size); 97 | static void mul_P(limb_t *result, const limb_t *x, size_t xcount, 98 | const limb_t *y, size_t ycount); 99 | static void reduceQuick_P(limb_t *result, const limb_t *x, 100 | const limb_t *y, size_t size); 101 | 102 | static limb_t isZero(const limb_t *x, size_t size); 103 | 104 | private: 105 | // Constructor and destructor are private - cannot instantiate this class. 106 | BigNumberUtil() {} 107 | ~BigNumberUtil() {} 108 | }; 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /src/modules/Crypto/BlockCipher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "BlockCipher.h" 24 | 25 | /** 26 | * \class BlockCipher BlockCipher.h 27 | * \brief Abstract base class for block ciphers. 28 | * 29 | * Block ciphers always operate in electronic codebook (ECB) mode. 30 | * Higher-level classes such as CFB128 and CTR128 wrap the block cipher to 31 | * create more useful classes for encryption and decryption of bulk data. 32 | * 33 | * References: http://en.wikipedia.org/wiki/Block_cipher, 34 | * http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29 35 | */ 36 | 37 | /** 38 | * \brief Constructs a block cipher. 39 | */ 40 | BlockCipher::BlockCipher() 41 | { 42 | } 43 | 44 | /** 45 | * \brief Destroys this block cipher object. 46 | * 47 | * Subclasses are responsible for clearing temporary key schedules 48 | * and other buffers so as to avoid leaking sensitive information. 49 | * 50 | * \sa clear() 51 | */ 52 | BlockCipher::~BlockCipher() 53 | { 54 | } 55 | 56 | /** 57 | * \fn size_t BlockCipher::blockSize() const 58 | * \brief Size of a single block processed by this cipher, in bytes. 59 | * 60 | * \return Returns the size of a block in bytes. 61 | * 62 | * \sa keySize(), encryptBlock() 63 | */ 64 | 65 | /** 66 | * \fn size_t BlockCipher::keySize() const 67 | * \brief Default size of the key for this block cipher, in bytes. 68 | * 69 | * This value indicates the default, or recommended, size for the key. 70 | * 71 | * \sa setKey(), blockSize() 72 | */ 73 | 74 | /** 75 | * \fn bool BlockCipher::setKey(const uint8_t *key, size_t len) 76 | * \brief Sets the key to use for future encryption and decryption operations. 77 | * 78 | * \param key The key to use. 79 | * \param len The length of the key. 80 | * \return Returns false if the key length is not supported, or the key 81 | * is somehow "weak" and unusable by this cipher. 82 | * 83 | * Use clear() or the destructor to remove the key and any other sensitive 84 | * data from the object once encryption or decryption is complete. 85 | * 86 | * \sa keySize(), clear() 87 | */ 88 | 89 | /** 90 | * \fn void BlockCipher::encryptBlock(uint8_t *output, const uint8_t *input) 91 | * \brief Encrypts a single block using this cipher. 92 | * 93 | * \param output The output buffer to put the ciphertext into. 94 | * Must be at least blockSize() bytes in length. 95 | * \param input The input buffer to read the plaintext from which is 96 | * allowed to overlap with \a output. Must be at least blockSize() 97 | * bytes in length. 98 | * 99 | * \sa decryptBlock(), blockSize() 100 | */ 101 | 102 | /** 103 | * \fn void BlockCipher::decryptBlock(uint8_t *output, const uint8_t *input) 104 | * \brief Decrypts a single block using this cipher. 105 | * 106 | * \param output The output buffer to put the plaintext into. 107 | * Must be at least blockSize() bytes in length. 108 | * \param input The input buffer to read the ciphertext from which is 109 | * allowed to overlap with \a output. Must be at least blockSize() 110 | * bytes in length. 111 | * 112 | * \sa encryptBlock(), blockSize() 113 | */ 114 | 115 | /** 116 | * \fn void BlockCipher::clear() 117 | * \brief Clears all security-sensitive state from this block cipher. 118 | * 119 | * Security-sensitive information includes key schedules and any 120 | * temporary state that is used by encryptBlock() or decryptBlock() 121 | * which is stored in the object itself. 122 | * 123 | * \sa setKey(), encryptBlock(), decryptBlock() 124 | */ 125 | -------------------------------------------------------------------------------- /src/modules/Crypto/BlockCipher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_BLOCKCIPHER_h 24 | #define CRYPTO_BLOCKCIPHER_h 25 | 26 | #include 27 | #include 28 | 29 | class BlockCipher 30 | { 31 | public: 32 | BlockCipher(); 33 | virtual ~BlockCipher(); 34 | 35 | virtual size_t blockSize() const = 0; 36 | virtual size_t keySize() const = 0; 37 | 38 | virtual bool setKey(const uint8_t *key, size_t len) = 0; 39 | 40 | virtual void encryptBlock(uint8_t *output, const uint8_t *input) = 0; 41 | virtual void decryptBlock(uint8_t *output, const uint8_t *input) = 0; 42 | 43 | virtual void clear() = 0; 44 | }; 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/modules/Crypto/CTR.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "CTR.h" 24 | #include "Crypto.h" 25 | #include 26 | 27 | /** 28 | * \class CTRCommon CTR.h 29 | * \brief Concrete base class to assist with implementing CTR mode for 30 | * 128-bit block ciphers. 31 | * 32 | * Reference: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation 33 | * 34 | * \sa CTR 35 | */ 36 | 37 | /** 38 | * \brief Constructs a new cipher in CTR mode. 39 | * 40 | * This constructor should be followed by a call to setBlockCipher(). 41 | */ 42 | CTRCommon::CTRCommon() 43 | : blockCipher(0) 44 | , posn(16) 45 | , counterStart(0) 46 | { 47 | } 48 | 49 | CTRCommon::~CTRCommon() 50 | { 51 | // It is assumed that the subclass will clear sensitive 52 | // information in the block cipher. 53 | clean(counter); 54 | clean(state); 55 | } 56 | 57 | size_t CTRCommon::keySize() const 58 | { 59 | return blockCipher->keySize(); 60 | } 61 | 62 | size_t CTRCommon::ivSize() const 63 | { 64 | return 16; 65 | } 66 | 67 | /** 68 | * \brief Sets the counter size for the IV. 69 | * 70 | * \param size The number of bytes on the end of the counter block 71 | * that are relevant when incrementing, between 1 and 16. 72 | * \return Returns false if the \a size value is not between 1 and 16. 73 | * 74 | * When the counter is incremented during encrypt(), only the last 75 | * \a size bytes are considered relevant. This can be useful 76 | * to improve performance when the higher level protocol specifies that 77 | * only the least significant N bytes "count". The high level protocol 78 | * should explicitly generate a new initial counter value and key long 79 | * before the \a size bytes overflow and wrap around. 80 | * 81 | * By default, the counter size is 16 which is the same as the block size 82 | * of the underlying block cipher. 83 | * 84 | * \sa setIV() 85 | */ 86 | bool CTRCommon::setCounterSize(size_t size) 87 | { 88 | if (size < 1 || size > 16) 89 | return false; 90 | counterStart = 16 - size; 91 | return true; 92 | } 93 | 94 | bool CTRCommon::setKey(const uint8_t *key, size_t len) 95 | { 96 | // Verify the cipher's block size, just in case. 97 | if (blockCipher->blockSize() != 16) 98 | return false; 99 | 100 | // Set the key on the underlying block cipher. 101 | return blockCipher->setKey(key, len); 102 | } 103 | 104 | /** 105 | * \brief Sets the initial counter value to use for future encryption and 106 | * decryption operations. 107 | * 108 | * \param iv The initial counter value which must contain exactly 16 bytes. 109 | * \param len The length of the counter value, which mut be 16. 110 | * \return Returns false if \a len is not exactly 16. 111 | * 112 | * The precise method to generate the initial counter is not defined by 113 | * this class. Usually higher level protocols like SSL/TLS and SSH 114 | * specify how to construct the initial counter value. This class merely 115 | * increments the counter every time a new block of keystream data is needed. 116 | * 117 | * \sa encrypt(), setCounterSize() 118 | */ 119 | bool CTRCommon::setIV(const uint8_t *iv, size_t len) 120 | { 121 | if (len != 16) 122 | return false; 123 | memcpy(counter, iv, len); 124 | posn = 16; 125 | return true; 126 | } 127 | 128 | void CTRCommon::encrypt(uint8_t *output, const uint8_t *input, size_t len) 129 | { 130 | while (len > 0) { 131 | if (posn >= 16) { 132 | // Generate a new encrypted counter block. 133 | blockCipher->encryptBlock(state, counter); 134 | posn = 0; 135 | 136 | // Increment the counter, taking care not to reveal 137 | // any timing information about the starting value. 138 | // We iterate through the entire counter region even 139 | // if we could stop earlier because a byte is non-zero. 140 | uint16_t temp = 1; 141 | uint8_t index = 16; 142 | while (index > counterStart) { 143 | --index; 144 | temp += counter[index]; 145 | counter[index] = (uint8_t)temp; 146 | temp >>= 8; 147 | } 148 | } 149 | uint8_t templen = 16 - posn; 150 | if (templen > len) 151 | templen = len; 152 | len -= templen; 153 | while (templen > 0) { 154 | *output++ = *input++ ^ state[posn++]; 155 | --templen; 156 | } 157 | } 158 | } 159 | 160 | void CTRCommon::decrypt(uint8_t *output, const uint8_t *input, size_t len) 161 | { 162 | encrypt(output, input, len); 163 | } 164 | 165 | void CTRCommon::clear() 166 | { 167 | blockCipher->clear(); 168 | clean(counter); 169 | clean(state); 170 | posn = 16; 171 | } 172 | 173 | /** 174 | * \fn void CTRCommon::setBlockCipher(BlockCipher *cipher) 175 | * \brief Sets the block cipher to use for this CTR object. 176 | * 177 | * \param cipher The block cipher to use to implement CTR mode, 178 | * which must have a block size of 16 bytes (128 bits). 179 | * 180 | * \note This class only works with block ciphers whose block size is 181 | * 16 bytes (128 bits). If the \a cipher has a different block size, 182 | * then setKey() will fail and return false. 183 | */ 184 | 185 | /** 186 | * \class CTR CTR.h 187 | * \brief Implementation of the Counter (CTR) mode for 128-bit block ciphers. 188 | * 189 | * Counter mode converts a block cipher into a stream cipher. The specific 190 | * block cipher is passed as the template parameter T and the key is 191 | * specified via the setKey() function. 192 | * 193 | * Keystream blocks are generated by encrypting an increasing counter value 194 | * and XOR'ing it with each byte of input. The encrypt() and decrypt() 195 | * operations are identical. 196 | * 197 | * The template parameter T must be a concrete subclass of BlockCipher 198 | * indicating the specific block cipher to use. For example, the following 199 | * creates a CTR object using AES256 as the underlying cipher: 200 | * 201 | * \code 202 | * CTR ctr; 203 | * ctr.setKey(key, 32); 204 | * ctr.setIV(iv, 16); 205 | * ctr.setCounterSize(4); 206 | * ctr.encrypt(output, input, len); 207 | * \endcode 208 | * 209 | * In this example, the last 4 bytes of the IV are incremented to count 210 | * blocks. The remaining bytes are left unchanged from block to block. 211 | * 212 | * Reference: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation 213 | * 214 | * \sa CFB, OFB, CBC 215 | */ 216 | 217 | /** 218 | * \fn CTR::CTR() 219 | * \brief Constructs a new CTR object for the 128-bit block cipher T. 220 | */ 221 | -------------------------------------------------------------------------------- /src/modules/Crypto/CTR.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_CTR_h 24 | #define CRYPTO_CTR_h 25 | 26 | #include "Cipher.h" 27 | #include "BlockCipher.h" 28 | 29 | class CTRCommon : public Cipher 30 | { 31 | public: 32 | virtual ~CTRCommon(); 33 | 34 | size_t keySize() const; 35 | size_t ivSize() const; 36 | 37 | bool setCounterSize(size_t size); 38 | 39 | bool setKey(const uint8_t *key, size_t len); 40 | bool setIV(const uint8_t *iv, size_t len); 41 | 42 | void encrypt(uint8_t *output, const uint8_t *input, size_t len); 43 | void decrypt(uint8_t *output, const uint8_t *input, size_t len); 44 | 45 | void clear(); 46 | 47 | protected: 48 | CTRCommon(); 49 | void setBlockCipher(BlockCipher *cipher) { blockCipher = cipher; } 50 | 51 | private: 52 | BlockCipher *blockCipher; 53 | uint8_t counter[16]; 54 | uint8_t state[16]; 55 | uint8_t posn; 56 | uint8_t counterStart; 57 | }; 58 | 59 | template 60 | class CTR : public CTRCommon 61 | { 62 | public: 63 | CTR() { setBlockCipher(&cipher); } 64 | 65 | private: 66 | T cipher; 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /src/modules/Crypto/ChaCha.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_CHACHA_h 24 | #define CRYPTO_CHACHA_h 25 | 26 | #include "Cipher.h" 27 | 28 | class ChaChaPoly; 29 | 30 | class ChaCha : public Cipher 31 | { 32 | public: 33 | explicit ChaCha(uint8_t numRounds = 20); 34 | virtual ~ChaCha(); 35 | 36 | size_t keySize() const; 37 | size_t ivSize() const; 38 | 39 | uint8_t numRounds() const { return rounds; } 40 | void setNumRounds(uint8_t numRounds) { rounds = numRounds; } 41 | 42 | bool setKey(const uint8_t *key, size_t len); 43 | bool setIV(const uint8_t *iv, size_t len); 44 | bool setCounter(const uint8_t *counter, size_t len); 45 | 46 | void encrypt(uint8_t *output, const uint8_t *input, size_t len); 47 | void decrypt(uint8_t *output, const uint8_t *input, size_t len); 48 | 49 | void clear(); 50 | 51 | static void hashCore(uint32_t *output, const uint32_t *input, uint8_t rounds); 52 | 53 | private: 54 | uint8_t block[64]; 55 | uint8_t stream[64]; 56 | uint8_t rounds; 57 | uint8_t posn; 58 | 59 | void keystreamBlock(uint32_t *output); 60 | 61 | friend class ChaChaPoly; 62 | }; 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /src/modules/Crypto/ChaChaPoly.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "ChaChaPoly.h" 24 | #include "Crypto.h" 25 | #include "utility/EndianUtil.h" 26 | #include 27 | 28 | /** 29 | * \class ChaChaPoly ChaChaPoly.h 30 | * \brief Authenticated cipher based on ChaCha and Poly1305 31 | * 32 | * ChaChaPoly is an authenticated cipher based on a combination of 33 | * ChaCha with 20 rounds for encryption and Poly1305 for authentication. 34 | * The resulting cipher has a 256-bit key, a 64-bit or 96-bit 35 | * initialization vector, and a 128-bit authentication tag. 36 | * 37 | * Reference: https://tools.ietf.org/html/draft-irtf-cfrg-chacha20-poly1305-10 38 | * 39 | * \sa ChaCha, Poly1305, AuthenticatedCipher 40 | */ 41 | 42 | /** 43 | * \brief Constructs a new ChaChaPoly authenticated cipher. 44 | */ 45 | ChaChaPoly::ChaChaPoly() 46 | { 47 | state.authSize = 0; 48 | state.dataSize = 0; 49 | state.dataStarted = false; 50 | state.ivSize = 8; 51 | } 52 | 53 | /** 54 | * \brief Destroys this ChaChaPoly authenticated cipher. 55 | */ 56 | ChaChaPoly::~ChaChaPoly() 57 | { 58 | clean(state); 59 | } 60 | 61 | size_t ChaChaPoly::keySize() const 62 | { 63 | // Default key size is 256-bit, but any key size is allowed. 64 | return 32; 65 | } 66 | 67 | size_t ChaChaPoly::ivSize() const 68 | { 69 | // Return 8 but we also support 12-byte nonces in setIV(). 70 | return 8; 71 | } 72 | 73 | size_t ChaChaPoly::tagSize() const 74 | { 75 | // Any tag size between 1 and 16 is supported. 76 | return 16; 77 | } 78 | 79 | bool ChaChaPoly::setKey(const uint8_t *key, size_t len) 80 | { 81 | return chacha.setKey(key, len); 82 | } 83 | 84 | bool ChaChaPoly::setIV(const uint8_t *iv, size_t len) 85 | { 86 | // ChaCha::setIV() supports both 64-bit and 96-bit nonces. 87 | if (!chacha.setIV(iv, len)) 88 | return false; 89 | 90 | // Generate the key and nonce to use for Poly1305. 91 | uint32_t data[16]; 92 | chacha.keystreamBlock(data); 93 | poly1305.reset(data); 94 | memcpy(state.nonce, data + 4, 16); 95 | clean(data); 96 | 97 | // Reset the size counters for the auth data and payload. 98 | state.authSize = 0; 99 | state.dataSize = 0; 100 | state.dataStarted = false; 101 | state.ivSize = len; 102 | return true; 103 | } 104 | 105 | void ChaChaPoly::encrypt(uint8_t *output, const uint8_t *input, size_t len) 106 | { 107 | if (!state.dataStarted) { 108 | poly1305.pad(); 109 | state.dataStarted = true; 110 | } 111 | chacha.encrypt(output, input, len); 112 | poly1305.update(output, len); 113 | state.dataSize += len; 114 | } 115 | 116 | void ChaChaPoly::decrypt(uint8_t *output, const uint8_t *input, size_t len) 117 | { 118 | if (!state.dataStarted) { 119 | poly1305.pad(); 120 | state.dataStarted = true; 121 | } 122 | poly1305.update(input, len); 123 | chacha.encrypt(output, input, len); // encrypt() is the same as decrypt() 124 | state.dataSize += len; 125 | } 126 | 127 | void ChaChaPoly::addAuthData(const void *data, size_t len) 128 | { 129 | if (!state.dataStarted) { 130 | poly1305.update(data, len); 131 | state.authSize += len; 132 | } 133 | } 134 | 135 | void ChaChaPoly::computeTag(void *tag, size_t len) 136 | { 137 | uint64_t sizes[2]; 138 | 139 | // Pad the final Poly1305 block and then hash the sizes. 140 | poly1305.pad(); 141 | sizes[0] = htole64(state.authSize); 142 | sizes[1] = htole64(state.dataSize); 143 | poly1305.update(sizes, sizeof(sizes)); 144 | 145 | // Compute the tag and copy it to the return buffer. 146 | poly1305.finalize(state.nonce, tag, len); 147 | clean(sizes); 148 | } 149 | 150 | bool ChaChaPoly::checkTag(const void *tag, size_t len) 151 | { 152 | // Can never match if the expected tag length is too long. 153 | if (len > 16) 154 | return false; 155 | 156 | // Compute the tag and check it. 157 | uint8_t temp[16]; 158 | computeTag(temp, len); 159 | bool equal = secure_compare(temp, tag, len); 160 | clean(temp); 161 | return equal; 162 | } 163 | 164 | void ChaChaPoly::clear() 165 | { 166 | chacha.clear(); 167 | poly1305.clear(); 168 | clean(state); 169 | state.ivSize = 8; 170 | } 171 | -------------------------------------------------------------------------------- /src/modules/Crypto/ChaChaPoly.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_CHACHAPOLY_H 24 | #define CRYPTO_CHACHAPOLY_H 25 | 26 | #include "AuthenticatedCipher.h" 27 | #include "ChaCha.h" 28 | #include "Poly1305.h" 29 | 30 | class ChaChaPoly : public AuthenticatedCipher 31 | { 32 | public: 33 | ChaChaPoly(); 34 | virtual ~ChaChaPoly(); 35 | 36 | size_t keySize() const; 37 | size_t ivSize() const; 38 | size_t tagSize() const; 39 | 40 | bool setKey(const uint8_t *key, size_t len); 41 | bool setIV(const uint8_t *iv, size_t len); 42 | 43 | void encrypt(uint8_t *output, const uint8_t *input, size_t len); 44 | void decrypt(uint8_t *output, const uint8_t *input, size_t len); 45 | 46 | void addAuthData(const void *data, size_t len); 47 | 48 | void computeTag(void *tag, size_t len); 49 | bool checkTag(const void *tag, size_t len); 50 | 51 | void clear(); 52 | 53 | private: 54 | ChaCha chacha; 55 | Poly1305 poly1305; 56 | struct { 57 | uint8_t nonce[16]; 58 | uint64_t authSize; 59 | uint64_t dataSize; 60 | bool dataStarted; 61 | uint8_t ivSize; 62 | } state; 63 | }; 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/modules/Crypto/Cipher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "Cipher.h" 24 | 25 | /** 26 | * \class Cipher Cipher.h 27 | * \brief Abstract base class for stream ciphers. 28 | * 29 | * This class is intended for implementing ciphers that operate on arbitrary 30 | * amounts of data. In particular, stream ciphers where the number of 31 | * bytes that are input to encrypt() or decrypt() is exactly the same as 32 | * the number of bytes that are output. 33 | * 34 | * All of the stream ciphers such as ChaCha inherit directly from this class, 35 | * together with block cipher modes such as CTR and CFB. 36 | */ 37 | 38 | /** 39 | * \brief Constructs a new cipher object. 40 | */ 41 | Cipher::Cipher() 42 | { 43 | } 44 | 45 | /** 46 | * \brief Destroys this cipher object. 47 | * 48 | * Subclasses are responsible for clearing temporary key schedules 49 | * and other buffers so as to avoid leaking sensitive information. 50 | * 51 | * \sa clear() 52 | */ 53 | Cipher::~Cipher() 54 | { 55 | } 56 | 57 | /** 58 | * \fn size_t Cipher::keySize() const 59 | * \brief Default size of the key for this cipher, in bytes. 60 | * 61 | * If the cipher supports variable-sized keys, keySize() indicates the 62 | * default or recommended key size. The cipher may support other key sizes. 63 | * 64 | * \sa setKey(), ivSize() 65 | */ 66 | 67 | /** 68 | * \fn size_t Cipher::ivSize() const 69 | * \brief Size of the initialization vector for this cipher, in bytes. 70 | * 71 | * If the cipher does not need an initialization vector, this function 72 | * will return zero. 73 | */ 74 | 75 | /** 76 | * \fn bool Cipher::setKey(const uint8_t *key, size_t len) 77 | * \brief Sets the key to use for future encryption and decryption operations. 78 | * 79 | * \param key The key to use. 80 | * \param len The length of the key in bytes. 81 | * \return Returns false if the key length is not supported, or the key 82 | * is somehow "weak" and unusable by this cipher. 83 | * 84 | * Use clear() or the destructor to remove the key and any other sensitive 85 | * data from the object once encryption or decryption is complete. 86 | * 87 | * Calling setKey() resets the cipher. Any temporary data that was being 88 | * retained for encrypting partial blocks will be abandoned. 89 | * 90 | * \sa keySize(), clear() 91 | */ 92 | 93 | /** 94 | * \fn bool Cipher::setIV(const uint8_t *iv, size_t len) 95 | * \brief Sets the initialization vector to use for future encryption and 96 | * decryption operations. 97 | * 98 | * \param iv The initialization vector to use. 99 | * \param len The length of the initialization vector in bytes. 100 | * \return Returns false if the length is not supported. 101 | * 102 | * Initialization vectors should be set before the first call to 103 | * encrypt() or decrypt() after a setKey() call. If the initialization 104 | * vector is changed after encryption or decryption begins, 105 | * then the behaviour is undefined. 106 | * 107 | * \note The IV is not encoded into the output stream by encrypt(). 108 | * The caller is responsible for communicating the IV to the other party. 109 | * 110 | * \sa ivSize() 111 | */ 112 | 113 | /** 114 | * \fn void Cipher::encrypt(uint8_t *output, const uint8_t *input, size_t len) 115 | * \brief Encrypts an input buffer and writes the ciphertext to an 116 | * output buffer. 117 | * 118 | * \param output The output buffer to write to, which may be the same 119 | * buffer as \a input. The \a output buffer must have at least as many 120 | * bytes as the \a input buffer. 121 | * \param input The input buffer to read from. 122 | * \param len The number of bytes to encrypt. 123 | * 124 | * The encrypt() function can be called multiple times with different 125 | * regions of the plaintext data. 126 | * 127 | * \sa decrypt() 128 | */ 129 | 130 | /** 131 | * \fn void Cipher::decrypt(uint8_t *output, const uint8_t *input, size_t len) 132 | * \brief Decrypts an input buffer and writes the plaintext to an 133 | * output buffer. 134 | * 135 | * \param output The output buffer to write to, which may be the same 136 | * buffer as \a input. The \a output buffer must have at least as many 137 | * bytes as the \a input buffer. 138 | * \param input The input buffer to read from. 139 | * \param len The number of bytes to decrypt. 140 | * 141 | * The decrypt() function can be called multiple times with different 142 | * regions of the ciphertext data. 143 | * 144 | * \sa encrypt() 145 | */ 146 | 147 | /** 148 | * \fn void Cipher::clear() 149 | * \brief Clears all security-sensitive state from this cipher. 150 | * 151 | * Security-sensitive information includes key schedules, initialization 152 | * vectors, and any temporary state that is used by encrypt() or decrypt() 153 | * which is stored in the cipher itself. 154 | */ 155 | -------------------------------------------------------------------------------- /src/modules/Crypto/Cipher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_CIPHER_h 24 | #define CRYPTO_CIPHER_h 25 | 26 | #include 27 | #include 28 | 29 | class Cipher 30 | { 31 | public: 32 | Cipher(); 33 | virtual ~Cipher(); 34 | 35 | virtual size_t keySize() const = 0; 36 | virtual size_t ivSize() const = 0; 37 | 38 | virtual bool setKey(const uint8_t *key, size_t len) = 0; 39 | virtual bool setIV(const uint8_t *iv, size_t len) = 0; 40 | 41 | virtual void encrypt(uint8_t *output, const uint8_t *input, size_t len) = 0; 42 | virtual void decrypt(uint8_t *output, const uint8_t *input, size_t len) = 0; 43 | 44 | virtual void clear() = 0; 45 | }; 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/modules/Crypto/Crypto.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "Crypto.h" 24 | 25 | /** 26 | * \brief Cleans a block of bytes. 27 | * 28 | * \param dest The destination block to be cleaned. 29 | * \param size The size of the destination to be cleaned in bytes. 30 | * 31 | * Unlike memset(), this function attempts to prevent the compiler 32 | * from optimizing away the clear on a memory buffer. 33 | */ 34 | void clean(void *dest, size_t size) 35 | { 36 | // Force the use of volatile so that we actually clear the memory. 37 | // Otherwise the compiler might optimise the entire contents of this 38 | // function away, which will not be secure. 39 | volatile uint8_t *d = (volatile uint8_t *)dest; 40 | while (size > 0) { 41 | *d++ = 0; 42 | --size; 43 | } 44 | } 45 | 46 | /** 47 | * \fn void clean(T &var) 48 | * \brief Template function that cleans a variable. 49 | * 50 | * \param var A reference to the variable to clean. 51 | * 52 | * The variable will be cleared to all-zeroes in a secure manner. 53 | * Unlike memset(), this function attempts to prevent the compiler 54 | * from optimizing away the variable clear. 55 | */ 56 | 57 | /** 58 | * \brief Compares two memory blocks for equality. 59 | * 60 | * \param data1 Points to the first memory block. 61 | * \param data2 Points to the second memory block. 62 | * \param len The size of the memory blocks in bytes. 63 | * 64 | * Unlike memcmp(), this function attempts to compare the two memory blocks 65 | * in a way that will not reveal the contents in the instruction timing. 66 | * In particular, this function will not stop early if a byte is different. 67 | * It will instead continue onto the end of the array. 68 | */ 69 | bool secure_compare(const void *data1, const void *data2, size_t len) 70 | { 71 | uint8_t result = 0; 72 | const uint8_t *d1 = (const uint8_t *)data1; 73 | const uint8_t *d2 = (const uint8_t *)data2; 74 | while (len > 0) { 75 | result |= (*d1++ ^ *d2++); 76 | --len; 77 | } 78 | return (bool)((((uint16_t)0x0100) - result) >> 8); 79 | } 80 | 81 | /** 82 | * \brief Calculates the CRC-8 value over an array in memory. 83 | * 84 | * \param tag Starting tag to distinguish this calculation. 85 | * \param data The data to checksum. 86 | * \param size The number of bytes to checksum. 87 | * \return The CRC-8 value over the data. 88 | * 89 | * This function does not provide any real security. It is a simple 90 | * check that seed values have been initialized within EEPROM or Flash. 91 | * If the CRC-8 check fails, then it is assumed that the EEPROM/Flash 92 | * contents are invalid and should be re-initialized. 93 | * 94 | * Reference: http://www.sunshine2k.de/articles/coding/crc/understanding_crc.html#ch4 95 | */ 96 | uint8_t crypto_crc8(uint8_t tag, const void *data, unsigned size) 97 | { 98 | const uint8_t *d = (const uint8_t *)data; 99 | uint8_t crc = 0xFF ^ tag; 100 | uint8_t bit; 101 | while (size > 0) { 102 | crc ^= *d++; 103 | for (bit = 0; bit < 8; ++bit) { 104 | // if (crc & 0x80) 105 | // crc = (crc << 1) ^ 0x1D; 106 | // else 107 | // crc = (crc << 1); 108 | uint8_t generator = (uint8_t)((((int8_t)crc) >> 7) & 0x1D); 109 | crc = (crc << 1) ^ generator; 110 | } 111 | --size; 112 | } 113 | return crc; 114 | } 115 | -------------------------------------------------------------------------------- /src/modules/Crypto/Crypto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_h 24 | #define CRYPTO_h 25 | 26 | #include 27 | #include 28 | 29 | void clean(void *dest, size_t size); 30 | 31 | template 32 | inline void clean(T &var) 33 | { 34 | clean(&var, sizeof(T)); 35 | } 36 | 37 | bool secure_compare(const void *data1, const void *data2, size_t len); 38 | 39 | #if defined(ESP8266) 40 | extern "C" void system_soft_wdt_feed(void); 41 | #define crypto_feed_watchdog() system_soft_wdt_feed() 42 | #else 43 | #define crypto_feed_watchdog() do { ; } while (0) 44 | #endif 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/modules/Crypto/Curve25519.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_CURVE25519_h 24 | #define CRYPTO_CURVE25519_h 25 | 26 | #include "BigNumberUtil.h" 27 | 28 | class Ed25519; 29 | 30 | class Curve25519 31 | { 32 | public: 33 | static bool eval(uint8_t result[32], const uint8_t s[32], const uint8_t x[32]); 34 | 35 | static void dh1(uint8_t k[32], uint8_t f[32]); 36 | static bool dh2(uint8_t k[32], uint8_t f[32]); 37 | 38 | #if defined(TEST_CURVE25519_FIELD_OPS) 39 | public: 40 | #else 41 | private: 42 | #endif 43 | static uint8_t isWeakPoint(const uint8_t k[32]); 44 | 45 | static void reduce(limb_t *result, limb_t *x, uint8_t size); 46 | static limb_t reduceQuick(limb_t *x); 47 | 48 | static void mulNoReduce(limb_t *result, const limb_t *x, const limb_t *y); 49 | 50 | static void mul(limb_t *result, const limb_t *x, const limb_t *y); 51 | static void square(limb_t *result, const limb_t *x) 52 | { 53 | mul(result, x, x); 54 | } 55 | 56 | static void mulA24(limb_t *result, const limb_t *x); 57 | 58 | static void mul_P(limb_t *result, const limb_t *x, const limb_t *y); 59 | 60 | static void add(limb_t *result, const limb_t *x, const limb_t *y); 61 | static void sub(limb_t *result, const limb_t *x, const limb_t *y); 62 | 63 | static void cswap(limb_t select, limb_t *x, limb_t *y); 64 | static void cmove(limb_t select, limb_t *x, const limb_t *y); 65 | 66 | static void pow250(limb_t *result, const limb_t *x); 67 | static void recip(limb_t *result, const limb_t *x); 68 | static bool sqrt(limb_t *result, const limb_t *x); 69 | 70 | // Constructor and destructor are private - cannot instantiate this class. 71 | Curve25519() {} 72 | ~Curve25519() {} 73 | 74 | friend class Ed25519; 75 | }; 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /src/modules/Crypto/EAX.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_EAX_h 24 | #define CRYPTO_EAX_h 25 | 26 | #include "AuthenticatedCipher.h" 27 | #include "BlockCipher.h" 28 | #include "OMAC.h" 29 | 30 | class EAXCommon : public AuthenticatedCipher 31 | { 32 | public: 33 | virtual ~EAXCommon(); 34 | 35 | size_t keySize() const; 36 | size_t ivSize() const; 37 | size_t tagSize() const; 38 | 39 | bool setKey(const uint8_t *key, size_t len); 40 | bool setIV(const uint8_t *iv, size_t len); 41 | 42 | void encrypt(uint8_t *output, const uint8_t *input, size_t len); 43 | void decrypt(uint8_t *output, const uint8_t *input, size_t len); 44 | 45 | void addAuthData(const void *data, size_t len); 46 | 47 | void computeTag(void *tag, size_t len); 48 | bool checkTag(const void *tag, size_t len); 49 | 50 | void clear(); 51 | 52 | protected: 53 | EAXCommon(); 54 | void setBlockCipher(BlockCipher *cipher) 55 | { 56 | omac.setBlockCipher(cipher); 57 | } 58 | 59 | private: 60 | struct { 61 | uint8_t counter[16]; 62 | uint8_t stream[16]; 63 | uint8_t tag[16]; 64 | uint8_t hash[16]; 65 | uint8_t encPosn; 66 | uint8_t authMode; 67 | } state; 68 | OMAC omac; 69 | 70 | void closeAuthData(); 71 | void encryptCTR(uint8_t *output, const uint8_t *input, size_t len); 72 | void closeTag(); 73 | }; 74 | 75 | template 76 | class EAX : public EAXCommon 77 | { 78 | public: 79 | EAX() { setBlockCipher(&cipher); } 80 | 81 | private: 82 | T cipher; 83 | }; 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /src/modules/Crypto/Ed25519.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_ED25519_h 24 | #define CRYPTO_ED25519_h 25 | 26 | #include "BigNumberUtil.h" 27 | #include "SHA512.h" 28 | 29 | class Ed25519 30 | { 31 | public: 32 | static void sign(uint8_t signature[64], const uint8_t privateKey[32], 33 | const uint8_t publicKey[32], const void *message, 34 | size_t len); 35 | static bool verify(const uint8_t signature[64], const uint8_t publicKey[32], 36 | const void *message, size_t len); 37 | 38 | static void generatePrivateKey(uint8_t privateKey[32]); 39 | static void derivePublicKey(uint8_t publicKey[32], const uint8_t privateKey[32]); 40 | 41 | private: 42 | // Constructor and destructor are private - cannot instantiate this class. 43 | Ed25519(); 44 | ~Ed25519(); 45 | 46 | // Curve point represented in extended homogeneous coordinates. 47 | struct Point 48 | { 49 | limb_t x[32 / sizeof(limb_t)]; 50 | limb_t y[32 / sizeof(limb_t)]; 51 | limb_t z[32 / sizeof(limb_t)]; 52 | limb_t t[32 / sizeof(limb_t)]; 53 | }; 54 | 55 | static void reduceQFromBuffer(limb_t *result, const uint8_t buf[64], limb_t *temp); 56 | static void reduceQ(limb_t *result, limb_t *r); 57 | 58 | static void mul(Point &result, const limb_t *s, Point &p, bool constTime = true); 59 | static void mul(Point &result, const limb_t *s, bool constTime = true); 60 | 61 | static void add(Point &p, const Point &q); 62 | 63 | static bool equal(const Point &p, const Point &q); 64 | 65 | static void encodePoint(uint8_t *buf, Point &point); 66 | static bool decodePoint(Point &point, const uint8_t *buf); 67 | 68 | static void deriveKeys(SHA512 *hash, limb_t *a, const uint8_t privateKey[32]); 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/modules/Crypto/GCM.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_GCM_h 24 | #define CRYPTO_GCM_h 25 | 26 | #include "AuthenticatedCipher.h" 27 | #include "BlockCipher.h" 28 | #include "GHASH.h" 29 | 30 | class GCMCommon : public AuthenticatedCipher 31 | { 32 | public: 33 | virtual ~GCMCommon(); 34 | 35 | size_t keySize() const; 36 | size_t ivSize() const; 37 | size_t tagSize() const; 38 | 39 | bool setKey(const uint8_t *key, size_t len); 40 | bool setIV(const uint8_t *iv, size_t len); 41 | 42 | void encrypt(uint8_t *output, const uint8_t *input, size_t len); 43 | void decrypt(uint8_t *output, const uint8_t *input, size_t len); 44 | 45 | void addAuthData(const void *data, size_t len); 46 | 47 | void computeTag(void *tag, size_t len); 48 | bool checkTag(const void *tag, size_t len); 49 | 50 | void clear(); 51 | 52 | protected: 53 | GCMCommon(); 54 | void setBlockCipher(BlockCipher *cipher) { blockCipher = cipher; } 55 | 56 | private: 57 | BlockCipher *blockCipher; 58 | GHASH ghash; 59 | struct { 60 | uint8_t counter[16]; 61 | uint8_t stream[16]; 62 | uint8_t nonce[16]; 63 | uint64_t authSize; 64 | uint64_t dataSize; 65 | bool dataStarted; 66 | uint8_t posn; 67 | } state; 68 | }; 69 | 70 | template 71 | class GCM : public GCMCommon 72 | { 73 | public: 74 | GCM() { setBlockCipher(&cipher); } 75 | 76 | private: 77 | T cipher; 78 | }; 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /src/modules/Crypto/GF128.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_GF128_h 24 | #define CRYPTO_GF128_h 25 | 26 | #include 27 | 28 | class GF128 29 | { 30 | private: 31 | GF128() {} 32 | ~GF128() {} 33 | 34 | public: 35 | static void mulInit(uint32_t H[4], const void *key); 36 | static void mul(uint32_t Y[4], const uint32_t H[4]); 37 | static void dbl(uint32_t V[4]); 38 | static void dblEAX(uint32_t V[4]); 39 | static void dblXTS(uint32_t V[4]); 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/modules/Crypto/GHASH.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "GHASH.h" 24 | #include "GF128.h" 25 | #include "Crypto.h" 26 | #include 27 | 28 | /** 29 | * \class GHASH GHASH.h 30 | * \brief Implementation of the GHASH message authenticator. 31 | * 32 | * GHASH is the message authentication part of Galois Counter Mode (GCM). 33 | * 34 | * \note GHASH is not the same as GMAC. GHASH implements the low level 35 | * hashing primitive that is used by both GCM and GMAC. GMAC can be 36 | * simulated using GCM and an empty plaintext/ciphertext. 37 | * 38 | * References: NIST SP 800-38D, 39 | * http://en.wikipedia.org/wiki/Galois/Counter_Mode 40 | * 41 | * \sa GCM 42 | */ 43 | 44 | /** 45 | * \brief Constructs a new GHASH message authenticator. 46 | */ 47 | GHASH::GHASH() 48 | { 49 | state.posn = 0; 50 | } 51 | 52 | /** 53 | * \brief Destroys this GHASH message authenticator. 54 | */ 55 | GHASH::~GHASH() 56 | { 57 | clean(state); 58 | } 59 | 60 | /** 61 | * \brief Resets the GHASH message authenticator for a new session. 62 | * 63 | * \param key Points to the 16 byte authentication key. 64 | * 65 | * \sa update(), finalize() 66 | */ 67 | void GHASH::reset(const void *key) 68 | { 69 | GF128::mulInit(state.H, key); 70 | memset(state.Y, 0, sizeof(state.Y)); 71 | state.posn = 0; 72 | } 73 | 74 | /** 75 | * \brief Updates the message authenticator with more data. 76 | * 77 | * \param data Data to be hashed. 78 | * \param len Number of bytes of data to be hashed. 79 | * 80 | * If finalize() has already been called, then the behavior of update() will 81 | * be undefined. Call reset() first to start a new authentication process. 82 | * 83 | * \sa pad(), reset(), finalize() 84 | */ 85 | void GHASH::update(const void *data, size_t len) 86 | { 87 | // XOR the input with state.Y in 128-bit chunks and process them. 88 | const uint8_t *d = (const uint8_t *)data; 89 | while (len > 0) { 90 | uint8_t size = 16 - state.posn; 91 | if (size > len) 92 | size = len; 93 | uint8_t *y = ((uint8_t *)state.Y) + state.posn; 94 | for (uint8_t i = 0; i < size; ++i) 95 | y[i] ^= d[i]; 96 | state.posn += size; 97 | len -= size; 98 | d += size; 99 | if (state.posn == 16) { 100 | GF128::mul(state.Y, state.H); 101 | state.posn = 0; 102 | } 103 | } 104 | } 105 | 106 | /** 107 | * \brief Finalizes the authentication process and returns the token. 108 | * 109 | * \param token The buffer to return the token value in. 110 | * \param len The length of the \a token buffer between 0 and 16. 111 | * 112 | * If \a len is less than 16, then the token value will be truncated to 113 | * the first \a len bytes. If \a len is greater than 16, then the remaining 114 | * bytes will left unchanged. 115 | * 116 | * If finalize() is called again, then the returned \a token value is 117 | * undefined. Call reset() first to start a new authentication process. 118 | * 119 | * \sa reset(), update() 120 | */ 121 | void GHASH::finalize(void *token, size_t len) 122 | { 123 | // Pad with zeroes to a multiple of 16 bytes. 124 | pad(); 125 | 126 | // The token is the current value of Y. 127 | if (len > 16) 128 | len = 16; 129 | memcpy(token, state.Y, len); 130 | } 131 | 132 | /** 133 | * \brief Pads the input stream with zero bytes to a multiple of 16. 134 | * 135 | * \sa update() 136 | */ 137 | void GHASH::pad() 138 | { 139 | if (state.posn != 0) { 140 | // Padding involves XOR'ing the rest of state.Y with zeroes, 141 | // which does nothing. Immediately process the next chunk. 142 | GF128::mul(state.Y, state.H); 143 | state.posn = 0; 144 | } 145 | } 146 | 147 | /** 148 | * \brief Clears the authenticator's state, removing all sensitive data. 149 | */ 150 | void GHASH::clear() 151 | { 152 | clean(state); 153 | } 154 | -------------------------------------------------------------------------------- /src/modules/Crypto/GHASH.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_GHASH_h 24 | #define CRYPTO_GHASH_h 25 | 26 | #include 27 | #include 28 | 29 | class GHASH 30 | { 31 | public: 32 | GHASH(); 33 | ~GHASH(); 34 | 35 | void reset(const void *key); 36 | void update(const void *data, size_t len); 37 | void finalize(void *token, size_t len); 38 | 39 | void pad(); 40 | 41 | void clear(); 42 | 43 | private: 44 | struct { 45 | uint32_t H[4]; 46 | uint32_t Y[4]; 47 | uint8_t posn; 48 | } state; 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/modules/Crypto/Hash.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "Hash.h" 24 | #include 25 | 26 | /** 27 | * \class Hash Hash.h 28 | * \brief Abstract base class for cryptographic hash algorithms. 29 | * 30 | * \sa SHA256, SHA3_256, BLAKE2s 31 | */ 32 | 33 | /** 34 | * \brief Constructs a new hash object. 35 | */ 36 | Hash::Hash() 37 | { 38 | } 39 | 40 | /** 41 | * \brief Destroys this hash object. 42 | * 43 | * \note Subclasses are responsible for clearing any sensitive data 44 | * that remains in the hash object when it is destroyed. 45 | * 46 | * \sa clear() 47 | */ 48 | Hash::~Hash() 49 | { 50 | } 51 | 52 | /** 53 | * \fn size_t Hash::hashSize() const 54 | * \brief Size of the hash result from finalize(). 55 | * 56 | * \sa finalize(), blockSize() 57 | */ 58 | 59 | /** 60 | * \fn size_t Hash::blockSize() const 61 | * \brief Size of the internal block used by the hash algorithm. 62 | * 63 | * \sa update(), hashSize() 64 | */ 65 | 66 | /** 67 | * \fn void Hash::reset() 68 | * \brief Resets the hash ready for a new hashing process. 69 | * 70 | * \sa update(), finalize(), resetHMAC() 71 | */ 72 | 73 | /** 74 | * \fn void Hash::update(const void *data, size_t len) 75 | * \brief Updates the hash with more data. 76 | * 77 | * \param data Data to be hashed. 78 | * \param len Number of bytes of data to be hashed. 79 | * 80 | * If finalize() has already been called, then the behavior of update() will 81 | * be undefined. Call reset() first to start a new hashing process. 82 | * 83 | * \sa reset(), finalize() 84 | */ 85 | 86 | /** 87 | * \fn void Hash::finalize(void *hash, size_t len) 88 | * \brief Finalizes the hashing process and returns the hash. 89 | * 90 | * \param hash The buffer to return the hash value in. 91 | * \param len The length of the \a hash buffer, normally hashSize(). 92 | * 93 | * If \a len is less than hashSize(), then the hash value will be 94 | * truncated to the first \a len bytes. If \a len is greater than 95 | * hashSize(), then the remaining bytes will left unchanged. 96 | * 97 | * If finalize() is called again, then the returned \a hash value is 98 | * undefined. Call reset() first to start a new hashing process. 99 | * 100 | * \sa reset(), update(), finalizeHMAC() 101 | */ 102 | 103 | /** 104 | * \fn void Hash::clear() 105 | * \brief Clears the hash state, removing all sensitive data, and then 106 | * resets the hash ready for a new hashing process. 107 | * 108 | * \sa reset() 109 | */ 110 | 111 | /** 112 | * \fn void Hash::resetHMAC(const void *key, size_t keyLen) 113 | * \brief Resets the hash ready for a new HMAC hashing process. 114 | * 115 | * \param key Points to the HMAC key for the hashing process. 116 | * \param keyLen Size of the HMAC \a key in bytes. 117 | * 118 | * The following example computes a HMAC over a series of data blocks 119 | * with a specific key: 120 | * 121 | * \code 122 | * hash.resetHMAC(key, sizeof(key)); 123 | * hash.update(data1, sizeof(data1)); 124 | * hash.update(data2, sizeof(data2)); 125 | * ... 126 | * hash.update(dataN, sizeof(dataN)); 127 | * hash.finalizeHMAC(key, sizeof(key), hmac, sizeof(hmac)); 128 | * \endcode 129 | * 130 | * The same key must be passed to both resetHMAC() and finalizeHMAC(). 131 | * 132 | * \sa finalizeHMAC(), reset() 133 | */ 134 | 135 | /** 136 | * \fn void Hash::finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen) 137 | * \brief Finalizes the HMAC hashing process and returns the hash. 138 | * 139 | * \param key Points to the HMAC key for the hashing process. The contents 140 | * of this array must be identical to the value passed to resetHMAC(). 141 | * \param keyLen Size of the HMAC \a key in bytes. 142 | * \param hash The buffer to return the hash value in. 143 | * \param hashLen The length of the \a hash buffer, normally hashSize(). 144 | * 145 | * \sa resetHMAC(), finalize() 146 | */ 147 | 148 | /** 149 | * \brief Formats a HMAC key into a block. 150 | * 151 | * \param block The block to format the key into. Must be at least 152 | * blockSize() bytes in length. 153 | * \param key Points to the HMAC key for the hashing process. 154 | * \param len Length of the HMAC \a key in bytes. 155 | * \param pad Inner (0x36) or outer (0x5C) padding value to XOR with 156 | * the formatted HMAC key. 157 | * 158 | * This function is intended to help subclasses implement resetHMAC() and 159 | * finalizeHMAC() by directly formatting the HMAC key into the subclass's 160 | * internal block buffer and resetting the hash. 161 | */ 162 | void Hash::formatHMACKey(void *block, const void *key, size_t len, uint8_t pad) 163 | { 164 | size_t size = blockSize(); 165 | reset(); 166 | if (len <= size) { 167 | memcpy(block, key, len); 168 | } else { 169 | update(key, len); 170 | len = hashSize(); 171 | finalize(block, len); 172 | reset(); 173 | } 174 | uint8_t *b = (uint8_t *)block; 175 | memset(b + len, pad, size - len); 176 | while (len > 0) { 177 | *b++ ^= pad; 178 | --len; 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/modules/Crypto/Hash.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_HASH_h 24 | #define CRYPTO_HASH_h 25 | 26 | #include 27 | #include 28 | 29 | class Hash 30 | { 31 | public: 32 | Hash(); 33 | virtual ~Hash(); 34 | 35 | virtual size_t hashSize() const = 0; 36 | virtual size_t blockSize() const = 0; 37 | 38 | virtual void reset() = 0; 39 | virtual void update(const void *data, size_t len) = 0; 40 | virtual void finalize(void *hash, size_t len) = 0; 41 | 42 | virtual void clear() = 0; 43 | 44 | virtual void resetHMAC(const void *key, size_t keyLen) = 0; 45 | virtual void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen) = 0; 46 | 47 | protected: 48 | void formatHMACKey(void *block, const void *key, size_t len, uint8_t pad); 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/modules/Crypto/KeccakCore.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_KECCAKCORE_H 24 | #define CRYPTO_KECCAKCORE_H 25 | 26 | #include 27 | #include 28 | 29 | class KeccakCore 30 | { 31 | public: 32 | KeccakCore(); 33 | ~KeccakCore(); 34 | 35 | size_t capacity() const; 36 | void setCapacity(size_t capacity); 37 | 38 | size_t blockSize() const { return _blockSize; } 39 | 40 | void reset(); 41 | 42 | void update(const void *data, size_t size); 43 | void pad(uint8_t tag); 44 | 45 | void extract(void *data, size_t size); 46 | void encrypt(void *output, const void *input, size_t size); 47 | 48 | void clear(); 49 | 50 | void setHMACKey(const void *key, size_t len, uint8_t pad, size_t hashSize); 51 | 52 | private: 53 | struct { 54 | uint64_t A[5][5]; 55 | uint8_t inputSize; 56 | uint8_t outputSize; 57 | } state; 58 | uint8_t _blockSize; 59 | 60 | void keccakp(); 61 | }; 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/modules/Crypto/NoiseSource.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "NoiseSource.h" 24 | #include "RNG.h" 25 | 26 | /** 27 | * \class NoiseSource NoiseSource.h 28 | * \brief Abstract base class for random noise sources. 29 | * 30 | * \sa \link RNGClass RNG\endlink, TransistorNoiseSource 31 | */ 32 | 33 | /** 34 | * \brief Constructs a new random noise source. 35 | */ 36 | NoiseSource::NoiseSource() 37 | { 38 | } 39 | 40 | /** 41 | * \brief Destroys this random noise source. 42 | */ 43 | NoiseSource::~NoiseSource() 44 | { 45 | } 46 | 47 | /** 48 | * \fn bool NoiseSource::calibrating() const 49 | * \brief Determine if the noise source is still calibrating itself. 50 | * 51 | * \return Returns true if calibration is in progress; false if the noise 52 | * source is generating valid random data. 53 | * 54 | * Noise sources that require calibration start doing so at system startup 55 | * and then switch over to random data generation once calibration is complete. 56 | * Since no random data is being generated during calibration, the output 57 | * from \link RNGClass::rand() RNG.rand()\endlink may be predictable. 58 | * Use \link RNGClass::available() RNG.available()\endlink to determine 59 | * when sufficient entropy is available to generate good random values. 60 | * 61 | * It is possible that the noise source never exits calibration. This can 62 | * happen if the input voltage is insufficient to trigger noise or if the 63 | * noise source is not connected. Noise sources may also periodically 64 | * recalibrate themselves. 65 | * 66 | * \sa stir() 67 | */ 68 | 69 | /** 70 | * \fn void NoiseSource::stir() 71 | * \brief Stirs entropy from this noise source into the global random 72 | * number pool. 73 | * 74 | * This function should call output() to add the entropy from this noise 75 | * source to the global random number pool. 76 | * 77 | * The noise source should batch up the entropy data, providing between 78 | * 16 and 48 bytes of data each time. If the noise source does not have 79 | * sufficient entropy data at the moment, it should return without stiring 80 | * the current data in. 81 | * 82 | * \sa calibrating(), output() 83 | */ 84 | 85 | /** 86 | * \brief Called when the noise source is added to RNG with 87 | * \link RNGClass::addNoiseSource() RNG.addNoiseSource()\endlink. 88 | * 89 | * This function is intended for noise source initialization tasks that 90 | * must be performed after \link RNGClass::begin() RNG.begin()\endlink 91 | * has been called to initialize the global random number pool. 92 | * For example, if the noise source has a unique identifier or serial 93 | * number then this function can stir it into the pool at startup time. 94 | */ 95 | void NoiseSource::added() 96 | { 97 | // Nothing to do here. 98 | } 99 | 100 | /** 101 | * \brief Called from subclasses to output noise to the global random 102 | * number pool. 103 | * 104 | * \param data Points to the noise data. 105 | * \param len Number of bytes of noise data. 106 | * \param credit The number of bits of entropy to credit for the data. 107 | * Note that this is bits, not bytes. 108 | * 109 | * The default implementation of this function calls 110 | * \link RNGClass::stir() RNG.stir()\endlink to add the entropy from 111 | * this noise source to the global random number pool. 112 | * 113 | * This function may be overridden by subclasses to capture the raw 114 | * output from the noise source before it is mixed into the pool to 115 | * allow the raw data to be analyzed for randomness. 116 | */ 117 | void NoiseSource::output(const uint8_t *data, size_t len, unsigned int credit) 118 | { 119 | RNG.stir(data, len, credit); 120 | } 121 | -------------------------------------------------------------------------------- /src/modules/Crypto/NoiseSource.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_NOISESOURCE_H 24 | #define CRYPTO_NOISESOURCE_H 25 | 26 | #include 27 | #include 28 | 29 | class NoiseSource 30 | { 31 | public: 32 | NoiseSource(); 33 | virtual ~NoiseSource(); 34 | 35 | virtual bool calibrating() const = 0; 36 | virtual void stir() = 0; 37 | 38 | virtual void added(); 39 | 40 | protected: 41 | virtual void output(const uint8_t *data, size_t len, unsigned int credit); 42 | }; 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/modules/Crypto/OMAC.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "OMAC.h" 24 | #include "GF128.h" 25 | #include "Crypto.h" 26 | #include 27 | 28 | /** 29 | * \class OMAC OMAC.h 30 | * \brief Implementation of the OMAC message authenticator. 31 | * 32 | * OMAC is the message authentication part of EAX mode. It is provided 33 | * as a separate class for the convenience of applications that need 34 | * message authentication separate from encryption. 35 | * 36 | * References: https://en.wikipedia.org/wiki/EAX_mode, 37 | * http://web.cs.ucdavis.edu/~rogaway/papers/eax.html 38 | * 39 | * \sa EAX 40 | */ 41 | 42 | /** 43 | * \brief Constructs a new OMAC object. 44 | * 45 | * This constructor must be followed by a call to setBlockCipher() 46 | * to specify the block cipher to use. 47 | */ 48 | OMAC::OMAC() 49 | : _blockCipher(0) 50 | , posn(0) 51 | { 52 | } 53 | 54 | /** 55 | * \brief Destroys this OMAC object. 56 | * 57 | * \sa clear() 58 | */ 59 | OMAC::~OMAC() 60 | { 61 | clean(b); 62 | } 63 | 64 | /** 65 | * \fn BlockCipher *OMAC::blockCipher() const 66 | * \brief Gets the block cipher that is in use for this OMAC object. 67 | * 68 | * \sa setBlockCipher() 69 | */ 70 | 71 | /** 72 | * \fn void OMAC::setBlockCipher(BlockCipher *cipher) 73 | * \brief Sets the block cipher to use for this OMAC object. 74 | * 75 | * \param cipher The block cipher to use to implement OMAC. 76 | * This object must have a block size of 128 bits (16 bytes). 77 | * 78 | * \sa blockCipher() 79 | */ 80 | 81 | /** 82 | * \brief Initialises the first OMAC hashing context and creates the B value. 83 | * 84 | * \param omac The OMAC hashing context. 85 | * 86 | * This function must be called first before initNext(), update(), or 87 | * finalize() to create the B value from the OMAC algorithm which is 88 | * used to finalize later hashes. It is assumed that setBlockCipher() 89 | * has already been called. 90 | * 91 | * The tag value for the context is implicitly set to zero, which means 92 | * that the context can be used for ordinary hashing as long as the 93 | * data that follows is non-zero in length. Alternatively, initNext() 94 | * can be called to restart the context with a specific tag. 95 | * 96 | * This function must be called again whenever the block cipher or the 97 | * key changes. 98 | * 99 | * \sa initNext(), update(), finalize() 100 | */ 101 | void OMAC::initFirst(uint8_t omac[16]) 102 | { 103 | // Start the OMAC context. We assume that the data that follows 104 | // will be at least 1 byte in length so that we can encrypt the 105 | // zeroes now to derive the B value. 106 | memset(omac, 0, 16); 107 | _blockCipher->encryptBlock(omac, omac); 108 | posn = 0; 109 | 110 | // Generate the B value from the encrypted block of zeroes. 111 | // We will need this later when finalising the OMAC hashes. 112 | memcpy(b, omac, 16); 113 | GF128::dblEAX(b); 114 | } 115 | 116 | /** 117 | * \brief Initialises or restarts an OMAC hashing context. 118 | * 119 | * \param omac The OMAC hashing context. 120 | * \param tag The tag value indicating which OMAC calculation we are doing. 121 | * 122 | * It is assumed that initFirst() was called previously to create the B 123 | * value for the context. 124 | * 125 | * \sa initFirst(), update(), finalize() 126 | */ 127 | void OMAC::initNext(uint8_t omac[16], uint8_t tag) 128 | { 129 | memset(omac, 0, 15); 130 | omac[15] = tag; 131 | posn = 16; 132 | } 133 | 134 | /** 135 | * \brief Updates an OMAC hashing context with more data. 136 | * 137 | * \param omac The OMAC hashing context. 138 | * \param data Points to the data to be hashed. 139 | * \param size The number of bytes to be hashed. 140 | * 141 | * \sa initFirst(), initNext(), finalize() 142 | */ 143 | void OMAC::update(uint8_t omac[16], const uint8_t *data, size_t size) 144 | { 145 | while (size > 0) { 146 | // Encrypt the current block if it is already full. 147 | if (posn == 16) { 148 | _blockCipher->encryptBlock(omac, omac); 149 | posn = 0; 150 | } 151 | 152 | // XOR the incoming data with the current block. 153 | uint8_t len = 16 - posn; 154 | if (len > size) 155 | len = (uint8_t)size; 156 | for (uint8_t index = 0; index < len; ++index) 157 | omac[posn++] ^= data[index]; 158 | 159 | // Move onto the next block. 160 | size -= len; 161 | data += len; 162 | } 163 | } 164 | 165 | /** 166 | * \brief Finalises an OMAC hashing context. 167 | * 168 | * \param omac The OMAC hashing context on entry, the final OMAC value on exit. 169 | * 170 | * \sa initFirst(), initNext(), update() 171 | */ 172 | void OMAC::finalize(uint8_t omac[16]) 173 | { 174 | // Apply padding if necessary. 175 | if (posn != 16) { 176 | // Need padding: XOR with P = 2 * B. 177 | uint32_t p[4]; 178 | memcpy(p, b, 16); 179 | GF128::dblEAX(p); 180 | omac[posn] ^= 0x80; 181 | for (uint8_t index = 0; index < 16; ++index) 182 | omac[index] ^= ((const uint8_t *)p)[index]; 183 | clean(p); 184 | } else { 185 | // No padding necessary: XOR with B. 186 | for (uint8_t index = 0; index < 16; ++index) 187 | omac[index] ^= ((const uint8_t *)b)[index]; 188 | } 189 | 190 | // Encrypt the hash to get the final OMAC value. 191 | _blockCipher->encryptBlock(omac, omac); 192 | } 193 | 194 | /** 195 | * \brief Clears all security-sensitive state from this object. 196 | */ 197 | void OMAC::clear() 198 | { 199 | clean(b); 200 | } 201 | -------------------------------------------------------------------------------- /src/modules/Crypto/OMAC.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_OMAC_H 24 | #define CRYPTO_OMAC_H 25 | 26 | #include "BlockCipher.h" 27 | 28 | class OMAC 29 | { 30 | public: 31 | OMAC(); 32 | ~OMAC(); 33 | 34 | BlockCipher *blockCipher() const { return _blockCipher; } 35 | void setBlockCipher(BlockCipher *cipher) { _blockCipher = cipher; } 36 | 37 | void initFirst(uint8_t omac[16]); 38 | void initNext(uint8_t omac[16], uint8_t tag); 39 | void update(uint8_t omac[16], const uint8_t *data, size_t size); 40 | void finalize(uint8_t omac[16]); 41 | 42 | void clear(); 43 | 44 | private: 45 | BlockCipher *_blockCipher; 46 | uint32_t b[4]; 47 | uint8_t posn; 48 | }; 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/modules/Crypto/P521.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_P521_h 24 | #define CRYPTO_P521_h 25 | 26 | #include "BigNumberUtil.h" 27 | 28 | class Hash; 29 | 30 | class P521 31 | { 32 | public: 33 | 34 | static bool eval(uint8_t result[132], const uint8_t f[66], const uint8_t point[132]); 35 | 36 | static void dh1(uint8_t k[132], uint8_t f[66]); 37 | static bool dh2(const uint8_t k[132], uint8_t f[66]); 38 | 39 | static void sign(uint8_t signature[132], const uint8_t privateKey[66], 40 | const void *message, size_t len, Hash *hash = 0); 41 | static bool verify(const uint8_t signature[132], 42 | const uint8_t publicKey[132], 43 | const void *message, size_t len, Hash *hash = 0); 44 | 45 | static void generatePrivateKey(uint8_t privateKey[66]); 46 | static void derivePublicKey(uint8_t publicKey[132], const uint8_t privateKey[66]); 47 | 48 | static bool isValidPrivateKey(const uint8_t privateKey[66]); 49 | static bool isValidPublicKey(const uint8_t publicKey[132]); 50 | 51 | static bool isValidCurvePoint(const uint8_t point[132]) 52 | { 53 | return isValidPublicKey(point); 54 | } 55 | 56 | #if defined(TEST_P521_FIELD_OPS) 57 | public: 58 | #else 59 | private: 60 | #endif 61 | static void evaluate(limb_t *x, limb_t *y, const uint8_t f[66]); 62 | 63 | static void addAffine(limb_t *x1, limb_t *y1, 64 | const limb_t *x2, const limb_t *y2); 65 | 66 | static bool validate(const limb_t *x, const limb_t *y); 67 | static bool inRange(const limb_t *x); 68 | 69 | static void reduce(limb_t *result, const limb_t *x); 70 | static void reduceQuick(limb_t *x); 71 | 72 | static void mulNoReduce(limb_t *result, const limb_t *x, const limb_t *y); 73 | 74 | static void mul(limb_t *result, const limb_t *x, const limb_t *y); 75 | static void square(limb_t *result, const limb_t *x) 76 | { 77 | mul(result, x, x); 78 | } 79 | 80 | static void mulLiteral(limb_t *result, const limb_t *x, limb_t y); 81 | 82 | static void add(limb_t *result, const limb_t *x, const limb_t *y); 83 | static void sub(limb_t *result, const limb_t *x, const limb_t *y); 84 | 85 | static void dblPoint(limb_t *xout, limb_t *yout, limb_t *zout, 86 | const limb_t *xin, const limb_t *yin, 87 | const limb_t *zin); 88 | static void addPoint(limb_t *xout, limb_t *yout, limb_t *zout, 89 | const limb_t *x1, const limb_t *y1, 90 | const limb_t *z1, const limb_t *x2, 91 | const limb_t *y2); 92 | 93 | static void cmove(limb_t select, limb_t *x, const limb_t *y); 94 | static void cmove1(limb_t select, limb_t *x); 95 | 96 | static void recip(limb_t *result, const limb_t *x); 97 | 98 | static void reduceQ(limb_t *result, const limb_t *r); 99 | static void mulQ(limb_t *result, const limb_t *x, const limb_t *y); 100 | static void recipQ(limb_t *result, const limb_t *x); 101 | 102 | static void generateK(uint8_t k[66], const uint8_t hm[66], 103 | const uint8_t x[66], Hash *hash, uint64_t count); 104 | static void generateK(uint8_t k[66], const uint8_t hm[66], 105 | const uint8_t x[66], uint64_t count); 106 | 107 | // Constructor and destructor are private - cannot instantiate this class. 108 | P521() {} 109 | ~P521() {} 110 | }; 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /src/modules/Crypto/Poly1305.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_POLY1305_h 24 | #define CRYPTO_POLY1305_h 25 | 26 | #include "BigNumberUtil.h" 27 | #include 28 | 29 | class Poly1305 30 | { 31 | public: 32 | Poly1305(); 33 | ~Poly1305(); 34 | 35 | void reset(const void *key); 36 | void update(const void *data, size_t len); 37 | void finalize(const void *nonce, void *token, size_t len); 38 | 39 | void pad(); 40 | 41 | void clear(); 42 | 43 | private: 44 | struct { 45 | limb_t h[(16 / sizeof(limb_t)) + 1]; 46 | limb_t c[(16 / sizeof(limb_t)) + 1]; 47 | limb_t r[(16 / sizeof(limb_t))]; 48 | uint8_t chunkSize; 49 | } state; 50 | 51 | void processChunk(); 52 | }; 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/modules/Crypto/RNG.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_RNG_h 24 | #define CRYPTO_RNG_h 25 | 26 | #include 27 | #include 28 | 29 | class NoiseSource; 30 | 31 | class RNGClass 32 | { 33 | public: 34 | RNGClass(); 35 | ~RNGClass(); 36 | 37 | void begin(const char *tag); 38 | void addNoiseSource(NoiseSource &source); 39 | 40 | void setAutoSaveTime(uint16_t minutes); 41 | 42 | void rand(uint8_t *data, size_t len); 43 | bool available(size_t len) const; 44 | 45 | void stir(const uint8_t *data, size_t len, unsigned int credit = 0); 46 | 47 | void save(); 48 | 49 | void loop(); 50 | 51 | void destroy(); 52 | 53 | static const int SEED_SIZE = 48; 54 | 55 | private: 56 | uint32_t block[16]; 57 | uint32_t stream[16]; 58 | uint16_t credits : 13; 59 | uint16_t firstSave : 1; 60 | uint16_t initialized : 1; 61 | uint16_t trngPending : 1; 62 | unsigned long timer; 63 | unsigned long timeout; 64 | NoiseSource *noiseSources[4]; 65 | uint8_t count; 66 | uint8_t trngPosn; 67 | 68 | void rekey(); 69 | void mixTRNG(); 70 | }; 71 | 72 | extern RNGClass RNG; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/modules/Crypto/SHA256.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_SHA256_h 24 | #define CRYPTO_SHA256_h 25 | 26 | #include "Hash.h" 27 | 28 | class SHA256 : public Hash 29 | { 30 | public: 31 | SHA256(); 32 | virtual ~SHA256(); 33 | 34 | size_t hashSize() const; 35 | size_t blockSize() const; 36 | 37 | void reset(); 38 | void update(const void *data, size_t len); 39 | void finalize(void *hash, size_t len); 40 | 41 | void clear(); 42 | 43 | void resetHMAC(const void *key, size_t keyLen); 44 | void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen); 45 | 46 | private: 47 | struct { 48 | uint32_t h[8]; 49 | uint32_t w[16]; 50 | uint64_t length; 51 | uint8_t chunkSize; 52 | } state; 53 | 54 | void processChunk(); 55 | }; 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/modules/Crypto/SHA3.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "SHA3.h" 24 | #include "Crypto.h" 25 | 26 | /** 27 | * \class SHA3_256 SHA3.h 28 | * \brief SHA3-256 hash algorithm. 29 | * 30 | * Reference: http://en.wikipedia.org/wiki/SHA-3 31 | * 32 | * \sa SHA3_512 33 | */ 34 | 35 | /** 36 | * \brief Constructs a new SHA3-256 hash object. 37 | */ 38 | SHA3_256::SHA3_256() 39 | { 40 | core.setCapacity(512); 41 | } 42 | 43 | /** 44 | * \brief Destroys this hash object after clearing sensitive information. 45 | */ 46 | SHA3_256::~SHA3_256() 47 | { 48 | // The destructor for the KeccakCore object will do most of the work. 49 | } 50 | 51 | size_t SHA3_256::hashSize() const 52 | { 53 | return 32; 54 | } 55 | 56 | size_t SHA3_256::blockSize() const 57 | { 58 | return core.blockSize(); 59 | } 60 | 61 | void SHA3_256::reset() 62 | { 63 | core.reset(); 64 | } 65 | 66 | void SHA3_256::update(const void *data, size_t len) 67 | { 68 | core.update(data, len); 69 | } 70 | 71 | void SHA3_256::finalize(void *hash, size_t len) 72 | { 73 | // Pad the final block and then extract the hash value. 74 | core.pad(0x06); 75 | core.extract(hash, len); 76 | } 77 | 78 | void SHA3_256::clear() 79 | { 80 | core.clear(); 81 | } 82 | 83 | void SHA3_256::resetHMAC(const void *key, size_t keyLen) 84 | { 85 | core.setHMACKey(key, keyLen, 0x36, 32); 86 | } 87 | 88 | void SHA3_256::finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen) 89 | { 90 | uint8_t temp[32]; 91 | finalize(temp, sizeof(temp)); 92 | core.setHMACKey(key, keyLen, 0x5C, 32); 93 | core.update(temp, sizeof(temp)); 94 | finalize(hash, hashLen); 95 | clean(temp); 96 | } 97 | 98 | /** 99 | * \class SHA3_512 SHA3.h 100 | * \brief SHA3-512 hash algorithm. 101 | * 102 | * Reference: http://en.wikipedia.org/wiki/SHA-3 103 | * 104 | * \sa SHA3_256 105 | */ 106 | 107 | /** 108 | * \brief Constructs a new SHA3-512 hash object. 109 | */ 110 | SHA3_512::SHA3_512() 111 | { 112 | core.setCapacity(1024); 113 | } 114 | 115 | /** 116 | * \brief Destroys this hash object after clearing sensitive information. 117 | */ 118 | SHA3_512::~SHA3_512() 119 | { 120 | // The destructor for the KeccakCore object will do most of the work. 121 | } 122 | 123 | size_t SHA3_512::hashSize() const 124 | { 125 | return 64; 126 | } 127 | 128 | size_t SHA3_512::blockSize() const 129 | { 130 | return core.blockSize(); 131 | } 132 | 133 | void SHA3_512::reset() 134 | { 135 | core.reset(); 136 | } 137 | 138 | void SHA3_512::update(const void *data, size_t len) 139 | { 140 | core.update(data, len); 141 | } 142 | 143 | void SHA3_512::finalize(void *hash, size_t len) 144 | { 145 | // Pad the final block and then extract the hash value. 146 | core.pad(0x06); 147 | core.extract(hash, len); 148 | } 149 | 150 | void SHA3_512::clear() 151 | { 152 | core.clear(); 153 | } 154 | 155 | void SHA3_512::resetHMAC(const void *key, size_t keyLen) 156 | { 157 | core.setHMACKey(key, keyLen, 0x36, 64); 158 | } 159 | 160 | void SHA3_512::finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen) 161 | { 162 | uint8_t temp[64]; 163 | finalize(temp, sizeof(temp)); 164 | core.setHMACKey(key, keyLen, 0x5C, 64); 165 | core.update(temp, sizeof(temp)); 166 | finalize(hash, hashLen); 167 | clean(temp); 168 | } 169 | -------------------------------------------------------------------------------- /src/modules/Crypto/SHA3.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_SHA3_h 24 | #define CRYPTO_SHA3_h 25 | 26 | #include "KeccakCore.h" 27 | #include "Hash.h" 28 | 29 | class SHA3_256 : public Hash 30 | { 31 | public: 32 | SHA3_256(); 33 | virtual ~SHA3_256(); 34 | 35 | size_t hashSize() const; 36 | size_t blockSize() const; 37 | 38 | void reset(); 39 | void update(const void *data, size_t len); 40 | void finalize(void *hash, size_t len); 41 | 42 | void clear(); 43 | 44 | void resetHMAC(const void *key, size_t keyLen); 45 | void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen); 46 | 47 | private: 48 | KeccakCore core; 49 | }; 50 | 51 | class SHA3_512 : public Hash 52 | { 53 | public: 54 | SHA3_512(); 55 | virtual ~SHA3_512(); 56 | 57 | size_t hashSize() const; 58 | size_t blockSize() const; 59 | 60 | void reset(); 61 | void update(const void *data, size_t len); 62 | void finalize(void *hash, size_t len); 63 | 64 | void clear(); 65 | 66 | void resetHMAC(const void *key, size_t keyLen); 67 | void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen); 68 | 69 | private: 70 | KeccakCore core; 71 | }; 72 | 73 | #endif 74 | -------------------------------------------------------------------------------- /src/modules/Crypto/SHA512.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_SHA512_h 24 | #define CRYPTO_SHA512_h 25 | 26 | #include "Hash.h" 27 | 28 | class Ed25519; 29 | 30 | class SHA512 : public Hash 31 | { 32 | public: 33 | SHA512(); 34 | virtual ~SHA512(); 35 | 36 | size_t hashSize() const; 37 | size_t blockSize() const; 38 | 39 | void reset(); 40 | void update(const void *data, size_t len); 41 | void finalize(void *hash, size_t len); 42 | 43 | void clear(); 44 | 45 | void resetHMAC(const void *key, size_t keyLen); 46 | void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen); 47 | 48 | private: 49 | struct { 50 | uint64_t h[8]; 51 | uint64_t w[16]; 52 | uint64_t lengthLow; 53 | uint64_t lengthHigh; 54 | uint8_t chunkSize; 55 | } state; 56 | 57 | void processChunk(); 58 | 59 | friend class Ed25519; 60 | }; 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /src/modules/Crypto/SHAKE.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "SHAKE.h" 24 | 25 | /** 26 | * \class SHAKE SHAKE.h 27 | * \brief Abstract base class for the SHAKE Extendable-Output Functions (XOFs). 28 | * 29 | * Reference: http://en.wikipedia.org/wiki/SHA-3 30 | * 31 | * \sa SHAKE256, SHAKE128, SHA3_256 32 | */ 33 | 34 | /** 35 | * \brief Constructs a SHAKE object. 36 | * 37 | * \param capacity The capacity of the Keccak sponge function in bits which 38 | * should be a multiple of 64 and between 64 and 1536. 39 | */ 40 | SHAKE::SHAKE(size_t capacity) 41 | : finalized(false) 42 | { 43 | core.setCapacity(capacity); 44 | } 45 | 46 | /** 47 | * \brief Destroys this SHAKE object after clearing all sensitive information. 48 | */ 49 | SHAKE::~SHAKE() 50 | { 51 | } 52 | 53 | size_t SHAKE::blockSize() const 54 | { 55 | return core.blockSize(); 56 | } 57 | 58 | void SHAKE::reset() 59 | { 60 | core.reset(); 61 | finalized = false; 62 | } 63 | 64 | void SHAKE::update(const void *data, size_t len) 65 | { 66 | if (finalized) 67 | reset(); 68 | core.update(data, len); 69 | } 70 | 71 | void SHAKE::extend(uint8_t *data, size_t len) 72 | { 73 | if (!finalized) { 74 | core.pad(0x1F); 75 | finalized = true; 76 | } 77 | core.extract(data, len); 78 | } 79 | 80 | void SHAKE::encrypt(uint8_t *output, const uint8_t *input, size_t len) 81 | { 82 | if (!finalized) { 83 | core.pad(0x1F); 84 | finalized = true; 85 | } 86 | core.encrypt(output, input, len); 87 | } 88 | 89 | void SHAKE::clear() 90 | { 91 | core.clear(); 92 | finalized = false; 93 | } 94 | 95 | /** 96 | * \class SHAKE128 SHAKE.h 97 | * \brief SHAKE Extendable-Output Function (XOF) with 128-bit security. 98 | * 99 | * Reference: http://en.wikipedia.org/wiki/SHA-3 100 | * 101 | * \sa SHAKE256, SHAKE, SHA3_256 102 | */ 103 | 104 | /** 105 | * \fn SHAKE128::SHAKE128() 106 | * \brief Constructs a SHAKE object with 128-bit security. 107 | */ 108 | 109 | /** 110 | * \brief Destroys this SHAKE128 object after clearing all sensitive 111 | * information. 112 | */ 113 | SHAKE128::~SHAKE128() 114 | { 115 | } 116 | 117 | /** 118 | * \class SHAKE256 SHAKE.h 119 | * \brief SHAKE Extendable-Output Function (XOF) with 256-bit security. 120 | * 121 | * Reference: http://en.wikipedia.org/wiki/SHA-3 122 | * 123 | * \sa SHAKE128, SHAKE, SHA3_256 124 | */ 125 | 126 | /** 127 | * \fn SHAKE256::SHAKE256() 128 | * \brief Constructs a SHAKE object with 256-bit security. 129 | */ 130 | 131 | /** 132 | * \brief Destroys this SHAKE256 object after clearing all sensitive 133 | * information. 134 | */ 135 | SHAKE256::~SHAKE256() 136 | { 137 | } 138 | -------------------------------------------------------------------------------- /src/modules/Crypto/SHAKE.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_SHAKE_h 24 | #define CRYPTO_SHAKE_h 25 | 26 | #include "XOF.h" 27 | #include "KeccakCore.h" 28 | 29 | class SHAKE : public XOF 30 | { 31 | public: 32 | virtual ~SHAKE(); 33 | 34 | size_t blockSize() const; 35 | 36 | void reset(); 37 | void update(const void *data, size_t len); 38 | 39 | void extend(uint8_t *data, size_t len); 40 | void encrypt(uint8_t *output, const uint8_t *input, size_t len); 41 | 42 | void clear(); 43 | 44 | protected: 45 | SHAKE(size_t capacity); 46 | 47 | private: 48 | KeccakCore core; 49 | bool finalized; 50 | }; 51 | 52 | class SHAKE128 : public SHAKE 53 | { 54 | public: 55 | SHAKE128() : SHAKE(256) {} 56 | virtual ~SHAKE128(); 57 | }; 58 | 59 | class SHAKE256 : public SHAKE 60 | { 61 | public: 62 | SHAKE256() : SHAKE(512) {} 63 | virtual ~SHAKE256(); 64 | }; 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/modules/Crypto/XOF.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #include "XOF.h" 24 | 25 | /** 26 | * \class XOF XOF.h 27 | * \brief Abstract base class for Extendable-Output Functions (XOFs). 28 | * 29 | * Extendable-Output Functions, or XOFs, are a new class of cryptographic 30 | * primitive that was defined by NIST during the SHA-3 standardization 31 | * process. Essentially an XOF is a hash algorithm that has an 32 | * arbitrary-length output instead of a fixed-length digest. 33 | * 34 | * XOFs can be used for a variety of cryptographic tasks: 35 | * 36 | * \li Mask generation functions for RSA OAEP style padding. 37 | * \li Key derivation functions for expanding key seed material into 38 | * arbitrary amounts of keying material for a secure session. 39 | * \li Stream ciphers based on a key and IV. 40 | * 41 | * To use an XOF, it is first reset() and then data is added via multiple 42 | * calls to update(): 43 | * 44 | * \code 45 | * SHAKE256 xof; 46 | * xof.reset(); 47 | * xof.update(data1, sizeof(data1)); 48 | * xof.update(data2, sizeof(data2)); 49 | * ... 50 | * \endcode 51 | * 52 | * Once all input data has been added, the XOF switches into extend mode 53 | * to generate the arbitrary-length output data: 54 | * 55 | * \code 56 | * xof.extend(output1, sizeof(output1)); 57 | * xof.extend(output2, sizeof(output2)); 58 | * ... 59 | * \endcode 60 | * 61 | * Mask generation and key derivation is achieved as follows, where the 62 | * key is unique for each invocation: 63 | * 64 | * \code 65 | * SHAKE256 xof; 66 | * xof.reset(); 67 | * xof.update(key, sizeof(key)); 68 | * xof.extend(output, sizeof(output)); 69 | * \endcode 70 | * 71 | * Stream ciphers can be constructed as follows, using the special 72 | * encrypt() function that XOR's the output of extend() with the 73 | * input plaintext to generate the output ciphertext (or alternatively 74 | * XOR's the output of extend() with the ciphertext to recover the 75 | * plaintext): 76 | * 77 | * \code 78 | * SHAKE256 xof; 79 | * xof.reset(); 80 | * xof.update(key, sizeof(key)); 81 | * xof.update(iv, sizeof(iv)); 82 | * xof.encrypt(output1, input1, sizeof(input1)); 83 | * xof.encrypt(output2, input2, sizeof(input2)); 84 | * ... 85 | * \endcode 86 | * 87 | * If the key is reused, then the IV must be different for each session 88 | * or the encryption scheme can be easily broken. It is better to 89 | * generate a new key and IV combination for every session. 90 | * 91 | * It may also be a good idea to include some tag information with the input 92 | * data to distinguish different uses of the XOF. For example: 93 | * 94 | * \code 95 | * SHAKE256 xof; 96 | * xof.reset(); 97 | * xof.update(key, sizeof(key)); 98 | * xof.update(iv, sizeof(iv)); 99 | * xof.update("MyCrypt", 7); 100 | * xof.encrypt(output, input, sizeof(input)); 101 | * \endcode 102 | * 103 | * If the same key and IV was used with a different package, then it would 104 | * not generate the same output as "MyCrypt". 105 | * 106 | * NIST warns that XOFs should not be used in place of hash functions. 107 | * This is because of related outputs: if the same input is provided to 108 | * an XOF with different output lengths, then the shorter output will 109 | * be a prefix of the larger. This breaks the expected collision-resistance 110 | * of regular hash functions. There is typically no need to use an XOF 111 | * for hashing because NIST has already defined SHA3_256 and SHA3_512 112 | * for that purpose. 113 | * 114 | * Reference: http://en.wikipedia.org/wiki/SHA-3 115 | * 116 | * \sa SHAKE256, SHAKE128, SHA3_256 117 | */ 118 | 119 | /** 120 | * \brief Constructs a new XOF object. 121 | */ 122 | XOF::XOF() 123 | { 124 | } 125 | 126 | /** 127 | * \brief Destroys this XOF object. 128 | * 129 | * \note Subclasses are responsible for clearing any sensitive data 130 | * that remains in the XOF object when it is destroyed. 131 | * 132 | * \sa clear() 133 | */ 134 | XOF::~XOF() 135 | { 136 | } 137 | 138 | /** 139 | * \fn size_t XOF::blockSize() const 140 | * \brief Size of the internal block used by the XOF algorithm, in bytes. 141 | * 142 | * \sa update() 143 | */ 144 | 145 | /** 146 | * \fn void XOF::reset() 147 | * \brief Resets the XOF ready for a new session. 148 | * 149 | * \sa update(), extend(), encrypt() 150 | */ 151 | 152 | /** 153 | * \fn void XOF::update(const void *data, size_t len) 154 | * \brief Updates the XOF with more data. 155 | * 156 | * \param data Data to be hashed. 157 | * \param len Number of bytes of data to be added to the XOF. 158 | * 159 | * If extend() or encrypt() has already been called, then the behavior of 160 | * update() will be undefined. Call reset() first to start a new session. 161 | * 162 | * \sa reset(), extend(), encrypt() 163 | */ 164 | 165 | /** 166 | * \fn void XOF::extend(uint8_t *data, size_t len) 167 | * \brief Generates extendable output from this XOF. 168 | * 169 | * \param data The data buffer to be filled. 170 | * \param len The number of bytes to write to \a data. 171 | * 172 | * \sa reset(), update(), encrypt() 173 | */ 174 | 175 | /** 176 | * \fn void XOF::encrypt(uint8_t *output, const uint8_t *input, size_t len) 177 | * \brief Encrypts an input buffer with extendable output from this XOF. 178 | * 179 | * \param output The output buffer to write to, which may be the same 180 | * buffer as \a input. The \a output buffer must have at least as many 181 | * bytes as the \a input buffer. 182 | * \param input The input buffer to read from. 183 | * \param len The number of bytes to encrypt. 184 | * 185 | * This function is a convenience that generates data with extend() and 186 | * then XOR's it with the contents of \a input to generate the \a output. 187 | * This function can also be used to decrypt. 188 | * 189 | * The encrypt() function can be called multiple times with different 190 | * regions of the plaintext data. 191 | * 192 | * \sa reset(), update(), extend(), decrypt() 193 | */ 194 | 195 | /** 196 | * \fn void XOF::decrypt(uint8_t *output, const uint8_t *input, size_t len) 197 | * \brief Decrypts an input buffer with extendable output from this XOF. 198 | * 199 | * \param output The output buffer to write to, which may be the same 200 | * buffer as \a input. The \a output buffer must have at least as many 201 | * bytes as the \a input buffer. 202 | * \param input The input buffer to read from. 203 | * \param len The number of bytes to encrypt. 204 | * 205 | * This is a convenience function that merely calls encrypt(). 206 | * 207 | * \sa reset(), update(), extend(), encrypt() 208 | */ 209 | 210 | /** 211 | * \fn void XOF::clear() 212 | * \brief Clears the hash state, removing all sensitive data, and then 213 | * resets the XOF ready for a new session. 214 | * 215 | * \sa reset() 216 | */ 217 | -------------------------------------------------------------------------------- /src/modules/Crypto/XOF.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_XOF_h 24 | #define CRYPTO_XOF_h 25 | 26 | #include 27 | #include 28 | 29 | class XOF 30 | { 31 | public: 32 | XOF(); 33 | virtual ~XOF(); 34 | 35 | virtual size_t blockSize() const = 0; 36 | 37 | virtual void reset() = 0; 38 | virtual void update(const void *data, size_t len) = 0; 39 | 40 | virtual void extend(uint8_t *data, size_t len) = 0; 41 | virtual void encrypt(uint8_t *output, const uint8_t *input, size_t len) = 0; 42 | 43 | inline void decrypt(uint8_t *output, const uint8_t *input, size_t len) 44 | { 45 | encrypt(output, input, len); 46 | } 47 | 48 | virtual void clear() = 0; 49 | }; 50 | 51 | #endif 52 | -------------------------------------------------------------------------------- /src/modules/Crypto/XTS.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_XTS_h 24 | #define CRYPTO_XTS_h 25 | 26 | #include "BlockCipher.h" 27 | 28 | class XTSSingleKeyCommon; 29 | 30 | class XTSCommon 31 | { 32 | public: 33 | virtual ~XTSCommon(); 34 | 35 | virtual size_t keySize() const; 36 | size_t tweakSize() const; 37 | 38 | size_t sectorSize() const { return sectSize; } 39 | bool setSectorSize(size_t size); 40 | 41 | virtual bool setKey(const uint8_t *key, size_t len); 42 | bool setTweak(const uint8_t *tweak, size_t len); 43 | 44 | void encryptSector(uint8_t *output, const uint8_t *input); 45 | void decryptSector(uint8_t *output, const uint8_t *input); 46 | 47 | void clear(); 48 | 49 | protected: 50 | XTSCommon(); 51 | void setBlockCiphers(BlockCipher *cipher1, BlockCipher *cipher2) 52 | { 53 | blockCipher1 = cipher1; 54 | blockCipher2 = cipher2; 55 | } 56 | 57 | private: 58 | BlockCipher *blockCipher1; 59 | BlockCipher *blockCipher2; 60 | uint32_t twk[4]; 61 | size_t sectSize; 62 | 63 | friend class XTSSingleKeyCommon; 64 | }; 65 | 66 | class XTSSingleKeyCommon : public XTSCommon 67 | { 68 | public: 69 | virtual ~XTSSingleKeyCommon(); 70 | 71 | size_t keySize() const; 72 | bool setKey(const uint8_t *key, size_t len); 73 | 74 | protected: 75 | XTSSingleKeyCommon() : XTSCommon() {} 76 | }; 77 | 78 | template 79 | class XTS : public XTSCommon 80 | { 81 | public: 82 | XTS() { setBlockCiphers(&cipher1, &cipher2); } 83 | ~XTS() {} 84 | 85 | private: 86 | T1 cipher1; 87 | T2 cipher2; 88 | }; 89 | 90 | template 91 | class XTSSingleKey : public XTSSingleKeyCommon 92 | { 93 | public: 94 | XTSSingleKey() { setBlockCiphers(&cipher, &cipher); } 95 | ~XTSSingleKey() {} 96 | 97 | private: 98 | T cipher; 99 | }; 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /src/modules/Crypto/examples/TestAES/TestAES.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | /* 24 | This example runs tests on the AES implementation to verify correct behaviour. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | struct TestVector 32 | { 33 | const char *name; 34 | byte key[32]; 35 | byte plaintext[16]; 36 | byte ciphertext[16]; 37 | }; 38 | 39 | // Define the ECB test vectors from the FIPS specification. 40 | static TestVector const testVectorAES128 = { 41 | .name = "AES-128-ECB", 42 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 43 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, 44 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 45 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 46 | .ciphertext = {0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30, 47 | 0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A} 48 | }; 49 | static TestVector const testVectorAES192 = { 50 | .name = "AES-192-ECB", 51 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 52 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 53 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}, 54 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 55 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 56 | .ciphertext = {0xDD, 0xA9, 0x7C, 0xA4, 0x86, 0x4C, 0xDF, 0xE0, 57 | 0x6E, 0xAF, 0x70, 0xA0, 0xEC, 0x0D, 0x71, 0x91} 58 | }; 59 | static TestVector const testVectorAES256 = { 60 | .name = "AES-256-ECB", 61 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 62 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 63 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 64 | 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, 65 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 66 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 67 | .ciphertext = {0x8E, 0xA2, 0xB7, 0xCA, 0x51, 0x67, 0x45, 0xBF, 68 | 0xEA, 0xFC, 0x49, 0x90, 0x4B, 0x49, 0x60, 0x89} 69 | }; 70 | 71 | AES128 aes128; 72 | AES192 aes192; 73 | AES256 aes256; 74 | 75 | byte buffer[16]; 76 | 77 | void testCipher(BlockCipher *cipher, const struct TestVector *test) 78 | { 79 | crypto_feed_watchdog(); 80 | Serial.print(test->name); 81 | Serial.print(" Encryption ... "); 82 | cipher->setKey(test->key, cipher->keySize()); 83 | cipher->encryptBlock(buffer, test->plaintext); 84 | if (memcmp(buffer, test->ciphertext, 16) == 0) 85 | Serial.println("Passed"); 86 | else 87 | Serial.println("Failed"); 88 | 89 | Serial.print(test->name); 90 | Serial.print(" Decryption ... "); 91 | cipher->decryptBlock(buffer, test->ciphertext); 92 | if (memcmp(buffer, test->plaintext, 16) == 0) 93 | Serial.println("Passed"); 94 | else 95 | Serial.println("Failed"); 96 | } 97 | 98 | void perfCipher(BlockCipher *cipher, const struct TestVector *test) 99 | { 100 | unsigned long start; 101 | unsigned long elapsed; 102 | int count; 103 | 104 | crypto_feed_watchdog(); 105 | 106 | Serial.print(test->name); 107 | Serial.print(" Set Key ... "); 108 | start = micros(); 109 | for (count = 0; count < 10000; ++count) { 110 | cipher->setKey(test->key, cipher->keySize()); 111 | } 112 | elapsed = micros() - start; 113 | Serial.print(elapsed / 10000.0); 114 | Serial.print("us per operation, "); 115 | Serial.print((10000.0 * 1000000.0) / elapsed); 116 | Serial.println(" per second"); 117 | 118 | Serial.print(test->name); 119 | Serial.print(" Encrypt ... "); 120 | start = micros(); 121 | for (count = 0; count < 5000; ++count) { 122 | cipher->encryptBlock(buffer, buffer); 123 | } 124 | elapsed = micros() - start; 125 | Serial.print(elapsed / (5000.0 * 16.0)); 126 | Serial.print("us per byte, "); 127 | Serial.print((16.0 * 5000.0 * 1000000.0) / elapsed); 128 | Serial.println(" bytes per second"); 129 | 130 | Serial.print(test->name); 131 | Serial.print(" Decrypt ... "); 132 | start = micros(); 133 | for (count = 0; count < 5000; ++count) { 134 | cipher->decryptBlock(buffer, buffer); 135 | } 136 | elapsed = micros() - start; 137 | Serial.print(elapsed / (5000.0 * 16.0)); 138 | Serial.print("us per byte, "); 139 | Serial.print((16.0 * 5000.0 * 1000000.0) / elapsed); 140 | Serial.println(" bytes per second"); 141 | 142 | Serial.println(); 143 | } 144 | 145 | void setup() 146 | { 147 | Serial.begin(9600); 148 | 149 | Serial.println(); 150 | 151 | Serial.println("State Sizes:"); 152 | Serial.print("AES128 ... "); 153 | Serial.println(sizeof(AES128)); 154 | Serial.print("AES192 ... "); 155 | Serial.println(sizeof(AES192)); 156 | Serial.print("AES256 ... "); 157 | Serial.println(sizeof(AES256)); 158 | Serial.println(); 159 | 160 | Serial.println("Test Vectors:"); 161 | testCipher(&aes128, &testVectorAES128); 162 | testCipher(&aes192, &testVectorAES192); 163 | testCipher(&aes256, &testVectorAES256); 164 | 165 | Serial.println(); 166 | 167 | Serial.println("Performance Tests:"); 168 | perfCipher(&aes128, &testVectorAES128); 169 | perfCipher(&aes192, &testVectorAES192); 170 | perfCipher(&aes256, &testVectorAES256); 171 | } 172 | 173 | void loop() 174 | { 175 | } 176 | -------------------------------------------------------------------------------- /src/modules/Crypto/examples/TestAESSmall/TestAESSmall.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | /* 24 | This example runs tests on the small AES implementation to verify behaviour. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | struct TestVector 32 | { 33 | const char *name; 34 | byte key[32]; 35 | byte plaintext[16]; 36 | byte ciphertext[16]; 37 | }; 38 | 39 | // Define the ECB test vectors from the FIPS specification. 40 | static TestVector const testVectorAES128 = { 41 | .name = "AES-128-ECB", 42 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 43 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, 44 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 45 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 46 | .ciphertext = {0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30, 47 | 0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A} 48 | }; 49 | static TestVector const testVectorAES192 = { 50 | .name = "AES-192-ECB", 51 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 52 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 53 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}, 54 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 55 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 56 | .ciphertext = {0xDD, 0xA9, 0x7C, 0xA4, 0x86, 0x4C, 0xDF, 0xE0, 57 | 0x6E, 0xAF, 0x70, 0xA0, 0xEC, 0x0D, 0x71, 0x91} 58 | }; 59 | static TestVector const testVectorAES256 = { 60 | .name = "AES-256-ECB", 61 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 62 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 63 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 64 | 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, 65 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 66 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 67 | .ciphertext = {0x8E, 0xA2, 0xB7, 0xCA, 0x51, 0x67, 0x45, 0xBF, 68 | 0xEA, 0xFC, 0x49, 0x90, 0x4B, 0x49, 0x60, 0x89} 69 | }; 70 | 71 | AESSmall128 aes128; 72 | AESSmall256 aes256; 73 | 74 | byte buffer[16]; 75 | 76 | void testCipher(BlockCipher *cipher, const struct TestVector *test) 77 | { 78 | crypto_feed_watchdog(); 79 | Serial.print(test->name); 80 | Serial.print(" Encryption ... "); 81 | cipher->setKey(test->key, cipher->keySize()); 82 | cipher->encryptBlock(buffer, test->plaintext); 83 | if (memcmp(buffer, test->ciphertext, 16) == 0) 84 | Serial.println("Passed"); 85 | else 86 | Serial.println("Failed"); 87 | 88 | Serial.print(test->name); 89 | Serial.print(" Decryption ... "); 90 | cipher->decryptBlock(buffer, test->ciphertext); 91 | if (memcmp(buffer, test->plaintext, 16) == 0) 92 | Serial.println("Passed"); 93 | else 94 | Serial.println("Failed"); 95 | } 96 | 97 | void perfCipher(BlockCipher *cipher, const struct TestVector *test) 98 | { 99 | unsigned long start; 100 | unsigned long elapsed; 101 | int count; 102 | 103 | crypto_feed_watchdog(); 104 | 105 | Serial.print(test->name); 106 | Serial.print(" Set Key ... "); 107 | start = micros(); 108 | for (count = 0; count < 10000; ++count) { 109 | cipher->setKey(test->key, cipher->keySize()); 110 | } 111 | elapsed = micros() - start; 112 | Serial.print(elapsed / 10000.0); 113 | Serial.print("us per operation, "); 114 | Serial.print((10000.0 * 1000000.0) / elapsed); 115 | Serial.println(" per second"); 116 | 117 | Serial.print(test->name); 118 | Serial.print(" Encrypt ... "); 119 | start = micros(); 120 | for (count = 0; count < 5000; ++count) { 121 | cipher->encryptBlock(buffer, buffer); 122 | } 123 | elapsed = micros() - start; 124 | Serial.print(elapsed / (5000.0 * 16.0)); 125 | Serial.print("us per byte, "); 126 | Serial.print((16.0 * 5000.0 * 1000000.0) / elapsed); 127 | Serial.println(" bytes per second"); 128 | 129 | Serial.print(test->name); 130 | Serial.print(" Decrypt ... "); 131 | start = micros(); 132 | for (count = 0; count < 5000; ++count) { 133 | cipher->decryptBlock(buffer, buffer); 134 | } 135 | elapsed = micros() - start; 136 | Serial.print(elapsed / (5000.0 * 16.0)); 137 | Serial.print("us per byte, "); 138 | Serial.print((16.0 * 5000.0 * 1000000.0) / elapsed); 139 | Serial.println(" bytes per second"); 140 | 141 | Serial.println(); 142 | } 143 | 144 | void setup() 145 | { 146 | Serial.begin(9600); 147 | 148 | Serial.println(); 149 | 150 | Serial.println("State Sizes:"); 151 | Serial.print("AESSmall128 ... "); 152 | Serial.println(sizeof(AESSmall128)); 153 | Serial.print("AESSmall256 ... "); 154 | Serial.println(sizeof(AESSmall256)); 155 | Serial.println(); 156 | 157 | Serial.println("Test Vectors:"); 158 | testCipher(&aes128, &testVectorAES128); 159 | testCipher(&aes256, &testVectorAES256); 160 | 161 | Serial.println(); 162 | 163 | Serial.println("Performance Tests:"); 164 | perfCipher(&aes128, &testVectorAES128); 165 | perfCipher(&aes256, &testVectorAES256); 166 | } 167 | 168 | void loop() 169 | { 170 | } 171 | -------------------------------------------------------------------------------- /src/modules/Crypto/examples/TestAESTiny/TestAESTiny.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | /* 24 | This example runs tests on the tiny AES implementation to verify behaviour. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | struct TestVector 32 | { 33 | const char *name; 34 | byte key[32]; 35 | byte plaintext[16]; 36 | byte ciphertext[16]; 37 | }; 38 | 39 | // Define the ECB test vectors from the FIPS specification. 40 | static TestVector const testVectorAES128 = { 41 | .name = "AES-128-ECB", 42 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 43 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, 44 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 45 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 46 | .ciphertext = {0x69, 0xC4, 0xE0, 0xD8, 0x6A, 0x7B, 0x04, 0x30, 47 | 0xD8, 0xCD, 0xB7, 0x80, 0x70, 0xB4, 0xC5, 0x5A} 48 | }; 49 | static TestVector const testVectorAES192 = { 50 | .name = "AES-192-ECB", 51 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 52 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 53 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17}, 54 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 55 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 56 | .ciphertext = {0xDD, 0xA9, 0x7C, 0xA4, 0x86, 0x4C, 0xDF, 0xE0, 57 | 0x6E, 0xAF, 0x70, 0xA0, 0xEC, 0x0D, 0x71, 0x91} 58 | }; 59 | static TestVector const testVectorAES256 = { 60 | .name = "AES-256-ECB", 61 | .key = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 62 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 63 | 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 64 | 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F}, 65 | .plaintext = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 66 | 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}, 67 | .ciphertext = {0x8E, 0xA2, 0xB7, 0xCA, 0x51, 0x67, 0x45, 0xBF, 68 | 0xEA, 0xFC, 0x49, 0x90, 0x4B, 0x49, 0x60, 0x89} 69 | }; 70 | 71 | AESTiny128 aes128; 72 | AESTiny256 aes256; 73 | 74 | byte buffer[16]; 75 | 76 | void testCipher(BlockCipher *cipher, const struct TestVector *test) 77 | { 78 | crypto_feed_watchdog(); 79 | Serial.print(test->name); 80 | Serial.print(" Encryption ... "); 81 | cipher->setKey(test->key, cipher->keySize()); 82 | cipher->encryptBlock(buffer, test->plaintext); 83 | if (memcmp(buffer, test->ciphertext, 16) == 0) 84 | Serial.println("Passed"); 85 | else 86 | Serial.println("Failed"); 87 | } 88 | 89 | void perfCipher(BlockCipher *cipher, const struct TestVector *test) 90 | { 91 | unsigned long start; 92 | unsigned long elapsed; 93 | int count; 94 | 95 | crypto_feed_watchdog(); 96 | 97 | Serial.print(test->name); 98 | Serial.print(" Set Key ... "); 99 | start = micros(); 100 | for (count = 0; count < 10000; ++count) { 101 | cipher->setKey(test->key, cipher->keySize()); 102 | } 103 | elapsed = micros() - start; 104 | Serial.print(elapsed / 10000.0); 105 | Serial.print("us per operation, "); 106 | Serial.print((10000.0 * 1000000.0) / elapsed); 107 | Serial.println(" per second"); 108 | 109 | Serial.print(test->name); 110 | Serial.print(" Encrypt ... "); 111 | start = micros(); 112 | for (count = 0; count < 5000; ++count) { 113 | cipher->encryptBlock(buffer, buffer); 114 | } 115 | elapsed = micros() - start; 116 | Serial.print(elapsed / (5000.0 * 16.0)); 117 | Serial.print("us per byte, "); 118 | Serial.print((16.0 * 5000.0 * 1000000.0) / elapsed); 119 | Serial.println(" bytes per second"); 120 | 121 | Serial.println(); 122 | } 123 | 124 | void setup() 125 | { 126 | Serial.begin(9600); 127 | 128 | Serial.println(); 129 | 130 | Serial.println("State Sizes:"); 131 | Serial.print("AESTiny128 ... "); 132 | Serial.println(sizeof(AESTiny128)); 133 | Serial.print("AESTiny256 ... "); 134 | Serial.println(sizeof(AESTiny256)); 135 | Serial.println(); 136 | 137 | Serial.println("Test Vectors:"); 138 | testCipher(&aes128, &testVectorAES128); 139 | testCipher(&aes256, &testVectorAES256); 140 | 141 | Serial.println(); 142 | 143 | Serial.println("Performance Tests:"); 144 | perfCipher(&aes128, &testVectorAES128); 145 | perfCipher(&aes256, &testVectorAES256); 146 | } 147 | 148 | void loop() 149 | { 150 | } 151 | -------------------------------------------------------------------------------- /src/modules/Crypto/examples/TestCurve25519/TestCurve25519.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | /* 24 | This example runs tests on the Curve25519 algorithm. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | void printNumber(const char *name, const uint8_t *x) 33 | { 34 | static const char hexchars[] = "0123456789ABCDEF"; 35 | Serial.print(name); 36 | Serial.print(" = "); 37 | for (uint8_t posn = 0; posn < 32; ++posn) { 38 | Serial.print(hexchars[(x[posn] >> 4) & 0x0F]); 39 | Serial.print(hexchars[x[posn] & 0x0F]); 40 | } 41 | Serial.println(); 42 | } 43 | 44 | // Check the eval() function using the test vectors from 45 | // section 6.1 of RFC 7748. 46 | void testEval() 47 | { 48 | static uint8_t alice_private[32] = { 49 | 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d, 50 | 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45, 51 | 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a, 52 | 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a 53 | }; 54 | static uint8_t const alice_public[32] = { 55 | 0x85, 0x20, 0xf0, 0x09, 0x89, 0x30, 0xa7, 0x54, 56 | 0x74, 0x8b, 0x7d, 0xdc, 0xb4, 0x3e, 0xf7, 0x5a, 57 | 0x0d, 0xbf, 0x3a, 0x0d, 0x26, 0x38, 0x1a, 0xf4, 58 | 0xeb, 0xa4, 0xa9, 0x8e, 0xaa, 0x9b, 0x4e, 0x6a 59 | }; 60 | static uint8_t bob_private[32] = { 61 | 0x5d, 0xab, 0x08, 0x7e, 0x62, 0x4a, 0x8a, 0x4b, 62 | 0x79, 0xe1, 0x7f, 0x8b, 0x83, 0x80, 0x0e, 0xe6, 63 | 0x6f, 0x3b, 0xb1, 0x29, 0x26, 0x18, 0xb6, 0xfd, 64 | 0x1c, 0x2f, 0x8b, 0x27, 0xff, 0x88, 0xe0, 0xeb 65 | }; 66 | static uint8_t const bob_public[32] = { 67 | 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4, 68 | 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37, 69 | 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d, 70 | 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f 71 | }; 72 | static uint8_t const shared_secret[32] = { 73 | 0x4a, 0x5d, 0x9d, 0x5b, 0xa4, 0xce, 0x2d, 0xe1, 74 | 0x72, 0x8e, 0x3b, 0xf4, 0x80, 0x35, 0x0f, 0x25, 75 | 0xe0, 0x7e, 0x21, 0xc9, 0x47, 0xd1, 0x9e, 0x33, 76 | 0x76, 0xf0, 0x9b, 0x3c, 0x1e, 0x16, 0x17, 0x42 77 | }; 78 | 79 | // Fix up the private keys by applying the standard masks. 80 | alice_private[0] &= 0xF8; 81 | alice_private[31] = (alice_private[31] & 0x7F) | 0x40; 82 | bob_private[0] &= 0xF8; 83 | bob_private[31] = (bob_private[31] & 0x7F) | 0x40; 84 | 85 | // Evaluate the curve function and check the public keys. 86 | uint8_t result[32]; 87 | Serial.println("Fixed test vectors:"); 88 | Serial.print("Computing Alice's public key ... "); 89 | Serial.flush(); 90 | unsigned long start = micros(); 91 | Curve25519::eval(result, alice_private, 0); 92 | unsigned long elapsed = micros() - start; 93 | if (memcmp(result, alice_public, 32) == 0) { 94 | Serial.print("ok"); 95 | } else { 96 | Serial.println("failed"); 97 | printNumber("actual ", result); 98 | printNumber("expected", alice_public); 99 | } 100 | Serial.print(" (elapsed "); 101 | Serial.print(elapsed); 102 | Serial.println(" us)"); 103 | Serial.print("Computing Bob's public key ... "); 104 | Serial.flush(); 105 | start = micros(); 106 | Curve25519::eval(result, bob_private, 0); 107 | elapsed = micros() - start; 108 | if (memcmp(result, bob_public, 32) == 0) { 109 | Serial.print("ok"); 110 | } else { 111 | Serial.println("failed"); 112 | printNumber("actual ", result); 113 | printNumber("expected", bob_public); 114 | } 115 | Serial.print(" (elapsed "); 116 | Serial.print(elapsed); 117 | Serial.println(" us)"); 118 | 119 | // Compute the shared secret from each side. 120 | Serial.print("Computing Alice's shared secret ... "); 121 | Serial.flush(); 122 | start = micros(); 123 | Curve25519::eval(result, alice_private, bob_public); 124 | elapsed = micros() - start; 125 | if (memcmp(result, shared_secret, 32) == 0) { 126 | Serial.print("ok"); 127 | } else { 128 | Serial.println("failed"); 129 | printNumber("actual ", result); 130 | printNumber("expected", shared_secret); 131 | } 132 | Serial.print(" (elapsed "); 133 | Serial.print(elapsed); 134 | Serial.println(" us)"); 135 | Serial.print("Computing Bob's shared secret ... "); 136 | Serial.flush(); 137 | start = micros(); 138 | Curve25519::eval(result, bob_private, alice_public); 139 | elapsed = micros() - start; 140 | if (memcmp(result, shared_secret, 32) == 0) { 141 | Serial.print("ok"); 142 | } else { 143 | Serial.println("failed"); 144 | printNumber("actual ", result); 145 | printNumber("expected", shared_secret); 146 | } 147 | Serial.print(" (elapsed "); 148 | Serial.print(elapsed); 149 | Serial.println(" us)"); 150 | } 151 | 152 | void testDH() 153 | { 154 | static uint8_t alice_k[32]; 155 | static uint8_t alice_f[32]; 156 | static uint8_t bob_k[32]; 157 | static uint8_t bob_f[32]; 158 | 159 | Serial.println("Diffie-Hellman key exchange:"); 160 | Serial.print("Generate random k/f for Alice ... "); 161 | Serial.flush(); 162 | unsigned long start = micros(); 163 | Curve25519::dh1(alice_k, alice_f); 164 | unsigned long elapsed = micros() - start; 165 | Serial.print("elapsed "); 166 | Serial.print(elapsed); 167 | Serial.println(" us"); 168 | 169 | Serial.print("Generate random k/f for Bob ... "); 170 | Serial.flush(); 171 | start = micros(); 172 | Curve25519::dh1(bob_k, bob_f); 173 | elapsed = micros() - start; 174 | Serial.print("elapsed "); 175 | Serial.print(elapsed); 176 | Serial.println(" us"); 177 | 178 | Serial.print("Generate shared secret for Alice ... "); 179 | Serial.flush(); 180 | start = micros(); 181 | Curve25519::dh2(bob_k, alice_f); 182 | elapsed = micros() - start; 183 | Serial.print("elapsed "); 184 | Serial.print(elapsed); 185 | Serial.println(" us"); 186 | 187 | Serial.print("Generate shared secret for Bob ... "); 188 | Serial.flush(); 189 | start = micros(); 190 | Curve25519::dh2(alice_k, bob_f); 191 | elapsed = micros() - start; 192 | Serial.print("elapsed "); 193 | Serial.print(elapsed); 194 | Serial.println(" us"); 195 | 196 | Serial.print("Check that the shared secrets match ... "); 197 | if (memcmp(alice_k, bob_k, 32) == 0) 198 | Serial.println("ok"); 199 | else 200 | Serial.println("failed"); 201 | } 202 | 203 | void setup() 204 | { 205 | Serial.begin(9600); 206 | 207 | // Start the random number generator. We don't initialise a noise 208 | // source here because we don't need one for testing purposes. 209 | // Real DH applications should of course use a proper noise source. 210 | RNG.begin("TestCurve25519 1.0"); 211 | 212 | // Perform the tests. 213 | testEval(); 214 | Serial.println(); 215 | testDH(); 216 | Serial.println(); 217 | } 218 | 219 | void loop() 220 | { 221 | } 222 | -------------------------------------------------------------------------------- /src/modules/Crypto/examples/TestEd25519/TestEd25519.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | /* 24 | This example runs tests on the Ed25519 algorithm. 25 | */ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | struct TestVector 34 | { 35 | const char *name; 36 | uint8_t privateKey[32]; 37 | uint8_t publicKey[32]; 38 | uint8_t message[2]; 39 | size_t len; 40 | uint8_t signature[64]; 41 | }; 42 | 43 | // Test vectors for Ed25519 from: 44 | // https://tools.ietf.org/html/draft-irtf-cfrg-eddsa-05 45 | static TestVector const testVectorEd25519_1 PROGMEM = { 46 | .name = "Ed25519 #1", 47 | .privateKey = {0x9d, 0x61, 0xb1, 0x9d, 0xef, 0xfd, 0x5a, 0x60, 48 | 0xba, 0x84, 0x4a, 0xf4, 0x92, 0xec, 0x2c, 0xc4, 49 | 0x44, 0x49, 0xc5, 0x69, 0x7b, 0x32, 0x69, 0x19, 50 | 0x70, 0x3b, 0xac, 0x03, 0x1c, 0xae, 0x7f, 0x60}, 51 | .publicKey = {0xd7, 0x5a, 0x98, 0x01, 0x82, 0xb1, 0x0a, 0xb7, 52 | 0xd5, 0x4b, 0xfe, 0xd3, 0xc9, 0x64, 0x07, 0x3a, 53 | 0x0e, 0xe1, 0x72, 0xf3, 0xda, 0xa6, 0x23, 0x25, 54 | 0xaf, 0x02, 0x1a, 0x68, 0xf7, 0x07, 0x51, 0x1a}, 55 | .message = {0x00, 0x00}, 56 | .len = 0, 57 | .signature = {0xe5, 0x56, 0x43, 0x00, 0xc3, 0x60, 0xac, 0x72, 58 | 0x90, 0x86, 0xe2, 0xcc, 0x80, 0x6e, 0x82, 0x8a, 59 | 0x84, 0x87, 0x7f, 0x1e, 0xb8, 0xe5, 0xd9, 0x74, 60 | 0xd8, 0x73, 0xe0, 0x65, 0x22, 0x49, 0x01, 0x55, 61 | 0x5f, 0xb8, 0x82, 0x15, 0x90, 0xa3, 0x3b, 0xac, 62 | 0xc6, 0x1e, 0x39, 0x70, 0x1c, 0xf9, 0xb4, 0x6b, 63 | 0xd2, 0x5b, 0xf5, 0xf0, 0x59, 0x5b, 0xbe, 0x24, 64 | 0x65, 0x51, 0x41, 0x43, 0x8e, 0x7a, 0x10, 0x0b} 65 | }; 66 | static TestVector const testVectorEd25519_2 PROGMEM = { 67 | .name = "Ed25519 #2", 68 | .privateKey = {0x4c, 0xcd, 0x08, 0x9b, 0x28, 0xff, 0x96, 0xda, 69 | 0x9d, 0xb6, 0xc3, 0x46, 0xec, 0x11, 0x4e, 0x0f, 70 | 0x5b, 0x8a, 0x31, 0x9f, 0x35, 0xab, 0xa6, 0x24, 71 | 0xda, 0x8c, 0xf6, 0xed, 0x4f, 0xb8, 0xa6, 0xfb}, 72 | .publicKey = {0x3d, 0x40, 0x17, 0xc3, 0xe8, 0x43, 0x89, 0x5a, 73 | 0x92, 0xb7, 0x0a, 0xa7, 0x4d, 0x1b, 0x7e, 0xbc, 74 | 0x9c, 0x98, 0x2c, 0xcf, 0x2e, 0xc4, 0x96, 0x8c, 75 | 0xc0, 0xcd, 0x55, 0xf1, 0x2a, 0xf4, 0x66, 0x0c}, 76 | .message = {0x72, 0x00}, 77 | .len = 1, 78 | .signature = {0x92, 0xa0, 0x09, 0xa9, 0xf0, 0xd4, 0xca, 0xb8, 79 | 0x72, 0x0e, 0x82, 0x0b, 0x5f, 0x64, 0x25, 0x40, 80 | 0xa2, 0xb2, 0x7b, 0x54, 0x16, 0x50, 0x3f, 0x8f, 81 | 0xb3, 0x76, 0x22, 0x23, 0xeb, 0xdb, 0x69, 0xda, 82 | 0x08, 0x5a, 0xc1, 0xe4, 0x3e, 0x15, 0x99, 0x6e, 83 | 0x45, 0x8f, 0x36, 0x13, 0xd0, 0xf1, 0x1d, 0x8c, 84 | 0x38, 0x7b, 0x2e, 0xae, 0xb4, 0x30, 0x2a, 0xee, 85 | 0xb0, 0x0d, 0x29, 0x16, 0x12, 0xbb, 0x0c, 0x00} 86 | }; 87 | 88 | static TestVector testVector; 89 | 90 | void printNumber(const char *name, const uint8_t *x, uint8_t len) 91 | { 92 | static const char hexchars[] = "0123456789ABCDEF"; 93 | Serial.print(name); 94 | Serial.print(" = "); 95 | for (uint8_t posn = 0; posn < len; ++posn) { 96 | Serial.print(hexchars[(x[posn] >> 4) & 0x0F]); 97 | Serial.print(hexchars[x[posn] & 0x0F]); 98 | } 99 | Serial.println(); 100 | } 101 | 102 | void testFixedVectors(const struct TestVector *test) 103 | { 104 | // Copy the test vector out of program memory. 105 | memcpy_P(&testVector, test, sizeof(TestVector)); 106 | test = &testVector; 107 | 108 | // Sign using the test vector. 109 | uint8_t signature[64]; 110 | Serial.print(test->name); 111 | Serial.print(" sign ... "); 112 | Serial.flush(); 113 | unsigned long start = micros(); 114 | Ed25519::sign(signature, test->privateKey, test->publicKey, 115 | test->message, test->len); 116 | unsigned long elapsed = micros() - start; 117 | if (memcmp(signature, test->signature, 64) == 0) { 118 | Serial.print("ok"); 119 | } else { 120 | Serial.println("failed"); 121 | printNumber("actual ", signature, 64); 122 | printNumber("expected", test->signature, 64); 123 | } 124 | Serial.print(" (elapsed "); 125 | Serial.print(elapsed); 126 | Serial.println(" us)"); 127 | 128 | // Verify using the test vector. 129 | Serial.print(test->name); 130 | Serial.print(" verify ... "); 131 | Serial.flush(); 132 | start = micros(); 133 | bool verified = Ed25519::verify(signature, test->publicKey, test->message, test->len); 134 | elapsed = micros() - start; 135 | if (verified) { 136 | Serial.print("ok"); 137 | } else { 138 | Serial.println("failed"); 139 | } 140 | Serial.print(" (elapsed "); 141 | Serial.print(elapsed); 142 | Serial.println(" us)"); 143 | 144 | // Check derivation of the public key from the private key. 145 | Serial.print(test->name); 146 | Serial.print(" derive public key ... "); 147 | Serial.flush(); 148 | start = micros(); 149 | Ed25519::derivePublicKey(signature, test->privateKey); 150 | elapsed = micros() - start; 151 | if (memcmp(signature, test->publicKey, 32) == 0) { 152 | Serial.print("ok"); 153 | } else { 154 | Serial.println("failed"); 155 | printNumber("actual ", signature, 32); 156 | printNumber("expected", test->publicKey, 32); 157 | } 158 | Serial.print(" (elapsed "); 159 | Serial.print(elapsed); 160 | Serial.println(" us)"); 161 | } 162 | 163 | void testFixedVectors() 164 | { 165 | testFixedVectors(&testVectorEd25519_1); 166 | testFixedVectors(&testVectorEd25519_2); 167 | } 168 | 169 | void setup() 170 | { 171 | Serial.begin(9600); 172 | 173 | // Start the random number generator. We don't initialise a noise 174 | // source here because we don't need one for testing purposes. 175 | // Real applications should of course use a proper noise source. 176 | RNG.begin("TestEd25519 1.0"); 177 | 178 | // Perform the tests. 179 | testFixedVectors(); 180 | Serial.println(); 181 | } 182 | 183 | void loop() 184 | { 185 | } 186 | -------------------------------------------------------------------------------- /src/modules/Crypto/examples/TestRNG/TestRNG.ino: -------------------------------------------------------------------------------- 1 | 2 | // Example of initializing and using the random number generator. 3 | 4 | #include 5 | #include 6 | #include 7 | //#include 8 | 9 | // Change "MyApp 1.0" to some other tag for your application 10 | // so that different applications will generate different results 11 | // even if the input noise or seed data is otherwise identical. 12 | #define RNG_APP_TAG "MyApp 1.0" 13 | 14 | // Noise source to seed the random number generator. 15 | TransistorNoiseSource noise(A1); 16 | //RingOscillatorNoiseSource noise; 17 | 18 | bool calibrating = false; 19 | byte data[32]; 20 | unsigned long startTime; 21 | size_t length = 48; // First block should wait for the pool to fill up. 22 | 23 | void setup() { 24 | Serial.begin(9600); 25 | Serial.println("start"); 26 | 27 | // Initialize the random number generator. 28 | RNG.begin(RNG_APP_TAG); 29 | 30 | // Add the noise source to the list of sources known to RNG. 31 | RNG.addNoiseSource(noise); 32 | 33 | startTime = millis(); 34 | } 35 | 36 | void printHex(const byte *data, unsigned len) 37 | { 38 | static char const hexchars[] = "0123456789ABCDEF"; 39 | unsigned long time = millis() - startTime; 40 | Serial.print(time / 1000); 41 | Serial.print('.'); 42 | Serial.print((time / 100) % 10); 43 | Serial.print(": "); 44 | while (len > 0) { 45 | int b = *data++; 46 | Serial.print(hexchars[(b >> 4) & 0x0F]); 47 | Serial.print(hexchars[b & 0x0F]); 48 | --len; 49 | } 50 | Serial.println(); 51 | } 52 | 53 | void loop() { 54 | // Track changes to the calibration state on the noise source. 55 | bool newCalibrating = noise.calibrating(); 56 | if (newCalibrating != calibrating) { 57 | calibrating = newCalibrating; 58 | if (calibrating) 59 | Serial.println("calibrating"); 60 | } 61 | 62 | // Perform regular housekeeping on the random number generator. 63 | RNG.loop(); 64 | 65 | // Generate output whenever 32 bytes of entropy have been accumulated. 66 | // The first time through, we wait for 48 bytes for a full entropy pool. 67 | if (RNG.available(length)) { 68 | RNG.rand(data, sizeof(data)); 69 | printHex(data, sizeof(data)); 70 | length = 32; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/modules/Crypto/keywords.txt: -------------------------------------------------------------------------------- 1 | AES128 KEYWORD1 2 | AES192 KEYWORD1 3 | AES256 KEYWORD1 4 | AESTiny128 KEYWORD1 5 | AESTiny256 KEYWORD1 6 | AESSmall128 KEYWORD1 7 | AESSmall256 KEYWORD1 8 | ChaCha KEYWORD1 9 | ChaChaPoly KEYWORD1 10 | 11 | BLAKE2b KEYWORD1 12 | BLAKE2s KEYWORD1 13 | SHA256 KEYWORD1 14 | SHA512 KEYWORD1 15 | SHA3_256 KEYWORD1 16 | SHA3_512 KEYWORD1 17 | KeccakCore KEYWORD1 18 | Poly1305 KEYWORD1 19 | GHASH KEYWORD1 20 | OMAC KEYWORD1 21 | GF128 KEYWORD1 22 | 23 | SHAKE128 KEYWORD1 24 | SHAKE256 KEYWORD1 25 | 26 | Curve25519 KEYWORD1 27 | Ed25519 KEYWORD1 28 | 29 | CBC KEYWORD1 30 | CFB KEYWORD1 31 | CTR KEYWORD1 32 | OFB KEYWORD1 33 | GCM KEYWORD1 34 | EAX KEYWORD1 35 | 36 | RNG KEYWORD1 37 | 38 | keySize KEYWORD2 39 | ivSize KEYWORD2 40 | tagSize KEYWORD2 41 | setKey KEYWORD2 42 | setIV KEYWORD2 43 | encrypt KEYWORD2 44 | decrypt KEYWORD2 45 | clear KEYWORD2 46 | addAuthData KEYWORD2 47 | 48 | hashSize KEYWORD2 49 | blockSize KEYWORD2 50 | reset KEYWORD2 51 | update KEYWORD2 52 | finalize KEYWORD2 53 | 54 | begin KEYWORD2 55 | setAutoSaveTime KEYWORD2 56 | rand KEYWORD2 57 | available KEYWORD2 58 | stir KEYWORD2 59 | save KEYWORD2 60 | loop KEYWORD2 61 | destroy KEYWORD2 62 | calibrating KEYWORD2 63 | 64 | eval KEYWORD2 65 | dh1 KEYWORD2 66 | dh2 KEYWORD2 67 | 68 | sign KEYWORD2 69 | verify KEYWORD2 70 | generatePrivateKey KEYWORD2 71 | derivePublicKey KEYWORD2 72 | -------------------------------------------------------------------------------- /src/modules/Crypto/library.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Crypto", 3 | "version": "0.2.0", 4 | "keywords": "AES128,AES192,AES256,Speck,CTR,CFB,CBC,OFB,EAX,GCM,XTS,ChaCha,ChaChaPoly,EAX,GCM,SHA256,SHA512,SHA3_256,SHA3_512,BLAKE2s,BLAKE2b,SHAKE128,SHAKE256,Poly1305,GHASH,OMAC,Curve25519,Ed25519,P521,RNG,NOISE", 5 | "description": "Arduino CryptoLibs - All cryptographic algorithms have been optimized for 8-bit Arduino platforms like the Uno", 6 | "authors": 7 | { 8 | "name": "Rhys Weatherley", 9 | "email": "rhys.weatherley@gmail.com", 10 | "url": "https://rweather.github.io/arduinolibs/crypto.html" 11 | }, 12 | "export": { 13 | "include": "libraries/Crypto" 14 | }, 15 | "repository": 16 | { 17 | "type": "git", 18 | "url": "https://github.com/rweather/arduinolibs.git" 19 | }, 20 | "frameworks": "arduino", 21 | "platforms": "*" 22 | } 23 | -------------------------------------------------------------------------------- /src/modules/Crypto/utility/EndianUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_ENDIANUTIL_H 24 | #define CRYPTO_ENDIANUTIL_H 25 | 26 | #include 27 | 28 | #if !defined(HOST_BUILD) 29 | 30 | // CPU is assumed to be little endian. Edit this file if you 31 | // need to port this library to a big endian CPU. 32 | 33 | #define CRYPTO_LITTLE_ENDIAN 1 34 | 35 | #define htole16(x) (x) 36 | #define le16toh(x) (x) 37 | #define htobe16(x) \ 38 | (__extension__ ({ \ 39 | uint16_t _temp = (x); \ 40 | ((_temp >> 8) & 0x00FF) | \ 41 | ((_temp << 8) & 0xFF00); \ 42 | })) 43 | #define be16toh(x) (htobe16((x))) 44 | 45 | #define htole32(x) (x) 46 | #define le32toh(x) (x) 47 | #define htobe32(x) \ 48 | (__extension__ ({ \ 49 | uint32_t _temp = (x); \ 50 | ((_temp >> 24) & 0x000000FF) | \ 51 | ((_temp >> 8) & 0x0000FF00) | \ 52 | ((_temp << 8) & 0x00FF0000) | \ 53 | ((_temp << 24) & 0xFF000000); \ 54 | })) 55 | #define be32toh(x) (htobe32((x))) 56 | 57 | #define htole64(x) (x) 58 | #define le64toh(x) (x) 59 | #define htobe64(x) \ 60 | (__extension__ ({ \ 61 | uint64_t __temp = (x); \ 62 | uint32_t __low = htobe32((uint32_t)__temp); \ 63 | uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \ 64 | (((uint64_t)__low) << 32) | __high; \ 65 | })) 66 | #define be64toh(x) (htobe64((x))) 67 | 68 | #else // HOST_BUILD 69 | 70 | #include 71 | #if __BYTE_ORDER == __LITTLE_ENDIAN 72 | #define CRYPTO_LITTLE_ENDIAN 1 73 | #endif 74 | 75 | #endif // HOST_BUILD 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /src/modules/Crypto/utility/LimbUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_LIMBUTIL_H 24 | #define CRYPTO_LIMBUTIL_H 25 | 26 | #include "ProgMemUtil.h" 27 | 28 | // Number of limbs in a big number value of various sizes. 29 | #define NUM_LIMBS_BITS(n) \ 30 | (((n) + sizeof(limb_t) * 8 - 1) / (8 * sizeof(limb_t))) 31 | #define NUM_LIMBS_128BIT NUM_LIMBS_BITS(128) 32 | #define NUM_LIMBS_256BIT NUM_LIMBS_BITS(256) 33 | #define NUM_LIMBS_512BIT NUM_LIMBS_BITS(512) 34 | 35 | // The number of bits in a limb. 36 | #define LIMB_BITS (8 * sizeof(limb_t)) 37 | 38 | // Read a limb-sized quantity from program memory. 39 | #if BIGNUMBER_LIMB_8BIT 40 | #define pgm_read_limb(x) (pgm_read_byte((x))) 41 | #elif BIGNUMBER_LIMB_16BIT 42 | #define pgm_read_limb(x) (pgm_read_word((x))) 43 | #elif BIGNUMBER_LIMB_32BIT 44 | #define pgm_read_limb(x) (pgm_read_dword((x))) 45 | #elif BIGNUMBER_LIMB_64BIT 46 | #define pgm_read_limb(x) (pgm_read_qword((x))) 47 | #endif 48 | 49 | // Expand a 32-bit value into a set of limbs depending upon the limb size. 50 | // This is used when initializing constant big number values in the code. 51 | // For 64-bit system compatibility it is necessary to use LIMB_PAIR(x, y). 52 | #if BIGNUMBER_LIMB_8BIT 53 | #define LIMB(value) ((uint8_t)(value)), \ 54 | ((uint8_t)((value) >> 8)), \ 55 | ((uint8_t)((value) >> 16)), \ 56 | ((uint8_t)((value) >> 24)) 57 | #define LIMB_PAIR(x,y) LIMB((x)), LIMB((y)) 58 | #elif BIGNUMBER_LIMB_16BIT 59 | #define LIMB(value) ((uint16_t)(value)), \ 60 | ((uint16_t)(((uint32_t)(value)) >> 16)) 61 | #define LIMB_PAIR(x,y) LIMB((x)), LIMB((y)) 62 | #elif BIGNUMBER_LIMB_32BIT 63 | #define LIMB(value) (value) 64 | #define LIMB_PAIR(x,y) LIMB((x)), LIMB((y)) 65 | #elif BIGNUMBER_LIMB_64BIT 66 | #define LIMB(value) (value) 67 | #define LIMB_PAIR(x,y) ((((uint64_t)(y)) << 32) | ((uint64_t)(x))) 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/modules/Crypto/utility/ProgMemUtil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Southern Storm Software, Pty Ltd. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included 12 | * in all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | 23 | #ifndef CRYPTO_PROGMEMUTIL_H 24 | #define CRYPTO_PROGMEMUTIL_H 25 | 26 | #if defined(__AVR__) 27 | #include 28 | #define pgm_read_qword(x) \ 29 | (__extension__ ({ \ 30 | const uint32_t *_temp = (const uint32_t *)(x); \ 31 | ((uint64_t)pgm_read_dword(_temp)) | \ 32 | (((uint64_t)pgm_read_dword(_temp + 1)) << 32); \ 33 | })) 34 | #elif defined(ESP8266) || defined(ESP32) 35 | #include 36 | #define pgm_read_qword(x) \ 37 | (__extension__ ({ \ 38 | const uint32_t *_temp = (const uint32_t *)(x); \ 39 | ((uint64_t)pgm_read_dword(_temp)) | \ 40 | (((uint64_t)pgm_read_dword(_temp + 1)) << 32); \ 41 | })) 42 | #else 43 | #include 44 | #define PROGMEM 45 | #define pgm_read_byte(x) (*(x)) 46 | #define pgm_read_word(x) (*(x)) 47 | #define pgm_read_dword(x) (*(x)) 48 | #define pgm_read_qword(x) (*(x)) 49 | #define memcpy_P(d,s,l) memcpy((d), (s), (l)) 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /src/modules/mqtt/PubSubClient.h: -------------------------------------------------------------------------------- 1 | /* 2 | PubSubClient.h - A simple client for MQTT. 3 | Nick O'Leary 4 | http://knolleary.net 5 | */ 6 | 7 | #ifndef PubSubClient_h 8 | #define PubSubClient_h 9 | 10 | #include 11 | #include "IPAddress.h" 12 | #include "Client.h" 13 | #include "Stream.h" 14 | 15 | #define MQTT_VERSION_3_1 3 16 | #define MQTT_VERSION_3_1_1 4 17 | 18 | // MQTT_VERSION : Pick the version 19 | //#define MQTT_VERSION MQTT_VERSION_3_1 20 | #ifndef MQTT_VERSION 21 | #define MQTT_VERSION MQTT_VERSION_3_1_1 22 | #endif 23 | 24 | // MQTT_MAX_PACKET_SIZE : Maximum packet size 25 | #ifndef MQTT_MAX_PACKET_SIZE 26 | #define MQTT_MAX_PACKET_SIZE 400 27 | #endif 28 | 29 | // MQTT_KEEPALIVE : keepAlive interval in Seconds 30 | #ifndef MQTT_KEEPALIVE 31 | #define MQTT_KEEPALIVE 60 //阿里云要求不得小于60秒 32 | //#define MQTT_KEEPALIVE 300 //最大300秒 33 | #endif 34 | 35 | // MQTT_SOCKET_TIMEOUT: socket timeout interval in Seconds 36 | #ifndef MQTT_SOCKET_TIMEOUT 37 | #define MQTT_SOCKET_TIMEOUT 15 38 | #endif 39 | 40 | // MQTT_MAX_TRANSFER_SIZE : limit how much data is passed to the network client 41 | // in each write call. Needed for the Arduino Wifi Shield. Leave undefined to 42 | // pass the entire MQTT packet in each write call. 43 | //#define MQTT_MAX_TRANSFER_SIZE 60 44 | 45 | // Possible values for client.state() 46 | #define MQTT_CONNECTION_TIMEOUT -4 47 | #define MQTT_CONNECTION_LOST -3 48 | #define MQTT_CONNECT_FAILED -2 49 | #define MQTT_DISCONNECTED -1 50 | #define MQTT_CONNECTED 0 51 | #define MQTT_CONNECT_BAD_PROTOCOL 1 52 | #define MQTT_CONNECT_BAD_CLIENT_ID 2 53 | #define MQTT_CONNECT_UNAVAILABLE 3 54 | #define MQTT_CONNECT_BAD_CREDENTIALS 4 55 | #define MQTT_CONNECT_UNAUTHORIZED 5 56 | 57 | #define MQTTCONNECT 1 << 4 // Client request to connect to Server 58 | #define MQTTCONNACK 2 << 4 // Connect Acknowledgment 59 | #define MQTTPUBLISH 3 << 4 // Publish message 60 | #define MQTTPUBACK 4 << 4 // Publish Acknowledgment 61 | #define MQTTPUBREC 5 << 4 // Publish Received (assured delivery part 1) 62 | #define MQTTPUBREL 6 << 4 // Publish Release (assured delivery part 2) 63 | #define MQTTPUBCOMP 7 << 4 // Publish Complete (assured delivery part 3) 64 | #define MQTTSUBSCRIBE 8 << 4 // Client Subscribe request 65 | #define MQTTSUBACK 9 << 4 // Subscribe Acknowledgment 66 | #define MQTTUNSUBSCRIBE 10 << 4 // Client Unsubscribe request 67 | #define MQTTUNSUBACK 11 << 4 // Unsubscribe Acknowledgment 68 | #define MQTTPINGREQ 12 << 4 // PING Request 69 | #define MQTTPINGRESP 13 << 4 // PING Response 70 | #define MQTTDISCONNECT 14 << 4 // Client is Disconnecting 71 | #define MQTTReserved 15 << 4 // Reserved 72 | 73 | #define MQTTQOS0 (0 << 1) 74 | #define MQTTQOS1 (1 << 1) 75 | #define MQTTQOS2 (2 << 1) 76 | 77 | #ifdef ESP8266 78 | #include 79 | #define MQTT_CALLBACK_SIGNATURE std::function callback 80 | #else 81 | #define MQTT_CALLBACK_SIGNATURE void (*callback)(char*, uint8_t*, unsigned int) 82 | #endif 83 | 84 | class PubSubClient { 85 | private: 86 | Client* _client; 87 | uint8_t buffer[MQTT_MAX_PACKET_SIZE]; 88 | uint16_t nextMsgId; 89 | unsigned long lastOutActivity; 90 | unsigned long lastInActivity; 91 | bool pingOutstanding; 92 | MQTT_CALLBACK_SIGNATURE; 93 | uint16_t readPacket(uint8_t*); 94 | boolean readByte(uint8_t * result); 95 | boolean readByte(uint8_t * result, uint16_t * index); 96 | boolean write(uint8_t header, uint8_t* buf, uint16_t length); 97 | uint16_t writeString(const char* string, uint8_t* buf, uint16_t pos); 98 | IPAddress ip; 99 | const char* domain; 100 | uint16_t port; 101 | Stream* stream; 102 | int _state; 103 | public: 104 | PubSubClient(); 105 | PubSubClient(Client& client); 106 | PubSubClient(IPAddress, uint16_t, Client& client); 107 | PubSubClient(IPAddress, uint16_t, Client& client, Stream&); 108 | PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 109 | PubSubClient(IPAddress, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 110 | PubSubClient(uint8_t *, uint16_t, Client& client); 111 | PubSubClient(uint8_t *, uint16_t, Client& client, Stream&); 112 | PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 113 | PubSubClient(uint8_t *, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 114 | PubSubClient(const char*, uint16_t, Client& client); 115 | PubSubClient(const char*, uint16_t, Client& client, Stream&); 116 | PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client); 117 | PubSubClient(const char*, uint16_t, MQTT_CALLBACK_SIGNATURE,Client& client, Stream&); 118 | 119 | PubSubClient& setServer(IPAddress ip, uint16_t port); 120 | PubSubClient& setServer(uint8_t * ip, uint16_t port); 121 | PubSubClient& setServer(const char * domain, uint16_t port); 122 | PubSubClient& setCallback(MQTT_CALLBACK_SIGNATURE); 123 | PubSubClient& setClient(Client& client); 124 | PubSubClient& setStream(Stream& stream); 125 | 126 | boolean connect(const char* id); 127 | boolean connect(const char* id, const char* user, const char* pass); 128 | boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); 129 | boolean connect(const char* id, const char* user, const char* pass, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage); 130 | void disconnect(); 131 | boolean publish(const char* topic, const char* payload); 132 | boolean publish(const char* topic, const char* payload, boolean retained); 133 | boolean publish(const char* topic, const uint8_t * payload, unsigned int plength); 134 | boolean publish(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); 135 | boolean publish_P(const char* topic, const uint8_t * payload, unsigned int plength, boolean retained); 136 | boolean subscribe(const char* topic); 137 | boolean subscribe(const char* topic, uint8_t qos); 138 | boolean unsubscribe(const char* topic); 139 | boolean loop(); 140 | boolean connected(); 141 | int state(); 142 | }; 143 | 144 | 145 | #endif 146 | --------------------------------------------------------------------------------