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.