comparison libtomcrypt/src/hashes/blake2s.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents
children
comparison
equal deleted inserted replaced
1470:8bba51a55704 1471:6dba84798cd5
1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
2 *
3 * LibTomCrypt is a library that provides various cryptographic
4 * algorithms in a highly modular and flexible manner.
5 *
6 * The library is free for all purposes without any express
7 * guarantee it works.
8 */
9
10 /*
11 BLAKE2 reference source code package - reference C implementations
12
13 Copyright 2012, Samuel Neves <[email protected]>. You may use this under the
14 terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
15 your option. The terms of these licenses can be found at:
16
17 - CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
18 - OpenSSL license : https://www.openssl.org/source/license.html
19 - Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
20
21 More information about the BLAKE2 hash function can be found at
22 https://blake2.net.
23 */
24 /* see also https://www.ietf.org/rfc/rfc7693.txt */
25
26 #include "tomcrypt.h"
27
28 #ifdef LTC_BLAKE2S
29
30 enum blake2s_constant {
31 BLAKE2S_BLOCKBYTES = 64,
32 BLAKE2S_OUTBYTES = 32,
33 BLAKE2S_KEYBYTES = 32,
34 BLAKE2S_SALTBYTES = 8,
35 BLAKE2S_PERSONALBYTES = 8,
36 BLAKE2S_PARAM_SIZE = 32
37 };
38
39 /* param offsets */
40 enum {
41 O_DIGEST_LENGTH = 0,
42 O_KEY_LENGTH = 1,
43 O_FANOUT = 2,
44 O_DEPTH = 3,
45 O_LEAF_LENGTH = 4,
46 O_NODE_OFFSET = 8,
47 O_XOF_LENGTH = 12,
48 O_NODE_DEPTH = 14,
49 O_INNER_LENGTH = 15,
50 O_SALT = 16,
51 O_PERSONAL = 24
52 };
53
54 /*
55 struct blake2s_param {
56 unsigned char digest_length;
57 unsigned char key_length;
58 unsigned char fanout;
59 unsigned char depth;
60 ulong32 leaf_length;
61 ulong32 node_offset;
62 ushort16 xof_length;
63 unsigned char node_depth;
64 unsigned char inner_length;
65 unsigned char salt[BLAKE2S_SALTBYTES];
66 unsigned char personal[BLAKE2S_PERSONALBYTES];
67 };
68 */
69
70 const struct ltc_hash_descriptor blake2s_128_desc =
71 {
72 "blake2s-128",
73 21,
74 16,
75 64,
76 { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 4 },
77 11,
78 &blake2s_128_init,
79 &blake2s_process,
80 &blake2s_done,
81 &blake2s_128_test,
82 NULL
83 };
84
85 const struct ltc_hash_descriptor blake2s_160_desc =
86 {
87 "blake2s-160",
88 22,
89 20,
90 64,
91 { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 5 },
92 11,
93 &blake2s_160_init,
94 &blake2s_process,
95 &blake2s_done,
96 &blake2s_160_test,
97 NULL
98 };
99
100 const struct ltc_hash_descriptor blake2s_224_desc =
101 {
102 "blake2s-224",
103 23,
104 28,
105 64,
106 { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 7 },
107 11,
108 &blake2s_224_init,
109 &blake2s_process,
110 &blake2s_done,
111 &blake2s_224_test,
112 NULL
113 };
114
115 const struct ltc_hash_descriptor blake2s_256_desc =
116 {
117 "blake2s-256",
118 24,
119 32,
120 64,
121 { 1, 3, 6, 1, 4, 1, 1722, 12, 2, 2, 8 },
122 11,
123 &blake2s_256_init,
124 &blake2s_process,
125 &blake2s_done,
126 &blake2s_256_test,
127 NULL
128 };
129
130 static const ulong32 blake2s_IV[8] = {
131 0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
132 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
133 };
134
135 static const unsigned char blake2s_sigma[10][16] = {
136 { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 },
137 { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
138 { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
139 { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
140 { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 },
141 { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
142 { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 },
143 { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 },
144 { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
145 { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
146 };
147
148 static void blake2s_set_lastnode(hash_state *md) { md->blake2s.f[1] = 0xffffffffUL; }
149
150 /* Some helper functions, not necessarily useful */
151 static int blake2s_is_lastblock(const hash_state *md) { return md->blake2s.f[0] != 0; }
152
153 static void blake2s_set_lastblock(hash_state *md)
154 {
155 if (md->blake2s.last_node)
156 blake2s_set_lastnode(md);
157
158 md->blake2s.f[0] = 0xffffffffUL;
159 }
160
161 static void blake2s_increment_counter(hash_state *md, const ulong32 inc)
162 {
163 md->blake2s.t[0] += inc;
164 if (md->blake2s.t[0] < inc) md->blake2s.t[1]++;
165 }
166
167 static int blake2s_init0(hash_state *md)
168 {
169 int i;
170 XMEMSET(&md->blake2s, 0, sizeof(struct blake2s_state));
171
172 for (i = 0; i < 8; ++i)
173 md->blake2s.h[i] = blake2s_IV[i];
174
175 return CRYPT_OK;
176 }
177
178 /* init2 xors IV with input parameter block */
179 static int blake2s_init_param(hash_state *md, const unsigned char *P)
180 {
181 unsigned long i;
182
183 blake2s_init0(md);
184
185 /* IV XOR ParamBlock */
186 for (i = 0; i < 8; ++i) {
187 ulong32 tmp;
188 LOAD32L(tmp, P + i * 4);
189 md->blake2s.h[i] ^= tmp;
190 }
191
192 md->blake2s.outlen = P[O_DIGEST_LENGTH];
193 return CRYPT_OK;
194 }
195
196 int blake2s_init(hash_state *md, unsigned long outlen, const unsigned char *key, unsigned long keylen)
197 {
198 unsigned char P[BLAKE2S_PARAM_SIZE];
199 int err;
200
201 LTC_ARGCHK(md != NULL);
202
203 if ((!outlen) || (outlen > BLAKE2S_OUTBYTES))
204 return CRYPT_INVALID_ARG;
205
206 if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2S_KEYBYTES))
207 return CRYPT_INVALID_ARG;
208
209 XMEMSET(P, 0, sizeof(P));
210
211 P[O_DIGEST_LENGTH] = (unsigned char)outlen;
212 P[O_KEY_LENGTH] = (unsigned char)keylen;
213 P[O_FANOUT] = 1;
214 P[O_DEPTH] = 1;
215
216 err = blake2s_init_param(md, P);
217 if (err != CRYPT_OK) return err;
218
219 if (key) {
220 unsigned char block[BLAKE2S_BLOCKBYTES];
221
222 XMEMSET(block, 0, BLAKE2S_BLOCKBYTES);
223 XMEMCPY(block, key, keylen);
224 blake2s_process(md, block, BLAKE2S_BLOCKBYTES);
225
226 #ifdef LTC_CLEAN_STACK
227 zeromem(block, sizeof(block));
228 #endif
229 }
230 return CRYPT_OK;
231 }
232
233 int blake2s_128_init(hash_state *md) { return blake2s_init(md, 16, NULL, 0); }
234
235 int blake2s_160_init(hash_state *md) { return blake2s_init(md, 20, NULL, 0); }
236
237 int blake2s_224_init(hash_state *md) { return blake2s_init(md, 28, NULL, 0); }
238
239 int blake2s_256_init(hash_state *md) { return blake2s_init(md, 32, NULL, 0); }
240
241 #define G(r, i, a, b, c, d) \
242 do { \
243 a = a + b + m[blake2s_sigma[r][2 * i + 0]]; \
244 d = ROR(d ^ a, 16); \
245 c = c + d; \
246 b = ROR(b ^ c, 12); \
247 a = a + b + m[blake2s_sigma[r][2 * i + 1]]; \
248 d = ROR(d ^ a, 8); \
249 c = c + d; \
250 b = ROR(b ^ c, 7); \
251 } while (0)
252 #define ROUND(r) \
253 do { \
254 G(r, 0, v[0], v[4], v[8], v[12]); \
255 G(r, 1, v[1], v[5], v[9], v[13]); \
256 G(r, 2, v[2], v[6], v[10], v[14]); \
257 G(r, 3, v[3], v[7], v[11], v[15]); \
258 G(r, 4, v[0], v[5], v[10], v[15]); \
259 G(r, 5, v[1], v[6], v[11], v[12]); \
260 G(r, 6, v[2], v[7], v[8], v[13]); \
261 G(r, 7, v[3], v[4], v[9], v[14]); \
262 } while (0)
263
264 #ifdef LTC_CLEAN_STACK
265 static int _blake2s_compress(hash_state *md, const unsigned char *buf)
266 #else
267 static int blake2s_compress(hash_state *md, const unsigned char *buf)
268 #endif
269 {
270 unsigned long i;
271 ulong32 m[16];
272 ulong32 v[16];
273
274 for (i = 0; i < 16; ++i) {
275 LOAD32L(m[i], buf + i * sizeof(m[i]));
276 }
277
278 for (i = 0; i < 8; ++i)
279 v[i] = md->blake2s.h[i];
280
281 v[8] = blake2s_IV[0];
282 v[9] = blake2s_IV[1];
283 v[10] = blake2s_IV[2];
284 v[11] = blake2s_IV[3];
285 v[12] = md->blake2s.t[0] ^ blake2s_IV[4];
286 v[13] = md->blake2s.t[1] ^ blake2s_IV[5];
287 v[14] = md->blake2s.f[0] ^ blake2s_IV[6];
288 v[15] = md->blake2s.f[1] ^ blake2s_IV[7];
289
290 ROUND(0);
291 ROUND(1);
292 ROUND(2);
293 ROUND(3);
294 ROUND(4);
295 ROUND(5);
296 ROUND(6);
297 ROUND(7);
298 ROUND(8);
299 ROUND(9);
300
301 for (i = 0; i < 8; ++i)
302 md->blake2s.h[i] = md->blake2s.h[i] ^ v[i] ^ v[i + 8];
303
304 return CRYPT_OK;
305 }
306 #undef G
307 #undef ROUND
308
309 #ifdef LTC_CLEAN_STACK
310 static int blake2s_compress(hash_state *md, const unsigned char *buf)
311 {
312 int err;
313 err = _blake2s_compress(md, buf);
314 burn_stack(sizeof(ulong32) * (32) + sizeof(unsigned long));
315 return err;
316 }
317 #endif
318
319 int blake2s_process(hash_state *md, const unsigned char *in, unsigned long inlen)
320 {
321 LTC_ARGCHK(md != NULL);
322 LTC_ARGCHK(in != NULL);
323
324 if (md->blake2s.curlen > sizeof(md->blake2s.buf)) {
325 return CRYPT_INVALID_ARG;
326 }
327
328 if (inlen > 0) {
329 unsigned long left = md->blake2s.curlen;
330 unsigned long fill = BLAKE2S_BLOCKBYTES - left;
331 if (inlen > fill) {
332 md->blake2s.curlen = 0;
333 XMEMCPY(md->blake2s.buf + (left % sizeof(md->blake2s.buf)), in, fill); /* Fill buffer */
334 blake2s_increment_counter(md, BLAKE2S_BLOCKBYTES);
335 blake2s_compress(md, md->blake2s.buf); /* Compress */
336 in += fill;
337 inlen -= fill;
338 while (inlen > BLAKE2S_BLOCKBYTES) {
339 blake2s_increment_counter(md, BLAKE2S_BLOCKBYTES);
340 blake2s_compress(md, in);
341 in += BLAKE2S_BLOCKBYTES;
342 inlen -= BLAKE2S_BLOCKBYTES;
343 }
344 }
345 XMEMCPY(md->blake2s.buf + md->blake2s.curlen, in, inlen);
346 md->blake2s.curlen += inlen;
347 }
348 return CRYPT_OK;
349 }
350
351 int blake2s_done(hash_state *md, unsigned char *out)
352 {
353 unsigned char buffer[BLAKE2S_OUTBYTES] = { 0 };
354 unsigned long i;
355
356 LTC_ARGCHK(md != NULL);
357 LTC_ARGCHK(out != NULL);
358
359 /* if(md->blake2s.outlen != outlen) return CRYPT_INVALID_ARG; */
360
361 if (blake2s_is_lastblock(md))
362 return CRYPT_ERROR;
363
364 blake2s_increment_counter(md, md->blake2s.curlen);
365 blake2s_set_lastblock(md);
366 XMEMSET(md->blake2s.buf + md->blake2s.curlen, 0, BLAKE2S_BLOCKBYTES - md->blake2s.curlen); /* Padding */
367 blake2s_compress(md, md->blake2s.buf);
368
369 for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */
370 STORE32L(md->blake2s.h[i], buffer + i * 4);
371
372 XMEMCPY(out, buffer, md->blake2s.outlen);
373 zeromem(md, sizeof(hash_state));
374 #ifdef LTC_CLEAN_STACK
375 zeromem(buffer, sizeof(buffer));
376 #endif
377 return CRYPT_OK;
378 }
379
380 /**
381 Self-test the hash
382 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
383 */
384 int blake2s_256_test(void)
385 {
386 #ifndef LTC_TEST
387 return CRYPT_NOP;
388 #else
389 static const struct {
390 const char *msg;
391 unsigned char hash[32];
392 } tests[] = {
393 { "",
394 { 0x69, 0x21, 0x7a, 0x30, 0x79, 0x90, 0x80, 0x94,
395 0xe1, 0x11, 0x21, 0xd0, 0x42, 0x35, 0x4a, 0x7c,
396 0x1f, 0x55, 0xb6, 0x48, 0x2c, 0xa1, 0xa5, 0x1e,
397 0x1b, 0x25, 0x0d, 0xfd, 0x1e, 0xd0, 0xee, 0xf9 } },
398 { "abc",
399 { 0x50, 0x8c, 0x5e, 0x8c, 0x32, 0x7c, 0x14, 0xe2,
400 0xe1, 0xa7, 0x2b, 0xa3, 0x4e, 0xeb, 0x45, 0x2f,
401 0x37, 0x45, 0x8b, 0x20, 0x9e, 0xd6, 0x3a, 0x29,
402 0x4d, 0x99, 0x9b, 0x4c, 0x86, 0x67, 0x59, 0x82 } },
403 { "12345678901234567890123456789012345678901234567890"
404 "12345678901234567890123456789012345678901234567890"
405 "12345678901234567890123456789012345678901234567890"
406 "12345678901234567890123456789012345678901234567890"
407 "12345678901234567890123456789012345678901234567890"
408 "12345678901234567890123456789012345678901234567890",
409 { 0xa3, 0x78, 0x8b, 0x5b, 0x59, 0xee, 0xe4, 0x41,
410 0x95, 0x23, 0x58, 0x00, 0xa4, 0xf9, 0xfa, 0x41,
411 0x86, 0x0c, 0x7b, 0x1c, 0x35, 0xa2, 0x42, 0x70,
412 0x50, 0x80, 0x79, 0x56, 0xe3, 0xbe, 0x31, 0x74 } },
413
414 { NULL, { 0 } }
415 };
416
417 int i;
418 unsigned char tmp[32];
419 hash_state md;
420
421 for (i = 0; tests[i].msg != NULL; i++) {
422 blake2s_256_init(&md);
423 blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
424 blake2s_done(&md, tmp);
425 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_256", i)) {
426 return CRYPT_FAIL_TESTVECTOR;
427 }
428
429 }
430 return CRYPT_OK;
431 #endif
432 }
433
434 /**
435 Self-test the hash
436 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
437 */
438 int blake2s_224_test(void)
439 {
440 #ifndef LTC_TEST
441 return CRYPT_NOP;
442 #else
443 static const struct {
444 const char *msg;
445 unsigned char hash[28];
446 } tests[] = {
447 { "",
448 { 0x1f, 0xa1, 0x29, 0x1e, 0x65, 0x24, 0x8b, 0x37,
449 0xb3, 0x43, 0x34, 0x75, 0xb2, 0xa0, 0xdd, 0x63,
450 0xd5, 0x4a, 0x11, 0xec, 0xc4, 0xe3, 0xe0, 0x34,
451 0xe7, 0xbc, 0x1e, 0xf4 } },
452 { "abc",
453 { 0x0b, 0x03, 0x3f, 0xc2, 0x26, 0xdf, 0x7a, 0xbd,
454 0xe2, 0x9f, 0x67, 0xa0, 0x5d, 0x3d, 0xc6, 0x2c,
455 0xf2, 0x71, 0xef, 0x3d, 0xfe, 0xa4, 0xd3, 0x87,
456 0x40, 0x7f, 0xbd, 0x55 } },
457
458 { NULL, { 0 } }
459 };
460
461 int i;
462 unsigned char tmp[28];
463 hash_state md;
464
465 for (i = 0; tests[i].msg != NULL; i++) {
466 blake2s_224_init(&md);
467 blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
468 blake2s_done(&md, tmp);
469 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_224", i)) {
470 return CRYPT_FAIL_TESTVECTOR;
471 }
472
473 }
474 return CRYPT_OK;
475 #endif
476 }
477
478 /**
479 Self-test the hash
480 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
481 */
482 int blake2s_160_test(void)
483 {
484 #ifndef LTC_TEST
485 return CRYPT_NOP;
486 #else
487 static const struct {
488 const char *msg;
489 unsigned char hash[20];
490 } tests[] = {
491 { "",
492 { 0x35, 0x4c, 0x9c, 0x33, 0xf7, 0x35, 0x96, 0x24,
493 0x18, 0xbd, 0xac, 0xb9, 0x47, 0x98, 0x73, 0x42,
494 0x9c, 0x34, 0x91, 0x6f} },
495 { "abc",
496 { 0x5a, 0xe3, 0xb9, 0x9b, 0xe2, 0x9b, 0x01, 0x83,
497 0x4c, 0x3b, 0x50, 0x85, 0x21, 0xed, 0xe6, 0x04,
498 0x38, 0xf8, 0xde, 0x17 } },
499
500 { NULL, { 0 } }
501 };
502
503 int i;
504 unsigned char tmp[20];
505 hash_state md;
506
507 for (i = 0; tests[i].msg != NULL; i++) {
508 blake2s_160_init(&md);
509 blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
510 blake2s_done(&md, tmp);
511 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_160", i)) {
512 return CRYPT_FAIL_TESTVECTOR;
513 }
514
515 }
516 return CRYPT_OK;
517 #endif
518 }
519
520 /**
521 Self-test the hash
522 @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
523 */
524 int blake2s_128_test(void)
525 {
526 #ifndef LTC_TEST
527 return CRYPT_NOP;
528 #else
529 static const struct {
530 const char *msg;
531 unsigned char hash[16];
532 } tests[] = {
533 { "",
534 { 0x64, 0x55, 0x0d, 0x6f, 0xfe, 0x2c, 0x0a, 0x01,
535 0xa1, 0x4a, 0xba, 0x1e, 0xad, 0xe0, 0x20, 0x0c } },
536 { "abc",
537 { 0xaa, 0x49, 0x38, 0x11, 0x9b, 0x1d, 0xc7, 0xb8,
538 0x7c, 0xba, 0xd0, 0xff, 0xd2, 0x00, 0xd0, 0xae } },
539
540 { NULL, { 0 } }
541 };
542
543 int i;
544 unsigned char tmp[16];
545 hash_state md;
546
547 for (i = 0; tests[i].msg != NULL; i++) {
548 blake2s_128_init(&md);
549 blake2s_process(&md, (unsigned char *)tests[i].msg, (unsigned long)strlen(tests[i].msg));
550 blake2s_done(&md, tmp);
551 if (compare_testvector(tmp, sizeof(tmp), tests[i].hash, sizeof(tests[i].hash), "BLAKE2S_128", i)) {
552 return CRYPT_FAIL_TESTVECTOR;
553 }
554 }
555 return CRYPT_OK;
556 #endif
557 }
558
559 #endif
560
561 /* ref: $Format:%D$ */
562 /* git commit: $Format:%H$ */
563 /* commit time: $Format:%ai$ */