1/* 2 * Argon2 reference source code package - reference C implementations 3 * 4 * Copyright 2015 5 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves 6 * 7 * You may use this work under the terms of a Creative Commons CC0 1.0 8 * License/Waiver or the Apache Public License 2.0, at your option. The terms of 9 * these licenses can be found at: 10 * 11 * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0 12 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * You should have received a copy of both of these licenses along with this 15 * software. If not, they may be obtained at the above URLs. 16 */ 17 18#include <stdint.h> 19#include <string.h> 20#include <stdio.h> 21 22#include "blake2.h" 23#include "blake2-impl.h" 24 25static const uint64_t blake2b_IV[8] = { 26 UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b), 27 UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1), 28 UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f), 29 UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)}; 30 31static const unsigned int blake2b_sigma[12][16] = { 32 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 33 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, 34 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4}, 35 {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8}, 36 {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13}, 37 {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9}, 38 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11}, 39 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10}, 40 {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5}, 41 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0}, 42 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 43 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3}, 44}; 45 46static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) { 47 S->f[1] = (uint64_t)-1; 48} 49 50static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) { 51 if (S->last_node) { 52 blake2b_set_lastnode(S); 53 } 54 S->f[0] = (uint64_t)-1; 55} 56 57static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S, 58 uint64_t inc) { 59 S->t[0] += inc; 60 S->t[1] += (S->t[0] < inc); 61} 62 63static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) { 64 clear_internal_memory(S, sizeof(*S)); /* wipe */ 65 blake2b_set_lastblock(S); /* invalidate for further use */ 66} 67 68static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) { 69 memset(S, 0, sizeof(*S)); 70 memcpy(S->h, blake2b_IV, sizeof(S->h)); 71} 72 73int blake2b_init_param(blake2b_state *S, const blake2b_param *P) { 74 const unsigned char *p = (const unsigned char *)P; 75 unsigned int i; 76 77 if (NULL == P || NULL == S) { 78 return -1; 79 } 80 81 blake2b_init0(S); 82 /* IV XOR Parameter Block */ 83 for (i = 0; i < 8; ++i) { 84 S->h[i] ^= load64(&p[i * sizeof(S->h[i])]); 85 } 86 S->outlen = P->digest_length; 87 return 0; 88} 89 90/* Sequential blake2b initialization */ 91int blake2b_init(blake2b_state *S, size_t outlen) { 92 blake2b_param P; 93 94 if (S == NULL) { 95 return -1; 96 } 97 98 if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { 99 blake2b_invalidate_state(S); 100 return -1; 101 } 102 103 /* Setup Parameter Block for unkeyed BLAKE2 */ 104 P.digest_length = (uint8_t)outlen; 105 P.key_length = 0; 106 P.fanout = 1; 107 P.depth = 1; 108 P.leaf_length = 0; 109 P.node_offset = 0; 110 P.node_depth = 0; 111 P.inner_length = 0; 112 memset(P.reserved, 0, sizeof(P.reserved)); 113 memset(P.salt, 0, sizeof(P.salt)); 114 memset(P.personal, 0, sizeof(P.personal)); 115 116 return blake2b_init_param(S, &P); 117} 118 119int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key, 120 size_t keylen) { 121 blake2b_param P; 122 123 if (S == NULL) { 124 return -1; 125 } 126 127 if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) { 128 blake2b_invalidate_state(S); 129 return -1; 130 } 131 132 if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) { 133 blake2b_invalidate_state(S); 134 return -1; 135 } 136 137 /* Setup Parameter Block for keyed BLAKE2 */ 138 P.digest_length = (uint8_t)outlen; 139 P.key_length = (uint8_t)keylen; 140 P.fanout = 1; 141 P.depth = 1; 142 P.leaf_length = 0; 143 P.node_offset = 0; 144 P.node_depth = 0; 145 P.inner_length = 0; 146 memset(P.reserved, 0, sizeof(P.reserved)); 147 memset(P.salt, 0, sizeof(P.salt)); 148 memset(P.personal, 0, sizeof(P.personal)); 149 150 if (blake2b_init_param(S, &P) < 0) { 151 blake2b_invalidate_state(S); 152 return -1; 153 } 154 155 { 156 uint8_t block[BLAKE2B_BLOCKBYTES]; 157 memset(block, 0, BLAKE2B_BLOCKBYTES); 158 memcpy(block, key, keylen); 159 blake2b_update(S, block, BLAKE2B_BLOCKBYTES); 160 /* Burn the key from stack */ 161 clear_internal_memory(block, BLAKE2B_BLOCKBYTES); 162 } 163 return 0; 164} 165 166static void blake2b_compress(blake2b_state *S, const uint8_t *block) { 167 uint64_t m[16]; 168 uint64_t v[16]; 169 unsigned int i, r; 170 171 for (i = 0; i < 16; ++i) { 172 m[i] = load64(block + i * sizeof(m[i])); 173 } 174 175 for (i = 0; i < 8; ++i) { 176 v[i] = S->h[i]; 177 } 178 179 v[8] = blake2b_IV[0]; 180 v[9] = blake2b_IV[1]; 181 v[10] = blake2b_IV[2]; 182 v[11] = blake2b_IV[3]; 183 v[12] = blake2b_IV[4] ^ S->t[0]; 184 v[13] = blake2b_IV[5] ^ S->t[1]; 185 v[14] = blake2b_IV[6] ^ S->f[0]; 186 v[15] = blake2b_IV[7] ^ S->f[1]; 187 188#define G(r, i, a, b, c, d) \ 189 do { \ 190 a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \ 191 d = rotr64(d ^ a, 32); \ 192 c = c + d; \ 193 b = rotr64(b ^ c, 24); \ 194 a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \ 195 d = rotr64(d ^ a, 16); \ 196 c = c + d; \ 197 b = rotr64(b ^ c, 63); \ 198 } while ((void)0, 0) 199 200#define ROUND(r) \ 201 do { \ 202 G(r, 0, v[0], v[4], v[8], v[12]); \ 203 G(r, 1, v[1], v[5], v[9], v[13]); \ 204 G(r, 2, v[2], v[6], v[10], v[14]); \ 205 G(r, 3, v[3], v[7], v[11], v[15]); \ 206 G(r, 4, v[0], v[5], v[10], v[15]); \ 207 G(r, 5, v[1], v[6], v[11], v[12]); \ 208 G(r, 6, v[2], v[7], v[8], v[13]); \ 209 G(r, 7, v[3], v[4], v[9], v[14]); \ 210 } while ((void)0, 0) 211 212 for (r = 0; r < 12; ++r) { 213 ROUND(r); 214 } 215 216 for (i = 0; i < 8; ++i) { 217 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8]; 218 } 219 220#undef G 221#undef ROUND 222} 223 224int blake2b_update(blake2b_state *S, const void *in, size_t inlen) { 225 const uint8_t *pin = (const uint8_t *)in; 226 227 if (inlen == 0) { 228 return 0; 229 } 230 231 /* Sanity check */ 232 if (S == NULL || in == NULL) { 233 return -1; 234 } 235 236 /* Is this a reused state? */ 237 if (S->f[0] != 0) { 238 return -1; 239 } 240 241 if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) { 242 /* Complete current block */ 243 size_t left = S->buflen; 244 size_t fill = BLAKE2B_BLOCKBYTES - left; 245 memcpy(&S->buf[left], pin, fill); 246 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); 247 blake2b_compress(S, S->buf); 248 S->buflen = 0; 249 inlen -= fill; 250 pin += fill; 251 /* Avoid buffer copies when possible */ 252 while (inlen > BLAKE2B_BLOCKBYTES) { 253 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES); 254 blake2b_compress(S, pin); 255 inlen -= BLAKE2B_BLOCKBYTES; 256 pin += BLAKE2B_BLOCKBYTES; 257 } 258 } 259 memcpy(&S->buf[S->buflen], pin, inlen); 260 S->buflen += (unsigned int)inlen; 261 return 0; 262} 263 264int blake2b_final(blake2b_state *S, void *out, size_t outlen) { 265 uint8_t buffer[BLAKE2B_OUTBYTES] = {0}; 266 unsigned int i; 267 268 /* Sanity checks */ 269 if (S == NULL || out == NULL || outlen < S->outlen) { 270 return -1; 271 } 272 273 /* Is this a reused state? */ 274 if (S->f[0] != 0) { 275 return -1; 276 } 277 278 blake2b_increment_counter(S, S->buflen); 279 blake2b_set_lastblock(S); 280 memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */ 281 blake2b_compress(S, S->buf); 282 283 for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */ 284 store64(buffer + sizeof(S->h[i]) * i, S->h[i]); 285 } 286 287 memcpy(out, buffer, S->outlen); 288 clear_internal_memory(buffer, sizeof(buffer)); 289 clear_internal_memory(S->buf, sizeof(S->buf)); 290 clear_internal_memory(S->h, sizeof(S->h)); 291 return 0; 292} 293 294int blake2b(void *out, size_t outlen, const void *in, size_t inlen, 295 const void *key, size_t keylen) { 296 blake2b_state S; 297 int ret = -1; 298 299 /* Verify parameters */ 300 if (NULL == in && inlen > 0) { 301 goto fail; 302 } 303 304 if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) { 305 goto fail; 306 } 307 308 if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) { 309 goto fail; 310 } 311 312 if (keylen > 0) { 313 if (blake2b_init_key(&S, outlen, key, keylen) < 0) { 314 goto fail; 315 } 316 } else { 317 if (blake2b_init(&S, outlen) < 0) { 318 goto fail; 319 } 320 } 321 322 if (blake2b_update(&S, in, inlen) < 0) { 323 goto fail; 324 } 325 ret = blake2b_final(&S, out, outlen); 326 327fail: 328 clear_internal_memory(&S, sizeof(S)); 329 return ret; 330} 331 332/* Argon2 Team - Begin Code */ 333int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) { 334 uint8_t *out = (uint8_t *)pout; 335 blake2b_state blake_state; 336 uint8_t outlen_bytes[sizeof(uint32_t)] = {0}; 337 int ret = -1; 338 339 if (outlen > UINT32_MAX) { 340 goto fail; 341 } 342 343 /* Ensure little-endian byte order! */ 344 store32(outlen_bytes, (uint32_t)outlen); 345 346#define TRY(statement) \ 347 do { \ 348 ret = statement; \ 349 if (ret < 0) { \ 350 goto fail; \ 351 } \ 352 } while ((void)0, 0) 353 354 if (outlen <= BLAKE2B_OUTBYTES) { 355 TRY(blake2b_init(&blake_state, outlen)); 356 TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); 357 TRY(blake2b_update(&blake_state, in, inlen)); 358 TRY(blake2b_final(&blake_state, out, outlen)); 359 } else { 360 uint32_t toproduce; 361 uint8_t out_buffer[BLAKE2B_OUTBYTES]; 362 uint8_t in_buffer[BLAKE2B_OUTBYTES]; 363 TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES)); 364 TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes))); 365 TRY(blake2b_update(&blake_state, in, inlen)); 366 TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES)); 367 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); 368 out += BLAKE2B_OUTBYTES / 2; 369 toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2; 370 371 while (toproduce > BLAKE2B_OUTBYTES) { 372 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); 373 TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer, 374 BLAKE2B_OUTBYTES, NULL, 0)); 375 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2); 376 out += BLAKE2B_OUTBYTES / 2; 377 toproduce -= BLAKE2B_OUTBYTES / 2; 378 } 379 380 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES); 381 TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL, 382 0)); 383 memcpy(out, out_buffer, toproduce); 384 } 385fail: 386 clear_internal_memory(&blake_state, sizeof(blake_state)); 387 return ret; 388#undef TRY 389} 390/* Argon2 Team - End Code */ 391