2 * An extremely minimal crypto library for Arduino devices.
4 * The SHA256 and AES implementations are derived from axTLS
5 * (http://axtls.sourceforge.net/), Copyright (c) 2008, Cameron Rich.
7 * Ported and refactored by Chris Ellis 2016.
17 #define SHA256_SIZE 32
18 #define SHA256HMAC_SIZE 32
19 #define SHA256HMAC_BLOCKSIZE 64
20 #define AES_MAXROUNDS 14
21 #define AES_BLOCKSIZE 16
22 #define AES_IV_SIZE 16
23 #define AES_IV_LENGTH 16
24 #define AES_128_KEY_LENGTH 16
25 #define AES_256_KEY_LENGTH 16
28 * Compute a SHA256 hash
35 * Update the hash with new data
37 void doUpdate(const byte *msg, int len);
38 void doUpdate(const char *msg, unsigned int len) { doUpdate((byte*) msg, len); }
39 void doUpdate(const char *msg) { doUpdate((byte*) msg, strlen(msg)); }
41 * Compute the final hash and store it in [digest], digest must be
44 void doFinal(byte *digest);
46 * Compute the final hash and check it matches this given expected hash
48 bool matches(const byte *expected);
50 void SHA256_Process(const byte digest[64]);
56 #define HMAC_OPAD 0x5C
57 #define HMAC_IPAD 0x36
60 * Compute a HMAC using SHA256
66 * Compute a SHA256 HMAC with the given [key] key of [length] bytes
69 SHA256HMAC(const byte *key, unsigned int keyLen);
71 * Update the hash with new data
73 void doUpdate(const byte *msg, unsigned int len);
74 void doUpdate(const char *msg, unsigned int len) { doUpdate((byte*) msg, len); }
75 void doUpdate(const char *msg) { doUpdate((byte*) msg, strlen(msg)); }
77 * Compute the final hash and store it in [digest], digest must be
80 void doFinal(byte *digest);
82 * Compute the final hash and check it matches this given expected hash
84 bool matches(const byte *expected);
86 void blockXor(const byte *in, byte *out, byte val, byte len);
88 byte _innerKey[SHA256HMAC_BLOCKSIZE];
89 byte _outerKey[SHA256HMAC_BLOCKSIZE];
93 * AES 128 and 256, based on code from axTLS
105 CIPHER_ENCRYPT = 0x01,
106 CIPHER_DECRYPT = 0x02
109 * Create this cipher instance in either encrypt or decrypt mode
111 * Use the given [key] which must be 16 bytes long for AES 128 and
112 * 32 bytes for AES 256
114 * Use the given [iv] initialistion vection which must be 16 bytes long
116 * Use the either AES 128 or AES 256 as specified by [mode]
118 * Either encrypt or decrypt as specified by [cipherMode]
120 AES(const uint8_t *key, const uint8_t *iv, AES_MODE mode, CIPHER_MODE cipherMode);
122 * Either encrypt or decrypt [in] and store into [out] for [length] bytes.
124 * Note: the length must be a multiple of 16 bytes
126 void process(const uint8_t *in, uint8_t *out, int length);
127 void encryptCTR(const uint8_t *in, uint8_t *out, int length);
128 void encryptCBC(const uint8_t *in, uint8_t *out, int length);
129 void decryptCBC(const uint8_t *in, uint8_t *out, int length);
133 void encrypt(uint32_t *data);
134 void decrypt(uint32_t *data);
137 uint32_t _ks[(AES_MAXROUNDS+1)*8];
138 uint8_t _iv[AES_IV_SIZE];
139 CIPHER_MODE _cipherMode;
143 * ESP8266 specific random number generator
149 * Fill the [dst] array with [length] random bytes
151 static void fill(uint8_t *dst, unsigned int length);
157 * Get a 32bit random number
159 static uint32_t getLong();