2 * Argon2 reference source code package - reference C implementations
5 * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
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:
11 * - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
12 * - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
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.
23 #include "blake2-impl.h"
25 void clear_internal_memory(void *v, size_t n);
27 static const uint64_t blake2b_IV[8] = {
28 UINT64_C(0x6a09e667f3bcc908), UINT64_C(0xbb67ae8584caa73b),
29 UINT64_C(0x3c6ef372fe94f82b), UINT64_C(0xa54ff53a5f1d36f1),
30 UINT64_C(0x510e527fade682d1), UINT64_C(0x9b05688c2b3e6c1f),
31 UINT64_C(0x1f83d9abfb41bd6b), UINT64_C(0x5be0cd19137e2179)};
33 static const unsigned int blake2b_sigma[12][16] = {
34 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
35 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
36 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4},
37 {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8},
38 {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
39 {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9},
40 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
41 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
42 {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5},
43 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0},
44 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
45 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3},
48 static BLAKE2_INLINE void blake2b_set_lastnode(blake2b_state *S) {
49 S->f[1] = (uint64_t)-1;
52 static BLAKE2_INLINE void blake2b_set_lastblock(blake2b_state *S) {
54 blake2b_set_lastnode(S);
56 S->f[0] = (uint64_t)-1;
59 static BLAKE2_INLINE void blake2b_increment_counter(blake2b_state *S,
62 S->t[1] += (S->t[0] < inc);
65 static BLAKE2_INLINE void blake2b_invalidate_state(blake2b_state *S) {
66 clear_internal_memory(S, sizeof(*S)); /* wipe */
67 blake2b_set_lastblock(S); /* invalidate for further use */
70 static BLAKE2_INLINE void blake2b_init0(blake2b_state *S) {
71 memset(S, 0, sizeof(*S));
72 memcpy(S->h, blake2b_IV, sizeof(S->h));
75 int blake2b_init_param(blake2b_state *S, const blake2b_param *P) {
76 const unsigned char *p = (const unsigned char *)P;
79 if (NULL == P || NULL == S) {
84 /* IV XOR Parameter Block */
85 for (i = 0; i < 8; ++i) {
86 S->h[i] ^= load64(&p[i * sizeof(S->h[i])]);
88 S->outlen = P->digest_length;
92 /* Sequential blake2b initialization */
93 int blake2b_init(blake2b_state *S, size_t outlen) {
100 if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
101 blake2b_invalidate_state(S);
105 /* Setup Parameter Block for unkeyed BLAKE2 */
106 P.digest_length = (uint8_t)outlen;
114 memset(P.reserved, 0, sizeof(P.reserved));
115 memset(P.salt, 0, sizeof(P.salt));
116 memset(P.personal, 0, sizeof(P.personal));
118 return blake2b_init_param(S, &P);
121 int blake2b_init_key(blake2b_state *S, size_t outlen, const void *key,
129 if ((outlen == 0) || (outlen > BLAKE2B_OUTBYTES)) {
130 blake2b_invalidate_state(S);
134 if ((key == 0) || (keylen == 0) || (keylen > BLAKE2B_KEYBYTES)) {
135 blake2b_invalidate_state(S);
139 /* Setup Parameter Block for keyed BLAKE2 */
140 P.digest_length = (uint8_t)outlen;
141 P.key_length = (uint8_t)keylen;
148 memset(P.reserved, 0, sizeof(P.reserved));
149 memset(P.salt, 0, sizeof(P.salt));
150 memset(P.personal, 0, sizeof(P.personal));
152 if (blake2b_init_param(S, &P) < 0) {
153 blake2b_invalidate_state(S);
158 uint8_t block[BLAKE2B_BLOCKBYTES];
159 memset(block, 0, BLAKE2B_BLOCKBYTES);
160 memcpy(block, key, keylen);
161 blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
162 /* Burn the key from stack */
163 clear_internal_memory(block, BLAKE2B_BLOCKBYTES);
168 static void blake2b_compress(blake2b_state *S, const uint8_t *block) {
173 for (i = 0; i < 16; ++i) {
174 m[i] = load64(block + i * sizeof(m[i]));
177 for (i = 0; i < 8; ++i) {
181 v[8] = blake2b_IV[0];
182 v[9] = blake2b_IV[1];
183 v[10] = blake2b_IV[2];
184 v[11] = blake2b_IV[3];
185 v[12] = blake2b_IV[4] ^ S->t[0];
186 v[13] = blake2b_IV[5] ^ S->t[1];
187 v[14] = blake2b_IV[6] ^ S->f[0];
188 v[15] = blake2b_IV[7] ^ S->f[1];
190 #define G(r, i, a, b, c, d) \
192 a = a + b + m[blake2b_sigma[r][2 * i + 0]]; \
193 d = rotr64(d ^ a, 32); \
195 b = rotr64(b ^ c, 24); \
196 a = a + b + m[blake2b_sigma[r][2 * i + 1]]; \
197 d = rotr64(d ^ a, 16); \
199 b = rotr64(b ^ c, 63); \
204 G(r, 0, v[0], v[4], v[8], v[12]); \
205 G(r, 1, v[1], v[5], v[9], v[13]); \
206 G(r, 2, v[2], v[6], v[10], v[14]); \
207 G(r, 3, v[3], v[7], v[11], v[15]); \
208 G(r, 4, v[0], v[5], v[10], v[15]); \
209 G(r, 5, v[1], v[6], v[11], v[12]); \
210 G(r, 6, v[2], v[7], v[8], v[13]); \
211 G(r, 7, v[3], v[4], v[9], v[14]); \
214 for (r = 0; r < 12; ++r) {
218 for (i = 0; i < 8; ++i) {
219 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
226 int blake2b_update(blake2b_state *S, const void *in, size_t inlen) {
227 const uint8_t *pin = (const uint8_t *)in;
234 if (S == NULL || in == NULL) {
238 /* Is this a reused state? */
243 if (S->buflen + inlen > BLAKE2B_BLOCKBYTES) {
244 /* Complete current block */
245 size_t left = S->buflen;
246 size_t fill = BLAKE2B_BLOCKBYTES - left;
247 memcpy(&S->buf[left], pin, fill);
248 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
249 blake2b_compress(S, S->buf);
253 /* Avoid buffer copies when possible */
254 while (inlen > BLAKE2B_BLOCKBYTES) {
255 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
256 blake2b_compress(S, pin);
257 inlen -= BLAKE2B_BLOCKBYTES;
258 pin += BLAKE2B_BLOCKBYTES;
261 memcpy(&S->buf[S->buflen], pin, inlen);
262 S->buflen += (unsigned int)inlen;
266 int blake2b_final(blake2b_state *S, void *out, size_t outlen) {
267 uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
271 if (S == NULL || out == NULL || outlen < S->outlen) {
275 /* Is this a reused state? */
280 blake2b_increment_counter(S, S->buflen);
281 blake2b_set_lastblock(S);
282 memset(&S->buf[S->buflen], 0, BLAKE2B_BLOCKBYTES - S->buflen); /* Padding */
283 blake2b_compress(S, S->buf);
285 for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */
286 store64(buffer + sizeof(S->h[i]) * i, S->h[i]);
289 memcpy(out, buffer, S->outlen);
290 clear_internal_memory(buffer, sizeof(buffer));
291 clear_internal_memory(S->buf, sizeof(S->buf));
292 clear_internal_memory(S->h, sizeof(S->h));
296 int blake2b(void *out, size_t outlen, const void *in, size_t inlen,
297 const void *key, size_t keylen) {
301 /* Verify parameters */
302 if (NULL == in && inlen > 0) {
306 if (NULL == out || outlen == 0 || outlen > BLAKE2B_OUTBYTES) {
310 if ((NULL == key && keylen > 0) || keylen > BLAKE2B_KEYBYTES) {
315 if (blake2b_init_key(&S, outlen, key, keylen) < 0) {
319 if (blake2b_init(&S, outlen) < 0) {
324 if (blake2b_update(&S, in, inlen) < 0) {
327 ret = blake2b_final(&S, out, outlen);
330 clear_internal_memory(&S, sizeof(S));
334 /* Argon2 Team - Begin Code */
335 int blake2b_long(void *pout, size_t outlen, const void *in, size_t inlen) {
336 uint8_t *out = (uint8_t *)pout;
337 blake2b_state blake_state;
338 uint8_t outlen_bytes[sizeof(uint32_t)] = {0};
341 if (outlen > UINT32_MAX) {
345 /* Ensure little-endian byte order! */
346 store32(outlen_bytes, (uint32_t)outlen);
348 #define TRY(statement) \
356 if (outlen <= BLAKE2B_OUTBYTES) {
357 TRY(blake2b_init(&blake_state, outlen));
358 TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
359 TRY(blake2b_update(&blake_state, in, inlen));
360 TRY(blake2b_final(&blake_state, out, outlen));
363 uint8_t out_buffer[BLAKE2B_OUTBYTES];
364 uint8_t in_buffer[BLAKE2B_OUTBYTES];
365 TRY(blake2b_init(&blake_state, BLAKE2B_OUTBYTES));
366 TRY(blake2b_update(&blake_state, outlen_bytes, sizeof(outlen_bytes)));
367 TRY(blake2b_update(&blake_state, in, inlen));
368 TRY(blake2b_final(&blake_state, out_buffer, BLAKE2B_OUTBYTES));
369 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
370 out += BLAKE2B_OUTBYTES / 2;
371 toproduce = (uint32_t)outlen - BLAKE2B_OUTBYTES / 2;
373 while (toproduce > BLAKE2B_OUTBYTES) {
374 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
375 TRY(blake2b(out_buffer, BLAKE2B_OUTBYTES, in_buffer,
376 BLAKE2B_OUTBYTES, NULL, 0));
377 memcpy(out, out_buffer, BLAKE2B_OUTBYTES / 2);
378 out += BLAKE2B_OUTBYTES / 2;
379 toproduce -= BLAKE2B_OUTBYTES / 2;
382 memcpy(in_buffer, out_buffer, BLAKE2B_OUTBYTES);
383 TRY(blake2b(out_buffer, toproduce, in_buffer, BLAKE2B_OUTBYTES, NULL,
385 memcpy(out, out_buffer, toproduce);
388 clear_internal_memory(&blake_state, sizeof(blake_state));
392 /* Argon2 Team - End Code */