25 #include "utility/EndianUtil.h"
26 #include "utility/RotateUtil.h"
27 #include "utility/ProgMemUtil.h"
110 #define BLAKE2b_IV0 0x6a09e667f3bcc908ULL
111 #define BLAKE2b_IV1 0xbb67ae8584caa73bULL
112 #define BLAKE2b_IV2 0x3c6ef372fe94f82bULL
113 #define BLAKE2b_IV3 0xa54ff53a5f1d36f1ULL
114 #define BLAKE2b_IV4 0x510e527fade682d1ULL
115 #define BLAKE2b_IV5 0x9b05688c2b3e6c1fULL
116 #define BLAKE2b_IV6 0x1f83d9abfb41bd6bULL
117 #define BLAKE2b_IV7 0x5be0cd19137e2179ULL
121 state.h[0] = BLAKE2b_IV0 ^ 0x01010040;
122 state.h[1] = BLAKE2b_IV1;
123 state.h[2] = BLAKE2b_IV2;
124 state.h[3] = BLAKE2b_IV3;
125 state.h[4] = BLAKE2b_IV4;
126 state.h[5] = BLAKE2b_IV5;
127 state.h[6] = BLAKE2b_IV6;
128 state.h[7] = BLAKE2b_IV7;
131 state.lengthHigh = 0;
143 if (outputLength < 1)
145 else if (outputLength > 64)
147 state.h[0] = BLAKE2b_IV0 ^ 0x01010000 ^ outputLength;
148 state.h[1] = BLAKE2b_IV1;
149 state.h[2] = BLAKE2b_IV2;
150 state.h[3] = BLAKE2b_IV3;
151 state.h[4] = BLAKE2b_IV4;
152 state.h[5] = BLAKE2b_IV5;
153 state.h[6] = BLAKE2b_IV6;
154 state.h[7] = BLAKE2b_IV7;
157 state.lengthHigh = 0;
176 if (outputLength < 1)
178 else if (outputLength > 64)
180 state.h[0] = BLAKE2b_IV0 ^ 0x01010000 ^ (keyLen << 8) ^ outputLength;
181 state.h[1] = BLAKE2b_IV1;
182 state.h[2] = BLAKE2b_IV2;
183 state.h[3] = BLAKE2b_IV3;
184 state.h[4] = BLAKE2b_IV4;
185 state.h[5] = BLAKE2b_IV5;
186 state.h[6] = BLAKE2b_IV6;
187 state.h[7] = BLAKE2b_IV7;
190 memcpy(state.m, key, keyLen);
191 memset(((uint8_t *)state.m) + keyLen, 0, 128 - keyLen);
192 state.chunkSize = 128;
193 state.lengthLow = 128;
199 state.lengthHigh = 0;
205 const uint8_t *d = (
const uint8_t *)data;
207 if (state.chunkSize == 128) {
213 uint8_t size = 128 - state.chunkSize;
216 memcpy(((uint8_t *)state.m) + state.chunkSize, d, size);
217 state.chunkSize += size;
218 uint64_t temp = state.lengthLow;
219 state.lengthLow += size;
220 if (state.lengthLow < temp)
230 memset(((uint8_t *)state.m) + state.chunkSize, 0, 128 - state.chunkSize);
231 processChunk(0xFFFFFFFFFFFFFFFFULL);
234 for (uint8_t posn = 0; posn < 8; ++posn)
235 state.m[posn] = htole64(state.h[posn]);
240 memcpy(hash, state.m, len);
252 state.lengthLow += 128;
253 state.chunkSize = 128;
261 state.lengthLow += 128;
262 state.chunkSize = 128;
263 update(temp,
sizeof(temp));
269 static const uint8_t sigma[12][16] PROGMEM = {
270 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
271 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
272 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
273 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
274 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
275 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
276 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
277 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
278 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
279 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0},
280 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
281 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
285 #define quarterRound(a, b, c, d, i) \
288 uint64_t _a = (a) + _b + state.m[pgm_read_byte(&(sigma[index][2 * (i)]))]; \
289 uint64_t _d = rightRotate32_64((d) ^ _a); \
290 uint64_t _c = (c) + _d; \
291 _b = rightRotate24_64(_b ^ _c); \
292 _a += _b + state.m[pgm_read_byte(&(sigma[index][2 * (i) + 1]))]; \
293 (d) = _d = rightRotate16_64(_d ^ _a); \
296 (b) = rightRotate63_64(_b ^ _c); \
300 void BLAKE2b::processChunk(uint64_t f0)
306 #if !defined(CRYPTO_LITTLE_ENDIAN)
307 for (index = 0; index < 16; ++index)
308 state.m[index] = le64toh(state.m[index]);
312 memcpy(v, state.h,
sizeof(state.h));
317 v[12] = BLAKE2b_IV4 ^ state.lengthLow;
318 v[13] = BLAKE2b_IV5 ^ state.lengthHigh;
319 v[14] = BLAKE2b_IV6 ^ f0;
323 for (index = 0; index < 12; ++index) {
325 quarterRound(v[0], v[4], v[8], v[12], 0);
326 quarterRound(v[1], v[5], v[9], v[13], 1);
327 quarterRound(v[2], v[6], v[10], v[14], 2);
328 quarterRound(v[3], v[7], v[11], v[15], 3);
331 quarterRound(v[0], v[5], v[10], v[15], 4);
332 quarterRound(v[1], v[6], v[11], v[12], 5);
333 quarterRound(v[2], v[7], v[8], v[13], 6);
334 quarterRound(v[3], v[4], v[9], v[14], 7);
338 for (index = 0; index < 8; ++index)
339 state.h[index] ^= (v[index] ^ v[index + 8]);
void finalize(void *hash, size_t len)
Finalizes the hashing process and returns the hash.
BLAKE2b()
Constructs a BLAKE2b hash object.
void clear()
Clears the hash state, removing all sensitive data, and then resets the hash ready for a new hashing ...
void finalizeHMAC(const void *key, size_t keyLen, void *hash, size_t hashLen)
Finalizes the HMAC hashing process and returns the hash.
size_t hashSize() const
Size of the hash result from finalize().
void update(const void *data, size_t len)
Updates the hash with more data.
size_t blockSize() const
Size of the internal block used by the hash algorithm.
void reset()
Resets the hash ready for a new hashing process.
void resetHMAC(const void *key, size_t keyLen)
Resets the hash ready for a new HMAC hashing process.
virtual ~BLAKE2b()
Destroys this BLAKE2b hash object after clearing sensitive information.
void formatHMACKey(void *block, const void *key, size_t len, uint8_t pad)
Formats a HMAC key into a block.