]> pd.if.org Git - zpackage/blob - libtomcrypt/src/hashes/blake2s.c
commit files needed for zpm-fetchurl
[zpackage] / libtomcrypt / src / hashes / blake2s.c
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 <sneves@dei.uc.pt>.  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$ */