28 #ifdef ARCH_LITTLE_ENDIAN
29 #ifndef NATIVE_LITTLE_ENDIAN
30 #define NATIVE_LITTLE_ENDIAN
34 const cx_hash_info_t cx_blake2b_info
40 (cx_err_t(*)(cx_hash_t * ctx,
const uint8_t *data,
size_t len)) cx_blake2b_update,
41 (cx_err_t(*)(cx_hash_t * ctx,
uint8_t *digest)) cx_blake2b_final,
42 (cx_err_t(*)(cx_hash_t * ctx,
size_t output_size)) cx_blake2b_init_no_throw,
43 (size_t(*)(
const cx_hash_t *ctx)) cx_blake2b_get_output_size};
45 cx_err_t cx_blake2b_init_no_throw(cx_blake2b_t *hash,
size_t size)
47 return cx_blake2b_init2_no_throw(hash, size, NULL, 0, NULL, 0);
50 cx_err_t cx_blake2b_init2_no_throw(cx_blake2b_t *hash,
57 if (salt == NULL && salt_len != 0) {
60 if (perso == NULL && perso_len != 0) {
63 if (salt_len > 16 || perso_len > 16) {
66 if (size % 8 != 0 || size < 8 || size > 512) {
69 memset(hash, 0,
sizeof(cx_blake2b_t));
72 hash->output_size = size;
73 hash->header.info = &cx_blake2b_info;
75 if (blake2b_init(&hash->ctx, size, salt, salt_len, perso, perso_len) < 0) {
81 return CX_INVALID_PARAMETER;
84 cx_err_t cx_blake2b_update(cx_blake2b_t *ctx,
const uint8_t *data,
size_t len)
87 return CX_INVALID_PARAMETER;
89 if (data == NULL && len != 0) {
90 return CX_INVALID_PARAMETER;
92 blake2b_update(&ctx->ctx, data, len);
96 cx_err_t cx_blake2b_final(cx_blake2b_t *ctx,
uint8_t *digest)
98 (void) blake2b_final(&ctx->ctx, digest, ctx->output_size);
102 size_t cx_blake2b_get_output_size(
const cx_blake2b_t *ctx)
104 return ctx->output_size;
107 cx_err_t cx_blake2b(cx_hash_t *hash,
115 blake2b_update(&((cx_blake2b_t *) hash)->ctx, in, len);
117 sz = ((cx_blake2b_t *) hash)->output_size;
118 if (out && (out_len < sz)) {
119 return INVALID_PARAMETER;
121 if ((
size_t) blake2b_final(&((cx_blake2b_t *) hash)->ctx, out, out_len) != sz) {
122 return INVALID_PARAMETER;
157 #if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
158 #if defined(_MSC_VER)
159 #define BLAKE2_INLINE __inline
160 #elif defined(__GNUC__)
161 #define BLAKE2_INLINE __inline__
163 #define BLAKE2_INLINE
166 #define BLAKE2_INLINE inline
169 #if defined(BLAKE2_UNUSED)
170 static BLAKE2_INLINE
uint16_t load16(
const void *src)
172 #if defined(NATIVE_LITTLE_ENDIAN)
174 memcpy(&w, src,
sizeof w);
182 static BLAKE2_INLINE
void store16(
void *dst,
uint16_t w)
184 #if defined(NATIVE_LITTLE_ENDIAN)
185 memcpy(dst, &w,
sizeof w);
193 static BLAKE2_INLINE uint32_t load32(
const void *src)
195 #if defined(NATIVE_LITTLE_ENDIAN)
197 memcpy(&w, src,
sizeof w);
201 return ((uint32_t) (p[0]) << 0) | ((uint32_t) (p[1]) << 8) | ((uint32_t) (p[2]) << 16)
202 | ((uint32_t) (p[3]) << 24);
206 static BLAKE2_INLINE uint64_t load48(
const void *src)
209 return ((uint64_t) (p[0]) << 0) | ((uint64_t) (p[1]) << 8) | ((uint64_t) (p[2]) << 16)
210 | ((uint64_t) (p[3]) << 24) | ((uint64_t) (p[4]) << 32) | ((uint64_t) (p[5]) << 40);
213 static BLAKE2_INLINE
void store48(
void *dst, uint64_t w)
226 static BLAKE2_INLINE
void store32(
void *dst, uint32_t w)
228 #if defined(NATIVE_LITTLE_ENDIAN)
229 memcpy(dst, &w,
sizeof w);
238 static BLAKE2_INLINE uint64_t load64(
const void *src)
240 #if defined(NATIVE_LITTLE_ENDIAN)
242 memcpy(&w, src,
sizeof w);
246 return ((uint64_t) (p[0]) << 0) | ((uint64_t) (p[1]) << 8) | ((uint64_t) (p[2]) << 16)
247 | ((uint64_t) (p[3]) << 24) | ((uint64_t) (p[4]) << 32) | ((uint64_t) (p[5]) << 40)
248 | ((uint64_t) (p[6]) << 48) | ((uint64_t) (p[7]) << 56);
252 static BLAKE2_INLINE
void store64(
void *dst, uint64_t w)
254 #if defined(NATIVE_LITTLE_ENDIAN)
255 memcpy(dst, &w,
sizeof w);
269 #if defined(BLAKE2_UNUSED)
270 static BLAKE2_INLINE uint32_t rotr32(
const uint32_t w,
const unsigned c)
272 return (w >> c) | (w << (32 - c));
276 static BLAKE2_INLINE uint64_t rotr64(
const uint64_t w,
const unsigned c)
278 return (w >> c) | (w << (64 - c));
282 static BLAKE2_INLINE
void secure_zero_memory(
void *v,
size_t n)
291 static const uint64_t blake2b_IV[8] = {0x6a09e667f3bcc908ULL,
292 0xbb67ae8584caa73bULL,
293 0x3c6ef372fe94f82bULL,
294 0xa54ff53a5f1d36f1ULL,
295 0x510e527fade682d1ULL,
296 0x9b05688c2b3e6c1fULL,
297 0x1f83d9abfb41bd6bULL,
298 0x5be0cd19137e2179ULL};
300 static const uint8_t blake2b_sigma[12][16] = {
301 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
302 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 },
303 {11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 },
304 {7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 },
305 {9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13},
306 {2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 },
307 {12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11},
308 {13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10},
309 {6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 },
310 {10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0 },
311 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
312 {14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
315 static void blake2b_set_lastnode(blake2b_state *S)
317 S->f[1] = (uint64_t) -1;
321 static int blake2b_is_lastblock(
const blake2b_state *S)
326 static void blake2b_set_lastblock(blake2b_state *S)
329 blake2b_set_lastnode(S);
332 S->f[0] = (uint64_t) -1;
335 static void blake2b_increment_counter(blake2b_state *S,
const uint64_t inc)
338 S->t[1] += (S->t[0] < inc);
341 static void blake2b_init0(blake2b_state *S)
344 memset(S, 0,
sizeof(blake2b_state));
346 for (i = 0; i < 8; ++i) {
347 S->h[i] = blake2b_IV[i];
352 int blake2b_init_param(blake2b_state *S,
const blake2b_param *P)
360 for (i = 0; i < 8; ++i) {
361 S->h[i] ^= load64(p +
sizeof(S->h[i]) * i);
364 S->outlen = P->digest_length;
368 int blake2b_init(blake2b_state *S,
377 if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
378 return CX_INVALID_PARAMETER;
381 P->digest_length = (
uint8_t) outlen;
385 store32(&P->leaf_length, 0);
386 store32(&P->node_offset, 0);
387 store32(&P->xof_length, 0);
390 memset(P->reserved, 0,
sizeof(P->reserved));
391 memset(P->salt, 0,
sizeof(P->salt));
392 memset(P->personal, 0,
sizeof(P->personal));
394 memcpy(P->salt, salt, salt_len);
397 memcpy(P->personal, personal, personal_len);
399 return blake2b_init_param(S, P);
402 int blake2b_init_key(blake2b_state *S,
size_t outlen,
const void *key,
size_t keylen)
406 if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) {
410 if (!key || !keylen || keylen > BLAKE2B_KEYBYTES) {
414 P->digest_length = (
uint8_t) outlen;
415 P->key_length = (
uint8_t) keylen;
418 store32(&P->leaf_length, 0);
419 store32(&P->node_offset, 0);
420 store32(&P->xof_length, 0);
423 memset(P->reserved, 0,
sizeof(P->reserved));
424 memset(P->salt, 0,
sizeof(P->salt));
425 memset(P->personal, 0,
sizeof(P->personal));
427 if (blake2b_init_param(S, P) < 0) {
433 #define block G_cx.blake.block1
434 memset(block, 0, BLAKE2B_BLOCKBYTES);
435 memcpy(block, key, keylen);
436 blake2b_update(S, block, BLAKE2B_BLOCKBYTES);
437 secure_zero_memory(block, BLAKE2B_BLOCKBYTES);
443 #define G(r, i, a, b, c, d) \
445 a = a + b + m[blake2b_sigma[r][2 * (i) + 0]]; \
446 d = rotr64(d ^ a, 32); \
448 b = rotr64(b ^ c, 24); \
449 a = a + b + m[blake2b_sigma[r][2 * (i) + 1]]; \
450 d = rotr64(d ^ a, 16); \
452 b = rotr64(b ^ c, 63); \
455 static void blake2b_compress(blake2b_state *S,
const uint8_t block[BLAKE2B_BLOCKBYTES])
461 #define m G_cx.blake.m
462 #define v G_cx.blake.v
466 for (i = 0; i < 16; ++i) {
467 m[i] = load64(block + i *
sizeof(m[i]));
470 for (i = 0; i < 8; ++i) {
474 v[8] = blake2b_IV[0];
475 v[9] = blake2b_IV[1];
476 v[10] = blake2b_IV[2];
477 v[11] = blake2b_IV[3];
478 v[12] = blake2b_IV[4] ^ S->t[0];
479 v[13] = blake2b_IV[5] ^ S->t[1];
480 v[14] = blake2b_IV[6] ^ S->f[0];
481 v[15] = blake2b_IV[7] ^ S->f[1];
483 for (
int r = 0; r < 12; r++) {
484 for (i = 0; i < 4; i++) {
485 G(r, i, v[i], v[4 + i], v[8 + i], v[12 + i]);
488 for (i = 0; i < 4; i++) {
489 G(r, 4 + i, v[i], v[4 + ((i + 1) & 3)], v[8 + ((i + 2) & 3)], v[12 + ((i + 3) & 3)]);
493 for (i = 0; i < 8; ++i) {
494 S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
503 void blake2b_update(blake2b_state *S,
const void *pin,
size_t inlen)
507 size_t left = S->buflen;
508 size_t fill = BLAKE2B_BLOCKBYTES - left;
511 memcpy(S->buf + left, in, fill);
512 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
513 blake2b_compress(S, S->buf);
516 while (inlen > BLAKE2B_BLOCKBYTES) {
517 blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
518 blake2b_compress(S, in);
519 in += BLAKE2B_BLOCKBYTES;
520 inlen -= BLAKE2B_BLOCKBYTES;
523 memcpy(S->buf + S->buflen, in, inlen);
528 int blake2b_final(blake2b_state *S,
void *out,
size_t outlen)
532 #define buffer G_cx.blake.buffer
533 memset(buffer, 0, BLAKE2B_OUTBYTES);
535 if ((out != NULL) && (outlen < S->outlen)) {
539 if (blake2b_is_lastblock(S)) {
543 blake2b_increment_counter(S, S->buflen);
544 blake2b_set_lastblock(S);
545 memset(S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen);
546 blake2b_compress(S, S->buf);
548 for (i = 0; i < 8; ++i) {
549 store64(buffer +
sizeof(S->h[i]) * i, S->h[i]);
551 memcpy(S->buf, buffer, S->outlen);
553 memcpy(out, buffer, S->outlen);
555 secure_zero_memory(buffer,
sizeof(buffer));
562 #if defined(BLAKE2_UNUSED)
564 int blake2b(
void *out,
size_t outlen,
const void *in,
size_t inlen,
const void *key,
size_t keylen)
569 if (NULL == in && inlen > 0) {
577 if (NULL == key && keylen > 0) {
581 if (!outlen || outlen > BLAKE2B_OUTBYTES) {
585 if (keylen > BLAKE2B_KEYBYTES) {
590 if (blake2b_init_key(S, outlen, key, keylen) < 0) {
595 if (blake2b_init(S, outlen) < 0) {
600 blake2b_update(S, (
const uint8_t *) in, inlen);
601 return blake2b_final(S, out, outlen);
604 int blake2(
void *out,
size_t outlen,
const void *in,
size_t inlen,
const void *key,
size_t keylen)
606 return blake2b(out, outlen, in, inlen, key, keylen);
609 #if defined(BLAKE2B_SELFTEST)
611 #include "blake2-kat.h"
615 uint8_t buf[BLAKE2_KAT_LENGTH];
618 for (i = 0; i < BLAKE2B_KEYBYTES; ++i) {
622 for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
627 for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
628 uint8_t hash[BLAKE2B_OUTBYTES];
629 blake2b(hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES);
631 if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {
637 for (step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {
638 for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
639 uint8_t hash[BLAKE2B_OUTBYTES];
645 if ((err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0) {
649 while (mlen >= step) {
650 blake2b_update(&S, p, step);
654 blake2b_update(&S, p, mlen);
655 if ((err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {
659 if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {