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