Coverage Report

Created: 2022-12-08 06:10

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