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