1 /* 2 BLAKE2 reference source code package - reference C implementations 3 4 Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the 5 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at 6 your option. The terms of these licenses can be found at: 7 8 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 9 - OpenSSL license : https://www.openssl.org/source/license.html 10 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 11 12 More information about the BLAKE2 hash function can be found at 13 https://blake2.net. 14 */ 15 16 #include <stdint.h> 17 #include <string.h> 18 #include <stdio.h> 19 20 #include "utils/prng/blake2.h" 21 #include "utils/prng/blake2-impl.h" 22 23 static const uint64_t blake2b_IV[8] = { 24 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 25 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 26 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL}; 27 28 static const uint8_t blake2b_sigma[12][16] = { 29 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 30 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, 31 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, 32 {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, 33 {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, 34 {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, 35 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, 36 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, 37 {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, 38 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, 39 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 40 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}}; 41 42 static void blake2b_set_lastnode(blake2b_state *S) { S->f[1] = (uint64_t)-1; } 43 44 /* Some helper functions, not necessarily useful */ 45 static int blake2b_is_lastblock(const blake2b_state *S) { return S->f[0] != 0; } 46 47 static void blake2b_set_lastblock(blake2b_state *S) { 48 if (S->last_node) blake2b_set_lastnode(S); 49 50 S->f[0] = (uint64_t)-1; 51 } 52 53 static void blake2b_increment_counter(blake2b_state *S, const uint64_t inc) { 54 S->t[0] += inc; 55 S->t[1] += (S->t[0] < inc); 56 } 57 58 static void blake2b_init0(blake2b_state *S) { 59 size_t i; 60 memset(S, 0, sizeof(blake2b_state)); 61 62 for (i = 0; i < 8; ++i) S->h[i] = blake2b_IV[i]; 63 } 64 65 /* init xors IV with input parameter block */ 66 int blake2b_init_param(blake2b_state *S, const blake2b_param *P) { 67 const uint8_t *p = (const uint8_t *)(P); 68 size_t i; 69 70 blake2b_init0(S); 71 72 /* IV XOR ParamBlock */ 73 for (i = 0; i < 8; ++i) S->h[i] ^= load64(p + sizeof(S->h[i]) * i); 74 75 S->outlen = P->digest_length; SHA256(string message,vector<int64_t> & digest)76 return 0; 77 } 78 79 int blake2b_init(blake2b_state *S, size_t outlen) { 80 blake2b_param P[1]; 81 82 if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) return -1; 83 84 P->digest_length = (uint8_t)outlen; 85 P->key_length = 0; 86 P->fanout = 1; 87 P->depth = 1; 88 store32(&P->leaf_length, 0); 89 store32(&P->node_offset, 0); 90 store32(&P->xof_length, 0); 91 P->node_depth = 0; 92 P->inner_length = 0; 93 memset(P->reserved, 0, sizeof(P->reserved)); 94 memset(P->salt, 0, sizeof(P->salt)); 95 memset(P->personal, 0, sizeof(P->personal)); 96 return blake2b_init_param(S, P); 97 } 98 99 int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, 100 size_t keylen) { 101 blake2b_param P[1]; 102 103 if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) return -1; 104 105 if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) return -1; 106 107 P->digest_length = (uint8_t)outlen; 108 P->key_length = (uint8_t)keylen; 109 P->fanout = 1; 110 P->depth = 1; 111 store32(&P->leaf_length, 0); 112 store32(&P->node_offset, 0); 113 store32(&P->xof_length, 0); 114 P->node_depth = 0; 115 P->inner_length = 0; 116 memset(P->reserved, 0, sizeof(P->reserved)); 117 memset(P->salt, 0, sizeof(P->salt)); 118 memset(P->personal, 0, sizeof(P->personal)); 119 120 if (blake2b_init_param(S, P) < 0) return -1; 121 122 { 123 uint8_t block[BLAKE2B_BLOCKBYTES]; 124 memset(block, 0, BLAKE2B_BLOCKBYTES); 125 memcpy(block, key, keylen); 126 blake2b_update(S, block, BLAKE2B_BLOCKBYTES); 127 secure_zero_memory(block, BLAKE2B_BLOCKBYTES); /* Burn the key from stack */ 128 } 129 return 0; 130 } 131 132 #define G(r, i, a, b, c, d) \ 133 do { \ 134 a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ 135 d = rotr64(d ^ a, 32); \ 136 c = c + d; \ 137 b = rotr64(b ^ c, 24); \ 138 a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ 139 d = rotr64(d ^ a, 16); \ 140 c = c + d; \ 141 b = rotr64(b ^ c, 63); \ 142 } while (0) 143 144 #define ROUND(r) \ 145 do { \ 146 G(r, 0, v[0], v[4], v[8], v[12]); \ 147 G(r, 1, v[1], v[5], v[9], v[13]); \ 148 G(r, 2, v[2], v[6], v[10], v[14]); \ 149 G(r, 3, v[3], v[7], v[11], v[15]); \ 150 G(r, 4, v[0], v[5], v[10], v[15]); \ 151 G(r, 5, v[1], v[6], v[11], v[12]); \ 152 G(r, 6, v[2], v[7], v[8], v[13]); \ 153 G(r, 7, v[3], v[4], v[9], v[14]); \ 154 } while (0) 155 156 static void blake2b_compress(blake2b_state *S, 157 const uint8_t block[BLAKE2B_BLOCKBYTES]) { 158 uint64_t m[16]; 159 uint64_t v[16]; 160 size_t i; 161 162 for (i = 0; i < 16; ++i) { 163 m[i] = load64(block + i * sizeof(m[i])); 164 } 165 166 for (i = 0; i < 8; ++i) { HashString(std::string message)167 v[i] = S->h[i]; 168 } 169 170 v[8] = blake2b_IV[0]; 171 v[9] = blake2b_IV[1]; 172 v[10] = blake2b_IV[2]; 173 v[11] = blake2b_IV[3]; 174 v[12] = blake2b_IV[4] ^ S->t[0]; 175 v[13] = blake2b_IV[5] ^ S->t[1]; 176 v[14] = blake2b_IV[6] ^ S->f[0]; 177 v[15] = blake2b_IV[7] ^ S->f[1]; 178 179 ROUND(0); 180 ROUND(1); 181 ROUND(2); 182 ROUND(3); 183 ROUND(4); 184 ROUND(5); 185 ROUND(6); 186 ROUND(7); 187 ROUND(8); 188 ROUND(9); 189 ROUND(10); 190 ROUND(11); 191 192 for (i = 0; i < 8; ++i) { 193 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; 194 } 195 } 196 197 #undef G 198 #undef ROUND 199 200 int blake2b_update(blake2b_state *S, const void *pin, size_t inlen) { 201 const unsigned char *in = (const unsigned char *)pin; 202 if (inlen > 0) { 203 size_t left = S->buflen; 204 size_t fill = BLAKE2B_BLOCKBYTES - left; 205 if (inlen > fill) { 206 S->buflen = 0; 207 memcpy(S->buf + left, in, fill); /* Fill buffer */ 208 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); 209 blake2b_compress(S, S->buf); /* Compress */ 210 in += fill; 211 inlen -= fill; 212 while (inlen > BLAKE2B_BLOCKBYTES) { 213 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); 214 blake2b_compress(S, in); 215 in += BLAKE2B_BLOCKBYTES; 216 inlen -= BLAKE2B_BLOCKBYTES; 217 } 218 } 219 memcpy(S->buf + S->buflen, in, inlen); 220 S->buflen += inlen; 221 } 222 return 0; 223 } 224 225 int blake2b_final(blake2b_state *S, void *out, size_t outlen) { 226 uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; 227 size_t i; 228 229 if (out == NULL || outlen < S->outlen) return -1; 230 231 if (blake2b_is_lastblock(S)) return -1; 232 233 blake2b_increment_counter(S, S->buflen); 234 blake2b_set_lastblock(S); 235 memset(S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ 236 blake2b_compress(S, S->buf); 237 238 for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */ 239 store64(buffer + sizeof(S->h[i]) * i, S->h[i]); 240 241 memcpy(out, buffer, S->outlen); 242 secure_zero_memory(buffer, sizeof(buffer)); 243 return 0; 244 } 245 246 /* inlen, at least, should be uint64_t. Others can be size_t. */ 247 int blake2b(void *out, size_t outlen, const void *in, size_t inlen, 248 const void *key, size_t keylen) { 249 blake2b_state S[1]; 250 251 /* Verify parameters */ 252 if (NULL == in && inlen > 0) return -1; 253 254 if (NULL == out) return -1; 255 256 if (NULL == key && keylen > 0) return -1; 257 258 if (!outlen || outlen > BLAKE2B_OUTBYTES) return -1; 259 260 if (keylen > BLAKE2B_KEYBYTES) return -1; 261 262 if (keylen > 0) { 263 if (blake2b_init_key(S, outlen, key, keylen) < 0) return -1; 264 } else { 265 if (blake2b_init(S, outlen) < 0) return -1; 266 } 267 268 blake2b_update(S, (const uint8_t *)in, inlen); 269 blake2b_final(S, out, outlen); 270 return 0; 271 } 272 273 int blake2(void *out, size_t outlen, const void *in, size_t inlen, 274 const void *key, size_t keylen) { 275 return blake2b(out, outlen, in, inlen, key, keylen); 276 } 277 278 #if defined(SUPERCOP) 279 int crypto_hash(unsigned char *out, unsigned char *in, 280 unsigned long long inlen) { 281 return blake2b(out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0); 282 } 283 #endif 284 285 #if defined(BLAKE2B_SELFTEST) 286 #include <string.h> 287 #include "blake2-kat.h" 288 int main(void) { 289 uint8_t key[BLAKE2B_KEYBYTES]; 290 uint8_t buf[BLAKE2_KAT_LENGTH]; 291 size_t i, step; 292 293 for (i = 0; i < BLAKE2B_KEYBYTES; ++i) key[i] = (uint8_t)i; 294 295 for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) buf[i] = (uint8_t)i; 296 297 /* Test simple API */ 298 for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 299 uint8_t hash[BLAKE2B_OUTBYTES]; 300 blake2b(hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES); 301 302 if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) { 303 goto fail; 304 } 305 } 306 307 /* Test streaming API */ 308 for (step = 1; step < BLAKE2B_BLOCKBYTES; ++step) { 309 for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) { 310 uint8_t hash[BLAKE2B_OUTBYTES]; 311 blake2b_state S; 312 uint8_t *p = buf; 313 size_t mlen = i; 314 int err = 0; 315 316 if ((err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, 317 BLAKE2B_KEYBYTES)) < 0) { 318 goto fail; 319 } 320 321 while (mlen >= step) { 322 if ((err = blake2b_update(&S, p, step)) < 0) { 323 goto fail; 324 } 325 mlen -= step; 326 p += step; 327 } 328 if ((err = blake2b_update(&S, p, mlen)) < 0) { 329 goto fail; 330 } 331 if ((err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) { 332 goto fail; 333 } 334 335 if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) { 336 goto fail; 337 } 338 } 339 } 340 341 puts("ok"); 342 return 0; 343 fail: 344 puts("error"); 345 return -1; 346 } 347 #endif 348