Coverage Report

Created: 2022-12-08 06:10

/src/libgcrypt/cipher/blake2.c
Line
Count
Source (jump to first uncovered line)
1
/* blake2.c - BLAKE2b and BLAKE2s hash functions (RFC 7693)
2
 * Copyright (C) 2017  Jussi Kivilinna <jussi.kivilinna@iki.fi>
3
 *
4
 * This file is part of Libgcrypt.
5
 *
6
 * Libgcrypt is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU Lesser general Public License as
8
 * published by the Free Software Foundation; either version 2.1 of
9
 * the License, or (at your option) any later version.
10
 *
11
 * Libgcrypt is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18
 */
19
20
/* The code is based on public-domain/CC0 BLAKE2 reference implementation
21
 * by Samual Neves, at https://github.com/BLAKE2/BLAKE2/tree/master/ref
22
 * Copyright 2012, Samuel Neves <sneves@dei.uc.pt>
23
 */
24
25
#include <config.h>
26
#include <string.h>
27
#include "g10lib.h"
28
#include "bithelp.h"
29
#include "bufhelp.h"
30
#include "cipher.h"
31
#include "hash-common.h"
32
33
/* USE_AVX indicates whether to compile with Intel AVX code. */
34
#undef USE_AVX
35
#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX) && \
36
    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
37
     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
38
# define USE_AVX 1
39
#endif
40
41
/* USE_AVX2 indicates whether to compile with Intel AVX2 code. */
42
#undef USE_AVX2
43
#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX2) && \
44
    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
45
     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
46
# define USE_AVX2 1
47
#endif
48
49
/* USE_AVX512 indicates whether to compile with Intel AVX512 code. */
50
#undef USE_AVX512
51
#if defined(__x86_64__) && defined(HAVE_GCC_INLINE_ASM_AVX512) && \
52
    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
53
     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
54
# define USE_AVX512 1
55
#endif
56
57
/* AMD64 assembly implementations use SystemV ABI, ABI conversion and additional
58
 * stack to store XMM6-XMM15 needed on Win64. */
59
#undef ASM_FUNC_ABI
60
#undef ASM_EXTRA_STACK
61
#if (defined(USE_AVX) || defined(USE_AVX2) || defined(USE_AVX512)) \
62
    && defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)
63
# define ASM_FUNC_ABI __attribute__((sysv_abi))
64
# define ASM_EXTRA_STACK (10 * 16)
65
#else
66
# define ASM_FUNC_ABI
67
0
# define ASM_EXTRA_STACK 0
68
#endif
69
70
0
#define BLAKE2B_BLOCKBYTES 128
71
0
#define BLAKE2B_OUTBYTES 64
72
0
#define BLAKE2B_KEYBYTES 64
73
74
0
#define BLAKE2S_BLOCKBYTES 64
75
0
#define BLAKE2S_OUTBYTES 32
76
0
#define BLAKE2S_KEYBYTES 32
77
78
typedef struct
79
{
80
  u64 h[8];
81
  u64 t[2];
82
  u64 f[2];
83
} BLAKE2B_STATE;
84
85
struct blake2b_param_s
86
{
87
  byte digest_length;
88
  byte key_length;
89
  byte fanout;
90
  byte depth;
91
  byte leaf_length[4];
92
  byte node_offset[4];
93
  byte xof_length[4];
94
  byte node_depth;
95
  byte inner_length;
96
  byte reserved[14];
97
  byte salt[16];
98
  byte personal[16];
99
};
100
101
typedef struct BLAKE2B_CONTEXT_S
102
{
103
  BLAKE2B_STATE state;
104
  byte buf[BLAKE2B_BLOCKBYTES];
105
  size_t buflen;
106
  size_t outlen;
107
#ifdef USE_AVX2
108
  unsigned int use_avx2:1;
109
#endif
110
#ifdef USE_AVX512
111
  unsigned int use_avx512:1;
112
#endif
113
} BLAKE2B_CONTEXT;
114
115
typedef struct
116
{
117
  u32 h[8];
118
  u32 t[2];
119
  u32 f[2];
120
} BLAKE2S_STATE;
121
122
struct blake2s_param_s
123
{
124
  byte digest_length;
125
  byte key_length;
126
  byte fanout;
127
  byte depth;
128
  byte leaf_length[4];
129
  byte node_offset[4];
130
  byte xof_length[2];
131
  byte node_depth;
132
  byte inner_length;
133
  /* byte reserved[0]; */
134
  byte salt[8];
135
  byte personal[8];
136
};
137
138
typedef struct BLAKE2S_CONTEXT_S
139
{
140
  BLAKE2S_STATE state;
141
  byte buf[BLAKE2S_BLOCKBYTES];
142
  size_t buflen;
143
  size_t outlen;
144
#ifdef USE_AVX
145
  unsigned int use_avx:1;
146
#endif
147
#ifdef USE_AVX512
148
  unsigned int use_avx512:1;
149
#endif
150
} BLAKE2S_CONTEXT;
151
152
typedef unsigned int (*blake2_transform_t)(void *S, const void *inblk,
153
             size_t nblks);
154
155
156
static const u64 blake2b_IV[8] =
157
{
158
  U64_C(0x6a09e667f3bcc908), U64_C(0xbb67ae8584caa73b),
159
  U64_C(0x3c6ef372fe94f82b), U64_C(0xa54ff53a5f1d36f1),
160
  U64_C(0x510e527fade682d1), U64_C(0x9b05688c2b3e6c1f),
161
  U64_C(0x1f83d9abfb41bd6b), U64_C(0x5be0cd19137e2179)
162
};
163
164
static const u32 blake2s_IV[8] =
165
{
166
  0x6A09E667UL, 0xBB67AE85UL, 0x3C6EF372UL, 0xA54FF53AUL,
167
  0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL
168
};
169
170
static byte zero_block[BLAKE2B_BLOCKBYTES] = { 0, };
171
172
173
static void blake2_write(void *S, const void *inbuf, size_t inlen,
174
       byte *tmpbuf, size_t *tmpbuflen, size_t blkbytes,
175
       blake2_transform_t transform_fn)
176
0
{
177
0
  const byte* in = inbuf;
178
0
  unsigned int burn = 0;
179
180
0
  if (inlen > 0)
181
0
    {
182
0
      size_t left = *tmpbuflen;
183
0
      size_t fill = blkbytes - left;
184
0
      size_t nblks;
185
186
0
      if (inlen > fill)
187
0
  {
188
0
    if (fill > 0)
189
0
      buf_cpy (tmpbuf + left, in, fill); /* Fill buffer */
190
0
    left = 0;
191
192
0
    burn = transform_fn (S, tmpbuf, 1); /* Increment counter + Compress */
193
194
0
    in += fill;
195
0
    inlen -= fill;
196
197
0
    nblks = inlen / blkbytes - !(inlen % blkbytes);
198
0
    if (nblks)
199
0
      {
200
0
        burn = transform_fn(S, in, nblks);
201
0
        in += blkbytes * nblks;
202
0
        inlen -= blkbytes * nblks;
203
0
      }
204
0
  }
205
206
0
      gcry_assert (inlen > 0);
207
208
0
      buf_cpy (tmpbuf + left, in, inlen);
209
0
      *tmpbuflen = left + inlen;
210
0
    }
211
212
0
  if (burn)
213
0
    _gcry_burn_stack (burn);
214
215
0
  return;
216
0
}
217
218
219
static inline void blake2b_set_lastblock(BLAKE2B_STATE *S)
220
0
{
221
0
  S->f[0] = U64_C(0xffffffffffffffff);
222
0
}
223
224
static inline int blake2b_is_lastblock(const BLAKE2B_STATE *S)
225
0
{
226
0
  return S->f[0] != 0;
227
0
}
228
229
static inline void blake2b_increment_counter(BLAKE2B_STATE *S, const int inc)
230
0
{
231
0
  S->t[0] += (u64)inc;
232
0
  S->t[1] += (S->t[0] < (u64)inc) - (inc < 0);
233
0
}
234
235
static inline u64 rotr64(u64 x, u64 n)
236
0
{
237
0
  return ((x >> (n & 63)) | (x << ((64 - n) & 63)));
238
0
}
239
240
static unsigned int blake2b_transform_generic(BLAKE2B_STATE *S,
241
                                              const void *inblks,
242
                                              size_t nblks)
243
0
{
244
0
  static const byte blake2b_sigma[12][16] =
245
0
  {
246
0
    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
247
0
    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 },
248
0
    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 },
249
0
    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 },
250
0
    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 },
251
0
    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 },
252
0
    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 },
253
0
    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 },
254
0
    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 },
255
0
    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 },
256
0
    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
257
0
    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 }
258
0
  };
259
0
  const byte* in = inblks;
260
0
  u64 m[16];
261
0
  u64 v[16];
262
263
0
  while (nblks--)
264
0
    {
265
      /* Increment counter */
266
0
      blake2b_increment_counter (S, BLAKE2B_BLOCKBYTES);
267
268
      /* Compress */
269
0
      m[0] = buf_get_le64 (in + 0 * sizeof(m[0]));
270
0
      m[1] = buf_get_le64 (in + 1 * sizeof(m[0]));
271
0
      m[2] = buf_get_le64 (in + 2 * sizeof(m[0]));
272
0
      m[3] = buf_get_le64 (in + 3 * sizeof(m[0]));
273
0
      m[4] = buf_get_le64 (in + 4 * sizeof(m[0]));
274
0
      m[5] = buf_get_le64 (in + 5 * sizeof(m[0]));
275
0
      m[6] = buf_get_le64 (in + 6 * sizeof(m[0]));
276
0
      m[7] = buf_get_le64 (in + 7 * sizeof(m[0]));
277
0
      m[8] = buf_get_le64 (in + 8 * sizeof(m[0]));
278
0
      m[9] = buf_get_le64 (in + 9 * sizeof(m[0]));
279
0
      m[10] = buf_get_le64 (in + 10 * sizeof(m[0]));
280
0
      m[11] = buf_get_le64 (in + 11 * sizeof(m[0]));
281
0
      m[12] = buf_get_le64 (in + 12 * sizeof(m[0]));
282
0
      m[13] = buf_get_le64 (in + 13 * sizeof(m[0]));
283
0
      m[14] = buf_get_le64 (in + 14 * sizeof(m[0]));
284
0
      m[15] = buf_get_le64 (in + 15 * sizeof(m[0]));
285
286
0
      v[ 0] = S->h[0];
287
0
      v[ 1] = S->h[1];
288
0
      v[ 2] = S->h[2];
289
0
      v[ 3] = S->h[3];
290
0
      v[ 4] = S->h[4];
291
0
      v[ 5] = S->h[5];
292
0
      v[ 6] = S->h[6];
293
0
      v[ 7] = S->h[7];
294
0
      v[ 8] = blake2b_IV[0];
295
0
      v[ 9] = blake2b_IV[1];
296
0
      v[10] = blake2b_IV[2];
297
0
      v[11] = blake2b_IV[3];
298
0
      v[12] = blake2b_IV[4] ^ S->t[0];
299
0
      v[13] = blake2b_IV[5] ^ S->t[1];
300
0
      v[14] = blake2b_IV[6] ^ S->f[0];
301
0
      v[15] = blake2b_IV[7] ^ S->f[1];
302
303
0
#define G(r,i,a,b,c,d)                      \
304
0
  do {                                      \
305
0
    a = a + b + m[blake2b_sigma[r][2*i+0]]; \
306
0
    d = rotr64(d ^ a, 32);                  \
307
0
    c = c + d;                              \
308
0
    b = rotr64(b ^ c, 24);                  \
309
0
    a = a + b + m[blake2b_sigma[r][2*i+1]]; \
310
0
    d = rotr64(d ^ a, 16);                  \
311
0
    c = c + d;                              \
312
0
    b = rotr64(b ^ c, 63);                  \
313
0
  } while(0)
314
315
0
#define ROUND(r)                    \
316
0
  do {                              \
317
0
    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
318
0
    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
319
0
    G(r,2,v[ 2],v[ 6],v[10],v[14]); \
320
0
    G(r,3,v[ 3],v[ 7],v[11],v[15]); \
321
0
    G(r,4,v[ 0],v[ 5],v[10],v[15]); \
322
0
    G(r,5,v[ 1],v[ 6],v[11],v[12]); \
323
0
    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
324
0
    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
325
0
  } while(0)
326
327
0
      ROUND(0);
328
0
      ROUND(1);
329
0
      ROUND(2);
330
0
      ROUND(3);
331
0
      ROUND(4);
332
0
      ROUND(5);
333
0
      ROUND(6);
334
0
      ROUND(7);
335
0
      ROUND(8);
336
0
      ROUND(9);
337
0
      ROUND(10);
338
0
      ROUND(11);
339
340
0
#undef G
341
0
#undef ROUND
342
343
0
      S->h[0] = S->h[0] ^ v[0] ^ v[0 + 8];
344
0
      S->h[1] = S->h[1] ^ v[1] ^ v[1 + 8];
345
0
      S->h[2] = S->h[2] ^ v[2] ^ v[2 + 8];
346
0
      S->h[3] = S->h[3] ^ v[3] ^ v[3 + 8];
347
0
      S->h[4] = S->h[4] ^ v[4] ^ v[4 + 8];
348
0
      S->h[5] = S->h[5] ^ v[5] ^ v[5 + 8];
349
0
      S->h[6] = S->h[6] ^ v[6] ^ v[6 + 8];
350
0
      S->h[7] = S->h[7] ^ v[7] ^ v[7 + 8];
351
352
0
      in += BLAKE2B_BLOCKBYTES;
353
0
    }
354
355
0
  return sizeof(void *) * 4 + sizeof(u64) * 16 * 2;
356
0
}
357
358
#ifdef USE_AVX2
359
unsigned int _gcry_blake2b_transform_amd64_avx2(BLAKE2B_STATE *S,
360
                                                const void *inblks,
361
                                                size_t nblks) ASM_FUNC_ABI;
362
#endif
363
364
#ifdef USE_AVX512
365
unsigned int _gcry_blake2b_transform_amd64_avx512(BLAKE2B_STATE *S,
366
                                                  const void *inblks,
367
                                                  size_t nblks) ASM_FUNC_ABI;
368
#endif
369
370
static unsigned int blake2b_transform(void *ctx, const void *inblks,
371
                                      size_t nblks)
372
0
{
373
0
  BLAKE2B_CONTEXT *c = ctx;
374
0
  unsigned int nburn;
375
376
0
  if (0)
377
0
    {}
378
0
#ifdef USE_AVX512
379
0
  else if (c->use_avx512)
380
0
    nburn = _gcry_blake2b_transform_amd64_avx512(&c->state, inblks, nblks);
381
0
#endif
382
0
#ifdef USE_AVX2
383
0
  else if (c->use_avx2)
384
0
    nburn = _gcry_blake2b_transform_amd64_avx2(&c->state, inblks, nblks);
385
0
#endif
386
0
  else
387
0
    nburn = blake2b_transform_generic(&c->state, inblks, nblks);
388
389
0
  if (nburn)
390
0
    nburn += ASM_EXTRA_STACK;
391
392
0
  return nburn;
393
0
}
394
395
static void blake2b_final(void *ctx)
396
0
{
397
0
  BLAKE2B_CONTEXT *c = ctx;
398
0
  BLAKE2B_STATE *S = &c->state;
399
0
  unsigned int burn;
400
0
  size_t i;
401
402
0
  gcry_assert (sizeof(c->buf) >= c->outlen);
403
0
  if (blake2b_is_lastblock(S))
404
0
    return;
405
406
0
  if (c->buflen < BLAKE2B_BLOCKBYTES)
407
0
    memset (c->buf + c->buflen, 0, BLAKE2B_BLOCKBYTES - c->buflen); /* Padding */
408
0
  blake2b_set_lastblock (S);
409
0
  blake2b_increment_counter (S, (int)c->buflen - BLAKE2B_BLOCKBYTES);
410
0
  burn = blake2b_transform (ctx, c->buf, 1);
411
412
  /* Output full hash to buffer */
413
0
  for (i = 0; i < 8; ++i)
414
0
    buf_put_le64 (c->buf + sizeof(S->h[i]) * i, S->h[i]);
415
416
  /* Zero out extra buffer bytes. */
417
0
  if (c->outlen < sizeof(c->buf))
418
0
    memset (c->buf + c->outlen, 0, sizeof(c->buf) - c->outlen);
419
420
0
  if (burn)
421
0
    _gcry_burn_stack (burn);
422
0
}
423
424
static byte *blake2b_read(void *ctx)
425
0
{
426
0
  BLAKE2B_CONTEXT *c = ctx;
427
0
  return c->buf;
428
0
}
429
430
static void blake2b_write(void *ctx, const void *inbuf, size_t inlen)
431
0
{
432
0
  BLAKE2B_CONTEXT *c = ctx;
433
0
  BLAKE2B_STATE *S = &c->state;
434
0
  blake2_write(S, inbuf, inlen, c->buf, &c->buflen, BLAKE2B_BLOCKBYTES,
435
0
         blake2b_transform);
436
0
}
437
438
static inline void blake2b_init_param(BLAKE2B_STATE *S,
439
              const struct blake2b_param_s *P)
440
0
{
441
0
  const byte *p = (const byte *)P;
442
0
  size_t i;
443
444
  /* init xors IV with input parameter block */
445
446
  /* IV XOR ParamBlock */
447
0
  for (i = 0; i < 8; ++i)
448
0
    S->h[i] = blake2b_IV[i] ^ buf_get_le64(p + sizeof(S->h[i]) * i);
449
0
}
450
451
static inline gcry_err_code_t blake2b_init(BLAKE2B_CONTEXT *ctx,
452
             const byte *key, size_t keylen)
453
0
{
454
0
  struct blake2b_param_s P[1] = { { 0, } };
455
0
  BLAKE2B_STATE *S = &ctx->state;
456
457
0
  if (!ctx->outlen || ctx->outlen > BLAKE2B_OUTBYTES)
458
0
    return GPG_ERR_INV_ARG;
459
0
  if (sizeof(P[0]) != sizeof(u64) * 8)
460
0
    return GPG_ERR_INTERNAL;
461
0
  if (keylen && (!key || keylen > BLAKE2B_KEYBYTES))
462
0
    return GPG_ERR_INV_KEYLEN;
463
464
0
  P->digest_length = ctx->outlen;
465
0
  P->key_length = keylen;
466
0
  P->fanout = 1;
467
0
  P->depth = 1;
468
469
0
  blake2b_init_param (S, P);
470
0
  wipememory (P, sizeof(P));
471
472
0
  if (key)
473
0
    {
474
0
      blake2b_write (ctx, key, keylen);
475
0
      blake2b_write (ctx, zero_block, BLAKE2B_BLOCKBYTES - keylen);
476
0
    }
477
478
0
  return 0;
479
0
}
480
481
static gcry_err_code_t blake2b_init_ctx(void *ctx, unsigned int flags,
482
          const byte *key, size_t keylen,
483
          unsigned int dbits)
484
0
{
485
0
  BLAKE2B_CONTEXT *c = ctx;
486
0
  unsigned int features = _gcry_get_hw_features ();
487
488
0
  (void)features;
489
0
  (void)flags;
490
491
0
  memset (c, 0, sizeof (*c));
492
493
0
#ifdef USE_AVX2
494
0
  c->use_avx2 = !!(features & HWF_INTEL_AVX2);
495
0
#endif
496
0
#ifdef USE_AVX512
497
0
  c->use_avx512 = !!(features & HWF_INTEL_AVX512);
498
0
#endif
499
500
0
  c->outlen = dbits / 8;
501
0
  c->buflen = 0;
502
0
  return blake2b_init(c, key, keylen);
503
0
}
504
505
/* Variable-length Hash Function H'.  */
506
gcry_err_code_t
507
blake2b_vl_hash (const void *in, size_t inlen, size_t outputlen, void *output)
508
0
{
509
0
  gcry_err_code_t ec;
510
0
  BLAKE2B_CONTEXT ctx;
511
0
  unsigned char buf[4];
512
513
0
  ec = blake2b_init_ctx (&ctx, 0, NULL, 0,
514
0
                         (outputlen < 64 ? outputlen: 64)*8);
515
0
  if (ec)
516
0
    return ec;
517
518
0
  buf_put_le32 (buf, outputlen);
519
0
  blake2b_write (&ctx, buf, 4);
520
0
  blake2b_write (&ctx, in, inlen);
521
0
  blake2b_final (&ctx);
522
523
0
  if (outputlen <= 64)
524
0
    memcpy (output, ctx.buf, outputlen);
525
0
  else
526
0
    {
527
0
      int r = (outputlen-1)/32 - 1;
528
0
      unsigned int remained = outputlen - 32*r;
529
0
      int i;
530
0
      unsigned char d[64];
531
532
0
      i = 0;
533
0
      while (1)
534
0
        {
535
0
          memcpy (d, ctx.buf, 64);
536
0
          memcpy ((unsigned char *)output+i*32, d, 32);
537
538
0
          if (++i >= r)
539
0
            break;
540
541
0
          ec = blake2b_init_ctx (&ctx, 0, NULL, 0, 64*8);
542
0
          if (ec)
543
0
            return ec;
544
545
0
          blake2b_write (&ctx, d, 64);
546
0
          blake2b_final (&ctx);
547
0
        }
548
549
0
      ec = blake2b_init_ctx (&ctx, 0, NULL, 0, remained*8);
550
0
      if (ec)
551
0
        return ec;
552
553
0
      blake2b_write (&ctx, d, 64);
554
0
      blake2b_final (&ctx);
555
556
0
      memcpy ((unsigned char *)output+r*32, ctx.buf, remained);
557
0
    }
558
559
0
  wipememory (buf, sizeof (buf));
560
0
  wipememory (&ctx, sizeof (ctx));
561
0
  return 0;
562
0
}
563
564
static inline void blake2s_set_lastblock(BLAKE2S_STATE *S)
565
0
{
566
0
  S->f[0] = 0xFFFFFFFFUL;
567
0
}
568
569
static inline int blake2s_is_lastblock(BLAKE2S_STATE *S)
570
0
{
571
0
  return S->f[0] != 0;
572
0
}
573
574
static inline void blake2s_increment_counter(BLAKE2S_STATE *S, const int inc)
575
0
{
576
0
  S->t[0] += (u32)inc;
577
0
  S->t[1] += (S->t[0] < (u32)inc) - (inc < 0);
578
0
}
579
580
static unsigned int blake2s_transform_generic(BLAKE2S_STATE *S,
581
                                              const void *inblks,
582
                                              size_t nblks)
583
0
{
584
0
  static const byte blake2s_sigma[10][16] =
585
0
  {
586
0
    {  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15 },
587
0
    { 14, 10,  4,  8,  9, 15, 13,  6,  1, 12,  0,  2, 11,  7,  5,  3 },
588
0
    { 11,  8, 12,  0,  5,  2, 15, 13, 10, 14,  3,  6,  7,  1,  9,  4 },
589
0
    {  7,  9,  3,  1, 13, 12, 11, 14,  2,  6,  5, 10,  4,  0, 15,  8 },
590
0
    {  9,  0,  5,  7,  2,  4, 10, 15, 14,  1, 11, 12,  6,  8,  3, 13 },
591
0
    {  2, 12,  6, 10,  0, 11,  8,  3,  4, 13,  7,  5, 15, 14,  1,  9 },
592
0
    { 12,  5,  1, 15, 14, 13,  4, 10,  0,  7,  6,  3,  9,  2,  8, 11 },
593
0
    { 13, 11,  7, 14, 12,  1,  3,  9,  5,  0, 15,  4,  8,  6,  2, 10 },
594
0
    {  6, 15, 14,  9, 11,  3,  0,  8, 12,  2, 13,  7,  1,  4, 10,  5 },
595
0
    { 10,  2,  8,  4,  7,  6,  1,  5, 15, 11,  9, 14,  3, 12, 13 , 0 },
596
0
  };
597
0
  unsigned int burn = 0;
598
0
  const byte* in = inblks;
599
0
  u32 m[16];
600
0
  u32 v[16];
601
602
0
  while (nblks--)
603
0
    {
604
      /* Increment counter */
605
0
      blake2s_increment_counter (S, BLAKE2S_BLOCKBYTES);
606
607
      /* Compress */
608
0
      m[0] = buf_get_le32 (in + 0 * sizeof(m[0]));
609
0
      m[1] = buf_get_le32 (in + 1 * sizeof(m[0]));
610
0
      m[2] = buf_get_le32 (in + 2 * sizeof(m[0]));
611
0
      m[3] = buf_get_le32 (in + 3 * sizeof(m[0]));
612
0
      m[4] = buf_get_le32 (in + 4 * sizeof(m[0]));
613
0
      m[5] = buf_get_le32 (in + 5 * sizeof(m[0]));
614
0
      m[6] = buf_get_le32 (in + 6 * sizeof(m[0]));
615
0
      m[7] = buf_get_le32 (in + 7 * sizeof(m[0]));
616
0
      m[8] = buf_get_le32 (in + 8 * sizeof(m[0]));
617
0
      m[9] = buf_get_le32 (in + 9 * sizeof(m[0]));
618
0
      m[10] = buf_get_le32 (in + 10 * sizeof(m[0]));
619
0
      m[11] = buf_get_le32 (in + 11 * sizeof(m[0]));
620
0
      m[12] = buf_get_le32 (in + 12 * sizeof(m[0]));
621
0
      m[13] = buf_get_le32 (in + 13 * sizeof(m[0]));
622
0
      m[14] = buf_get_le32 (in + 14 * sizeof(m[0]));
623
0
      m[15] = buf_get_le32 (in + 15 * sizeof(m[0]));
624
625
0
      v[ 0] = S->h[0];
626
0
      v[ 1] = S->h[1];
627
0
      v[ 2] = S->h[2];
628
0
      v[ 3] = S->h[3];
629
0
      v[ 4] = S->h[4];
630
0
      v[ 5] = S->h[5];
631
0
      v[ 6] = S->h[6];
632
0
      v[ 7] = S->h[7];
633
0
      v[ 8] = blake2s_IV[0];
634
0
      v[ 9] = blake2s_IV[1];
635
0
      v[10] = blake2s_IV[2];
636
0
      v[11] = blake2s_IV[3];
637
0
      v[12] = S->t[0] ^ blake2s_IV[4];
638
0
      v[13] = S->t[1] ^ blake2s_IV[5];
639
0
      v[14] = S->f[0] ^ blake2s_IV[6];
640
0
      v[15] = S->f[1] ^ blake2s_IV[7];
641
642
0
#define G(r,i,a,b,c,d)                      \
643
0
  do {                                      \
644
0
    a = a + b + m[blake2s_sigma[r][2*i+0]]; \
645
0
    d = ror(d ^ a, 16);                     \
646
0
    c = c + d;                              \
647
0
    b = ror(b ^ c, 12);                     \
648
0
    a = a + b + m[blake2s_sigma[r][2*i+1]]; \
649
0
    d = ror(d ^ a, 8);                      \
650
0
    c = c + d;                              \
651
0
    b = ror(b ^ c, 7);                      \
652
0
  } while(0)
653
654
0
#define ROUND(r)                    \
655
0
  do {                              \
656
0
    G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
657
0
    G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
658
0
    G(r,2,v[ 2],v[ 6],v[10],v[14]); \
659
0
    G(r,3,v[ 3],v[ 7],v[11],v[15]); \
660
0
    G(r,4,v[ 0],v[ 5],v[10],v[15]); \
661
0
    G(r,5,v[ 1],v[ 6],v[11],v[12]); \
662
0
    G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
663
0
    G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
664
0
  } while(0)
665
666
0
      ROUND(0);
667
0
      ROUND(1);
668
0
      ROUND(2);
669
0
      ROUND(3);
670
0
      ROUND(4);
671
0
      ROUND(5);
672
0
      ROUND(6);
673
0
      ROUND(7);
674
0
      ROUND(8);
675
0
      ROUND(9);
676
677
0
#undef G
678
0
#undef ROUND
679
680
0
      S->h[0] = S->h[0] ^ v[0] ^ v[0 + 8];
681
0
      S->h[1] = S->h[1] ^ v[1] ^ v[1 + 8];
682
0
      S->h[2] = S->h[2] ^ v[2] ^ v[2 + 8];
683
0
      S->h[3] = S->h[3] ^ v[3] ^ v[3 + 8];
684
0
      S->h[4] = S->h[4] ^ v[4] ^ v[4 + 8];
685
0
      S->h[5] = S->h[5] ^ v[5] ^ v[5 + 8];
686
0
      S->h[6] = S->h[6] ^ v[6] ^ v[6 + 8];
687
0
      S->h[7] = S->h[7] ^ v[7] ^ v[7 + 8];
688
689
0
      in += BLAKE2S_BLOCKBYTES;
690
0
    }
691
692
0
  return burn;
693
0
}
694
695
#ifdef USE_AVX
696
unsigned int _gcry_blake2s_transform_amd64_avx(BLAKE2S_STATE *S,
697
                                               const void *inblks,
698
                                               size_t nblks) ASM_FUNC_ABI;
699
#endif
700
701
#ifdef USE_AVX512
702
unsigned int _gcry_blake2s_transform_amd64_avx512(BLAKE2S_STATE *S,
703
                                                  const void *inblks,
704
                                                  size_t nblks) ASM_FUNC_ABI;
705
#endif
706
707
static unsigned int blake2s_transform(void *ctx, const void *inblks,
708
                                      size_t nblks)
709
0
{
710
0
  BLAKE2S_CONTEXT *c = ctx;
711
0
  unsigned int nburn;
712
713
0
  if (0)
714
0
    { }
715
0
#ifdef USE_AVX512
716
0
  else if (c->use_avx512)
717
0
    nburn = _gcry_blake2s_transform_amd64_avx512(&c->state, inblks, nblks);
718
0
#endif
719
0
#ifdef USE_AVX
720
0
  else if (c->use_avx)
721
0
    nburn = _gcry_blake2s_transform_amd64_avx(&c->state, inblks, nblks);
722
0
#endif
723
0
  else
724
0
    nburn = blake2s_transform_generic(&c->state, inblks, nblks);
725
726
0
  if (nburn)
727
0
    nburn += ASM_EXTRA_STACK;
728
729
0
  return nburn;
730
0
}
731
732
static void blake2s_final(void *ctx)
733
0
{
734
0
  BLAKE2S_CONTEXT *c = ctx;
735
0
  BLAKE2S_STATE *S = &c->state;
736
0
  unsigned int burn;
737
0
  size_t i;
738
739
0
  gcry_assert (sizeof(c->buf) >= c->outlen);
740
0
  if (blake2s_is_lastblock(S))
741
0
    return;
742
743
0
  if (c->buflen < BLAKE2S_BLOCKBYTES)
744
0
    memset (c->buf + c->buflen, 0, BLAKE2S_BLOCKBYTES - c->buflen); /* Padding */
745
0
  blake2s_set_lastblock (S);
746
0
  blake2s_increment_counter (S, (int)c->buflen - BLAKE2S_BLOCKBYTES);
747
0
  burn = blake2s_transform (ctx, c->buf, 1);
748
749
  /* Output full hash to buffer */
750
0
  for (i = 0; i < 8; ++i)
751
0
    buf_put_le32 (c->buf + sizeof(S->h[i]) * i, S->h[i]);
752
753
  /* Zero out extra buffer bytes. */
754
0
  if (c->outlen < sizeof(c->buf))
755
0
    memset (c->buf + c->outlen, 0, sizeof(c->buf) - c->outlen);
756
757
0
  if (burn)
758
0
    _gcry_burn_stack (burn);
759
0
}
760
761
static byte *blake2s_read(void *ctx)
762
0
{
763
0
  BLAKE2S_CONTEXT *c = ctx;
764
0
  return c->buf;
765
0
}
766
767
static void blake2s_write(void *ctx, const void *inbuf, size_t inlen)
768
0
{
769
0
  BLAKE2S_CONTEXT *c = ctx;
770
0
  BLAKE2S_STATE *S = &c->state;
771
0
  blake2_write(S, inbuf, inlen, c->buf, &c->buflen, BLAKE2S_BLOCKBYTES,
772
0
         blake2s_transform);
773
0
}
774
775
static inline void blake2s_init_param(BLAKE2S_STATE *S,
776
              const struct blake2s_param_s *P)
777
0
{
778
0
  const byte *p = (const byte *)P;
779
0
  size_t i;
780
781
  /* init2 xors IV with input parameter block */
782
783
  /* IV XOR ParamBlock */
784
0
  for (i = 0; i < 8; ++i)
785
0
    S->h[i] ^= blake2s_IV[i] ^ buf_get_le32(&p[i * 4]);
786
0
}
787
788
static inline gcry_err_code_t blake2s_init(BLAKE2S_CONTEXT *ctx,
789
             const byte *key, size_t keylen)
790
0
{
791
0
  struct blake2s_param_s P[1] = { { 0, } };
792
0
  BLAKE2S_STATE *S = &ctx->state;
793
794
0
  if (!ctx->outlen || ctx->outlen > BLAKE2S_OUTBYTES)
795
0
    return GPG_ERR_INV_ARG;
796
0
  if (sizeof(P[0]) != sizeof(u32) * 8)
797
0
    return GPG_ERR_INTERNAL;
798
0
  if (keylen && (!key || keylen > BLAKE2S_KEYBYTES))
799
0
    return GPG_ERR_INV_KEYLEN;
800
801
0
  P->digest_length = ctx->outlen;
802
0
  P->key_length = keylen;
803
0
  P->fanout = 1;
804
0
  P->depth = 1;
805
806
0
  blake2s_init_param (S, P);
807
0
  wipememory (P, sizeof(P));
808
809
0
  if (key)
810
0
    {
811
0
      blake2s_write (ctx, key, keylen);
812
0
      blake2s_write (ctx, zero_block, BLAKE2S_BLOCKBYTES - keylen);
813
0
    }
814
815
0
  return 0;
816
0
}
817
818
static gcry_err_code_t blake2s_init_ctx(void *ctx, unsigned int flags,
819
          const byte *key, size_t keylen,
820
          unsigned int dbits)
821
0
{
822
0
  BLAKE2S_CONTEXT *c = ctx;
823
0
  unsigned int features = _gcry_get_hw_features ();
824
825
0
  (void)features;
826
0
  (void)flags;
827
828
0
  memset (c, 0, sizeof (*c));
829
830
0
#ifdef USE_AVX
831
0
  c->use_avx = !!(features & HWF_INTEL_AVX);
832
0
#endif
833
0
#ifdef USE_AVX
834
0
  c->use_avx512 = !!(features & HWF_INTEL_AVX512);
835
0
#endif
836
837
0
  c->outlen = dbits / 8;
838
0
  c->buflen = 0;
839
0
  return blake2s_init(c, key, keylen);
840
0
}
841
842
/* Selftests from "RFC 7693, Appendix E. BLAKE2b and BLAKE2s Self-Test
843
 * Module C Source". */
844
static void selftest_seq(byte *out, size_t len, u32 seed)
845
0
{
846
0
  size_t i;
847
0
  u32 t, a, b;
848
849
0
  a = 0xDEAD4BAD * seed;
850
0
  b = 1;
851
852
0
  for (i = 0; i < len; i++)
853
0
    {
854
0
      t = a + b;
855
0
      a = b;
856
0
      b = t;
857
0
      out[i] = (t >> 24) & 0xFF;
858
0
    }
859
0
}
860
861
static gpg_err_code_t
862
selftests_blake2b (int algo, int extended, selftest_report_func_t report)
863
0
{
864
0
  static const byte blake2b_res[32] =
865
0
  {
866
0
    0xC2, 0x3A, 0x78, 0x00, 0xD9, 0x81, 0x23, 0xBD,
867
0
    0x10, 0xF5, 0x06, 0xC6, 0x1E, 0x29, 0xDA, 0x56,
868
0
    0x03, 0xD7, 0x63, 0xB8, 0xBB, 0xAD, 0x2E, 0x73,
869
0
    0x7F, 0x5E, 0x76, 0x5A, 0x7B, 0xCC, 0xD4, 0x75
870
0
  };
871
0
  static const size_t b2b_md_len[4] = { 20, 32, 48, 64 };
872
0
  static const size_t b2b_in_len[6] = { 0, 3, 128, 129, 255, 1024 };
873
0
  size_t i, j, outlen, inlen;
874
0
  byte in[1024], key[64];
875
0
  BLAKE2B_CONTEXT ctx;
876
0
  BLAKE2B_CONTEXT ctx2;
877
0
  const char *what;
878
0
  const char *errtxt;
879
880
0
  (void)extended;
881
882
0
  what = "rfc7693 BLAKE2b selftest";
883
884
  /* 256-bit hash for testing */
885
0
  if (blake2b_init_ctx(&ctx, 0, NULL, 0, 32 * 8))
886
0
    {
887
0
      errtxt = "init failed";
888
0
      goto failed;
889
0
    }
890
891
0
  for (i = 0; i < 4; i++)
892
0
    {
893
0
      outlen = b2b_md_len[i];
894
0
      for (j = 0; j < 6; j++)
895
0
  {
896
0
    inlen = b2b_in_len[j];
897
898
0
    selftest_seq(in, inlen, inlen); /* unkeyed hash */
899
0
    blake2b_init_ctx(&ctx2, 0, NULL, 0, outlen * 8);
900
0
    blake2b_write(&ctx2, in, inlen);
901
0
    blake2b_final(&ctx2);
902
0
    blake2b_write(&ctx, ctx2.buf, outlen); /* hash the hash */
903
904
0
    selftest_seq(key, outlen, outlen); /* keyed hash */
905
0
    blake2b_init_ctx(&ctx2, 0, key, outlen, outlen * 8);
906
0
    blake2b_write(&ctx2, in, inlen);
907
0
    blake2b_final(&ctx2);
908
0
    blake2b_write(&ctx, ctx2.buf, outlen); /* hash the hash */
909
0
  }
910
0
    }
911
912
  /* compute and compare the hash of hashes */
913
0
  blake2b_final(&ctx);
914
0
  for (i = 0; i < 32; i++)
915
0
    {
916
0
      if (ctx.buf[i] != blake2b_res[i])
917
0
  {
918
0
    errtxt = "digest mismatch";
919
0
    goto failed;
920
0
  }
921
0
    }
922
923
0
  return 0;
924
925
0
failed:
926
0
  if (report)
927
0
    report ("digest", algo, what, errtxt);
928
0
  return GPG_ERR_SELFTEST_FAILED;
929
0
}
930
931
static gpg_err_code_t
932
selftests_blake2s (int algo, int extended, selftest_report_func_t report)
933
0
{
934
0
  static const byte blake2s_res[32] =
935
0
  {
936
0
    0x6A, 0x41, 0x1F, 0x08, 0xCE, 0x25, 0xAD, 0xCD,
937
0
    0xFB, 0x02, 0xAB, 0xA6, 0x41, 0x45, 0x1C, 0xEC,
938
0
    0x53, 0xC5, 0x98, 0xB2, 0x4F, 0x4F, 0xC7, 0x87,
939
0
    0xFB, 0xDC, 0x88, 0x79, 0x7F, 0x4C, 0x1D, 0xFE
940
0
  };
941
0
  static const size_t b2s_md_len[4] = { 16, 20, 28, 32 };
942
0
  static const size_t b2s_in_len[6] = { 0, 3, 64, 65, 255, 1024 };
943
0
  size_t i, j, outlen, inlen;
944
0
  byte in[1024], key[32];
945
0
  BLAKE2S_CONTEXT ctx;
946
0
  BLAKE2S_CONTEXT ctx2;
947
0
  const char *what;
948
0
  const char *errtxt;
949
950
0
  (void)extended;
951
952
0
  what = "rfc7693 BLAKE2s selftest";
953
954
  /* 256-bit hash for testing */
955
0
  if (blake2s_init_ctx(&ctx, 0, NULL, 0, 32 * 8))
956
0
    {
957
0
      errtxt = "init failed";
958
0
      goto failed;
959
0
    }
960
961
0
  for (i = 0; i < 4; i++)
962
0
    {
963
0
      outlen = b2s_md_len[i];
964
0
      for (j = 0; j < 6; j++)
965
0
  {
966
0
    inlen = b2s_in_len[j];
967
968
0
    selftest_seq(in, inlen, inlen); /* unkeyed hash */
969
0
    blake2s_init_ctx(&ctx2, 0, NULL, 0, outlen * 8);
970
0
    blake2s_write(&ctx2, in, inlen);
971
0
    blake2s_final(&ctx2);
972
0
    blake2s_write(&ctx, ctx2.buf, outlen); /* hash the hash */
973
974
0
    selftest_seq(key, outlen, outlen); /* keyed hash */
975
0
    blake2s_init_ctx(&ctx2, 0, key, outlen, outlen * 8);
976
0
    blake2s_write(&ctx2, in, inlen);
977
0
    blake2s_final(&ctx2);
978
0
    blake2s_write(&ctx, ctx2.buf, outlen); /* hash the hash */
979
0
  }
980
0
    }
981
982
  /* compute and compare the hash of hashes */
983
0
  blake2s_final(&ctx);
984
0
  for (i = 0; i < 32; i++)
985
0
    {
986
0
      if (ctx.buf[i] != blake2s_res[i])
987
0
  {
988
0
    errtxt = "digest mismatch";
989
0
    goto failed;
990
0
  }
991
0
    }
992
993
0
  return 0;
994
995
0
failed:
996
0
  if (report)
997
0
    report ("digest", algo, what, errtxt);
998
0
  return GPG_ERR_SELFTEST_FAILED;
999
0
}
1000
1001
1002
gcry_err_code_t _gcry_blake2_init_with_key(void *ctx, unsigned int flags,
1003
             const unsigned char *key,
1004
             size_t keylen, int algo)
1005
0
{
1006
0
  gcry_err_code_t rc;
1007
0
  switch (algo)
1008
0
    {
1009
0
    case GCRY_MD_BLAKE2B_512:
1010
0
      rc = blake2b_init_ctx (ctx, flags, key, keylen, 512);
1011
0
      break;
1012
0
    case GCRY_MD_BLAKE2B_384:
1013
0
      rc = blake2b_init_ctx (ctx, flags, key, keylen, 384);
1014
0
      break;
1015
0
    case GCRY_MD_BLAKE2B_256:
1016
0
      rc = blake2b_init_ctx (ctx, flags, key, keylen, 256);
1017
0
      break;
1018
0
    case GCRY_MD_BLAKE2B_160:
1019
0
      rc = blake2b_init_ctx (ctx, flags, key, keylen, 160);
1020
0
      break;
1021
0
    case GCRY_MD_BLAKE2S_256:
1022
0
      rc = blake2s_init_ctx (ctx, flags, key, keylen, 256);
1023
0
      break;
1024
0
    case GCRY_MD_BLAKE2S_224:
1025
0
      rc = blake2s_init_ctx (ctx, flags, key, keylen, 224);
1026
0
      break;
1027
0
    case GCRY_MD_BLAKE2S_160:
1028
0
      rc = blake2s_init_ctx (ctx, flags, key, keylen, 160);
1029
0
      break;
1030
0
    case GCRY_MD_BLAKE2S_128:
1031
0
      rc = blake2s_init_ctx (ctx, flags, key, keylen, 128);
1032
0
      break;
1033
0
    default:
1034
0
      rc = GPG_ERR_DIGEST_ALGO;
1035
0
      break;
1036
0
    }
1037
1038
0
  return rc;
1039
0
}
1040
1041
1042
#define DEFINE_BLAKE2_VARIANT(bs, BS, dbits, oid_branch) \
1043
  static void blake2##bs##_##dbits##_init(void *ctx, unsigned int flags) \
1044
0
  { \
1045
0
    int err = blake2##bs##_init_ctx (ctx, flags, NULL, 0, dbits); \
1046
0
    gcry_assert (err == 0); \
1047
0
  } \
Unexecuted instantiation: blake2.c:blake2b_512_init
Unexecuted instantiation: blake2.c:blake2b_384_init
Unexecuted instantiation: blake2.c:blake2b_256_init
Unexecuted instantiation: blake2.c:blake2b_160_init
Unexecuted instantiation: blake2.c:blake2s_256_init
Unexecuted instantiation: blake2.c:blake2s_224_init
Unexecuted instantiation: blake2.c:blake2s_160_init
Unexecuted instantiation: blake2.c:blake2s_128_init
1048
  static void \
1049
  _gcry_blake2##bs##_##dbits##_hash_buffers(void *outbuf, size_t nbytes, \
1050
        const gcry_buffer_t *iov, int iovcnt) \
1051
0
  { \
1052
0
    BLAKE2##BS##_CONTEXT hd; \
1053
0
    (void)nbytes; \
1054
0
    blake2##bs##_##dbits##_init (&hd, 0); \
1055
0
    for (;iovcnt > 0; iov++, iovcnt--) \
1056
0
      blake2##bs##_write (&hd, (const char*)iov[0].data + iov[0].off, \
1057
0
                          iov[0].len); \
1058
0
    blake2##bs##_final (&hd); \
1059
0
    memcpy (outbuf, blake2##bs##_read (&hd), dbits / 8); \
1060
0
  } \
Unexecuted instantiation: blake2.c:_gcry_blake2b_512_hash_buffers
Unexecuted instantiation: blake2.c:_gcry_blake2b_384_hash_buffers
Unexecuted instantiation: blake2.c:_gcry_blake2b_256_hash_buffers
Unexecuted instantiation: blake2.c:_gcry_blake2b_160_hash_buffers
Unexecuted instantiation: blake2.c:_gcry_blake2s_256_hash_buffers
Unexecuted instantiation: blake2.c:_gcry_blake2s_224_hash_buffers
Unexecuted instantiation: blake2.c:_gcry_blake2s_160_hash_buffers
Unexecuted instantiation: blake2.c:_gcry_blake2s_128_hash_buffers
1061
  static const byte blake2##bs##_##dbits##_asn[] = { 0x30 }; \
1062
  static const gcry_md_oid_spec_t oid_spec_blake2##bs##_##dbits[] = \
1063
    { \
1064
      { " 1.3.6.1.4.1.1722.12.2." oid_branch }, \
1065
      { NULL } \
1066
    }; \
1067
  const gcry_md_spec_t _gcry_digest_spec_blake2##bs##_##dbits = \
1068
    { \
1069
      GCRY_MD_BLAKE2##BS##_##dbits, {0, 0}, \
1070
      "BLAKE2" #BS "_" #dbits, blake2##bs##_##dbits##_asn, \
1071
      DIM (blake2##bs##_##dbits##_asn), oid_spec_blake2##bs##_##dbits, \
1072
      dbits / 8, blake2##bs##_##dbits##_init, blake2##bs##_write, \
1073
      blake2##bs##_final, blake2##bs##_read, NULL, \
1074
      _gcry_blake2##bs##_##dbits##_hash_buffers, \
1075
      sizeof (BLAKE2##BS##_CONTEXT), selftests_blake2##bs \
1076
    };
1077
1078
DEFINE_BLAKE2_VARIANT(b, B, 512, "1.16")
1079
DEFINE_BLAKE2_VARIANT(b, B, 384, "1.12")
1080
DEFINE_BLAKE2_VARIANT(b, B, 256, "1.8")
1081
DEFINE_BLAKE2_VARIANT(b, B, 160, "1.5")
1082
1083
DEFINE_BLAKE2_VARIANT(s, S, 256, "2.8")
1084
DEFINE_BLAKE2_VARIANT(s, S, 224, "2.7")
1085
DEFINE_BLAKE2_VARIANT(s, S, 160, "2.5")
1086
DEFINE_BLAKE2_VARIANT(s, S, 128, "2.4")