Xuyi Wang / wolfSSL

Dependents:   OS

Revision:
17:ff9d1e86ad5f
Parent:
16:048e5e270a58
--- a/wolfcrypt/src/sha3.c	Tue Nov 19 14:32:16 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1101 +0,0 @@
-/* sha3.c
- *
- * Copyright (C) 2006-2017 wolfSSL Inc.
- *
- * This file is part of wolfSSL.
- *
- * wolfSSL is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * wolfSSL is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
- */
-
-
-#ifdef HAVE_CONFIG_H
-    #include <config.h>
-#endif
-
-#include <wolfssl/wolfcrypt/settings.h>
-
-#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT)
-
-#if defined(HAVE_FIPS) && \
-	defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
-
-    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
-    #define FIPS_NO_WRAPPERS
-
-    #ifdef USE_WINDOWS_API
-        #pragma code_seg(".fipsA$l")
-        #pragma const_seg(".fipsB$l")
-    #endif
-#endif
-
-#include <wolfssl/wolfcrypt/sha3.h>
-#include <wolfssl/wolfcrypt/error-crypt.h>
-
-#ifdef NO_INLINE
-    #include <wolfssl/wolfcrypt/misc.h>
-#else
-    #define WOLFSSL_MISC_INCLUDED
-    #include <wolfcrypt/src/misc.c>
-#endif
-
-
-#ifdef WOLFSSL_SHA3_SMALL
-/* Rotate a 64-bit value left.
- *
- * a  Number to rotate left.
- * r  Number od bits to rotate left.
- * returns the rotated number.
- */
-#define ROTL64(a, n)    (((a)<<(n))|((a)>>(64-(n))))
-
-/* An array of values to XOR for block operation. */
-static const word64 hash_keccak_r[24] =
-{
-    0x0000000000000001UL, 0x0000000000008082UL,
-    0x800000000000808aUL, 0x8000000080008000UL,
-    0x000000000000808bUL, 0x0000000080000001UL,
-    0x8000000080008081UL, 0x8000000000008009UL,
-    0x000000000000008aUL, 0x0000000000000088UL,
-    0x0000000080008009UL, 0x000000008000000aUL,
-    0x000000008000808bUL, 0x800000000000008bUL,
-    0x8000000000008089UL, 0x8000000000008003UL,
-    0x8000000000008002UL, 0x8000000000000080UL,
-    0x000000000000800aUL, 0x800000008000000aUL,
-    0x8000000080008081UL, 0x8000000000008080UL,
-    0x0000000080000001UL, 0x8000000080008008UL
-};
-
-/* Indeces used in swap and rotate operation. */
-#define K_I_0   10
-#define K_I_1    7
-#define K_I_2   11
-#define K_I_3   17
-#define K_I_4   18
-#define K_I_5    3
-#define K_I_6    5
-#define K_I_7   16
-#define K_I_8    8
-#define K_I_9   21
-#define K_I_10  24
-#define K_I_11   4
-#define K_I_12  15
-#define K_I_13  23
-#define K_I_14  19
-#define K_I_15  13
-#define K_I_16  12
-#define K_I_17   2
-#define K_I_18  20
-#define K_I_19  14
-#define K_I_20  22
-#define K_I_21   9
-#define K_I_22   6
-#define K_I_23   1
-
-/* Number of bits to rotate in swap and rotate operation. */
-#define K_R_0    1
-#define K_R_1    3
-#define K_R_2    6
-#define K_R_3   10
-#define K_R_4   15
-#define K_R_5   21
-#define K_R_6   28
-#define K_R_7   36
-#define K_R_8   45
-#define K_R_9   55
-#define K_R_10   2
-#define K_R_11  14
-#define K_R_12  27
-#define K_R_13  41
-#define K_R_14  56
-#define K_R_15   8
-#define K_R_16  25
-#define K_R_17  43
-#define K_R_18  62
-#define K_R_19  18
-#define K_R_20  39
-#define K_R_21  61
-#define K_R_22  20
-#define K_R_23  44
-
-/* Swap and rotate left operation.
- *
- * s   The state.
- * t1  Temporary value.
- * t2  Second temporary value.
- * i   The index of the loop.
- */
-#define SWAP_ROTL(s, t1, t2, i)                                         \
-do                                                                      \
-{                                                                       \
-    t2 = s[K_I_##i]; s[K_I_##i] = ROTL64(t1, K_R_##i);                  \
-}                                                                       \
-while (0)
-
-/* Mix the XOR of the column's values into each number by column.
- *
- * s  The state.
- * b  Temporary array of XORed column values.
- * x  The index of the column.
- * t  Temporary variable.
- */
-#define COL_MIX(s, b, x, t)                                             \
-do                                                                      \
-{                                                                       \
-    for (x = 0; x < 5; x++)                                             \
-        b[x] = s[x + 0] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20]; \
-    for (x = 0; x < 5; x++)                                             \
-    {                                                                   \
-        t = b[(x + 4) % 5] ^ ROTL64(b[(x + 1) % 5], 1);                 \
-        s[x +  0] ^= t;                                                 \
-        s[x +  5] ^= t;                                                 \
-        s[x + 10] ^= t;                                                 \
-        s[x + 15] ^= t;                                                 \
-        s[x + 20] ^= t;                                                 \
-    }                                                                   \
-}                                                                       \
-while (0)
-
-#ifdef SHA3_BY_SPEC
-/* Mix the row values.
- * BMI1 has ANDN instruction ((~a) & b) - Haswell and above.
- *
- * s   The state.
- * b   Temporary array of XORed row values.
- * y   The index of the row to work on.
- * x   The index of the column.
- * t0  Temporary variable.
- * t1  Temporary variable.
- */
-#define ROW_MIX(s, b, y, x, t0, t1)                                     \
-do                                                                      \
-{                                                                       \
-    for (y = 0; y < 5; y++)                                             \
-    {                                                                   \
-        for (x = 0; x < 5; x++)                                         \
-            b[x] = s[y * 5 + x];                                        \
-        for (x = 0; x < 5; x++)                                         \
-           s[y * 5 + x] = b[x] ^ (~b[(x + 1) % 5] & b[(x + 2) % 5]);    \
-    }                                                                   \
-}                                                                       \
-while (0)
-#else
-/* Mix the row values.
- * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)
- *
- * s   The state.
- * b   Temporary array of XORed row values.
- * y   The index of the row to work on.
- * x   The index of the column.
- * t0  Temporary variable.
- * t1  Temporary variable.
- */
-#define ROW_MIX(s, b, y, x, t12, t34)                                   \
-do                                                                      \
-{                                                                       \
-    for (y = 0; y < 5; y++)                                             \
-    {                                                                   \
-        for (x = 0; x < 5; x++)                                         \
-            b[x] = s[y * 5 + x];                                        \
-        t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]);                       \
-        s[y * 5 + 0] = b[0] ^ (b[2] &  t12);                            \
-        s[y * 5 + 1] =  t12 ^ (b[2] | b[3]);                            \
-        s[y * 5 + 2] = b[2] ^ (b[4] &  t34);                            \
-        s[y * 5 + 3] =  t34 ^ (b[4] | b[0]);                            \
-        s[y * 5 + 4] = b[4] ^ (b[1] & (b[0] ^ b[1]));                   \
-    }                                                                   \
-}                                                                       \
-while (0)
-#endif /* SHA3_BY_SPEC */
-
-/* The block operation performed on the state.
- *
- * s  The state.
- */
-static void BlockSha3(word64 *s)
-{
-    byte i, x, y;
-    word64 t0, t1;
-    word64 b[5];
-
-    for (i = 0; i < 24; i++)
-    {
-        COL_MIX(s, b, x, t0);
-
-        t0 = s[1];
-        SWAP_ROTL(s, t0, t1,  0);
-        SWAP_ROTL(s, t1, t0,  1);
-        SWAP_ROTL(s, t0, t1,  2);
-        SWAP_ROTL(s, t1, t0,  3);
-        SWAP_ROTL(s, t0, t1,  4);
-        SWAP_ROTL(s, t1, t0,  5);
-        SWAP_ROTL(s, t0, t1,  6);
-        SWAP_ROTL(s, t1, t0,  7);
-        SWAP_ROTL(s, t0, t1,  8);
-        SWAP_ROTL(s, t1, t0,  9);
-        SWAP_ROTL(s, t0, t1, 10);
-        SWAP_ROTL(s, t1, t0, 11);
-        SWAP_ROTL(s, t0, t1, 12);
-        SWAP_ROTL(s, t1, t0, 13);
-        SWAP_ROTL(s, t0, t1, 14);
-        SWAP_ROTL(s, t1, t0, 15);
-        SWAP_ROTL(s, t0, t1, 16);
-        SWAP_ROTL(s, t1, t0, 17);
-        SWAP_ROTL(s, t0, t1, 18);
-        SWAP_ROTL(s, t1, t0, 19);
-        SWAP_ROTL(s, t0, t1, 20);
-        SWAP_ROTL(s, t1, t0, 21);
-        SWAP_ROTL(s, t0, t1, 22);
-        SWAP_ROTL(s, t1, t0, 23);
-
-        ROW_MIX(s, b, y, x, t0, t1);
-
-        s[0] ^= hash_keccak_r[i];
-    }
-}
-#else
-/* Rotate a 64-bit value left.
- *
- * a  Number to rotate left.
- * r  Number od bits to rotate left.
- * returns the rotated number.
- */
-#define ROTL64(a, n)    (((a)<<(n))|((a)>>(64-(n))))
-
-/* An array of values to XOR for block operation. */
-static const word64 hash_keccak_r[24] =
-{
-    0x0000000000000001UL, 0x0000000000008082UL,
-    0x800000000000808aUL, 0x8000000080008000UL,
-    0x000000000000808bUL, 0x0000000080000001UL,
-    0x8000000080008081UL, 0x8000000000008009UL,
-    0x000000000000008aUL, 0x0000000000000088UL,
-    0x0000000080008009UL, 0x000000008000000aUL,
-    0x000000008000808bUL, 0x800000000000008bUL,
-    0x8000000000008089UL, 0x8000000000008003UL,
-    0x8000000000008002UL, 0x8000000000000080UL,
-    0x000000000000800aUL, 0x800000008000000aUL,
-    0x8000000080008081UL, 0x8000000000008080UL,
-    0x0000000080000001UL, 0x8000000080008008UL
-};
-
-/* Indeces used in swap and rotate operation. */
-#define KI_0     6
-#define KI_1    12
-#define KI_2    18
-#define KI_3    24
-#define KI_4     3
-#define KI_5     9
-#define KI_6    10
-#define KI_7    16
-#define KI_8    22
-#define KI_9     1
-#define KI_10    7
-#define KI_11   13
-#define KI_12   19
-#define KI_13   20
-#define KI_14    4
-#define KI_15    5
-#define KI_16   11
-#define KI_17   17
-#define KI_18   23
-#define KI_19    2
-#define KI_20    8
-#define KI_21   14
-#define KI_22   15
-#define KI_23   21
-
-/* Number of bits to rotate in swap and rotate operation. */
-#define KR_0    44
-#define KR_1    43
-#define KR_2    21
-#define KR_3    14
-#define KR_4    28
-#define KR_5    20
-#define KR_6     3
-#define KR_7    45
-#define KR_8    61
-#define KR_9     1
-#define KR_10    6
-#define KR_11   25
-#define KR_12    8
-#define KR_13   18
-#define KR_14   27
-#define KR_15   36
-#define KR_16   10
-#define KR_17   15
-#define KR_18   56
-#define KR_19   62
-#define KR_20   55
-#define KR_21   39
-#define KR_22   41
-#define KR_23    2
-
-/* Mix the XOR of the column's values into each number by column.
- *
- * s  The state.
- * b  Temporary array of XORed column values.
- * x  The index of the column.
- * t  Temporary variable.
- */
-#define COL_MIX(s, b, x, t)                                     \
-do                                                              \
-{                                                               \
-    b[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];                 \
-    b[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];                 \
-    b[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];                 \
-    b[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];                 \
-    b[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];                 \
-    t = b[(0 + 4) % 5] ^ ROTL64(b[(0 + 1) % 5], 1);             \
-    s[ 0] ^= t; s[ 5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t; \
-    t = b[(1 + 4) % 5] ^ ROTL64(b[(1 + 1) % 5], 1);             \
-    s[ 1] ^= t; s[ 6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t; \
-    t = b[(2 + 4) % 5] ^ ROTL64(b[(2 + 1) % 5], 1);             \
-    s[ 2] ^= t; s[ 7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t; \
-    t = b[(3 + 4) % 5] ^ ROTL64(b[(3 + 1) % 5], 1);             \
-    s[ 3] ^= t; s[ 8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t; \
-    t = b[(4 + 4) % 5] ^ ROTL64(b[(4 + 1) % 5], 1);             \
-    s[ 4] ^= t; s[ 9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t; \
-}                                                               \
-while (0)
-
-#define S(s1, i) ROTL64(s1[KI_##i], KR_##i)
-
-#ifdef SHA3_BY_SPEC
-/* Mix the row values.
- * BMI1 has ANDN instruction ((~a) & b) - Haswell and above.
- *
- * s2  The new state.
- * s1  The current state.
- * b   Temporary array of XORed row values.
- * t0  Temporary variable. (Unused)
- * t1  Temporary variable. (Unused)
- */
-#define ROW_MIX(s2, s1, b, t0, t1)            \
-do                                            \
-{                                             \
-    b[0] = s1[0];                             \
-    b[1] = S(s1, 0);                          \
-    b[2] = S(s1, 1);                          \
-    b[3] = S(s1, 2);                          \
-    b[4] = S(s1, 3);                          \
-    s2[0] = b[0] ^ (~b[1] & b[2]);            \
-    s2[1] = b[1] ^ (~b[2] & b[3]);            \
-    s2[2] = b[2] ^ (~b[3] & b[4]);            \
-    s2[3] = b[3] ^ (~b[4] & b[0]);            \
-    s2[4] = b[4] ^ (~b[0] & b[1]);            \
-    b[0] = S(s1, 4);                          \
-    b[1] = S(s1, 5);                          \
-    b[2] = S(s1, 6);                          \
-    b[3] = S(s1, 7);                          \
-    b[4] = S(s1, 8);                          \
-    s2[5] = b[0] ^ (~b[1] & b[2]);            \
-    s2[6] = b[1] ^ (~b[2] & b[3]);            \
-    s2[7] = b[2] ^ (~b[3] & b[4]);            \
-    s2[8] = b[3] ^ (~b[4] & b[0]);            \
-    s2[9] = b[4] ^ (~b[0] & b[1]);            \
-    b[0] = S(s1, 9);                          \
-    b[1] = S(s1, 10);                         \
-    b[2] = S(s1, 11);                         \
-    b[3] = S(s1, 12);                         \
-    b[4] = S(s1, 13);                         \
-    s2[10] = b[0] ^ (~b[1] & b[2]);           \
-    s2[11] = b[1] ^ (~b[2] & b[3]);           \
-    s2[12] = b[2] ^ (~b[3] & b[4]);           \
-    s2[13] = b[3] ^ (~b[4] & b[0]);           \
-    s2[14] = b[4] ^ (~b[0] & b[1]);           \
-    b[0] = S(s1, 14);                         \
-    b[1] = S(s1, 15);                         \
-    b[2] = S(s1, 16);                         \
-    b[3] = S(s1, 17);                         \
-    b[4] = S(s1, 18);                         \
-    s2[15] = b[0] ^ (~b[1] & b[2]);           \
-    s2[16] = b[1] ^ (~b[2] & b[3]);           \
-    s2[17] = b[2] ^ (~b[3] & b[4]);           \
-    s2[18] = b[3] ^ (~b[4] & b[0]);           \
-    s2[19] = b[4] ^ (~b[0] & b[1]);           \
-    b[0] = S(s1, 19);                         \
-    b[1] = S(s1, 20);                         \
-    b[2] = S(s1, 21);                         \
-    b[3] = S(s1, 22);                         \
-    b[4] = S(s1, 23);                         \
-    s2[20] = b[0] ^ (~b[1] & b[2]);           \
-    s2[21] = b[1] ^ (~b[2] & b[3]);           \
-    s2[22] = b[2] ^ (~b[3] & b[4]);           \
-    s2[23] = b[3] ^ (~b[4] & b[0]);           \
-    s2[24] = b[4] ^ (~b[0] & b[1]);           \
-}                                             \
-while (0)
-#else
-/* Mix the row values.
- * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)
- *
- * s2  The new state.
- * s1  The current state.
- * b   Temporary array of XORed row values.
- * t12 Temporary variable.
- * t34 Temporary variable.
- */
-#define ROW_MIX(s2, s1, b, t12, t34)          \
-do                                            \
-{                                             \
-    b[0] = s1[0];                             \
-    b[1] = S(s1, 0);                          \
-    b[2] = S(s1, 1);                          \
-    b[3] = S(s1, 2);                          \
-    b[4] = S(s1, 3);                          \
-    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
-    s2[0] = b[0] ^ (b[2] &  t12);             \
-    s2[1] =  t12 ^ (b[2] | b[3]);             \
-    s2[2] = b[2] ^ (b[4] &  t34);             \
-    s2[3] =  t34 ^ (b[4] | b[0]);             \
-    s2[4] = b[4] ^ (b[1] & (b[0] ^ b[1]));    \
-    b[0] = S(s1, 4);                          \
-    b[1] = S(s1, 5);                          \
-    b[2] = S(s1, 6);                          \
-    b[3] = S(s1, 7);                          \
-    b[4] = S(s1, 8);                          \
-    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
-    s2[5] = b[0] ^ (b[2] &  t12);             \
-    s2[6] =  t12 ^ (b[2] | b[3]);             \
-    s2[7] = b[2] ^ (b[4] &  t34);             \
-    s2[8] =  t34 ^ (b[4] | b[0]);             \
-    s2[9] = b[4] ^ (b[1] & (b[0] ^ b[1]));    \
-    b[0] = S(s1, 9);                          \
-    b[1] = S(s1, 10);                         \
-    b[2] = S(s1, 11);                         \
-    b[3] = S(s1, 12);                         \
-    b[4] = S(s1, 13);                         \
-    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
-    s2[10] = b[0] ^ (b[2] &  t12);            \
-    s2[11] =  t12 ^ (b[2] | b[3]);            \
-    s2[12] = b[2] ^ (b[4] &  t34);            \
-    s2[13] =  t34 ^ (b[4] | b[0]);            \
-    s2[14] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \
-    b[0] = S(s1, 14);                         \
-    b[1] = S(s1, 15);                         \
-    b[2] = S(s1, 16);                         \
-    b[3] = S(s1, 17);                         \
-    b[4] = S(s1, 18);                         \
-    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
-    s2[15] = b[0] ^ (b[2] &  t12);            \
-    s2[16] =  t12 ^ (b[2] | b[3]);            \
-    s2[17] = b[2] ^ (b[4] &  t34);            \
-    s2[18] =  t34 ^ (b[4] | b[0]);            \
-    s2[19] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \
-    b[0] = S(s1, 19);                         \
-    b[1] = S(s1, 20);                         \
-    b[2] = S(s1, 21);                         \
-    b[3] = S(s1, 22);                         \
-    b[4] = S(s1, 23);                         \
-    t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
-    s2[20] = b[0] ^ (b[2] &  t12);            \
-    s2[21] =  t12 ^ (b[2] | b[3]);            \
-    s2[22] = b[2] ^ (b[4] &  t34);            \
-    s2[23] =  t34 ^ (b[4] | b[0]);            \
-    s2[24] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \
-}                                             \
-while (0)
-#endif /* SHA3_BY_SPEC */
-
-/* The block operation performed on the state.
- *
- * s  The state.
- */
-static void BlockSha3(word64 *s)
-{
-    word64 n[25];
-    word64 b[5];
-    word64 t0;
-#ifndef SHA3_BY_SPEC
-    word64 t1;
-#endif
-    byte i;
-
-    for (i = 0; i < 24; i += 2)
-    {
-        COL_MIX(s, b, x, t0);
-        ROW_MIX(n, s, b, t0, t1);
-        n[0] ^= hash_keccak_r[i];
-
-        COL_MIX(n, b, x, t0);
-        ROW_MIX(s, n, b, t0, t1);
-        s[0] ^= hash_keccak_r[i+1];
-    }
-}
-#endif /* WOLFSSL_SHA3_SMALL */
-
-/* Convert the array of bytes, in little-endian order, to a 64-bit integer.
- *
- * a  Array of bytes.
- * returns a 64-bit integer.
- */
-static word64 Load64BitBigEndian(const byte* a)
-{
-#ifdef BIG_ENDIAN_ORDER
-    word64 n = 0;
-    int i;
-
-    for (i = 0; i < 8; i++)
-        n |= (word64)a[i] << (8 * i);
-
-    return n;
-#else
-    return *(word64*)a;
-#endif
-}
-
-/* Initialize the state for a SHA3-224 hash operation.
- *
- * sha3   wc_Sha3 object holding state.
- * returns 0 on success.
- */
-static int InitSha3(wc_Sha3* sha3)
-{
-    int i;
-
-    for (i = 0; i < 25; i++)
-        sha3->s[i] = 0;
-    sha3->i = 0;
-
-    return 0;
-}
-
-/* Update the SHA-3 hash state with message data.
- *
- * sha3  wc_Sha3 object holding state.
- * data  Message data to be hashed.
- * len   Length of the message data.
- * p     Number of 64-bit numbers in a block of data to process.
- * returns 0 on success.
- */
-static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
-{
-    byte i;
-    byte l;
-    byte *t;
-
-    if (sha3->i > 0)
-    {
-        l = p * 8 - sha3->i;
-        if (l > len) {
-            l = (byte)len;
-        }
-
-        t = &sha3->t[sha3->i];
-        for (i = 0; i < l; i++)
-            t[i] = data[i];
-        data += i;
-        len -= i;
-        sha3->i += i;
-
-        if (sha3->i == p * 8)
-        {
-            for (i = 0; i < p; i++)
-                sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
-            BlockSha3(sha3->s);
-            sha3->i = 0;
-        }
-    }
-    while (len >= ((word32)(p * 8)))
-    {
-        for (i = 0; i < p; i++)
-            sha3->s[i] ^= Load64BitBigEndian(data + 8 * i);
-        BlockSha3(sha3->s);
-        len -= p * 8;
-        data += p * 8;
-    }
-    for (i = 0; i < len; i++)
-        sha3->t[i] = data[i];
-    sha3->i += i;
-
-    return 0;
-}
-
-/* Calculate the SHA-3 hash based on all the message data seen.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result.
- * p     Number of 64-bit numbers in a block of data to process.
- * len   Number of bytes in output.
- * returns 0 on success.
- */
-static int Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte l)
-{
-    byte i;
-    byte *s8 = (byte *)sha3->s;
-
-    sha3->t[p * 8 - 1]  = 0x00;
-    sha3->t[  sha3->i]  = 0x06;
-    sha3->t[p * 8 - 1] |= 0x80;
-    for (i=sha3->i + 1; i < p * 8 - 1; i++)
-        sha3->t[i] = 0;
-    for (i = 0; i < p; i++)
-        sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
-    BlockSha3(sha3->s);
-#if defined(BIG_ENDIAN_ORDER)
-    ByteReverseWords64(sha3->s, sha3->s, ((l+7)/8)*8);
-#endif
-    for (i = 0; i < l; i++)
-        hash[i] = s8[i];
-
-    return 0;
-}
-
-/* Initialize the state for a SHA-3 hash operation.
- *
- * sha3   wc_Sha3 object holding state.
- * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
- * devId  Device identifier for asynchronous operation.
- * returns 0 on success.
- */
-static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)
-{
-    int ret = 0;
-
-    if (sha3 == NULL)
-        return BAD_FUNC_ARG;
-
-    sha3->heap = heap;
-    ret = InitSha3(sha3);
-    if (ret != 0)
-        return ret;
-
-#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
-    ret = wolfAsync_DevCtxInit(&sha3->asyncDev,
-                        WOLFSSL_ASYNC_MARKER_SHA3, sha3->heap, devId);
-#else
-    (void)devId;
-#endif /* WOLFSSL_ASYNC_CRYPT */
-
-    return ret;
-}
-
-/* Update the SHA-3 hash state with message data.
- *
- * sha3  wc_Sha3 object holding state.
- * data  Message data to be hashed.
- * len   Length of the message data.
- * p     Number of 64-bit numbers in a block of data to process.
- * returns 0 on success.
- */
-static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
-{
-    int ret = 0;
-
-    if (sha3 == NULL || (data == NULL && len > 0)) {
-        return BAD_FUNC_ARG;
-    }
-
-#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
-    if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {
-    #if defined(HAVE_INTEL_QA)
-        return IntelQaSymSha3(&sha3->asyncDev, NULL, data, len);
-    #endif
-    }
-#endif /* WOLFSSL_ASYNC_CRYPT */
-
-    Sha3Update(sha3, data, len, p);
-
-    return ret;
-}
-
-/* Calculate the SHA-3 hash based on all the message data seen.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result.
- * p     Number of 64-bit numbers in a block of data to process.
- * len   Number of bytes in output.
- * returns 0 on success.
- */
-static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)
-{
-    int ret;
-
-    if (sha3 == NULL || hash == NULL) {
-        return BAD_FUNC_ARG;
-    }
-
-#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
-    if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {
-    #if defined(HAVE_INTEL_QA)
-        return IntelQaSymSha3(&sha3->asyncDev, hash, NULL,
-                              SHA3_DIGEST_SIZE);
-    #endif
-    }
-#endif /* WOLFSSL_ASYNC_CRYPT */
-
-    ret = Sha3Final(sha3, hash, p, len);
-    if (ret != 0)
-        return ret;
-
-    return InitSha3(sha3);  /* reset state */
-}
-
-/* Dispose of any dynamically allocated data from the SHA3-384 operation.
- * (Required for async ops.)
- *
- * sha3  wc_Sha3 object holding state.
- * returns 0 on success.
- */
-static void wc_Sha3Free(wc_Sha3* sha3)
-{
-    (void)sha3;
-
-#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
-    if (sha3 == NULL)
-        return;
-
-    wolfAsync_DevCtxFree(&sha3->asyncDev, WOLFSSL_ASYNC_MARKER_SHA3);
-#endif /* WOLFSSL_ASYNC_CRYPT */
-}
-
-
-/* Copy the state of the SHA3 operation.
- *
- * src  wc_Sha3 object holding state top copy.
- * dst  wc_Sha3 object to copy into.
- * returns 0 on success.
- */
-static int wc_Sha3Copy(wc_Sha3* src, wc_Sha3* dst)
-{
-    int ret = 0;
-
-    if (src == NULL || dst == NULL)
-        return BAD_FUNC_ARG;
-
-    XMEMCPY(dst, src, sizeof(wc_Sha3));
-
-#ifdef WOLFSSL_ASYNC_CRYPT
-    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
-#endif
-
-    return ret;
-}
-
-/* Calculate the SHA3-224 hash based on all the message data so far.
- * More message data can be added, after this operation, using the current
- * state.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 28 bytes.
- * p     Number of 64-bit numbers in a block of data to process.
- * len   Number of bytes in output.
- * returns 0 on success.
- */
-static int wc_Sha3GetHash(wc_Sha3* sha3, byte* hash, byte p, byte len)
-{
-    int ret;
-    wc_Sha3 tmpSha3;
-
-    if (sha3 == NULL || hash == NULL)
-        return BAD_FUNC_ARG;
-
-    ret = wc_Sha3Copy(sha3, &tmpSha3);
-    if (ret == 0) {
-        ret = wc_Sha3Final(&tmpSha3, hash, p, len);
-    }
-    return ret;
-}
-
-
-/* Initialize the state for a SHA3-224 hash operation.
- *
- * sha3   wc_Sha3 object holding state.
- * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
- * devId  Device identifier for asynchronous operation.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_InitSha3_224(wc_Sha3* sha3, void* heap, int devId)
-{
-    return wc_InitSha3(sha3, heap, devId);
-}
-
-/* Update the SHA3-224 hash state with message data.
- *
- * sha3  wc_Sha3 object holding state.
- * data  Message data to be hashed.
- * len   Length of the message data.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_224_Update(wc_Sha3* sha3, const byte* data, word32 len)
-{
-    return wc_Sha3Update(sha3, data, len, WC_SHA3_224_COUNT);
-}
-
-/* Calculate the SHA3-224 hash based on all the message data seen.
- * The state is initialized ready for a new message to hash.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 28 bytes.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_224_Final(wc_Sha3* sha3, byte* hash)
-{
-    return wc_Sha3Final(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE);
-}
-
-/* Dispose of any dynamically allocated data from the SHA3-224 operation.
- * (Required for async ops.)
- *
- * sha3  wc_Sha3 object holding state.
- * returns 0 on success.
- */
-WOLFSSL_API void wc_Sha3_224_Free(wc_Sha3* sha3)
-{
-    wc_Sha3Free(sha3);
-}
-
-/* Calculate the SHA3-224 hash based on all the message data so far.
- * More message data can be added, after this operation, using the current
- * state.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 28 bytes.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_224_GetHash(wc_Sha3* sha3, byte* hash)
-{
-    return wc_Sha3GetHash(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE);
-}
-
-/* Copy the state of the SHA3-224 operation.
- *
- * src  wc_Sha3 object holding state top copy.
- * dst  wc_Sha3 object to copy into.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_224_Copy(wc_Sha3* src, wc_Sha3* dst)
-{
-    return wc_Sha3Copy(src, dst);
-}
-
-
-/* Initialize the state for a SHA3-256 hash operation.
- *
- * sha3   wc_Sha3 object holding state.
- * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
- * devId  Device identifier for asynchronous operation.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_InitSha3_256(wc_Sha3* sha3, void* heap, int devId)
-{
-    return wc_InitSha3(sha3, heap, devId);
-}
-
-/* Update the SHA3-256 hash state with message data.
- *
- * sha3  wc_Sha3 object holding state.
- * data  Message data to be hashed.
- * len   Length of the message data.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_256_Update(wc_Sha3* sha3, const byte* data, word32 len)
-{
-    return wc_Sha3Update(sha3, data, len, WC_SHA3_256_COUNT);
-}
-
-/* Calculate the SHA3-256 hash based on all the message data seen.
- * The state is initialized ready for a new message to hash.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 32 bytes.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_256_Final(wc_Sha3* sha3, byte* hash)
-{
-    return wc_Sha3Final(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE);
-}
-
-/* Dispose of any dynamically allocated data from the SHA3-256 operation.
- * (Required for async ops.)
- *
- * sha3  wc_Sha3 object holding state.
- * returns 0 on success.
- */
-WOLFSSL_API void wc_Sha3_256_Free(wc_Sha3* sha3)
-{
-    wc_Sha3Free(sha3);
-}
-
-/* Calculate the SHA3-256 hash based on all the message data so far.
- * More message data can be added, after this operation, using the current
- * state.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 32 bytes.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_256_GetHash(wc_Sha3* sha3, byte* hash)
-{
-    return wc_Sha3GetHash(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE);
-}
-
-/* Copy the state of the SHA3-256 operation.
- *
- * src  wc_Sha3 object holding state top copy.
- * dst  wc_Sha3 object to copy into.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_256_Copy(wc_Sha3* src, wc_Sha3* dst)
-{
-    return wc_Sha3Copy(src, dst);
-}
-
-
-/* Initialize the state for a SHA3-384 hash operation.
- *
- * sha3   wc_Sha3 object holding state.
- * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
- * devId  Device identifier for asynchronous operation.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_InitSha3_384(wc_Sha3* sha3, void* heap, int devId)
-{
-    return wc_InitSha3(sha3, heap, devId);
-}
-
-/* Update the SHA3-384 hash state with message data.
- *
- * sha3  wc_Sha3 object holding state.
- * data  Message data to be hashed.
- * len   Length of the message data.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_384_Update(wc_Sha3* sha3, const byte* data, word32 len)
-{
-    return wc_Sha3Update(sha3, data, len, WC_SHA3_384_COUNT);
-}
-
-/* Calculate the SHA3-384 hash based on all the message data seen.
- * The state is initialized ready for a new message to hash.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 48 bytes.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_384_Final(wc_Sha3* sha3, byte* hash)
-{
-    return wc_Sha3Final(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE);
-}
-
-/* Dispose of any dynamically allocated data from the SHA3-384 operation.
- * (Required for async ops.)
- *
- * sha3  wc_Sha3 object holding state.
- * returns 0 on success.
- */
-WOLFSSL_API void wc_Sha3_384_Free(wc_Sha3* sha3)
-{
-    wc_Sha3Free(sha3);
-}
-
-/* Calculate the SHA3-384 hash based on all the message data so far.
- * More message data can be added, after this operation, using the current
- * state.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 48 bytes.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_384_GetHash(wc_Sha3* sha3, byte* hash)
-{
-    return wc_Sha3GetHash(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE);
-}
-
-/* Copy the state of the SHA3-384 operation.
- *
- * src  wc_Sha3 object holding state top copy.
- * dst  wc_Sha3 object to copy into.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_384_Copy(wc_Sha3* src, wc_Sha3* dst)
-{
-    return wc_Sha3Copy(src, dst);
-}
-
-
-/* Initialize the state for a SHA3-512 hash operation.
- *
- * sha3   wc_Sha3 object holding state.
- * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
- * devId  Device identifier for asynchronous operation.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_InitSha3_512(wc_Sha3* sha3, void* heap, int devId)
-{
-    return wc_InitSha3(sha3, heap, devId);
-}
-
-/* Update the SHA3-512 hash state with message data.
- *
- * sha3  wc_Sha3 object holding state.
- * data  Message data to be hashed.
- * len   Length of the message data.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_512_Update(wc_Sha3* sha3, const byte* data, word32 len)
-{
-    return wc_Sha3Update(sha3, data, len, WC_SHA3_512_COUNT);
-}
-
-/* Calculate the SHA3-512 hash based on all the message data seen.
- * The state is initialized ready for a new message to hash.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 64 bytes.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_512_Final(wc_Sha3* sha3, byte* hash)
-{
-    return wc_Sha3Final(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE);
-}
-
-/* Dispose of any dynamically allocated data from the SHA3-512 operation.
- * (Required for async ops.)
- *
- * sha3  wc_Sha3 object holding state.
- * returns 0 on success.
- */
-WOLFSSL_API void wc_Sha3_512_Free(wc_Sha3* sha3)
-{
-    wc_Sha3Free(sha3);
-}
-
-/* Calculate the SHA3-512 hash based on all the message data so far.
- * More message data can be added, after this operation, using the current
- * state.
- *
- * sha3  wc_Sha3 object holding state.
- * hash  Buffer to hold the hash result. Must be at least 64 bytes.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_512_GetHash(wc_Sha3* sha3, byte* hash)
-{
-    return wc_Sha3GetHash(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE);
-}
-
-/* Copy the state of the SHA3-512 operation.
- *
- * src  wc_Sha3 object holding state top copy.
- * dst  wc_Sha3 object to copy into.
- * returns 0 on success.
- */
-WOLFSSL_API int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst)
-{
-    return wc_Sha3Copy(src, dst);
-}
-
-#endif /* WOLFSSL_SHA3 */
-