Line data Source code
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 : # define USE_64BIT_BMI2 1
45 : #endif
46 :
47 :
48 : /* USE_64BIT_SHLD indicates whether to compile with 64-bit Intel SHLD code. */
49 : #undef USE_64BIT_SHLD
50 : #if defined(USE_64BIT) && defined (__GNUC__) && defined(__x86_64__)
51 : # define USE_64BIT_SHLD 1
52 : #endif
53 :
54 :
55 : /* USE_32BIT_BMI2 indicates whether to compile with 32-bit Intel BMI2 code. */
56 : #undef USE_32BIT_BMI2
57 : #if defined(USE_32BIT) && defined(HAVE_GCC_INLINE_ASM_BMI2)
58 : # define USE_32BIT_BMI2 1
59 : #endif
60 :
61 :
62 : /* USE_64BIT_ARM_NEON indicates whether to enable 64-bit ARM/NEON assembly
63 : * code. */
64 : #undef USE_64BIT_ARM_NEON
65 : #ifdef ENABLE_NEON_SUPPORT
66 : # if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) \
67 : && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) \
68 : && defined(HAVE_GCC_INLINE_ASM_NEON)
69 : # define USE_64BIT_ARM_NEON 1
70 : # endif
71 : #endif /*ENABLE_NEON_SUPPORT*/
72 :
73 :
74 : #if defined(USE_64BIT) || defined(USE_64BIT_ARM_NEON)
75 : # define NEED_COMMON64 1
76 : #endif
77 :
78 : #ifdef USE_32BIT
79 : # define NEED_COMMON32BI 1
80 : #endif
81 :
82 :
83 : #define SHA3_DELIMITED_SUFFIX 0x06
84 : #define SHAKE_DELIMITED_SUFFIX 0x1F
85 :
86 :
87 : typedef struct
88 : {
89 : union {
90 : #ifdef NEED_COMMON64
91 : u64 state64[25];
92 : #endif
93 : #ifdef NEED_COMMON32BI
94 : u32 state32bi[50];
95 : #endif
96 : } u;
97 : } KECCAK_STATE;
98 :
99 :
100 : typedef struct
101 : {
102 : unsigned int (*permute)(KECCAK_STATE *hd);
103 : unsigned int (*absorb)(KECCAK_STATE *hd, int pos, const byte *lanes,
104 : unsigned int nlanes, int blocklanes);
105 : unsigned int (*extract) (KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
106 : unsigned int outlen);
107 : } keccak_ops_t;
108 :
109 :
110 : typedef struct KECCAK_CONTEXT_S
111 : {
112 : KECCAK_STATE state;
113 : unsigned int outlen;
114 : unsigned int blocksize;
115 : unsigned int count;
116 : unsigned int suffix;
117 : const keccak_ops_t *ops;
118 : } KECCAK_CONTEXT;
119 :
120 :
121 :
122 : #ifdef NEED_COMMON64
123 :
124 : const u64 _gcry_keccak_round_consts_64bit[24 + 1] =
125 : {
126 : U64_C(0x0000000000000001), U64_C(0x0000000000008082),
127 : U64_C(0x800000000000808A), U64_C(0x8000000080008000),
128 : U64_C(0x000000000000808B), U64_C(0x0000000080000001),
129 : U64_C(0x8000000080008081), U64_C(0x8000000000008009),
130 : U64_C(0x000000000000008A), U64_C(0x0000000000000088),
131 : U64_C(0x0000000080008009), U64_C(0x000000008000000A),
132 : U64_C(0x000000008000808B), U64_C(0x800000000000008B),
133 : U64_C(0x8000000000008089), U64_C(0x8000000000008003),
134 : U64_C(0x8000000000008002), U64_C(0x8000000000000080),
135 : U64_C(0x000000000000800A), U64_C(0x800000008000000A),
136 : U64_C(0x8000000080008081), U64_C(0x8000000000008080),
137 : U64_C(0x0000000080000001), U64_C(0x8000000080008008),
138 : U64_C(0xFFFFFFFFFFFFFFFF)
139 : };
140 :
141 : static unsigned int
142 0 : keccak_extract64(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
143 : unsigned int outlen)
144 : {
145 : unsigned int i;
146 :
147 : /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
148 :
149 0 : for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
150 : {
151 0 : u64 tmp = hd->u.state64[i];
152 0 : buf_put_le64(outbuf, tmp);
153 0 : outbuf += 8;
154 : }
155 :
156 0 : return 0;
157 : }
158 :
159 : #endif /* NEED_COMMON64 */
160 :
161 :
162 : #ifdef NEED_COMMON32BI
163 :
164 : static const u32 round_consts_32bit[2 * 24] =
165 : {
166 : 0x00000001UL, 0x00000000UL, 0x00000000UL, 0x00000089UL,
167 : 0x00000000UL, 0x8000008bUL, 0x00000000UL, 0x80008080UL,
168 : 0x00000001UL, 0x0000008bUL, 0x00000001UL, 0x00008000UL,
169 : 0x00000001UL, 0x80008088UL, 0x00000001UL, 0x80000082UL,
170 : 0x00000000UL, 0x0000000bUL, 0x00000000UL, 0x0000000aUL,
171 : 0x00000001UL, 0x00008082UL, 0x00000000UL, 0x00008003UL,
172 : 0x00000001UL, 0x0000808bUL, 0x00000001UL, 0x8000000bUL,
173 : 0x00000001UL, 0x8000008aUL, 0x00000001UL, 0x80000081UL,
174 : 0x00000000UL, 0x80000081UL, 0x00000000UL, 0x80000008UL,
175 : 0x00000000UL, 0x00000083UL, 0x00000000UL, 0x80008003UL,
176 : 0x00000001UL, 0x80008088UL, 0x00000000UL, 0x80000088UL,
177 : 0x00000001UL, 0x00008000UL, 0x00000000UL, 0x80008082UL
178 : };
179 :
180 : static unsigned int
181 : keccak_extract32bi(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
182 : unsigned int outlen)
183 : {
184 : unsigned int i;
185 : u32 x0;
186 : u32 x1;
187 : u32 t;
188 :
189 : /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
190 :
191 : for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
192 : {
193 : x0 = hd->u.state32bi[i * 2 + 0];
194 : x1 = hd->u.state32bi[i * 2 + 1];
195 :
196 : t = (x0 & 0x0000FFFFUL) + (x1 << 16);
197 : x1 = (x0 >> 16) + (x1 & 0xFFFF0000UL);
198 : x0 = t;
199 : t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8);
200 : t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4);
201 : t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2);
202 : t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1);
203 : t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8);
204 : t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4);
205 : t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
206 : t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
207 :
208 : buf_put_le32(&outbuf[0], x0);
209 : buf_put_le32(&outbuf[4], x1);
210 : outbuf += 8;
211 : }
212 :
213 : return 0;
214 : }
215 :
216 : static inline void
217 : keccak_absorb_lane32bi(u32 *lane, u32 x0, u32 x1)
218 : {
219 : u32 t;
220 :
221 : t = (x0 ^ (x0 >> 1)) & 0x22222222UL; x0 = x0 ^ t ^ (t << 1);
222 : t = (x0 ^ (x0 >> 2)) & 0x0C0C0C0CUL; x0 = x0 ^ t ^ (t << 2);
223 : t = (x0 ^ (x0 >> 4)) & 0x00F000F0UL; x0 = x0 ^ t ^ (t << 4);
224 : t = (x0 ^ (x0 >> 8)) & 0x0000FF00UL; x0 = x0 ^ t ^ (t << 8);
225 : t = (x1 ^ (x1 >> 1)) & 0x22222222UL; x1 = x1 ^ t ^ (t << 1);
226 : t = (x1 ^ (x1 >> 2)) & 0x0C0C0C0CUL; x1 = x1 ^ t ^ (t << 2);
227 : t = (x1 ^ (x1 >> 4)) & 0x00F000F0UL; x1 = x1 ^ t ^ (t << 4);
228 : t = (x1 ^ (x1 >> 8)) & 0x0000FF00UL; x1 = x1 ^ t ^ (t << 8);
229 : lane[0] ^= (x0 & 0x0000FFFFUL) + (x1 << 16);
230 : lane[1] ^= (x0 >> 16) + (x1 & 0xFFFF0000UL);
231 : }
232 :
233 : #endif /* NEED_COMMON32BI */
234 :
235 :
236 : /* Construct generic 64-bit implementation. */
237 : #ifdef USE_64BIT
238 :
239 : #if __GNUC__ >= 4 && defined(__x86_64__)
240 :
241 0 : static inline void absorb_lanes64_8(u64 *dst, const byte *in)
242 : {
243 0 : asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
244 : "movdqu 0*16(%[in]), %%xmm4\n\t"
245 : "movdqu 1*16(%[dst]), %%xmm1\n\t"
246 : "movdqu 1*16(%[in]), %%xmm5\n\t"
247 : "movdqu 2*16(%[dst]), %%xmm2\n\t"
248 : "movdqu 3*16(%[dst]), %%xmm3\n\t"
249 : "pxor %%xmm4, %%xmm0\n\t"
250 : "pxor %%xmm5, %%xmm1\n\t"
251 : "movdqu 2*16(%[in]), %%xmm4\n\t"
252 : "movdqu 3*16(%[in]), %%xmm5\n\t"
253 : "movdqu %%xmm0, 0*16(%[dst])\n\t"
254 : "pxor %%xmm4, %%xmm2\n\t"
255 : "movdqu %%xmm1, 1*16(%[dst])\n\t"
256 : "pxor %%xmm5, %%xmm3\n\t"
257 : "movdqu %%xmm2, 2*16(%[dst])\n\t"
258 : "movdqu %%xmm3, 3*16(%[dst])\n\t"
259 : :
260 : : [dst] "r" (dst), [in] "r" (in)
261 : : "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "memory");
262 0 : }
263 :
264 0 : static inline void absorb_lanes64_4(u64 *dst, const byte *in)
265 : {
266 0 : asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
267 : "movdqu 0*16(%[in]), %%xmm4\n\t"
268 : "movdqu 1*16(%[dst]), %%xmm1\n\t"
269 : "movdqu 1*16(%[in]), %%xmm5\n\t"
270 : "pxor %%xmm4, %%xmm0\n\t"
271 : "pxor %%xmm5, %%xmm1\n\t"
272 : "movdqu %%xmm0, 0*16(%[dst])\n\t"
273 : "movdqu %%xmm1, 1*16(%[dst])\n\t"
274 : :
275 : : [dst] "r" (dst), [in] "r" (in)
276 : : "xmm0", "xmm1", "xmm4", "xmm5", "memory");
277 0 : }
278 :
279 0 : static inline void absorb_lanes64_2(u64 *dst, const byte *in)
280 : {
281 0 : asm ("movdqu 0*16(%[dst]), %%xmm0\n\t"
282 : "movdqu 0*16(%[in]), %%xmm4\n\t"
283 : "pxor %%xmm4, %%xmm0\n\t"
284 : "movdqu %%xmm0, 0*16(%[dst])\n\t"
285 : :
286 : : [dst] "r" (dst), [in] "r" (in)
287 : : "xmm0", "xmm4", "memory");
288 0 : }
289 :
290 : #else /* __x86_64__ */
291 :
292 : static inline void absorb_lanes64_8(u64 *dst, const byte *in)
293 : {
294 : dst[0] ^= buf_get_le64(in + 8 * 0);
295 : dst[1] ^= buf_get_le64(in + 8 * 1);
296 : dst[2] ^= buf_get_le64(in + 8 * 2);
297 : dst[3] ^= buf_get_le64(in + 8 * 3);
298 : dst[4] ^= buf_get_le64(in + 8 * 4);
299 : dst[5] ^= buf_get_le64(in + 8 * 5);
300 : dst[6] ^= buf_get_le64(in + 8 * 6);
301 : dst[7] ^= buf_get_le64(in + 8 * 7);
302 : }
303 :
304 : static inline void absorb_lanes64_4(u64 *dst, const byte *in)
305 : {
306 : dst[0] ^= buf_get_le64(in + 8 * 0);
307 : dst[1] ^= buf_get_le64(in + 8 * 1);
308 : dst[2] ^= buf_get_le64(in + 8 * 2);
309 : dst[3] ^= buf_get_le64(in + 8 * 3);
310 : }
311 :
312 : static inline void absorb_lanes64_2(u64 *dst, const byte *in)
313 : {
314 : dst[0] ^= buf_get_le64(in + 8 * 0);
315 : dst[1] ^= buf_get_le64(in + 8 * 1);
316 : }
317 :
318 : #endif /* !__x86_64__ */
319 :
320 0 : static inline void absorb_lanes64_1(u64 *dst, const byte *in)
321 : {
322 0 : dst[0] ^= buf_get_le64(in + 8 * 0);
323 0 : }
324 :
325 :
326 : # define ANDN64(x, y) (~(x) & (y))
327 : # define ROL64(x, n) (((x) << ((unsigned int)n & 63)) | \
328 : ((x) >> ((64 - (unsigned int)(n)) & 63)))
329 :
330 : # define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64
331 : # define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64
332 : # include "keccak_permute_64.h"
333 :
334 : # undef ANDN64
335 : # undef ROL64
336 : # undef KECCAK_F1600_PERMUTE_FUNC_NAME
337 : # undef KECCAK_F1600_ABSORB_FUNC_NAME
338 :
339 : static const keccak_ops_t keccak_generic64_ops =
340 : {
341 : .permute = keccak_f1600_state_permute64,
342 : .absorb = keccak_absorb_lanes64,
343 : .extract = keccak_extract64,
344 : };
345 :
346 : #endif /* USE_64BIT */
347 :
348 :
349 : /* Construct 64-bit Intel SHLD implementation. */
350 : #ifdef USE_64BIT_SHLD
351 :
352 : # define ANDN64(x, y) (~(x) & (y))
353 : # define ROL64(x, n) ({ \
354 : u64 tmp = (x); \
355 : asm ("shldq %1, %0, %0" \
356 : : "+r" (tmp) \
357 : : "J" ((n) & 63) \
358 : : "cc"); \
359 : tmp; })
360 :
361 : # define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_shld
362 : # define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_shld
363 : # include "keccak_permute_64.h"
364 :
365 : # undef ANDN64
366 : # undef ROL64
367 : # undef KECCAK_F1600_PERMUTE_FUNC_NAME
368 : # undef KECCAK_F1600_ABSORB_FUNC_NAME
369 :
370 : static const keccak_ops_t keccak_shld_64_ops =
371 : {
372 : .permute = keccak_f1600_state_permute64_shld,
373 : .absorb = keccak_absorb_lanes64_shld,
374 : .extract = keccak_extract64,
375 : };
376 :
377 : #endif /* USE_64BIT_SHLD */
378 :
379 :
380 : /* Construct 64-bit Intel BMI2 implementation. */
381 : #ifdef USE_64BIT_BMI2
382 :
383 : # define ANDN64(x, y) ({ \
384 : u64 tmp; \
385 : asm ("andnq %2, %1, %0" \
386 : : "=r" (tmp) \
387 : : "r0" (x), "rm" (y)); \
388 : tmp; })
389 :
390 : # define ROL64(x, n) ({ \
391 : u64 tmp; \
392 : asm ("rorxq %2, %1, %0" \
393 : : "=r" (tmp) \
394 : : "rm0" (x), "J" (64 - ((n) & 63))); \
395 : tmp; })
396 :
397 : # define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute64_bmi2
398 : # define KECCAK_F1600_ABSORB_FUNC_NAME keccak_absorb_lanes64_bmi2
399 : # include "keccak_permute_64.h"
400 :
401 : # undef ANDN64
402 : # undef ROL64
403 : # undef KECCAK_F1600_PERMUTE_FUNC_NAME
404 : # undef KECCAK_F1600_ABSORB_FUNC_NAME
405 :
406 : static const keccak_ops_t keccak_bmi2_64_ops =
407 : {
408 : .permute = keccak_f1600_state_permute64_bmi2,
409 : .absorb = keccak_absorb_lanes64_bmi2,
410 : .extract = keccak_extract64,
411 : };
412 :
413 : #endif /* USE_64BIT_BMI2 */
414 :
415 :
416 : /* 64-bit ARMv7/NEON implementation. */
417 : #ifdef USE_64BIT_ARM_NEON
418 :
419 : unsigned int _gcry_keccak_permute_armv7_neon(u64 *state);
420 : unsigned int _gcry_keccak_absorb_lanes64_armv7_neon(u64 *state, int pos,
421 : const byte *lanes,
422 : unsigned int nlanes,
423 : int blocklanes);
424 :
425 : static unsigned int keccak_permute64_armv7_neon(KECCAK_STATE *hd)
426 : {
427 : return _gcry_keccak_permute_armv7_neon(hd->u.state64);
428 : }
429 :
430 : static unsigned int
431 : keccak_absorb_lanes64_armv7_neon(KECCAK_STATE *hd, int pos, const byte *lanes,
432 : unsigned int nlanes, int blocklanes)
433 : {
434 : if (blocklanes < 0)
435 : {
436 : /* blocklanes == -1, permutationless absorb from keccak_final. */
437 :
438 : while (nlanes)
439 : {
440 : hd->u.state64[pos] ^= buf_get_le64(lanes);
441 : lanes += 8;
442 : nlanes--;
443 : }
444 :
445 : return 0;
446 : }
447 : else
448 : {
449 : return _gcry_keccak_absorb_lanes64_armv7_neon(hd->u.state64, pos, lanes,
450 : nlanes, blocklanes);
451 : }
452 : }
453 :
454 : static const keccak_ops_t keccak_armv7_neon_64_ops =
455 : {
456 : .permute = keccak_permute64_armv7_neon,
457 : .absorb = keccak_absorb_lanes64_armv7_neon,
458 : .extract = keccak_extract64,
459 : };
460 :
461 : #endif /* USE_64BIT_ARM_NEON */
462 :
463 :
464 : /* Construct generic 32-bit implementation. */
465 : #ifdef USE_32BIT
466 :
467 : # define ANDN32(x, y) (~(x) & (y))
468 : # define ROL32(x, n) (((x) << ((unsigned int)n & 31)) | \
469 : ((x) >> ((32 - (unsigned int)(n)) & 31)))
470 :
471 : # define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute32bi
472 : # include "keccak_permute_32.h"
473 :
474 : # undef ANDN32
475 : # undef ROL32
476 : # undef KECCAK_F1600_PERMUTE_FUNC_NAME
477 :
478 : static unsigned int
479 : keccak_absorb_lanes32bi(KECCAK_STATE *hd, int pos, const byte *lanes,
480 : unsigned int nlanes, int blocklanes)
481 : {
482 : unsigned int burn = 0;
483 :
484 : while (nlanes)
485 : {
486 : keccak_absorb_lane32bi(&hd->u.state32bi[pos * 2],
487 : buf_get_le32(lanes + 0),
488 : buf_get_le32(lanes + 4));
489 : lanes += 8;
490 : nlanes--;
491 :
492 : if (++pos == blocklanes)
493 : {
494 : burn = keccak_f1600_state_permute32bi(hd);
495 : pos = 0;
496 : }
497 : }
498 :
499 : return burn;
500 : }
501 :
502 : static const keccak_ops_t keccak_generic32bi_ops =
503 : {
504 : .permute = keccak_f1600_state_permute32bi,
505 : .absorb = keccak_absorb_lanes32bi,
506 : .extract = keccak_extract32bi,
507 : };
508 :
509 : #endif /* USE_32BIT */
510 :
511 :
512 : /* Construct 32-bit Intel BMI2 implementation. */
513 : #ifdef USE_32BIT_BMI2
514 :
515 : # define ANDN32(x, y) ({ \
516 : u32 tmp; \
517 : asm ("andnl %2, %1, %0" \
518 : : "=r" (tmp) \
519 : : "r0" (x), "rm" (y)); \
520 : tmp; })
521 :
522 : # define ROL32(x, n) ({ \
523 : u32 tmp; \
524 : asm ("rorxl %2, %1, %0" \
525 : : "=r" (tmp) \
526 : : "rm0" (x), "J" (32 - ((n) & 31))); \
527 : tmp; })
528 :
529 : # define KECCAK_F1600_PERMUTE_FUNC_NAME keccak_f1600_state_permute32bi_bmi2
530 : # include "keccak_permute_32.h"
531 :
532 : # undef ANDN32
533 : # undef ROL32
534 : # undef KECCAK_F1600_PERMUTE_FUNC_NAME
535 :
536 : static inline u32 pext(u32 x, u32 mask)
537 : {
538 : u32 tmp;
539 : asm ("pextl %2, %1, %0" : "=r" (tmp) : "r0" (x), "rm" (mask));
540 : return tmp;
541 : }
542 :
543 : static inline u32 pdep(u32 x, u32 mask)
544 : {
545 : u32 tmp;
546 : asm ("pdepl %2, %1, %0" : "=r" (tmp) : "r0" (x), "rm" (mask));
547 : return tmp;
548 : }
549 :
550 : static inline void
551 : keccak_absorb_lane32bi_bmi2(u32 *lane, u32 x0, u32 x1)
552 : {
553 : x0 = pdep(pext(x0, 0x55555555), 0x0000ffff) | (pext(x0, 0xaaaaaaaa) << 16);
554 : x1 = pdep(pext(x1, 0x55555555), 0x0000ffff) | (pext(x1, 0xaaaaaaaa) << 16);
555 :
556 : lane[0] ^= (x0 & 0x0000FFFFUL) + (x1 << 16);
557 : lane[1] ^= (x0 >> 16) + (x1 & 0xFFFF0000UL);
558 : }
559 :
560 : static unsigned int
561 : keccak_absorb_lanes32bi_bmi2(KECCAK_STATE *hd, int pos, const byte *lanes,
562 : unsigned int nlanes, int blocklanes)
563 : {
564 : unsigned int burn = 0;
565 :
566 : while (nlanes)
567 : {
568 : keccak_absorb_lane32bi_bmi2(&hd->u.state32bi[pos * 2],
569 : buf_get_le32(lanes + 0),
570 : buf_get_le32(lanes + 4));
571 : lanes += 8;
572 : nlanes--;
573 :
574 : if (++pos == blocklanes)
575 : {
576 : burn = keccak_f1600_state_permute32bi_bmi2(hd);
577 : pos = 0;
578 : }
579 : }
580 :
581 : return burn;
582 : }
583 :
584 : static unsigned int
585 : keccak_extract32bi_bmi2(KECCAK_STATE *hd, unsigned int pos, byte *outbuf,
586 : unsigned int outlen)
587 : {
588 : unsigned int i;
589 : u32 x0;
590 : u32 x1;
591 : u32 t;
592 :
593 : /* NOTE: when pos == 0, hd and outbuf may point to same memory (SHA-3). */
594 :
595 : for (i = pos; i < pos + outlen / 8 + !!(outlen % 8); i++)
596 : {
597 : x0 = hd->u.state32bi[i * 2 + 0];
598 : x1 = hd->u.state32bi[i * 2 + 1];
599 :
600 : t = (x0 & 0x0000FFFFUL) + (x1 << 16);
601 : x1 = (x0 >> 16) + (x1 & 0xFFFF0000UL);
602 : x0 = t;
603 :
604 : x0 = pdep(pext(x0, 0xffff0001), 0xaaaaaaab) | pdep(x0 >> 1, 0x55555554);
605 : x1 = pdep(pext(x1, 0xffff0001), 0xaaaaaaab) | pdep(x1 >> 1, 0x55555554);
606 :
607 : buf_put_le32(&outbuf[0], x0);
608 : buf_put_le32(&outbuf[4], x1);
609 : outbuf += 8;
610 : }
611 :
612 : return 0;
613 : }
614 :
615 : static const keccak_ops_t keccak_bmi2_32bi_ops =
616 : {
617 : .permute = keccak_f1600_state_permute32bi_bmi2,
618 : .absorb = keccak_absorb_lanes32bi_bmi2,
619 : .extract = keccak_extract32bi_bmi2,
620 : };
621 :
622 : #endif /* USE_32BIT */
623 :
624 :
625 : static void
626 0 : keccak_write (void *context, const void *inbuf_arg, size_t inlen)
627 : {
628 0 : KECCAK_CONTEXT *ctx = context;
629 0 : const size_t bsize = ctx->blocksize;
630 0 : const size_t blocklanes = bsize / 8;
631 0 : const byte *inbuf = inbuf_arg;
632 0 : unsigned int nburn, burn = 0;
633 : unsigned int count, i;
634 : unsigned int pos, nlanes;
635 :
636 0 : count = ctx->count;
637 :
638 0 : if (inlen && (count % 8))
639 : {
640 0 : byte lane[8] = { 0, };
641 :
642 : /* Complete absorbing partial input lane. */
643 :
644 0 : pos = count / 8;
645 :
646 0 : for (i = count % 8; inlen && i < 8; i++)
647 : {
648 0 : lane[i] = *inbuf++;
649 0 : inlen--;
650 0 : count++;
651 : }
652 :
653 0 : if (count == bsize)
654 0 : count = 0;
655 :
656 0 : nburn = ctx->ops->absorb(&ctx->state, pos, lane, 1,
657 0 : (count % 8) ? -1 : blocklanes);
658 0 : burn = nburn > burn ? nburn : burn;
659 : }
660 :
661 : /* Absorb full input lanes. */
662 :
663 0 : pos = count / 8;
664 0 : nlanes = inlen / 8;
665 0 : if (nlanes > 0)
666 : {
667 0 : nburn = ctx->ops->absorb(&ctx->state, pos, inbuf, nlanes, blocklanes);
668 0 : burn = nburn > burn ? nburn : burn;
669 0 : inlen -= nlanes * 8;
670 0 : inbuf += nlanes * 8;
671 0 : count += nlanes * 8;
672 0 : count = count % bsize;
673 : }
674 :
675 0 : if (inlen)
676 : {
677 0 : byte lane[8] = { 0, };
678 :
679 : /* Absorb remaining partial input lane. */
680 :
681 0 : pos = count / 8;
682 :
683 0 : for (i = count % 8; inlen && i < 8; i++)
684 : {
685 0 : lane[i] = *inbuf++;
686 0 : inlen--;
687 0 : count++;
688 : }
689 :
690 0 : nburn = ctx->ops->absorb(&ctx->state, pos, lane, 1, -1);
691 0 : burn = nburn > burn ? nburn : burn;
692 :
693 0 : gcry_assert(count < bsize);
694 : }
695 :
696 0 : ctx->count = count;
697 :
698 0 : if (burn)
699 0 : _gcry_burn_stack (burn);
700 0 : }
701 :
702 :
703 : static void
704 0 : keccak_init (int algo, void *context, unsigned int flags)
705 : {
706 0 : KECCAK_CONTEXT *ctx = context;
707 0 : KECCAK_STATE *hd = &ctx->state;
708 0 : unsigned int features = _gcry_get_hw_features ();
709 :
710 : (void)flags;
711 : (void)features;
712 :
713 0 : memset (hd, 0, sizeof *hd);
714 :
715 0 : ctx->count = 0;
716 :
717 : /* Select generic implementation. */
718 : #ifdef USE_64BIT
719 0 : ctx->ops = &keccak_generic64_ops;
720 : #elif defined USE_32BIT
721 : ctx->ops = &keccak_generic32bi_ops;
722 : #endif
723 :
724 : /* Select optimized implementation based in hw features. */
725 : if (0) {}
726 : #ifdef USE_64BIT_ARM_NEON
727 : else if (features & HWF_ARM_NEON)
728 : ctx->ops = &keccak_armv7_neon_64_ops;
729 : #endif
730 : #ifdef USE_64BIT_BMI2
731 0 : else if (features & HWF_INTEL_BMI2)
732 0 : ctx->ops = &keccak_bmi2_64_ops;
733 : #endif
734 : #ifdef USE_32BIT_BMI2
735 : else if (features & HWF_INTEL_BMI2)
736 : ctx->ops = &keccak_bmi2_32bi_ops;
737 : #endif
738 : #ifdef USE_64BIT_SHLD
739 0 : else if (features & HWF_INTEL_FAST_SHLD)
740 0 : ctx->ops = &keccak_shld_64_ops;
741 : #endif
742 :
743 : /* Set input block size, in Keccak terms this is called 'rate'. */
744 :
745 0 : switch (algo)
746 : {
747 : case GCRY_MD_SHA3_224:
748 0 : ctx->suffix = SHA3_DELIMITED_SUFFIX;
749 0 : ctx->blocksize = 1152 / 8;
750 0 : ctx->outlen = 224 / 8;
751 0 : break;
752 : case GCRY_MD_SHA3_256:
753 0 : ctx->suffix = SHA3_DELIMITED_SUFFIX;
754 0 : ctx->blocksize = 1088 / 8;
755 0 : ctx->outlen = 256 / 8;
756 0 : break;
757 : case GCRY_MD_SHA3_384:
758 0 : ctx->suffix = SHA3_DELIMITED_SUFFIX;
759 0 : ctx->blocksize = 832 / 8;
760 0 : ctx->outlen = 384 / 8;
761 0 : break;
762 : case GCRY_MD_SHA3_512:
763 0 : ctx->suffix = SHA3_DELIMITED_SUFFIX;
764 0 : ctx->blocksize = 576 / 8;
765 0 : ctx->outlen = 512 / 8;
766 0 : break;
767 : case GCRY_MD_SHAKE128:
768 0 : ctx->suffix = SHAKE_DELIMITED_SUFFIX;
769 0 : ctx->blocksize = 1344 / 8;
770 0 : ctx->outlen = 0;
771 0 : break;
772 : case GCRY_MD_SHAKE256:
773 0 : ctx->suffix = SHAKE_DELIMITED_SUFFIX;
774 0 : ctx->blocksize = 1088 / 8;
775 0 : ctx->outlen = 0;
776 0 : break;
777 : default:
778 0 : BUG();
779 : }
780 0 : }
781 :
782 : static void
783 0 : sha3_224_init (void *context, unsigned int flags)
784 : {
785 0 : keccak_init (GCRY_MD_SHA3_224, context, flags);
786 0 : }
787 :
788 : static void
789 0 : sha3_256_init (void *context, unsigned int flags)
790 : {
791 0 : keccak_init (GCRY_MD_SHA3_256, context, flags);
792 0 : }
793 :
794 : static void
795 0 : sha3_384_init (void *context, unsigned int flags)
796 : {
797 0 : keccak_init (GCRY_MD_SHA3_384, context, flags);
798 0 : }
799 :
800 : static void
801 0 : sha3_512_init (void *context, unsigned int flags)
802 : {
803 0 : keccak_init (GCRY_MD_SHA3_512, context, flags);
804 0 : }
805 :
806 : static void
807 0 : shake128_init (void *context, unsigned int flags)
808 : {
809 0 : keccak_init (GCRY_MD_SHAKE128, context, flags);
810 0 : }
811 :
812 : static void
813 0 : shake256_init (void *context, unsigned int flags)
814 : {
815 0 : keccak_init (GCRY_MD_SHAKE256, context, flags);
816 0 : }
817 :
818 : /* The routine final terminates the computation and
819 : * returns the digest.
820 : * The handle is prepared for a new cycle, but adding bytes to the
821 : * handle will the destroy the returned buffer.
822 : * Returns: 64 bytes representing the digest. When used for sha384,
823 : * we take the leftmost 48 of those bytes.
824 : */
825 : static void
826 0 : keccak_final (void *context)
827 : {
828 0 : KECCAK_CONTEXT *ctx = context;
829 0 : KECCAK_STATE *hd = &ctx->state;
830 0 : const size_t bsize = ctx->blocksize;
831 0 : const byte suffix = ctx->suffix;
832 0 : unsigned int nburn, burn = 0;
833 : unsigned int lastbytes;
834 : byte lane[8];
835 :
836 0 : lastbytes = ctx->count;
837 :
838 : /* Do the padding and switch to the squeezing phase */
839 :
840 : /* Absorb the last few bits and add the first bit of padding (which
841 : coincides with the delimiter in delimited suffix) */
842 0 : buf_put_le64(lane, (u64)suffix << ((lastbytes % 8) * 8));
843 0 : nburn = ctx->ops->absorb(&ctx->state, lastbytes / 8, lane, 1, -1);
844 0 : burn = nburn > burn ? nburn : burn;
845 :
846 : /* Add the second bit of padding. */
847 0 : buf_put_le64(lane, (u64)0x80 << (((bsize - 1) % 8) * 8));
848 0 : nburn = ctx->ops->absorb(&ctx->state, (bsize - 1) / 8, lane, 1, -1);
849 0 : burn = nburn > burn ? nburn : burn;
850 :
851 0 : if (suffix == SHA3_DELIMITED_SUFFIX)
852 : {
853 : /* Switch to the squeezing phase. */
854 0 : nburn = ctx->ops->permute(hd);
855 0 : burn = nburn > burn ? nburn : burn;
856 :
857 : /* Squeeze out the SHA3 digest. */
858 0 : nburn = ctx->ops->extract(hd, 0, (void *)hd, ctx->outlen);
859 0 : burn = nburn > burn ? nburn : burn;
860 : }
861 : else
862 : {
863 : /* Output for SHAKE can now be read with md_extract(). */
864 :
865 0 : ctx->count = 0;
866 : }
867 :
868 0 : wipememory(lane, sizeof(lane));
869 0 : if (burn)
870 0 : _gcry_burn_stack (burn);
871 0 : }
872 :
873 :
874 : static byte *
875 0 : keccak_read (void *context)
876 : {
877 0 : KECCAK_CONTEXT *ctx = (KECCAK_CONTEXT *) context;
878 0 : KECCAK_STATE *hd = &ctx->state;
879 0 : return (byte *)&hd->u;
880 : }
881 :
882 :
883 : static void
884 0 : keccak_extract (void *context, void *out, size_t outlen)
885 : {
886 0 : KECCAK_CONTEXT *ctx = context;
887 0 : KECCAK_STATE *hd = &ctx->state;
888 0 : const size_t bsize = ctx->blocksize;
889 0 : unsigned int nburn, burn = 0;
890 0 : byte *outbuf = out;
891 : unsigned int nlanes;
892 : unsigned int nleft;
893 : unsigned int count;
894 : unsigned int i;
895 : byte lane[8];
896 :
897 0 : count = ctx->count;
898 :
899 0 : while (count && outlen && (outlen < 8 || count % 8))
900 : {
901 : /* Extract partial lane. */
902 0 : nburn = ctx->ops->extract(hd, count / 8, lane, 8);
903 0 : burn = nburn > burn ? nburn : burn;
904 :
905 0 : for (i = count % 8; outlen && i < 8; i++)
906 : {
907 0 : *outbuf++ = lane[i];
908 0 : outlen--;
909 0 : count++;
910 : }
911 :
912 0 : gcry_assert(count <= bsize);
913 :
914 0 : if (count == bsize)
915 0 : count = 0;
916 : }
917 :
918 0 : if (outlen >= 8 && count)
919 : {
920 : /* Extract tail of partial block. */
921 0 : nlanes = outlen / 8;
922 0 : nleft = (bsize - count) / 8;
923 0 : nlanes = nlanes < nleft ? nlanes : nleft;
924 :
925 0 : nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
926 0 : burn = nburn > burn ? nburn : burn;
927 0 : outlen -= nlanes * 8;
928 0 : outbuf += nlanes * 8;
929 0 : count += nlanes * 8;
930 :
931 0 : gcry_assert(count <= bsize);
932 :
933 0 : if (count == bsize)
934 0 : count = 0;
935 : }
936 :
937 0 : while (outlen >= bsize)
938 : {
939 0 : gcry_assert(count == 0);
940 :
941 : /* Squeeze more. */
942 0 : nburn = ctx->ops->permute(hd);
943 0 : burn = nburn > burn ? nburn : burn;
944 :
945 : /* Extract full block. */
946 0 : nburn = ctx->ops->extract(hd, 0, outbuf, bsize);
947 0 : burn = nburn > burn ? nburn : burn;
948 :
949 0 : outlen -= bsize;
950 0 : outbuf += bsize;
951 : }
952 :
953 0 : if (outlen)
954 : {
955 0 : gcry_assert(outlen < bsize);
956 :
957 0 : if (count == 0)
958 : {
959 : /* Squeeze more. */
960 0 : nburn = ctx->ops->permute(hd);
961 0 : burn = nburn > burn ? nburn : burn;
962 : }
963 :
964 0 : if (outlen >= 8)
965 : {
966 : /* Extract head of partial block. */
967 0 : nlanes = outlen / 8;
968 0 : nburn = ctx->ops->extract(hd, count / 8, outbuf, nlanes * 8);
969 0 : burn = nburn > burn ? nburn : burn;
970 0 : outlen -= nlanes * 8;
971 0 : outbuf += nlanes * 8;
972 0 : count += nlanes * 8;
973 :
974 0 : gcry_assert(count < bsize);
975 : }
976 :
977 0 : if (outlen)
978 : {
979 : /* Extract head of partial lane. */
980 0 : nburn = ctx->ops->extract(hd, count / 8, lane, 8);
981 0 : burn = nburn > burn ? nburn : burn;
982 :
983 0 : for (i = count % 8; outlen && i < 8; i++)
984 : {
985 0 : *outbuf++ = lane[i];
986 0 : outlen--;
987 0 : count++;
988 : }
989 :
990 0 : gcry_assert(count < bsize);
991 : }
992 : }
993 :
994 0 : ctx->count = count;
995 :
996 0 : if (burn)
997 0 : _gcry_burn_stack (burn);
998 0 : }
999 :
1000 :
1001 :
1002 : /*
1003 : Self-test section.
1004 : */
1005 :
1006 :
1007 : static gpg_err_code_t
1008 0 : selftests_keccak (int algo, int extended, selftest_report_func_t report)
1009 : {
1010 : const char *what;
1011 : const char *errtxt;
1012 : const char *short_hash;
1013 : const char *long_hash;
1014 : const char *one_million_a_hash;
1015 : int hash_len;
1016 :
1017 0 : switch (algo)
1018 : {
1019 : default:
1020 0 : BUG();
1021 :
1022 : case GCRY_MD_SHA3_224:
1023 0 : short_hash =
1024 : "\xe6\x42\x82\x4c\x3f\x8c\xf2\x4a\xd0\x92\x34\xee\x7d\x3c\x76\x6f"
1025 : "\xc9\xa3\xa5\x16\x8d\x0c\x94\xad\x73\xb4\x6f\xdf";
1026 0 : long_hash =
1027 : "\x54\x3e\x68\x68\xe1\x66\x6c\x1a\x64\x36\x30\xdf\x77\x36\x7a\xe5"
1028 : "\xa6\x2a\x85\x07\x0a\x51\xc1\x4c\xbf\x66\x5c\xbc";
1029 0 : one_million_a_hash =
1030 : "\xd6\x93\x35\xb9\x33\x25\x19\x2e\x51\x6a\x91\x2e\x6d\x19\xa1\x5c"
1031 : "\xb5\x1c\x6e\xd5\xc1\x52\x43\xe7\xa7\xfd\x65\x3c";
1032 0 : hash_len = 28;
1033 0 : break;
1034 :
1035 : case GCRY_MD_SHA3_256:
1036 0 : short_hash =
1037 : "\x3a\x98\x5d\xa7\x4f\xe2\x25\xb2\x04\x5c\x17\x2d\x6b\xd3\x90\xbd"
1038 : "\x85\x5f\x08\x6e\x3e\x9d\x52\x5b\x46\xbf\xe2\x45\x11\x43\x15\x32";
1039 0 : long_hash =
1040 : "\x91\x6f\x60\x61\xfe\x87\x97\x41\xca\x64\x69\xb4\x39\x71\xdf\xdb"
1041 : "\x28\xb1\xa3\x2d\xc3\x6c\xb3\x25\x4e\x81\x2b\xe2\x7a\xad\x1d\x18";
1042 0 : one_million_a_hash =
1043 : "\x5c\x88\x75\xae\x47\x4a\x36\x34\xba\x4f\xd5\x5e\xc8\x5b\xff\xd6"
1044 : "\x61\xf3\x2a\xca\x75\xc6\xd6\x99\xd0\xcd\xcb\x6c\x11\x58\x91\xc1";
1045 0 : hash_len = 32;
1046 0 : break;
1047 :
1048 : case GCRY_MD_SHA3_384:
1049 0 : short_hash =
1050 : "\xec\x01\x49\x82\x88\x51\x6f\xc9\x26\x45\x9f\x58\xe2\xc6\xad\x8d"
1051 : "\xf9\xb4\x73\xcb\x0f\xc0\x8c\x25\x96\xda\x7c\xf0\xe4\x9b\xe4\xb2"
1052 : "\x98\xd8\x8c\xea\x92\x7a\xc7\xf5\x39\xf1\xed\xf2\x28\x37\x6d\x25";
1053 0 : long_hash =
1054 : "\x79\x40\x7d\x3b\x59\x16\xb5\x9c\x3e\x30\xb0\x98\x22\x97\x47\x91"
1055 : "\xc3\x13\xfb\x9e\xcc\x84\x9e\x40\x6f\x23\x59\x2d\x04\xf6\x25\xdc"
1056 : "\x8c\x70\x9b\x98\xb4\x3b\x38\x52\xb3\x37\x21\x61\x79\xaa\x7f\xc7";
1057 0 : one_million_a_hash =
1058 : "\xee\xe9\xe2\x4d\x78\xc1\x85\x53\x37\x98\x34\x51\xdf\x97\xc8\xad"
1059 : "\x9e\xed\xf2\x56\xc6\x33\x4f\x8e\x94\x8d\x25\x2d\x5e\x0e\x76\x84"
1060 : "\x7a\xa0\x77\x4d\xdb\x90\xa8\x42\x19\x0d\x2c\x55\x8b\x4b\x83\x40";
1061 0 : hash_len = 48;
1062 0 : break;
1063 :
1064 : case GCRY_MD_SHA3_512:
1065 0 : short_hash =
1066 : "\xb7\x51\x85\x0b\x1a\x57\x16\x8a\x56\x93\xcd\x92\x4b\x6b\x09\x6e"
1067 : "\x08\xf6\x21\x82\x74\x44\xf7\x0d\x88\x4f\x5d\x02\x40\xd2\x71\x2e"
1068 : "\x10\xe1\x16\xe9\x19\x2a\xf3\xc9\x1a\x7e\xc5\x76\x47\xe3\x93\x40"
1069 : "\x57\x34\x0b\x4c\xf4\x08\xd5\xa5\x65\x92\xf8\x27\x4e\xec\x53\xf0";
1070 0 : long_hash =
1071 : "\xaf\xeb\xb2\xef\x54\x2e\x65\x79\xc5\x0c\xad\x06\xd2\xe5\x78\xf9"
1072 : "\xf8\xdd\x68\x81\xd7\xdc\x82\x4d\x26\x36\x0f\xee\xbf\x18\xa4\xfa"
1073 : "\x73\xe3\x26\x11\x22\x94\x8e\xfc\xfd\x49\x2e\x74\xe8\x2e\x21\x89"
1074 : "\xed\x0f\xb4\x40\xd1\x87\xf3\x82\x27\x0c\xb4\x55\xf2\x1d\xd1\x85";
1075 0 : one_million_a_hash =
1076 : "\x3c\x3a\x87\x6d\xa1\x40\x34\xab\x60\x62\x7c\x07\x7b\xb9\x8f\x7e"
1077 : "\x12\x0a\x2a\x53\x70\x21\x2d\xff\xb3\x38\x5a\x18\xd4\xf3\x88\x59"
1078 : "\xed\x31\x1d\x0a\x9d\x51\x41\xce\x9c\xc5\xc6\x6e\xe6\x89\xb2\x66"
1079 : "\xa8\xaa\x18\xac\xe8\x28\x2a\x0e\x0d\xb5\x96\xc9\x0b\x0a\x7b\x87";
1080 0 : hash_len = 64;
1081 0 : break;
1082 :
1083 : case GCRY_MD_SHAKE128:
1084 0 : short_hash =
1085 : "\x58\x81\x09\x2d\xd8\x18\xbf\x5c\xf8\xa3\xdd\xb7\x93\xfb\xcb\xa7"
1086 : "\x40\x97\xd5\xc5\x26\xa6\xd3\x5f\x97\xb8\x33\x51\x94\x0f\x2c\xc8";
1087 0 : long_hash =
1088 : "\x7b\x6d\xf6\xff\x18\x11\x73\xb6\xd7\x89\x8d\x7f\xf6\x3f\xb0\x7b"
1089 : "\x7c\x23\x7d\xaf\x47\x1a\x5a\xe5\x60\x2a\xdb\xcc\xef\x9c\xcf\x4b";
1090 0 : one_million_a_hash =
1091 : "\x9d\x22\x2c\x79\xc4\xff\x9d\x09\x2c\xf6\xca\x86\x14\x3a\xa4\x11"
1092 : "\xe3\x69\x97\x38\x08\xef\x97\x09\x32\x55\x82\x6c\x55\x72\xef\x58";
1093 0 : hash_len = 32;
1094 0 : break;
1095 :
1096 : case GCRY_MD_SHAKE256:
1097 0 : short_hash =
1098 : "\x48\x33\x66\x60\x13\x60\xa8\x77\x1c\x68\x63\x08\x0c\xc4\x11\x4d"
1099 : "\x8d\xb4\x45\x30\xf8\xf1\xe1\xee\x4f\x94\xea\x37\xe7\x8b\x57\x39";
1100 0 : long_hash =
1101 : "\x98\xbe\x04\x51\x6c\x04\xcc\x73\x59\x3f\xef\x3e\xd0\x35\x2e\xa9"
1102 : "\xf6\x44\x39\x42\xd6\x95\x0e\x29\xa3\x72\xa6\x81\xc3\xde\xaf\x45";
1103 0 : one_million_a_hash =
1104 : "\x35\x78\xa7\xa4\xca\x91\x37\x56\x9c\xdf\x76\xed\x61\x7d\x31\xbb"
1105 : "\x99\x4f\xca\x9c\x1b\xbf\x8b\x18\x40\x13\xde\x82\x34\xdf\xd1\x3a";
1106 0 : hash_len = 32;
1107 0 : break;
1108 : }
1109 :
1110 0 : what = "short string";
1111 0 : errtxt = _gcry_hash_selftest_check_one (algo, 0, "abc", 3, short_hash,
1112 : hash_len);
1113 0 : if (errtxt)
1114 0 : goto failed;
1115 :
1116 0 : if (extended)
1117 : {
1118 0 : what = "long string";
1119 0 : errtxt = _gcry_hash_selftest_check_one
1120 : (algo, 0,
1121 : "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
1122 : "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
1123 : long_hash, hash_len);
1124 0 : if (errtxt)
1125 0 : goto failed;
1126 :
1127 0 : what = "one million \"a\"";
1128 0 : errtxt = _gcry_hash_selftest_check_one (algo, 1, NULL, 0,
1129 : one_million_a_hash, hash_len);
1130 0 : if (errtxt)
1131 0 : goto failed;
1132 : }
1133 :
1134 0 : return 0; /* Succeeded. */
1135 :
1136 : failed:
1137 0 : if (report)
1138 0 : report ("digest", algo, what, errtxt);
1139 0 : return GPG_ERR_SELFTEST_FAILED;
1140 : }
1141 :
1142 :
1143 : /* Run a full self-test for ALGO and return 0 on success. */
1144 : static gpg_err_code_t
1145 0 : run_selftests (int algo, int extended, selftest_report_func_t report)
1146 : {
1147 : gpg_err_code_t ec;
1148 :
1149 0 : switch (algo)
1150 : {
1151 : case GCRY_MD_SHA3_224:
1152 : case GCRY_MD_SHA3_256:
1153 : case GCRY_MD_SHA3_384:
1154 : case GCRY_MD_SHA3_512:
1155 : case GCRY_MD_SHAKE128:
1156 : case GCRY_MD_SHAKE256:
1157 0 : ec = selftests_keccak (algo, extended, report);
1158 0 : break;
1159 : default:
1160 0 : ec = GPG_ERR_DIGEST_ALGO;
1161 0 : break;
1162 : }
1163 :
1164 0 : return ec;
1165 : }
1166 :
1167 :
1168 :
1169 :
1170 : static byte sha3_224_asn[] = { 0x30 };
1171 : static gcry_md_oid_spec_t oid_spec_sha3_224[] =
1172 : {
1173 : { "2.16.840.1.101.3.4.2.7" },
1174 : /* PKCS#1 sha3_224WithRSAEncryption */
1175 : { "?" },
1176 : { NULL }
1177 : };
1178 : static byte sha3_256_asn[] = { 0x30 };
1179 : static gcry_md_oid_spec_t oid_spec_sha3_256[] =
1180 : {
1181 : { "2.16.840.1.101.3.4.2.8" },
1182 : /* PKCS#1 sha3_256WithRSAEncryption */
1183 : { "?" },
1184 : { NULL }
1185 : };
1186 : static byte sha3_384_asn[] = { 0x30 };
1187 : static gcry_md_oid_spec_t oid_spec_sha3_384[] =
1188 : {
1189 : { "2.16.840.1.101.3.4.2.9" },
1190 : /* PKCS#1 sha3_384WithRSAEncryption */
1191 : { "?" },
1192 : { NULL }
1193 : };
1194 : static byte sha3_512_asn[] = { 0x30 };
1195 : static gcry_md_oid_spec_t oid_spec_sha3_512[] =
1196 : {
1197 : { "2.16.840.1.101.3.4.2.10" },
1198 : /* PKCS#1 sha3_512WithRSAEncryption */
1199 : { "?" },
1200 : { NULL }
1201 : };
1202 : static byte shake128_asn[] = { 0x30 };
1203 : static gcry_md_oid_spec_t oid_spec_shake128[] =
1204 : {
1205 : { "2.16.840.1.101.3.4.2.11" },
1206 : /* PKCS#1 shake128WithRSAEncryption */
1207 : { "?" },
1208 : { NULL }
1209 : };
1210 : static byte shake256_asn[] = { 0x30 };
1211 : static gcry_md_oid_spec_t oid_spec_shake256[] =
1212 : {
1213 : { "2.16.840.1.101.3.4.2.12" },
1214 : /* PKCS#1 shake256WithRSAEncryption */
1215 : { "?" },
1216 : { NULL }
1217 : };
1218 :
1219 : gcry_md_spec_t _gcry_digest_spec_sha3_224 =
1220 : {
1221 : GCRY_MD_SHA3_224, {0, 1},
1222 : "SHA3-224", sha3_224_asn, DIM (sha3_224_asn), oid_spec_sha3_224, 28,
1223 : sha3_224_init, keccak_write, keccak_final, keccak_read, NULL,
1224 : sizeof (KECCAK_CONTEXT),
1225 : run_selftests
1226 : };
1227 : gcry_md_spec_t _gcry_digest_spec_sha3_256 =
1228 : {
1229 : GCRY_MD_SHA3_256, {0, 1},
1230 : "SHA3-256", sha3_256_asn, DIM (sha3_256_asn), oid_spec_sha3_256, 32,
1231 : sha3_256_init, keccak_write, keccak_final, keccak_read, NULL,
1232 : sizeof (KECCAK_CONTEXT),
1233 : run_selftests
1234 : };
1235 : gcry_md_spec_t _gcry_digest_spec_sha3_384 =
1236 : {
1237 : GCRY_MD_SHA3_384, {0, 1},
1238 : "SHA3-384", sha3_384_asn, DIM (sha3_384_asn), oid_spec_sha3_384, 48,
1239 : sha3_384_init, keccak_write, keccak_final, keccak_read, NULL,
1240 : sizeof (KECCAK_CONTEXT),
1241 : run_selftests
1242 : };
1243 : gcry_md_spec_t _gcry_digest_spec_sha3_512 =
1244 : {
1245 : GCRY_MD_SHA3_512, {0, 1},
1246 : "SHA3-512", sha3_512_asn, DIM (sha3_512_asn), oid_spec_sha3_512, 64,
1247 : sha3_512_init, keccak_write, keccak_final, keccak_read, NULL,
1248 : sizeof (KECCAK_CONTEXT),
1249 : run_selftests
1250 : };
1251 : gcry_md_spec_t _gcry_digest_spec_shake128 =
1252 : {
1253 : GCRY_MD_SHAKE128, {0, 1},
1254 : "SHAKE128", shake128_asn, DIM (shake128_asn), oid_spec_shake128, 0,
1255 : shake128_init, keccak_write, keccak_final, NULL, keccak_extract,
1256 : sizeof (KECCAK_CONTEXT),
1257 : run_selftests
1258 : };
1259 : gcry_md_spec_t _gcry_digest_spec_shake256 =
1260 : {
1261 : GCRY_MD_SHAKE256, {0, 1},
1262 : "SHAKE256", shake256_asn, DIM (shake256_asn), oid_spec_shake256, 0,
1263 : shake256_init, keccak_write, keccak_final, NULL, keccak_extract,
1264 : sizeof (KECCAK_CONTEXT),
1265 : run_selftests
1266 : };
|