LCOV - code coverage report
Current view: top level - cipher - keccak.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 262 0.0 %
Date: 2016-12-15 12:59:22 Functions: 0 18 0.0 %

          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             :   };

Generated by: LCOV version 1.12