Coverage Report

Created: 2024-11-21 07:03

/src/libgcrypt/cipher/keccak.c
Line
Count
Source (jump to first uncovered line)
1
/* keccak.c - SHA3 hash functions
2
 * Copyright (C) 2015  g10 Code GmbH
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
21
#include <config.h>
22
#include <string.h>
23
#include "g10lib.h"
24
#include "bithelp.h"
25
#include "bufhelp.h"
26
#include "cipher.h"
27
#include "hash-common.h"
28
29
30
31
/* USE_64BIT indicates whether to use 64-bit generic implementation.
32
 * USE_32BIT indicates whether to use 32-bit generic implementation. */
33
#undef USE_64BIT
34
#if defined(__x86_64__) || SIZEOF_UNSIGNED_LONG == 8
35
# define USE_64BIT 1
36
#else
37
# define USE_32BIT 1
38
#endif
39
40
41
/* USE_64BIT_BMI2 indicates whether to compile with 64-bit Intel BMI2 code. */
42
#undef USE_64BIT_BMI2
43
#if defined(USE_64BIT) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
44
    defined(HAVE_CPU_ARCH_X86)
45
# define USE_64BIT_BMI2 1
46
#endif
47
48
49
/* USE_64BIT_SHLD indicates whether to compile with 64-bit Intel SHLD code. */
50
#undef USE_64BIT_SHLD
51
#if defined(USE_64BIT) && defined (__GNUC__) && defined(__x86_64__) && \
52
    defined(HAVE_CPU_ARCH_X86)
53
# define USE_64BIT_SHLD 1
54
#endif
55
56
57
/* USE_32BIT_BMI2 indicates whether to compile with 32-bit Intel BMI2 code. */
58
#undef USE_32BIT_BMI2
59
#if defined(USE_32BIT) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
60
    defined(HAVE_CPU_ARCH_X86)
61
# define USE_32BIT_BMI2 1
62
#endif
63
64
65
/* USE_64BIT_AVX512 indicates whether to compile with Intel AVX512 code. */
66
#undef USE_64BIT_AVX512
67
#if defined(USE_64BIT) && defined(__x86_64__) && \
68
    defined(HAVE_GCC_INLINE_ASM_AVX512) && \
69
    (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
70
     defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS))
71
# define USE_64BIT_AVX512 1
72
#endif
73
74
75
/* USE_64BIT_ARM_NEON indicates whether to enable 64-bit ARM/NEON assembly
76
 * code. */
77
#undef USE_64BIT_ARM_NEON
78
#ifdef ENABLE_NEON_SUPPORT
79
# if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
80
     && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
81
     && defined(HAVE_GCC_INLINE_ASM_NEON)
82
#  define USE_64BIT_ARM_NEON 1
83
# endif
84
#endif /*ENABLE_NEON_SUPPORT*/
85
86
87
/* USE_S390X_CRYPTO indicates whether to enable zSeries code. */
88
#undef USE_S390X_CRYPTO
89
#if defined(HAVE_GCC_INLINE_ASM_S390X)
90
# define USE_S390X_CRYPTO 1
91
#endif /* USE_S390X_CRYPTO */
92
93
94
/* x86-64 vector register assembly implementations use SystemV ABI, ABI
95
 * conversion needed on Win64 through function attribute. */
96
#undef ASM_FUNC_ABI
97
#if defined(USE_64BIT_AVX512) && defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)
98
# define ASM_FUNC_ABI __attribute__((sysv_abi))
99
#else
100
# define ASM_FUNC_ABI
101
#endif
102
103
104
#if defined(USE_64BIT) || defined(USE_64BIT_ARM_NEON)
105
# define NEED_COMMON64 1
106
#endif
107
108
#ifdef USE_32BIT
109
# define NEED_COMMON32BI 1
110
#endif
111
112
113
20.6k
#define SHA3_DELIMITED_SUFFIX 0x06
114
126
#define SHAKE_DELIMITED_SUFFIX 0x1F
115
0
#define CSHAKE_DELIMITED_SUFFIX 0x04
116
117
typedef struct
118
{
119
  union {
120
#ifdef NEED_COMMON64
121
    u64 state64[25];
122
#endif
123
#ifdef NEED_COMMON32BI
124
    u32 state32bi[50];
125
#endif
126
  } u;
127
} KECCAK_STATE;
128
129
130
typedef struct
131
{
132
  unsigned int (*permute)(KECCAK_STATE *hd);
133
  unsigned int (*absorb)(KECCAK_STATE *hd, int pos, const byte *lanes,
134
       size_t nlanes, int blocklanes);
135
  unsigned int (*extract) (KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
136
         unsigned int outlen);
137
} keccak_ops_t;
138
139
140
typedef struct KECCAK_CONTEXT_S
141
{
142
  KECCAK_STATE state;
143
  unsigned int outlen;
144
  unsigned int blocksize;
145
  unsigned int count;
146
  unsigned int suffix:8;
147
  unsigned int shake_in_extract_mode:1;
148
  unsigned int shake_in_read_mode:1;
149
  const keccak_ops_t *ops;
150
#ifdef USE_S390X_CRYPTO
151
  unsigned int kimd_func;
152
  unsigned int buf_pos;
153
  byte buf[1344 / 8]; /* SHAKE128 requires biggest buffer, 1344 bits. */
154
#endif
155
} KECCAK_CONTEXT;
156
157
158
159
#ifdef NEED_COMMON64
160
161
const u64 _gcry_keccak_round_consts_64bit[24 + 1] =
162
{
163
  U64_C(0x0000000000000001), U64_C(0x0000000000008082),
164
  U64_C(0x800000000000808A), U64_C(0x8000000080008000),
165
  U64_C(0x000000000000808B), U64_C(0x0000000080000001),
166
  U64_C(0x8000000080008081), U64_C(0x8000000000008009),
167
  U64_C(0x000000000000008A), U64_C(0x0000000000000088),
168
  U64_C(0x0000000080008009), U64_C(0x000000008000000A),
169
  U64_C(0x000000008000808B), U64_C(0x800000000000008B),
170
  U64_C(0x8000000000008089), U64_C(0x8000000000008003),
171
  U64_C(0x8000000000008002), U64_C(0x8000000000000080),
172
  U64_C(0x000000000000800A), U64_C(0x800000008000000A),
173
  U64_C(0x8000000080008081), U64_C(0x8000000000008080),
174
  U64_C(0x0000000080000001), U64_C(0x8000000080008008),
175
  U64_C(0xFFFFFFFFFFFFFFFF)
176
};
177
178
static unsigned int
179
keccak_extract64(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
180
     unsigned int outlen)
181
18.3k
{
182
18.3k
  unsigned int i;
183
184
  /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
185
186
125k
  for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
187
106k
    {
188
106k
      u64 tmp = hd->u.state64[i];
189
106k
      buf_put_le64(outbuf, tmp);
190
106k
      outbuf += 8;
191
106k
    }
192
193
18.3k
  return 0;
194
18.3k
}
195
196
#endif /* NEED_COMMON64 */
197
198
199
#ifdef NEED_COMMON32BI
200
201
static const u32 round_consts_32bit[2 * 24] =
202
{
203
  0x00000001UL, 0x00000000UL, 0x00000000UL, 0x00000089UL,
204
  0x00000000UL, 0x8000008bUL, 0x00000000UL, 0x80008080UL,
205
  0x00000001UL, 0x0000008bUL, 0x00000001UL, 0x00008000UL,
206
  0x00000001UL, 0x80008088UL, 0x00000001UL, 0x80000082UL,
207
  0x00000000UL, 0x0000000bUL, 0x00000000UL, 0x0000000aUL,
208
  0x00000001UL, 0x00008082UL, 0x00000000UL, 0x00008003UL,
209
  0x00000001UL, 0x0000808bUL, 0x00000001UL, 0x8000000bUL,
210
  0x00000001UL, 0x8000008aUL, 0x00000001UL, 0x80000081UL,
211
  0x00000000UL, 0x80000081UL, 0x00000000UL, 0x80000008UL,
212
  0x00000000UL, 0x00000083UL, 0x00000000UL, 0x80008003UL,
213
  0x00000001UL, 0x80008088UL, 0x00000000UL, 0x80000088UL,
214
  0x00000001UL, 0x00008000UL, 0x00000000UL, 0x80008082UL
215
};
216
217
static unsigned int
218
keccak_extract32bi(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
219
       unsigned int outlen)
220
{
221
  unsigned int i;
222
  u32 x0;
223
  u32 x1;
224
  u32 t;
225
226
  /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
227
228
  for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
229
    {
230
      x0 = hd->u.state32bi[i * 2 + 0];
231
      x1 = hd->u.state32bi[i * 2 + 1];
232
233
      t = (x0 & 0x0000FFFFUL) + (x1 << 16);
234
      x1 = (x0 >> 16) + (x1 & 0xFFFF0000UL);
235
      x0 = t;
236
      t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8);
237
      t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4);
238
      t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2);
239
      t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1);
240
      t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8);
241
      t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4);
242
      t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
243
      t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
244
245
      buf_put_le32(&outbuf[0], x0);
246
      buf_put_le32(&outbuf[4], x1);
247
      outbuf += 8;
248
    }
249
250
  return 0;
251
}
252
253
static inline void
254
keccak_absorb_lane32bi(u32 *lane, u32 x0, u32 x1)
255
{
256
  u32 t;
257
258
  t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1);
259
  t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2);
260
  t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4);
261
  t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8);
262
  t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
263
  t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
264
  t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4);
265
  t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8);
266
  lane[0] ^= (x0 & 0x0000FFFFUL) + (x1 << 16);
267
  lane[1] ^= (x0 >> 16) + (x1 & 0xFFFF0000UL);
268
}
269
270
#endif /* NEED_COMMON32BI */
271
272
273
/* Construct generic 64-bit implementation. */
274
#ifdef USE_64BIT
275
276
#if __GNUC__ >= 4 && defined(__x86_64__)
277
278
static inline void absorb_lanes64_8(u64 *dst, const byte *in)
279
950k
{
280
950k
  asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
281
950k
       "movdqu 0*16(%[in]), %%xmm4\n\t"
282
950k
       "movdqu 1*16(%[dst]), %%xmm1\n\t"
283
950k
       "movdqu 1*16(%[in]), %%xmm5\n\t"
284
950k
       "movdqu 2*16(%[dst]), %%xmm2\n\t"
285
950k
       "movdqu 3*16(%[dst]), %%xmm3\n\t"
286
950k
       "pxor %%xmm4, %%xmm0\n\t"
287
950k
       "pxor %%xmm5, %%xmm1\n\t"
288
950k
       "movdqu 2*16(%[in]), %%xmm4\n\t"
289
950k
       "movdqu 3*16(%[in]), %%xmm5\n\t"
290
950k
       "movdqu %%xmm0, 0*16(%[dst])\n\t"
291
950k
       "pxor %%xmm4, %%xmm2\n\t"
292
950k
       "movdqu %%xmm1, 1*16(%[dst])\n\t"
293
950k
       "pxor %%xmm5, %%xmm3\n\t"
294
950k
       "movdqu %%xmm2, 2*16(%[dst])\n\t"
295
950k
       "movdqu %%xmm3, 3*16(%[dst])\n\t"
296
950k
       :
297
950k
       : [dst] "r" (dst), [in] "r" (in)
298
950k
       : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "memory");
299
950k
}
300
301
static inline void absorb_lanes64_4(u64 *dst, const byte *in)
302
158k
{
303
158k
  asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
304
158k
       "movdqu 0*16(%[in]), %%xmm4\n\t"
305
158k
       "movdqu 1*16(%[dst]), %%xmm1\n\t"
306
158k
       "movdqu 1*16(%[in]), %%xmm5\n\t"
307
158k
       "pxor %%xmm4, %%xmm0\n\t"
308
158k
       "pxor %%xmm5, %%xmm1\n\t"
309
158k
       "movdqu %%xmm0, 0*16(%[dst])\n\t"
310
158k
       "movdqu %%xmm1, 1*16(%[dst])\n\t"
311
158k
       :
312
158k
       : [dst] "r" (dst), [in] "r" (in)
313
158k
       : "xmm0", "xmm1", "xmm4", "xmm5", "memory");
314
158k
}
315
316
static inline void absorb_lanes64_2(u64 *dst, const byte *in)
317
120k
{
318
120k
  asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
319
120k
       "movdqu 0*16(%[in]), %%xmm4\n\t"
320
120k
       "pxor %%xmm4, %%xmm0\n\t"
321
120k
       "movdqu %%xmm0, 0*16(%[dst])\n\t"
322
120k
       :
323
120k
       : [dst] "r" (dst), [in] "r" (in)
324
120k
       : "xmm0", "xmm4", "memory");
325
120k
}
326
327
#else /* __x86_64__ */
328
329
static inline void absorb_lanes64_8(u64 *dst, const byte *in)
330
{
331
  dst[0] ^= buf_get_le64(in + 8 * 0);
332
  dst[1] ^= buf_get_le64(in + 8 * 1);
333
  dst[2] ^= buf_get_le64(in + 8 * 2);
334
  dst[3] ^= buf_get_le64(in + 8 * 3);
335
  dst[4] ^= buf_get_le64(in + 8 * 4);
336
  dst[5] ^= buf_get_le64(in + 8 * 5);
337
  dst[6] ^= buf_get_le64(in + 8 * 6);
338
  dst[7] ^= buf_get_le64(in + 8 * 7);
339
}
340
341
static inline void absorb_lanes64_4(u64 *dst, const byte *in)
342
{
343
  dst[0] ^= buf_get_le64(in + 8 * 0);
344
  dst[1] ^= buf_get_le64(in + 8 * 1);
345
  dst[2] ^= buf_get_le64(in + 8 * 2);
346
  dst[3] ^= buf_get_le64(in + 8 * 3);
347
}
348
349
static inline void absorb_lanes64_2(u64 *dst, const byte *in)
350
{
351
  dst[0] ^= buf_get_le64(in + 8 * 0);
352
  dst[1] ^= buf_get_le64(in + 8 * 1);
353
}
354
355
#endif /* !__x86_64__ */
356
357
static inline void absorb_lanes64_1(u64 *dst, const byte *in)
358
582k
{
359
582k
  dst[0] ^= buf_get_le64(in + 8 * 0);
360
582k
}
361
362
363
0
# define ANDN64(x, y) (~(x) & (y))
364
0
# define ROL64(x, n) (((x) << ((unsigned int)n & 63)) | \
365
0
          ((x) >> ((64 - (unsigned int)(n)) & 63)))
366
367
0
# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64
368
# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64
369
# include "keccak_permute_64.h"
370
371
# undef ANDN64
372
# undef ROL64
373
# undef KECCAK_F1600_PERMUTE_FUNC_NAME
374
# undef KECCAK_F1600_ABSORB_FUNC_NAME
375
376
static const keccak_ops_t keccak_generic64_ops =
377
{
378
  .permute = keccak_f1600_state_permute64,
379
  .absorb = keccak_absorb_lanes64,
380
  .extract = keccak_extract64,
381
};
382
383
#endif /* USE_64BIT */
384
385
386
/* Construct 64-bit Intel SHLD implementation. */
387
#ifdef USE_64BIT_SHLD
388
389
0
# define ANDN64(x, y) (~(x) & (y))
390
0
# define ROL64(x, n) ({ \
391
0
      u64 tmp = (x); \
392
0
      asm ("shldq %1, %0, %0" \
393
0
           : "+r" (tmp) \
394
0
           : "J" ((n) & 63) \
395
0
           : "cc"); \
396
0
      tmp; })
397
398
0
# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_shld
399
# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_shld
400
# include "keccak_permute_64.h"
401
402
# undef ANDN64
403
# undef ROL64
404
# undef KECCAK_F1600_PERMUTE_FUNC_NAME
405
# undef KECCAK_F1600_ABSORB_FUNC_NAME
406
407
static const keccak_ops_t keccak_shld_64_ops =
408
{
409
  .permute = keccak_f1600_state_permute64_shld,
410
  .absorb = keccak_absorb_lanes64_shld,
411
  .extract = keccak_extract64,
412
};
413
414
#endif /* USE_64BIT_SHLD */
415
416
417
/* Construct 64-bit Intel BMI2 implementation. */
418
#ifdef USE_64BIT_BMI2
419
420
438M
# define ANDN64(x, y) ({ \
421
438M
      u64 tmp; \
422
438M
      asm ("andnq %2, %1, %0" \
423
438M
           : "=r" (tmp) \
424
438M
           : "r0" (x), "rm" (y)); \
425
438M
      tmp; })
426
427
508M
# define ROL64(x, n) ({ \
428
508M
      u64 tmp; \
429
508M
      asm ("rorxq %2, %1, %0" \
430
508M
           : "=r" (tmp) \
431
508M
           : "rm0" (x), "J" (64 - ((n) & 63))); \
432
508M
      tmp; })
433
434
712k
# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_bmi2
435
# define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_bmi2
436
# include "keccak_permute_64.h"
437
438
# undef ANDN64
439
# undef ROL64
440
# undef KECCAK_F1600_PERMUTE_FUNC_NAME
441
# undef KECCAK_F1600_ABSORB_FUNC_NAME
442
443
static const keccak_ops_t keccak_bmi2_64_ops =
444
{
445
  .permute = keccak_f1600_state_permute64_bmi2,
446
  .absorb = keccak_absorb_lanes64_bmi2,
447
  .extract = keccak_extract64,
448
};
449
450
#endif /* USE_64BIT_BMI2 */
451
452
453
/* 64-bit Intel AVX512 implementation. */
454
#ifdef USE_64BIT_AVX512
455
456
extern ASM_FUNC_ABI unsigned int
457
_gcry_keccak_f1600_state_permute64_avx512(u64 *state, const u64 *rconst);
458
459
extern ASM_FUNC_ABI unsigned int
460
_gcry_keccak_absorb_blocks_avx512(u64 *state, const u64 *rconst,
461
                                  const byte *lanes, u64 nlanes,
462
                                  u64 blocklanes, u64 *new_lanes);
463
464
static unsigned int
465
keccak_f1600_state_permute64_avx512(KECCAK_STATE *hd)
466
0
{
467
0
  return _gcry_keccak_f1600_state_permute64_avx512 (
468
0
                                hd->u.state64, _gcry_keccak_round_consts_64bit);
469
0
}
470
471
static unsigned int
472
keccak_absorb_lanes64_avx512(KECCAK_STATE *hd, int pos, const byte *lanes,
473
           size_t nlanes, int blocklanes)
474
0
{
475
0
  while (nlanes)
476
0
    {
477
0
      if (pos == 0 && blocklanes > 0 && nlanes >= (size_t)blocklanes)
478
0
        {
479
          /* Get new pointer through u64 variable for "x32" compatibility. */
480
0
          u64 new_lanes;
481
0
          nlanes = _gcry_keccak_absorb_blocks_avx512 (
482
0
                            hd->u.state64, _gcry_keccak_round_consts_64bit,
483
0
                            lanes, nlanes, blocklanes, &new_lanes);
484
0
          lanes = (const byte *)(uintptr_t)new_lanes;
485
0
        }
486
487
0
      while (nlanes)
488
0
  {
489
0
    hd->u.state64[pos] ^= buf_get_le64 (lanes);
490
0
    lanes += 8;
491
0
    nlanes--;
492
493
0
    if (++pos == blocklanes)
494
0
      {
495
0
        keccak_f1600_state_permute64_avx512 (hd);
496
0
        pos = 0;
497
0
        break;
498
0
      }
499
0
  }
500
0
    }
501
502
0
  return 0;
503
0
}
504
505
static const keccak_ops_t keccak_avx512_64_ops =
506
{
507
  .permute = keccak_f1600_state_permute64_avx512,
508
  .absorb = keccak_absorb_lanes64_avx512,
509
  .extract = keccak_extract64,
510
};
511
512
#endif /* USE_64BIT_AVX512 */
513
514
515
/* 64-bit ARMv7/NEON implementation. */
516
#ifdef USE_64BIT_ARM_NEON
517
518
unsigned int _gcry_keccak_permute_armv7_neon(u64 *state);
519
unsigned int _gcry_keccak_absorb_lanes64_armv7_neon(u64 *state, int pos,
520
                const byte *lanes,
521
                size_t nlanes,
522
                int blocklanes);
523
524
static unsigned int keccak_permute64_armv7_neon(KECCAK_STATE *hd)
525
{
526
  return _gcry_keccak_permute_armv7_neon(hd->u.state64);
527
}
528
529
static unsigned int
530
keccak_absorb_lanes64_armv7_neon(KECCAK_STATE *hd, int pos, const byte *lanes,
531
         size_t nlanes, int blocklanes)
532
{
533
  if (blocklanes < 0)
534
    {
535
      /* blocklanes == -1, permutationless absorb from keccak_final. */
536
537
      while (nlanes)
538
  {
539
    hd->u.state64[pos] ^= buf_get_le64(lanes);
540
    lanes += 8;
541
    nlanes--;
542
  }
543
544
      return 0;
545
    }
546
  else
547
    {
548
      return _gcry_keccak_absorb_lanes64_armv7_neon(hd->u.state64, pos, lanes,
549
                nlanes, blocklanes);
550
    }
551
}
552
553
static const keccak_ops_t keccak_armv7_neon_64_ops =
554
{
555
  .permute = keccak_permute64_armv7_neon,
556
  .absorb = keccak_absorb_lanes64_armv7_neon,
557
  .extract = keccak_extract64,
558
};
559
560
#endif /* USE_64BIT_ARM_NEON */
561
562
563
/* Construct generic 32-bit implementation. */
564
#ifdef USE_32BIT
565
566
# define ANDN32(x, y) (~(x) & (y))
567
# define ROL32(x, n) (((x) << ((unsigned int)n & 31)) | \
568
          ((x) >> ((32 - (unsigned int)(n)) & 31)))
569
570
# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute32bi
571
# include "keccak_permute_32.h"
572
573
# undef ANDN32
574
# undef ROL32
575
# undef KECCAK_F1600_PERMUTE_FUNC_NAME
576
577
static unsigned int
578
keccak_absorb_lanes32bi(KECCAK_STATE *hd, int pos, const byte *lanes,
579
            size_t nlanes, int blocklanes)
580
{
581
  unsigned int burn = 0;
582
583
  while (nlanes)
584
    {
585
      keccak_absorb_lane32bi(&hd->u.state32bi[pos * 2],
586
           buf_get_le32(lanes + 0),
587
           buf_get_le32(lanes + 4));
588
      lanes += 8;
589
      nlanes--;
590
591
      if (++pos == blocklanes)
592
  {
593
    burn = keccak_f1600_state_permute32bi(hd);
594
    pos = 0;
595
  }
596
    }
597
598
  return burn;
599
}
600
601
static const keccak_ops_t keccak_generic32bi_ops =
602
{
603
  .permute = keccak_f1600_state_permute32bi,
604
  .absorb = keccak_absorb_lanes32bi,
605
  .extract = keccak_extract32bi,
606
};
607
608
#endif /* USE_32BIT */
609
610
611
/* Construct 32-bit Intel BMI2 implementation. */
612
#ifdef USE_32BIT_BMI2
613
614
# define ANDN32(x, y) ({ \
615
      u32 tmp; \
616
      asm ("andnl %2, %1, %0" \
617
           : "=r" (tmp) \
618
           : "r0" (x), "rm" (y)); \
619
      tmp; })
620
621
# define ROL32(x, n) ({ \
622
      u32 tmp; \
623
      asm ("rorxl %2, %1, %0" \
624
           : "=r" (tmp) \
625
           : "rm0" (x), "J" (32 - ((n) & 31))); \
626
      tmp; })
627
628
# define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute32bi_bmi2
629
# include "keccak_permute_32.h"
630
631
# undef ANDN32
632
# undef ROL32
633
# undef KECCAK_F1600_PERMUTE_FUNC_NAME
634
635
static inline u32 pext(u32 x, u32 mask)
636
{
637
  u32 tmp;
638
  asm ("pextl %2, %1, %0" : "=r" (tmp) : "r0" (x), "rm" (mask));
639
  return tmp;
640
}
641
642
static inline u32 pdep(u32 x, u32 mask)
643
{
644
  u32 tmp;
645
  asm ("pdepl %2, %1, %0" : "=r" (tmp) : "r0" (x), "rm" (mask));
646
  return tmp;
647
}
648
649
static inline void
650
keccak_absorb_lane32bi_bmi2(u32 *lane, u32 x0, u32 x1)
651
{
652
  x0 = pdep(pext(x0, 0x55555555), 0x0000ffff) | (pext(x0, 0xaaaaaaaa) << 16);
653
  x1 = pdep(pext(x1, 0x55555555), 0x0000ffff) | (pext(x1, 0xaaaaaaaa) << 16);
654
655
  lane[0] ^= (x0 & 0x0000FFFFUL) + (x1 << 16);
656
  lane[1] ^= (x0 >> 16) + (x1 & 0xFFFF0000UL);
657
}
658
659
static unsigned int
660
keccak_absorb_lanes32bi_bmi2(KECCAK_STATE *hd, int pos, const byte *lanes,
661
                 size_t nlanes, int blocklanes)
662
{
663
  unsigned int burn = 0;
664
665
  while (nlanes)
666
    {
667
      keccak_absorb_lane32bi_bmi2(&hd->u.state32bi[pos * 2],
668
                buf_get_le32(lanes + 0),
669
                buf_get_le32(lanes + 4));
670
      lanes += 8;
671
      nlanes--;
672
673
      if (++pos == blocklanes)
674
  {
675
    burn = keccak_f1600_state_permute32bi_bmi2(hd);
676
    pos = 0;
677
  }
678
    }
679
680
  return burn;
681
}
682
683
static unsigned int
684
keccak_extract32bi_bmi2(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
685
      unsigned int outlen)
686
{
687
  unsigned int i;
688
  u32 x0;
689
  u32 x1;
690
  u32 t;
691
692
  /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
693
694
  for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
695
    {
696
      x0 = hd->u.state32bi[i * 2 + 0];
697
      x1 = hd->u.state32bi[i * 2 + 1];
698
699
      t = (x0 & 0x0000FFFFUL) + (x1 << 16);
700
      x1 = (x0 >> 16) + (x1 & 0xFFFF0000UL);
701
      x0 = t;
702
703
      x0 = pdep(pext(x0, 0xffff0001), 0xaaaaaaab) | pdep(x0 >> 1, 0x55555554);
704
      x1 = pdep(pext(x1, 0xffff0001), 0xaaaaaaab) | pdep(x1 >> 1, 0x55555554);
705
706
      buf_put_le32(&outbuf[0], x0);
707
      buf_put_le32(&outbuf[4], x1);
708
      outbuf += 8;
709
    }
710
711
  return 0;
712
}
713
714
static const keccak_ops_t keccak_bmi2_32bi_ops =
715
{
716
  .permute = keccak_f1600_state_permute32bi_bmi2,
717
  .absorb = keccak_absorb_lanes32bi_bmi2,
718
  .extract = keccak_extract32bi_bmi2,
719
};
720
721
#endif /* USE_32BIT_BMI2 */
722
723
724
#ifdef USE_S390X_CRYPTO
725
#include "asm-inline-s390x.h"
726
727
static inline void
728
keccak_bwrite_s390x (void *context, const byte *in, size_t inlen)
729
{
730
  KECCAK_CONTEXT *ctx = context;
731
732
  /* Write full-blocks. */
733
  kimd_execute (ctx->kimd_func, &ctx->state, in, inlen);
734
  return;
735
}
736
737
static inline void
738
keccak_final_s390x (void *context)
739
{
740
  KECCAK_CONTEXT *ctx = context;
741
742
  if (ctx->suffix == SHA3_DELIMITED_SUFFIX)
743
    {
744
      klmd_execute (ctx->kimd_func, &ctx->state, ctx->buf, ctx->count);
745
    }
746
  else
747
    {
748
      gcry_assert(ctx->suffix == SHAKE_DELIMITED_SUFFIX);
749
750
      klmd_shake_execute (ctx->kimd_func, &ctx->state, NULL, 0, ctx->buf,
751
        ctx->count);
752
      ctx->count = 0;
753
      ctx->buf_pos = 0;
754
    }
755
756
  return;
757
}
758
759
static inline void
760
keccak_bextract_s390x (void *context, byte *out, size_t outlen)
761
{
762
  KECCAK_CONTEXT *ctx = context;
763
764
  /* Extract full-blocks. */
765
  klmd_shake_execute (ctx->kimd_func | KLMD_PADDING_STATE, &ctx->state,
766
          out, outlen, NULL, 0);
767
  return;
768
}
769
770
static void
771
keccak_write_s390x (void *context, const byte *inbuf, size_t inlen)
772
{
773
  KECCAK_CONTEXT *hd = context;
774
  const size_t blocksize = hd->blocksize;
775
  size_t inblocks;
776
  size_t copylen;
777
778
  while (hd->count)
779
    {
780
      if (hd->count == blocksize)  /* Flush the buffer. */
781
  {
782
    keccak_bwrite_s390x (hd, hd->buf, blocksize);
783
    hd->count = 0;
784
  }
785
      else
786
  {
787
    copylen = inlen;
788
    if (copylen > blocksize - hd->count)
789
      copylen = blocksize - hd->count;
790
791
    if (copylen == 0)
792
      break;
793
794
    buf_cpy (&hd->buf[hd->count], inbuf, copylen);
795
    hd->count += copylen;
796
    inbuf += copylen;
797
    inlen -= copylen;
798
  }
799
    }
800
801
  if (inlen == 0)
802
    return;
803
804
  if (inlen >= blocksize)
805
    {
806
      inblocks = inlen / blocksize;
807
      keccak_bwrite_s390x (hd, inbuf, inblocks * blocksize);
808
      hd->count = 0;
809
      inlen -= inblocks * blocksize;
810
      inbuf += inblocks * blocksize;
811
    }
812
813
  if (inlen)
814
    {
815
      buf_cpy (hd->buf, inbuf, inlen);
816
      hd->count = inlen;
817
    }
818
}
819
820
static void
821
keccak_extract_s390x (void *context, void *outbuf_arg, size_t outlen)
822
{
823
  KECCAK_CONTEXT *hd = context;
824
  const size_t blocksize = hd->blocksize;
825
  byte *outbuf = outbuf_arg;
826
827
  while (outlen)
828
    {
829
      gcry_assert(hd->count == 0 || hd->buf_pos < hd->count);
830
831
      if (hd->buf_pos < hd->count && outlen)
832
  {
833
    size_t copylen = hd->count - hd->buf_pos;
834
835
    if (copylen > outlen)
836
      copylen = outlen;
837
838
    buf_cpy (outbuf, &hd->buf[hd->buf_pos], copylen);
839
840
    outbuf += copylen;
841
    outlen -= copylen;
842
    hd->buf_pos += copylen;
843
  }
844
845
      if (hd->buf_pos == hd->count)
846
  {
847
    hd->buf_pos = 0;
848
    hd->count = 0;
849
  }
850
851
      if (outlen == 0)
852
  return;
853
854
      if (outlen >= blocksize)
855
  {
856
    size_t outblocks = outlen / blocksize;
857
858
    keccak_bextract_s390x (context, outbuf, outblocks * blocksize);
859
860
    outlen -= outblocks * blocksize;
861
    outbuf += outblocks * blocksize;
862
863
    if (outlen == 0)
864
      return;
865
  }
866
867
      keccak_bextract_s390x (context, hd->buf, blocksize);
868
      hd->count = blocksize;
869
    }
870
}
871
#endif /* USE_S390X_CRYPTO */
872
873
874
static void
875
keccak_write (void *context, const void *inbuf_arg, size_t inlen)
876
135k
{
877
135k
  KECCAK_CONTEXT *ctx = context;
878
135k
  const size_t bsize = ctx->blocksize;
879
135k
  const size_t blocklanes = bsize / 8;
880
135k
  const byte *inbuf = inbuf_arg;
881
135k
  unsigned int nburn, burn = 0;
882
135k
  unsigned int count, i;
883
135k
  unsigned int pos;
884
135k
  size_t nlanes;
885
886
#ifdef USE_S390X_CRYPTO
887
  if (ctx->kimd_func)
888
    {
889
      keccak_write_s390x (context, inbuf, inlen);
890
      return;
891
    }
892
#endif
893
894
135k
  count = ctx->count;
895
896
135k
  if (inlen && (count % 8))
897
12.2k
    {
898
12.2k
      byte lane[8] = { 0, };
899
900
      /* Complete absorbing partial input lane. */
901
902
12.2k
      pos = count / 8;
903
904
39.1k
      for (i = count % 8; inlen && i < 8; i++)
905
26.9k
  {
906
26.9k
    lane[i] = *inbuf++;
907
26.9k
    inlen--;
908
26.9k
    count++;
909
26.9k
  }
910
911
12.2k
      if (count == bsize)
912
1.06k
  count = 0;
913
914
12.2k
      nburn = ctx->ops->absorb(&ctx->state, pos, lane, 1,
915
12.2k
             (count % 8) ? -1 : blocklanes);
916
12.2k
      burn = nburn > burn ? nburn : burn;
917
12.2k
    }
918
919
  /* Absorb full input lanes. */
920
921
135k
  pos = count / 8;
922
135k
  nlanes = inlen / 8;
923
135k
  if (nlanes > 0)
924
28.7k
    {
925
28.7k
      nburn = ctx->ops->absorb(&ctx->state, pos, inbuf, nlanes, blocklanes);
926
28.7k
      burn = nburn > burn ? nburn : burn;
927
28.7k
      inlen -= nlanes * 8;
928
28.7k
      inbuf += nlanes * 8;
929
28.7k
      count = ((size_t) count + nlanes * 8) % bsize;
930
28.7k
    }
931
932
135k
  if (inlen)
933
15.6k
    {
934
15.6k
      byte lane[8] = { 0, };
935
936
      /* Absorb remaining partial input lane. */
937
938
15.6k
      pos = count / 8;
939
940
73.5k
      for (i = count % 8; inlen && i < 8; i++)
941
57.8k
  {
942
57.8k
    lane[i] = *inbuf++;
943
57.8k
    inlen--;
944
57.8k
    count++;
945
57.8k
  }
946
947
15.6k
      nburn = ctx->ops->absorb(&ctx->state, pos, lane, 1, -1);
948
15.6k
      burn = nburn > burn ? nburn : burn;
949
950
15.6k
      gcry_assert(count < bsize);
951
15.6k
    }
952
953
0
  ctx->count = count;
954
955
135k
  if (burn)
956
11.9k
    _gcry_burn_stack (burn);
957
135k
}
958
959
960
static void
961
keccak_init (int algo, void *context, unsigned int flags)
962
2.29k
{
963
2.29k
  KECCAK_CONTEXT *ctx = context;
964
2.29k
  KECCAK_STATE *hd = &ctx->state;
965
2.29k
  unsigned int features = _gcry_get_hw_features ();
966
967
2.29k
  (void)flags;
968
2.29k
  (void)features;
969
970
2.29k
  memset (hd, 0, sizeof *hd);
971
972
2.29k
  ctx->count = 0;
973
2.29k
  ctx->shake_in_extract_mode = 0;
974
2.29k
  ctx->shake_in_read_mode = 0;
975
976
  /* Select generic implementation. */
977
2.29k
#ifdef USE_64BIT
978
2.29k
  ctx->ops = &keccak_generic64_ops;
979
#elif defined USE_32BIT
980
  ctx->ops = &keccak_generic32bi_ops;
981
#endif
982
983
  /* Select optimized implementation based in hw features. */
984
2.29k
  if (0) {}
985
2.29k
#ifdef USE_64BIT_AVX512
986
2.29k
  else if (features & HWF_INTEL_AVX512)
987
0
    ctx->ops = &keccak_avx512_64_ops;
988
2.29k
#endif
989
#ifdef USE_64BIT_ARM_NEON
990
  else if (features & HWF_ARM_NEON)
991
    ctx->ops = &keccak_armv7_neon_64_ops;
992
#endif
993
2.29k
#ifdef USE_64BIT_BMI2
994
2.29k
  else if (features & HWF_INTEL_BMI2)
995
2.29k
    ctx->ops = &keccak_bmi2_64_ops;
996
0
#endif
997
#ifdef USE_32BIT_BMI2
998
  else if (features & HWF_INTEL_BMI2)
999
    ctx->ops = &keccak_bmi2_32bi_ops;
1000
#endif
1001
0
#ifdef USE_64BIT_SHLD
1002
0
  else if (features & HWF_INTEL_FAST_SHLD)
1003
0
    ctx->ops = &keccak_shld_64_ops;
1004
2.29k
#endif
1005
1006
  /* Set input block size, in Keccak terms this is called 'rate'. */
1007
1008
2.29k
  switch (algo)
1009
2.29k
    {
1010
736
    case GCRY_MD_SHA3_224:
1011
736
      ctx->suffix = SHA3_DELIMITED_SUFFIX;
1012
736
      ctx->blocksize = 1152 / 8;
1013
736
      ctx->outlen = 224 / 8;
1014
736
      break;
1015
478
    case GCRY_MD_SHA3_256:
1016
478
      ctx->suffix = SHA3_DELIMITED_SUFFIX;
1017
478
      ctx->blocksize = 1088 / 8;
1018
478
      ctx->outlen = 256 / 8;
1019
478
      break;
1020
414
    case GCRY_MD_SHA3_384:
1021
414
      ctx->suffix = SHA3_DELIMITED_SUFFIX;
1022
414
      ctx->blocksize = 832 / 8;
1023
414
      ctx->outlen = 384 / 8;
1024
414
      break;
1025
539
    case GCRY_MD_SHA3_512:
1026
539
      ctx->suffix = SHA3_DELIMITED_SUFFIX;
1027
539
      ctx->blocksize = 576 / 8;
1028
539
      ctx->outlen = 512 / 8;
1029
539
      break;
1030
0
    case GCRY_MD_CSHAKE128:
1031
74
    case GCRY_MD_SHAKE128:
1032
74
      ctx->suffix = SHAKE_DELIMITED_SUFFIX;
1033
74
      ctx->blocksize = 1344 / 8;
1034
74
      ctx->outlen = 256 / 8;
1035
74
      break;
1036
0
    case GCRY_MD_CSHAKE256:
1037
52
    case GCRY_MD_SHAKE256:
1038
52
      ctx->suffix = SHAKE_DELIMITED_SUFFIX;
1039
52
      ctx->blocksize = 1088 / 8;
1040
52
      ctx->outlen = 512 / 8;
1041
52
      break;
1042
0
    default:
1043
0
      BUG();
1044
2.29k
    }
1045
1046
#ifdef USE_S390X_CRYPTO
1047
  ctx->kimd_func = 0;
1048
  if ((features & HWF_S390X_MSA) != 0)
1049
    {
1050
      unsigned int kimd_func = 0;
1051
1052
      switch (algo)
1053
  {
1054
  case GCRY_MD_SHA3_224:
1055
    kimd_func = KMID_FUNCTION_SHA3_224;
1056
    break;
1057
  case GCRY_MD_SHA3_256:
1058
    kimd_func = KMID_FUNCTION_SHA3_256;
1059
    break;
1060
  case GCRY_MD_SHA3_384:
1061
    kimd_func = KMID_FUNCTION_SHA3_384;
1062
    break;
1063
  case GCRY_MD_SHA3_512:
1064
    kimd_func = KMID_FUNCTION_SHA3_512;
1065
    break;
1066
  case GCRY_MD_CSHAKE128:
1067
  case GCRY_MD_SHAKE128:
1068
    kimd_func = KMID_FUNCTION_SHAKE128;
1069
    break;
1070
  case GCRY_MD_CSHAKE256:
1071
  case GCRY_MD_SHAKE256:
1072
    kimd_func = KMID_FUNCTION_SHAKE256;
1073
    break;
1074
  }
1075
1076
      if ((kimd_query () & km_function_to_mask (kimd_func)) &&
1077
    (klmd_query () & km_function_to_mask (kimd_func)))
1078
  {
1079
    ctx->kimd_func = kimd_func;
1080
  }
1081
    }
1082
#endif
1083
2.29k
}
1084
1085
static void
1086
sha3_224_init (void *context, unsigned int flags)
1087
736
{
1088
736
  keccak_init (GCRY_MD_SHA3_224, context, flags);
1089
736
}
1090
1091
static void
1092
sha3_256_init (void *context, unsigned int flags)
1093
478
{
1094
478
  keccak_init (GCRY_MD_SHA3_256, context, flags);
1095
478
}
1096
1097
static void
1098
sha3_384_init (void *context, unsigned int flags)
1099
414
{
1100
414
  keccak_init (GCRY_MD_SHA3_384, context, flags);
1101
414
}
1102
1103
static void
1104
sha3_512_init (void *context, unsigned int flags)
1105
539
{
1106
539
  keccak_init (GCRY_MD_SHA3_512, context, flags);
1107
539
}
1108
1109
static void
1110
shake128_init (void *context, unsigned int flags)
1111
74
{
1112
74
  keccak_init (GCRY_MD_SHAKE128, context, flags);
1113
74
}
1114
1115
static void
1116
shake256_init (void *context, unsigned int flags)
1117
52
{
1118
52
  keccak_init (GCRY_MD_SHAKE256, context, flags);
1119
52
}
1120
1121
/* The routine final terminates the computation and
1122
 * returns the digest.
1123
 * The handle is prepared for a new cycle, but adding bytes to the
1124
 * handle will the destroy the returned buffer.
1125
 * Returns: 64 bytes representing the digest.  When used for sha384,
1126
 * we take the leftmost 48 of those bytes.
1127
 */
1128
static void
1129
keccak_final (void *context)
1130
18.3k
{
1131
18.3k
  KECCAK_CONTEXT *ctx = context;
1132
18.3k
  KECCAK_STATE *hd = &ctx->state;
1133
18.3k
  const size_t bsize = ctx->blocksize;
1134
18.3k
  const byte suffix = ctx->suffix;
1135
18.3k
  unsigned int nburn, burn = 0;
1136
18.3k
  unsigned int lastbytes;
1137
18.3k
  byte lane[8];
1138
1139
#ifdef USE_S390X_CRYPTO
1140
  if (ctx->kimd_func)
1141
    {
1142
      keccak_final_s390x (context);
1143
      return;
1144
    }
1145
#endif
1146
1147
18.3k
  lastbytes = ctx->count;
1148
1149
  /* Do the padding and switch to the squeezing phase */
1150
1151
  /* Absorb the last few bits and add the first bit of padding (which
1152
     coincides with the delimiter in delimited suffix) */
1153
18.3k
  buf_put_le64(lane, (u64)suffix << ((lastbytes % 8) * 8));
1154
18.3k
  nburn = ctx->ops->absorb(&ctx->state, lastbytes / 8, lane, 1, -1);
1155
18.3k
  burn = nburn > burn ? nburn : burn;
1156
1157
  /* Add the second bit of padding. */
1158
18.3k
  buf_put_le64(lane, (u64)0x80 << (((bsize - 1) % 8) * 8));
1159
18.3k
  nburn = ctx->ops->absorb(&ctx->state, (bsize - 1) / 8, lane, 1, -1);
1160
18.3k
  burn = nburn > burn ? nburn : burn;
1161
1162
18.3k
  if (suffix == SHA3_DELIMITED_SUFFIX)
1163
18.2k
    {
1164
      /* Switch to the squeezing phase. */
1165
18.2k
      nburn = ctx->ops->permute(hd);
1166
18.2k
      burn = nburn > burn ? nburn : burn;
1167
1168
      /* Squeeze out the SHA3 digest. */
1169
18.2k
      nburn = ctx->ops->extract(hd, 0, (void *)hd, ctx->outlen);
1170
18.2k
      burn = nburn > burn ? nburn : burn;
1171
18.2k
    }
1172
126
  else
1173
126
    {
1174
      /* Output for SHAKE can now be read with md_extract(). */
1175
1176
126
      ctx->count = 0;
1177
126
    }
1178
1179
18.3k
  wipememory(lane, sizeof(lane));
1180
18.3k
  if (burn)
1181
18.2k
    _gcry_burn_stack (burn);
1182
18.3k
}
1183
1184
1185
static byte *
1186
keccak_read (void *context)
1187
18.2k
{
1188
18.2k
  KECCAK_CONTEXT *ctx = (KECCAK_CONTEXT *) context;
1189
18.2k
  KECCAK_STATE *hd = &ctx->state;
1190
18.2k
  return (byte *)&hd->u;
1191
18.2k
}
1192
1193
1194
static gcry_err_code_t
1195
do_keccak_extract (void *context, void *out, size_t outlen)
1196
126
{
1197
126
  KECCAK_CONTEXT *ctx = context;
1198
126
  KECCAK_STATE *hd = &ctx->state;
1199
126
  const size_t bsize = ctx->blocksize;
1200
126
  unsigned int nburn, burn = 0;
1201
126
  byte *outbuf = out;
1202
126
  unsigned int nlanes;
1203
126
  unsigned int nleft;
1204
126
  unsigned int count;
1205
126
  unsigned int i;
1206
126
  byte lane[8];
1207
1208
#ifdef USE_S390X_CRYPTO
1209
  if (ctx->kimd_func)
1210
    {
1211
      keccak_extract_s390x (context, out, outlen);
1212
      return 0;
1213
    }
1214
#endif
1215
1216
126
  count = ctx->count;
1217
1218
126
  while (count && outlen && (outlen < 8 || count % 8))
1219
0
    {
1220
      /* Extract partial lane. */
1221
0
      nburn = ctx->ops->extract(hd, count / 8, lane, 8);
1222
0
      burn = nburn > burn ? nburn : burn;
1223
1224
0
      for (i = count % 8; outlen && i < 8; i++)
1225
0
  {
1226
0
    *outbuf++ = lane[i];
1227
0
    outlen--;
1228
0
    count++;
1229
0
  }
1230
1231
0
      gcry_assert(count <= bsize);
1232
1233
0
      if (count == bsize)
1234
0
  count = 0;
1235
0
    }
1236
1237
126
  if (outlen >= 8 && count)
1238
0
    {
1239
      /* Extract tail of partial block. */
1240
0
      nlanes = outlen / 8;
1241
0
      nleft = (bsize - count) / 8;
1242
0
      nlanes = nlanes < nleft ? nlanes : nleft;
1243
1244
0
      nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
1245
0
      burn = nburn > burn ? nburn : burn;
1246
0
      outlen -= nlanes * 8;
1247
0
      outbuf += nlanes * 8;
1248
0
      count += nlanes * 8;
1249
1250
0
      gcry_assert(count <= bsize);
1251
1252
0
      if (count == bsize)
1253
0
  count = 0;
1254
0
    }
1255
1256
126
  while (outlen >= bsize)
1257
0
    {
1258
0
      gcry_assert(count == 0);
1259
1260
      /* Squeeze more. */
1261
0
      nburn = ctx->ops->permute(hd);
1262
0
      burn = nburn > burn ? nburn : burn;
1263
1264
      /* Extract full block. */
1265
0
      nburn = ctx->ops->extract(hd, 0, outbuf, bsize);
1266
0
      burn = nburn > burn ? nburn : burn;
1267
1268
0
      outlen -= bsize;
1269
0
      outbuf += bsize;
1270
0
    }
1271
1272
126
  if (outlen)
1273
126
    {
1274
126
      gcry_assert(outlen < bsize);
1275
1276
126
      if (count == 0)
1277
126
  {
1278
    /* Squeeze more. */
1279
126
    nburn = ctx->ops->permute(hd);
1280
126
    burn = nburn > burn ? nburn : burn;
1281
126
  }
1282
1283
126
      if (outlen >= 8)
1284
126
  {
1285
    /* Extract head of partial block. */
1286
126
    nlanes = outlen / 8;
1287
126
    nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
1288
126
    burn = nburn > burn ? nburn : burn;
1289
126
    outlen -= nlanes * 8;
1290
126
    outbuf += nlanes * 8;
1291
126
    count += nlanes * 8;
1292
1293
126
    gcry_assert(count < bsize);
1294
126
  }
1295
1296
126
      if (outlen)
1297
0
  {
1298
    /* Extract head of partial lane. */
1299
0
    nburn = ctx->ops->extract(hd, count / 8, lane, 8);
1300
0
    burn = nburn > burn ? nburn : burn;
1301
1302
0
    for (i = count % 8; outlen && i < 8; i++)
1303
0
      {
1304
0
        *outbuf++ = lane[i];
1305
0
        outlen--;
1306
0
        count++;
1307
0
      }
1308
1309
0
    gcry_assert(count < bsize);
1310
0
  }
1311
126
    }
1312
1313
0
  ctx->count = count;
1314
1315
126
  if (burn)
1316
126
    _gcry_burn_stack (burn);
1317
1318
126
  return 0;
1319
126
}
1320
1321
1322
static gcry_err_code_t
1323
keccak_extract (void *context, void *out, size_t outlen)
1324
126
{
1325
126
  KECCAK_CONTEXT *ctx = context;
1326
1327
126
  if (ctx->shake_in_read_mode)
1328
0
    return GPG_ERR_INV_STATE;
1329
126
  if (!ctx->shake_in_extract_mode)
1330
126
    ctx->shake_in_extract_mode = 1;
1331
1332
126
  return do_keccak_extract (context, out, outlen);
1333
126
}
1334
1335
1336
static byte *
1337
keccak_shake_read (void *context)
1338
0
{
1339
0
  KECCAK_CONTEXT *ctx = (KECCAK_CONTEXT *) context;
1340
0
  KECCAK_STATE *hd = &ctx->state;
1341
1342
0
  if (ctx->shake_in_extract_mode)
1343
0
    {
1344
      /* Already in extract mode. */
1345
0
      return NULL;
1346
0
    }
1347
1348
0
  if (!ctx->shake_in_read_mode)
1349
0
    {
1350
0
      byte tmpbuf[64];
1351
1352
0
      gcry_assert(sizeof(tmpbuf) >= ctx->outlen);
1353
1354
0
      ctx->shake_in_read_mode = 1;
1355
1356
0
      do_keccak_extract (context, tmpbuf, ctx->outlen);
1357
0
      buf_cpy (&hd->u, tmpbuf, ctx->outlen);
1358
1359
0
      wipememory(tmpbuf, sizeof(tmpbuf));
1360
0
    }
1361
1362
0
  return (byte *)&hd->u;
1363
0
}
1364
1365
1366
/* Variant of the above shortcut function using multiple buffers.  */
1367
static void
1368
_gcry_sha3_hash_buffers (void *outbuf, size_t nbytes, const gcry_buffer_t *iov,
1369
       int iovcnt, const gcry_md_spec_t *spec)
1370
127
{
1371
127
  KECCAK_CONTEXT hd;
1372
1373
127
  spec->init (&hd, 0);
1374
254
  for (;iovcnt > 0; iov++, iovcnt--)
1375
127
    keccak_write (&hd, (const char*)iov[0].data + iov[0].off, iov[0].len);
1376
127
  keccak_final (&hd);
1377
127
  if (hd.suffix == SHA3_DELIMITED_SUFFIX)
1378
127
    memcpy (outbuf, keccak_read (&hd), spec->mdlen);
1379
0
  else
1380
0
    do_keccak_extract (&hd, outbuf, nbytes);
1381
127
}
1382
1383
1384
static void
1385
_gcry_sha3_224_hash_buffers (void *outbuf, size_t nbytes,
1386
           const gcry_buffer_t *iov, int iovcnt)
1387
28
{
1388
28
  _gcry_sha3_hash_buffers (outbuf, nbytes, iov, iovcnt,
1389
28
         &_gcry_digest_spec_sha3_224);
1390
28
}
1391
1392
static void
1393
_gcry_sha3_256_hash_buffers (void *outbuf, size_t nbytes,
1394
           const gcry_buffer_t *iov, int iovcnt)
1395
29
{
1396
29
  _gcry_sha3_hash_buffers (outbuf, nbytes, iov, iovcnt,
1397
29
         &_gcry_digest_spec_sha3_256);
1398
29
}
1399
1400
static void
1401
_gcry_sha3_384_hash_buffers (void *outbuf, size_t nbytes,
1402
           const gcry_buffer_t *iov, int iovcnt)
1403
27
{
1404
27
  _gcry_sha3_hash_buffers (outbuf, nbytes, iov, iovcnt,
1405
27
         &_gcry_digest_spec_sha3_384);
1406
27
}
1407
1408
static void
1409
_gcry_sha3_512_hash_buffers (void *outbuf, size_t nbytes,
1410
           const gcry_buffer_t *iov, int iovcnt)
1411
43
{
1412
43
  _gcry_sha3_hash_buffers (outbuf, nbytes, iov, iovcnt,
1413
43
         &_gcry_digest_spec_sha3_512);
1414
43
}
1415
1416
static void
1417
_gcry_shake128_hash_buffers (void *outbuf, size_t nbytes,
1418
           const gcry_buffer_t *iov, int iovcnt)
1419
0
{
1420
0
  _gcry_sha3_hash_buffers (outbuf, nbytes, iov, iovcnt,
1421
0
         &_gcry_digest_spec_shake128);
1422
0
}
1423
1424
static void
1425
_gcry_shake256_hash_buffers (void *outbuf, size_t nbytes,
1426
           const gcry_buffer_t *iov, int iovcnt)
1427
0
{
1428
0
  _gcry_sha3_hash_buffers (outbuf, nbytes, iov, iovcnt,
1429
0
         &_gcry_digest_spec_shake256);
1430
0
}
1431
1432
1433
static unsigned int
1434
cshake_input_n (KECCAK_CONTEXT *ctx, const void *n, unsigned int n_len)
1435
0
{
1436
0
  unsigned char buf[3];
1437
1438
0
  buf[0] = 1;
1439
0
  buf[1] = ctx->blocksize;
1440
0
  keccak_write (ctx, buf, 2);
1441
1442
  /* Here, N_LEN must be less than 255 */
1443
0
  if (n_len < 32)
1444
0
    {
1445
0
      buf[0] = 1;
1446
0
      buf[1] = n_len * 8;
1447
0
    }
1448
0
  else
1449
0
    {
1450
0
      buf[0] = 2;
1451
0
      buf[1] = (n_len * 8) >> 8;
1452
0
      buf[2] = (n_len * 8) & 0xff;
1453
0
    }
1454
1455
0
  keccak_write (ctx, buf, buf[0] + 1);
1456
0
  keccak_write (ctx, n, n_len);
1457
0
  return 2 + buf[0] + 1 + n_len;
1458
0
}
1459
1460
static void
1461
cshake_input_s (KECCAK_CONTEXT *ctx, const void *s, unsigned int s_len,
1462
                unsigned int len_written)
1463
0
{
1464
0
  unsigned char buf[168];
1465
0
  unsigned int padlen;
1466
1467
  /* Here, S_LEN must be less than 255 */
1468
0
  if (s_len < 32)
1469
0
    {
1470
0
      buf[0] = 1;
1471
0
      buf[1] = s_len * 8;
1472
0
    }
1473
0
  else
1474
0
    {
1475
0
      buf[0] = 2;
1476
0
      buf[1] = (s_len * 8) >> 8;
1477
0
      buf[2] = (s_len * 8) & 0xff;
1478
0
    }
1479
1480
0
  keccak_write (ctx, buf, buf[0] + 1);
1481
0
  keccak_write (ctx, s, s_len);
1482
1483
0
  len_written += buf[0] + 1 + s_len;
1484
0
  padlen = ctx->blocksize - (len_written % ctx->blocksize);
1485
0
  memset (buf, 0, padlen);
1486
0
  keccak_write (ctx, buf, padlen);
1487
0
}
1488
1489
gpg_err_code_t
1490
_gcry_cshake_customize (void *context, struct gcry_cshake_customization *p)
1491
0
{
1492
0
  KECCAK_CONTEXT *ctx = (KECCAK_CONTEXT *) context;
1493
0
  unsigned int len_written;
1494
1495
0
  if (p->n_len >= 255 || p->s_len >= 255)
1496
0
    return GPG_ERR_TOO_LARGE;
1497
1498
0
  if (p->n_len == 0 && p->s_len == 0)
1499
    /* No customization */
1500
0
    return 0;
1501
1502
0
  ctx->suffix = CSHAKE_DELIMITED_SUFFIX;
1503
#ifdef USE_S390X_CRYPTO
1504
  /* CSHAKE suffix is not supported by s390x/kimd. */
1505
  ctx->kimd_func = 0;
1506
#endif
1507
1508
0
  len_written = cshake_input_n (ctx, p->n, p->n_len);
1509
0
  cshake_input_s (ctx, p->s, p->s_len, len_written);
1510
0
  return 0;
1511
0
}
1512
1513
1514
static void
1515
cshake128_init (void *context, unsigned int flags)
1516
0
{
1517
0
  keccak_init (GCRY_MD_CSHAKE128, context, flags);
1518
0
}
1519
1520
static void
1521
cshake256_init (void *context, unsigned int flags)
1522
0
{
1523
0
  keccak_init (GCRY_MD_CSHAKE256, context, flags);
1524
0
}
1525
1526
static void
1527
cshake_hash_buffers (const gcry_md_spec_t *spec, void *outbuf, size_t nbytes,
1528
                     const gcry_buffer_t *iov, int iovcnt)
1529
0
{
1530
0
  KECCAK_CONTEXT ctx;
1531
1532
0
  spec->init (&ctx, 0);
1533
1534
0
  if (iovcnt < 2)
1535
0
    ; /* No customization, do same as SHAKE does.  */
1536
0
  else
1537
0
    {
1538
0
      if (iov[0].len != 0 || iov[1].len != 0)
1539
0
        {
1540
0
          const void *n = (unsigned char *)iov[0].data + iov[0].off;
1541
0
          size_t n_len = iov[0].len;
1542
0
          const void *s = (unsigned char *)iov[1].data + iov[1].off;
1543
0
          size_t s_len = iov[1].len;
1544
0
          size_t len;
1545
1546
0
          ctx.suffix = CSHAKE_DELIMITED_SUFFIX;
1547
#ifdef USE_S390X_CRYPTO
1548
          /* CSHAKE suffix is not supported by s390x/kimd. */
1549
          ctx.kimd_func = 0;
1550
#endif
1551
1552
0
          len = cshake_input_n (&ctx, n, n_len);
1553
0
          cshake_input_s (&ctx, s, s_len, len);
1554
0
        }
1555
0
      iovcnt -= 2;
1556
0
      iov += 2;
1557
0
    }
1558
1559
0
  for (;iovcnt > 0; iov++, iovcnt--)
1560
0
    keccak_write (&ctx, (const char*)iov[0].data + iov[0].off, iov[0].len);
1561
0
  keccak_final (&ctx);
1562
0
  do_keccak_extract (&ctx, outbuf, nbytes);
1563
0
}
1564
1565
static void
1566
_gcry_cshake128_hash_buffers (void *outbuf, size_t nbytes,
1567
                              const gcry_buffer_t *iov, int iovcnt)
1568
0
{
1569
0
  const gcry_md_spec_t *spec = &_gcry_digest_spec_shake128;
1570
1571
0
  cshake_hash_buffers (spec, outbuf, nbytes, iov, iovcnt);
1572
0
}
1573
1574
static void
1575
_gcry_cshake256_hash_buffers (void *outbuf, size_t nbytes,
1576
                              const gcry_buffer_t *iov, int iovcnt)
1577
0
{
1578
0
  const gcry_md_spec_t *spec = &_gcry_digest_spec_shake256;
1579
1580
0
  cshake_hash_buffers (spec, outbuf, nbytes, iov, iovcnt);
1581
0
}
1582

1583
/*
1584
     Self-test section.
1585
 */
1586
1587
1588
static gpg_err_code_t
1589
selftests_keccak (int algo, int extended, selftest_report_func_t report)
1590
0
{
1591
0
  const char *what;
1592
0
  const char *errtxt;
1593
0
  const char *short_hash;
1594
0
  const char *long_hash;
1595
0
  const char *one_million_a_hash;
1596
0
  int hash_len;
1597
1598
0
  switch (algo)
1599
0
  {
1600
0
    default:
1601
0
      BUG();
1602
1603
0
    case GCRY_MD_SHA3_224:
1604
0
      short_hash =
1605
0
  "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76\x6f"
1606
0
  "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf";
1607
0
      long_hash =
1608
0
  "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5"
1609
0
  "\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc";
1610
0
      one_million_a_hash =
1611
0
  "\xd6\x93\x35\xb9\x33\x25\x19\x2e\x51\x6a\x91\x2e\x6d\x19\xa1\x5c"
1612
0
  "\xb5\x1c\x6e\xd5\xc1\x52\x43\xe7\xa7\xfd\x65\x3c";
1613
0
      hash_len = 28;
1614
0
      break;
1615
1616
0
    case GCRY_MD_SHA3_256:
1617
0
      short_hash =
1618
0
  "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd"
1619
0
  "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32";
1620
0
      long_hash =
1621
0
  "\x91\x6f\x60\x61\xfe\x87\x97\x41\xca\x64\x69\xb4\x39\x71\xdf\xdb"
1622
0
  "\x28\xb1\xa3\x2d\xc3\x6c\xb3\x25\x4e\x81\x2b\xe2\x7a\xad\x1d\x18";
1623
0
      one_million_a_hash =
1624
0
  "\x5c\x88\x75\xae\x47\x4a\x36\x34\xba\x4f\xd5\x5e\xc8\x5b\xff\xd6"
1625
0
  "\x61\xf3\x2a\xca\x75\xc6\xd6\x99\xd0\xcd\xcb\x6c\x11\x58\x91\xc1";
1626
0
      hash_len = 32;
1627
0
      break;
1628
1629
0
    case GCRY_MD_SHA3_384:
1630
0
      short_hash =
1631
0
  "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad\x8d"
1632
0
  "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2"
1633
0
  "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28\x37\x6d\x25";
1634
0
      long_hash =
1635
0
  "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91"
1636
0
  "\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc"
1637
0
  "\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7";
1638
0
      one_million_a_hash =
1639
0
  "\xee\xe9\xe2\x4d\x78\xc1\x85\x53\x37\x98\x34\x51\xdf\x97\xc8\xad"
1640
0
  "\x9e\xed\xf2\x56\xc6\x33\x4f\x8e\x94\x8d\x25\x2d\x5e\x0e\x76\x84"
1641
0
  "\x7a\xa0\x77\x4d\xdb\x90\xa8\x42\x19\x0d\x2c\x55\x8b\x4b\x83\x40";
1642
0
      hash_len = 48;
1643
0
      break;
1644
1645
0
    case GCRY_MD_SHA3_512:
1646
0
      short_hash =
1647
0
  "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09\x6e"
1648
0
  "\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2\x71\x2e"
1649
0
  "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47\xe3\x93\x40"
1650
0
  "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27\x4e\xec\x53\xf0";
1651
0
      long_hash =
1652
0
  "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9"
1653
0
  "\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa"
1654
0
  "\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89"
1655
0
  "\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85";
1656
0
      one_million_a_hash =
1657
0
  "\x3c\x3a\x87\x6d\xa1\x40\x34\xab\x60\x62\x7c\x07\x7b\xb9\x8f\x7e"
1658
0
  "\x12\x0a\x2a\x53\x70\x21\x2d\xff\xb3\x38\x5a\x18\xd4\xf3\x88\x59"
1659
0
  "\xed\x31\x1d\x0a\x9d\x51\x41\xce\x9c\xc5\xc6\x6e\xe6\x89\xb2\x66"
1660
0
  "\xa8\xaa\x18\xac\xe8\x28\x2a\x0e\x0d\xb5\x96\xc9\x0b\x0a\x7b\x87";
1661
0
      hash_len = 64;
1662
0
      break;
1663
1664
0
    case GCRY_MD_CSHAKE128:
1665
0
    case GCRY_MD_SHAKE128:
1666
0
      short_hash =
1667
0
  "\x58\x81\x09\x2d\xd8\x18\xbf\x5c\xf8\xa3\xdd\xb7\x93\xfb\xcb\xa7"
1668
0
  "\x40\x97\xd5\xc5\x26\xa6\xd3\x5f\x97\xb8\x33\x51\x94\x0f\x2c\xc8";
1669
0
      long_hash =
1670
0
  "\x7b\x6d\xf6\xff\x18\x11\x73\xb6\xd7\x89\x8d\x7f\xf6\x3f\xb0\x7b"
1671
0
  "\x7c\x23\x7d\xaf\x47\x1a\x5a\xe5\x60\x2a\xdb\xcc\xef\x9c\xcf\x4b";
1672
0
      one_million_a_hash =
1673
0
  "\x9d\x22\x2c\x79\xc4\xff\x9d\x09\x2c\xf6\xca\x86\x14\x3a\xa4\x11"
1674
0
  "\xe3\x69\x97\x38\x08\xef\x97\x09\x32\x55\x82\x6c\x55\x72\xef\x58";
1675
0
      hash_len = 32;
1676
0
      break;
1677
1678
0
    case GCRY_MD_CSHAKE256:
1679
0
    case GCRY_MD_SHAKE256:
1680
0
      short_hash =
1681
0
  "\x48\x33\x66\x60\x13\x60\xa8\x77\x1c\x68\x63\x08\x0c\xc4\x11\x4d"
1682
0
  "\x8d\xb4\x45\x30\xf8\xf1\xe1\xee\x4f\x94\xea\x37\xe7\x8b\x57\x39";
1683
0
      long_hash =
1684
0
  "\x98\xbe\x04\x51\x6c\x04\xcc\x73\x59\x3f\xef\x3e\xd0\x35\x2e\xa9"
1685
0
  "\xf6\x44\x39\x42\xd6\x95\x0e\x29\xa3\x72\xa6\x81\xc3\xde\xaf\x45";
1686
0
      one_million_a_hash =
1687
0
  "\x35\x78\xa7\xa4\xca\x91\x37\x56\x9c\xdf\x76\xed\x61\x7d\x31\xbb"
1688
0
  "\x99\x4f\xca\x9c\x1b\xbf\x8b\x18\x40\x13\xde\x82\x34\xdf\xd1\x3a";
1689
0
      hash_len = 32;
1690
0
      break;
1691
0
  }
1692
1693
0
  what = "short string";
1694
0
  errtxt = _gcry_hash_selftest_check_one (algo, 0, "abc", 3, short_hash,
1695
0
            hash_len);
1696
0
  if (errtxt)
1697
0
    goto failed;
1698
1699
0
  if (extended)
1700
0
    {
1701
0
      what = "long string";
1702
0
      errtxt = _gcry_hash_selftest_check_one
1703
0
  (algo, 0,
1704
0
  "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
1705
0
  "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
1706
0
  long_hash, hash_len);
1707
0
      if (errtxt)
1708
0
  goto failed;
1709
1710
0
      what = "one million \"a\"";
1711
0
      errtxt = _gcry_hash_selftest_check_one (algo, 1, NULL, 0,
1712
0
                one_million_a_hash, hash_len);
1713
0
      if (errtxt)
1714
0
  goto failed;
1715
0
    }
1716
1717
0
  return 0; /* Succeeded. */
1718
1719
0
failed:
1720
0
  if (report)
1721
0
    report ("digest", algo, what, errtxt);
1722
0
  return GPG_ERR_SELFTEST_FAILED;
1723
0
}
1724
1725
1726
/* Run a full self-test for ALGO and return 0 on success.  */
1727
static gpg_err_code_t
1728
run_selftests (int algo, int extended, selftest_report_func_t report)
1729
0
{
1730
0
  gpg_err_code_t ec;
1731
1732
0
  switch (algo)
1733
0
    {
1734
0
    case GCRY_MD_SHA3_224:
1735
0
    case GCRY_MD_SHA3_256:
1736
0
    case GCRY_MD_SHA3_384:
1737
0
    case GCRY_MD_SHA3_512:
1738
0
    case GCRY_MD_CSHAKE128:
1739
0
    case GCRY_MD_SHAKE128:
1740
0
    case GCRY_MD_CSHAKE256:
1741
0
    case GCRY_MD_SHAKE256:
1742
0
      ec = selftests_keccak (algo, extended, report);
1743
0
      break;
1744
0
    default:
1745
0
      ec = GPG_ERR_DIGEST_ALGO;
1746
0
      break;
1747
0
    }
1748
1749
0
  return ec;
1750
0
}
1751
1752
1753
1754

1755
/* Object IDs obtained from
1756
 * https://csrc.nist.gov/projects/computer-security-objects-register/algorithm-registration#Hash
1757
 */
1758
static const byte sha3_224_asn[] =
1759
  { 0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
1760
    0x01, 0x65, 0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04,
1761
    0x1c
1762
  };
1763
static const gcry_md_oid_spec_t oid_spec_sha3_224[] =
1764
  {
1765
    { "2.16.840.1.101.3.4.2.7" },
1766
    /* id-rsassa-pkcs1-v1-5-with-sha3-224 */
1767
    { "2.16.840.1.101.3.4.3.13" },
1768
    /* id-ecdsa-with-sha3-224 */
1769
    { "2.16.840.1.101.3.4.3.9" },
1770
    { NULL }
1771
  };
1772
static const byte sha3_256_asn[] =
1773
  { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
1774
    0x01, 0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04,
1775
    0x20
1776
  };
1777
static const gcry_md_oid_spec_t oid_spec_sha3_256[] =
1778
  {
1779
    { "2.16.840.1.101.3.4.2.8" },
1780
    /* id-rsassa-pkcs1-v1-5-with-sha3-256 */
1781
    { "2.16.840.1.101.3.4.3.14" },
1782
    /* id-ecdsa-with-sha3-256 */
1783
    { "2.16.840.1.101.3.4.3.10" },
1784
    { NULL }
1785
  };
1786
static const byte sha3_384_asn[] =
1787
  { 0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
1788
    0x01, 0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04,
1789
    0x30
1790
  };
1791
static const gcry_md_oid_spec_t oid_spec_sha3_384[] =
1792
  {
1793
    { "2.16.840.1.101.3.4.2.9" },
1794
    /* id-rsassa-pkcs1-v1-5-with-sha3-384 */
1795
    { "2.16.840.1.101.3.4.3.15" },
1796
    /* id-ecdsa-with-sha3-384 */
1797
    { "2.16.840.1.101.3.4.3.11" },
1798
    { NULL }
1799
  };
1800
static const byte sha3_512_asn[] =
1801
  { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
1802
    0x01, 0x65, 0x03, 0x04, 0x02, 0x0a, 0x05, 0x00, 0x04,
1803
    0x40
1804
  };
1805
static const gcry_md_oid_spec_t oid_spec_sha3_512[] =
1806
  {
1807
    { "2.16.840.1.101.3.4.2.10" },
1808
    /* id-rsassa-pkcs1-v1-5-with-sha3-512 */
1809
    { "2.16.840.1.101.3.4.3.16" },
1810
    /* id-ecdsa-with-sha3-512 */
1811
    { "2.16.840.1.101.3.4.3.12" },
1812
    { NULL }
1813
  };
1814
static const byte shake128_asn[] =
1815
  { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
1816
    0x01, 0x65, 0x03, 0x04, 0x02, 0x0b, 0x05, 0x00, 0x04,
1817
    0x20
1818
  };
1819
static const gcry_md_oid_spec_t oid_spec_shake128[] =
1820
  {
1821
    { "2.16.840.1.101.3.4.2.11" },
1822
    /* RFC 8692 id-RSASSA-PSS-SHAKE128 */
1823
    { "1.3.6.1.5.5.7.6.30" },
1824
    /* RFC 8692 id-ecdsa-with-shake128 */
1825
    { "1.3.6.1.5.5.7.6.32" },
1826
    { NULL }
1827
  };
1828
static const byte shake256_asn[] =
1829
  { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
1830
    0x01, 0x65, 0x03, 0x04, 0x02, 0x0c, 0x05, 0x00, 0x04,
1831
    0x40
1832
  };
1833
static const gcry_md_oid_spec_t oid_spec_shake256[] =
1834
  {
1835
    { "2.16.840.1.101.3.4.2.12" },
1836
    /* RFC 8692 id-RSASSA-PSS-SHAKE256 */
1837
    { "1.3.6.1.5.5.7.6.31" },
1838
    /* RFC 8692 id-ecdsa-with-shake256 */
1839
    { "1.3.6.1.5.5.7.6.33" },
1840
    { NULL }
1841
  };
1842
1843
const gcry_md_spec_t _gcry_digest_spec_sha3_224 =
1844
  {
1845
    GCRY_MD_SHA3_224, {0, 1},
1846
    "SHA3-224", sha3_224_asn, DIM (sha3_224_asn), oid_spec_sha3_224, 28,
1847
    sha3_224_init, keccak_write, keccak_final, keccak_read, NULL,
1848
    _gcry_sha3_224_hash_buffers,
1849
    sizeof (KECCAK_CONTEXT),
1850
    run_selftests
1851
  };
1852
const gcry_md_spec_t _gcry_digest_spec_sha3_256 =
1853
  {
1854
    GCRY_MD_SHA3_256, {0, 1},
1855
    "SHA3-256", sha3_256_asn, DIM (sha3_256_asn), oid_spec_sha3_256, 32,
1856
    sha3_256_init, keccak_write, keccak_final, keccak_read, NULL,
1857
    _gcry_sha3_256_hash_buffers,
1858
    sizeof (KECCAK_CONTEXT),
1859
    run_selftests
1860
  };
1861
const gcry_md_spec_t _gcry_digest_spec_sha3_384 =
1862
  {
1863
    GCRY_MD_SHA3_384, {0, 1},
1864
    "SHA3-384", sha3_384_asn, DIM (sha3_384_asn), oid_spec_sha3_384, 48,
1865
    sha3_384_init, keccak_write, keccak_final, keccak_read, NULL,
1866
    _gcry_sha3_384_hash_buffers,
1867
    sizeof (KECCAK_CONTEXT),
1868
    run_selftests
1869
  };
1870
const gcry_md_spec_t _gcry_digest_spec_sha3_512 =
1871
  {
1872
    GCRY_MD_SHA3_512, {0, 1},
1873
    "SHA3-512", sha3_512_asn, DIM (sha3_512_asn), oid_spec_sha3_512, 64,
1874
    sha3_512_init, keccak_write, keccak_final, keccak_read, NULL,
1875
    _gcry_sha3_512_hash_buffers,
1876
    sizeof (KECCAK_CONTEXT),
1877
    run_selftests
1878
  };
1879
const gcry_md_spec_t _gcry_digest_spec_shake128 =
1880
  {
1881
    GCRY_MD_SHAKE128, {0, 1},
1882
    "SHAKE128", shake128_asn, DIM (shake128_asn), oid_spec_shake128, 32,
1883
    shake128_init, keccak_write, keccak_final, keccak_shake_read,
1884
    keccak_extract,
1885
    _gcry_shake128_hash_buffers,
1886
    sizeof (KECCAK_CONTEXT),
1887
    run_selftests
1888
  };
1889
const gcry_md_spec_t _gcry_digest_spec_shake256 =
1890
  {
1891
    GCRY_MD_SHAKE256, {0, 1},
1892
    "SHAKE256", shake256_asn, DIM (shake256_asn), oid_spec_shake256, 64,
1893
    shake256_init, keccak_write, keccak_final, keccak_shake_read,
1894
    keccak_extract,
1895
    _gcry_shake256_hash_buffers,
1896
    sizeof (KECCAK_CONTEXT),
1897
    run_selftests
1898
  };
1899
const gcry_md_spec_t _gcry_digest_spec_cshake128 =
1900
  {
1901
    GCRY_MD_CSHAKE128, {0, 1},
1902
    "CSHAKE128", NULL, 0, NULL, 32,
1903
    cshake128_init, keccak_write, keccak_final, keccak_shake_read,
1904
    keccak_extract, _gcry_cshake128_hash_buffers,
1905
    sizeof (KECCAK_CONTEXT),
1906
    run_selftests
1907
  };
1908
const gcry_md_spec_t _gcry_digest_spec_cshake256 =
1909
  {
1910
    GCRY_MD_CSHAKE256, {0, 1},
1911
    "CSHAKE256", NULL, 0, NULL, 64,
1912
    cshake256_init, keccak_write, keccak_final, keccak_shake_read,
1913
    keccak_extract, _gcry_cshake256_hash_buffers,
1914
    sizeof (KECCAK_CONTEXT),
1915
    run_selftests
1916
  };