Xuyi Wang / wolfcrypt

Dependents:   OS

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sha3.c Source File

sha3.c

00001 /* sha3.c
00002  *
00003  * Copyright (C) 2006-2017 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfcrypt/settings.h>
00028 
00029 #if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT)
00030 
00031 #if defined(HAVE_FIPS) && \
00032     defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
00033 
00034     /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
00035     #define FIPS_NO_WRAPPERS
00036 
00037     #ifdef USE_WINDOWS_API
00038         #pragma code_seg(".fipsA$l")
00039         #pragma const_seg(".fipsB$l")
00040     #endif
00041 #endif
00042 
00043 #include <wolfcrypt/sha3.h>
00044 #include <wolfcrypt/error-crypt.h>
00045 
00046 #ifdef NO_INLINE
00047     #include <wolfcrypt/misc.h>
00048 #else
00049     #define WOLFSSL_MISC_INCLUDED
00050     #include <wolfcrypt/src/misc.c>
00051 #endif
00052 
00053 
00054 #ifdef WOLFSSL_SHA3_SMALL
00055 /* Rotate a 64-bit value left.
00056  *
00057  * a  Number to rotate left.
00058  * r  Number od bits to rotate left.
00059  * returns the rotated number.
00060  */
00061 #define ROTL64(a, n)    (((a)<<(n))|((a)>>(64-(n))))
00062 
00063 /* An array of values to XOR for block operation. */
00064 static const word64 hash_keccak_r[24] =
00065 {
00066     0x0000000000000001UL, 0x0000000000008082UL,
00067     0x800000000000808aUL, 0x8000000080008000UL,
00068     0x000000000000808bUL, 0x0000000080000001UL,
00069     0x8000000080008081UL, 0x8000000000008009UL,
00070     0x000000000000008aUL, 0x0000000000000088UL,
00071     0x0000000080008009UL, 0x000000008000000aUL,
00072     0x000000008000808bUL, 0x800000000000008bUL,
00073     0x8000000000008089UL, 0x8000000000008003UL,
00074     0x8000000000008002UL, 0x8000000000000080UL,
00075     0x000000000000800aUL, 0x800000008000000aUL,
00076     0x8000000080008081UL, 0x8000000000008080UL,
00077     0x0000000080000001UL, 0x8000000080008008UL
00078 };
00079 
00080 /* Indeces used in swap and rotate operation. */
00081 #define K_I_0   10
00082 #define K_I_1    7
00083 #define K_I_2   11
00084 #define K_I_3   17
00085 #define K_I_4   18
00086 #define K_I_5    3
00087 #define K_I_6    5
00088 #define K_I_7   16
00089 #define K_I_8    8
00090 #define K_I_9   21
00091 #define K_I_10  24
00092 #define K_I_11   4
00093 #define K_I_12  15
00094 #define K_I_13  23
00095 #define K_I_14  19
00096 #define K_I_15  13
00097 #define K_I_16  12
00098 #define K_I_17   2
00099 #define K_I_18  20
00100 #define K_I_19  14
00101 #define K_I_20  22
00102 #define K_I_21   9
00103 #define K_I_22   6
00104 #define K_I_23   1
00105 
00106 /* Number of bits to rotate in swap and rotate operation. */
00107 #define K_R_0    1
00108 #define K_R_1    3
00109 #define K_R_2    6
00110 #define K_R_3   10
00111 #define K_R_4   15
00112 #define K_R_5   21
00113 #define K_R_6   28
00114 #define K_R_7   36
00115 #define K_R_8   45
00116 #define K_R_9   55
00117 #define K_R_10   2
00118 #define K_R_11  14
00119 #define K_R_12  27
00120 #define K_R_13  41
00121 #define K_R_14  56
00122 #define K_R_15   8
00123 #define K_R_16  25
00124 #define K_R_17  43
00125 #define K_R_18  62
00126 #define K_R_19  18
00127 #define K_R_20  39
00128 #define K_R_21  61
00129 #define K_R_22  20
00130 #define K_R_23  44
00131 
00132 /* Swap and rotate left operation.
00133  *
00134  * s   The state.
00135  * t1  Temporary value.
00136  * t2  Second temporary value.
00137  * i   The index of the loop.
00138  */
00139 #define SWAP_ROTL(s, t1, t2, i)                                         \
00140 do                                                                      \
00141 {                                                                       \
00142     t2 = s[K_I_##i]; s[K_I_##i] = ROTL64(t1, K_R_##i);                  \
00143 }                                                                       \
00144 while (0)
00145 
00146 /* Mix the XOR of the column's values into each number by column.
00147  *
00148  * s  The state.
00149  * b  Temporary array of XORed column values.
00150  * x  The index of the column.
00151  * t  Temporary variable.
00152  */
00153 #define COL_MIX(s, b, x, t)                                             \
00154 do                                                                      \
00155 {                                                                       \
00156     for (x = 0; x < 5; x++)                                             \
00157         b[x] = s[x + 0] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20]; \
00158     for (x = 0; x < 5; x++)                                             \
00159     {                                                                   \
00160         t = b[(x + 4) % 5] ^ ROTL64(b[(x + 1) % 5], 1);                 \
00161         s[x +  0] ^= t;                                                 \
00162         s[x +  5] ^= t;                                                 \
00163         s[x + 10] ^= t;                                                 \
00164         s[x + 15] ^= t;                                                 \
00165         s[x + 20] ^= t;                                                 \
00166     }                                                                   \
00167 }                                                                       \
00168 while (0)
00169 
00170 #ifdef SHA3_BY_SPEC
00171 /* Mix the row values.
00172  * BMI1 has ANDN instruction ((~a) & b) - Haswell and above.
00173  *
00174  * s   The state.
00175  * b   Temporary array of XORed row values.
00176  * y   The index of the row to work on.
00177  * x   The index of the column.
00178  * t0  Temporary variable.
00179  * t1  Temporary variable.
00180  */
00181 #define ROW_MIX(s, b, y, x, t0, t1)                                     \
00182 do                                                                      \
00183 {                                                                       \
00184     for (y = 0; y < 5; y++)                                             \
00185     {                                                                   \
00186         for (x = 0; x < 5; x++)                                         \
00187             b[x] = s[y * 5 + x];                                        \
00188         for (x = 0; x < 5; x++)                                         \
00189            s[y * 5 + x] = b[x] ^ (~b[(x + 1) % 5] & b[(x + 2) % 5]);    \
00190     }                                                                   \
00191 }                                                                       \
00192 while (0)
00193 #else
00194 /* Mix the row values.
00195  * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)
00196  *
00197  * s   The state.
00198  * b   Temporary array of XORed row values.
00199  * y   The index of the row to work on.
00200  * x   The index of the column.
00201  * t0  Temporary variable.
00202  * t1  Temporary variable.
00203  */
00204 #define ROW_MIX(s, b, y, x, t12, t34)                                   \
00205 do                                                                      \
00206 {                                                                       \
00207     for (y = 0; y < 5; y++)                                             \
00208     {                                                                   \
00209         for (x = 0; x < 5; x++)                                         \
00210             b[x] = s[y * 5 + x];                                        \
00211         t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]);                       \
00212         s[y * 5 + 0] = b[0] ^ (b[2] &  t12);                            \
00213         s[y * 5 + 1] =  t12 ^ (b[2] | b[3]);                            \
00214         s[y * 5 + 2] = b[2] ^ (b[4] &  t34);                            \
00215         s[y * 5 + 3] =  t34 ^ (b[4] | b[0]);                            \
00216         s[y * 5 + 4] = b[4] ^ (b[1] & (b[0] ^ b[1]));                   \
00217     }                                                                   \
00218 }                                                                       \
00219 while (0)
00220 #endif /* SHA3_BY_SPEC */
00221 
00222 /* The block operation performed on the state.
00223  *
00224  * s  The state.
00225  */
00226 static void BlockSha3(word64 *s)
00227 {
00228     byte i, x, y;
00229     word64 t0, t1;
00230     word64 b[5];
00231 
00232     for (i = 0; i < 24; i++)
00233     {
00234         COL_MIX(s, b, x, t0);
00235 
00236         t0 = s[1];
00237         SWAP_ROTL(s, t0, t1,  0);
00238         SWAP_ROTL(s, t1, t0,  1);
00239         SWAP_ROTL(s, t0, t1,  2);
00240         SWAP_ROTL(s, t1, t0,  3);
00241         SWAP_ROTL(s, t0, t1,  4);
00242         SWAP_ROTL(s, t1, t0,  5);
00243         SWAP_ROTL(s, t0, t1,  6);
00244         SWAP_ROTL(s, t1, t0,  7);
00245         SWAP_ROTL(s, t0, t1,  8);
00246         SWAP_ROTL(s, t1, t0,  9);
00247         SWAP_ROTL(s, t0, t1, 10);
00248         SWAP_ROTL(s, t1, t0, 11);
00249         SWAP_ROTL(s, t0, t1, 12);
00250         SWAP_ROTL(s, t1, t0, 13);
00251         SWAP_ROTL(s, t0, t1, 14);
00252         SWAP_ROTL(s, t1, t0, 15);
00253         SWAP_ROTL(s, t0, t1, 16);
00254         SWAP_ROTL(s, t1, t0, 17);
00255         SWAP_ROTL(s, t0, t1, 18);
00256         SWAP_ROTL(s, t1, t0, 19);
00257         SWAP_ROTL(s, t0, t1, 20);
00258         SWAP_ROTL(s, t1, t0, 21);
00259         SWAP_ROTL(s, t0, t1, 22);
00260         SWAP_ROTL(s, t1, t0, 23);
00261 
00262         ROW_MIX(s, b, y, x, t0, t1);
00263 
00264         s[0] ^= hash_keccak_r[i];
00265     }
00266 }
00267 #else
00268 /* Rotate a 64-bit value left.
00269  *
00270  * a  Number to rotate left.
00271  * r  Number od bits to rotate left.
00272  * returns the rotated number.
00273  */
00274 #define ROTL64(a, n)    (((a)<<(n))|((a)>>(64-(n))))
00275 
00276 /* An array of values to XOR for block operation. */
00277 static const word64 hash_keccak_r[24] =
00278 {
00279     0x0000000000000001UL, 0x0000000000008082UL,
00280     0x800000000000808aUL, 0x8000000080008000UL,
00281     0x000000000000808bUL, 0x0000000080000001UL,
00282     0x8000000080008081UL, 0x8000000000008009UL,
00283     0x000000000000008aUL, 0x0000000000000088UL,
00284     0x0000000080008009UL, 0x000000008000000aUL,
00285     0x000000008000808bUL, 0x800000000000008bUL,
00286     0x8000000000008089UL, 0x8000000000008003UL,
00287     0x8000000000008002UL, 0x8000000000000080UL,
00288     0x000000000000800aUL, 0x800000008000000aUL,
00289     0x8000000080008081UL, 0x8000000000008080UL,
00290     0x0000000080000001UL, 0x8000000080008008UL
00291 };
00292 
00293 /* Indeces used in swap and rotate operation. */
00294 #define KI_0     6
00295 #define KI_1    12
00296 #define KI_2    18
00297 #define KI_3    24
00298 #define KI_4     3
00299 #define KI_5     9
00300 #define KI_6    10
00301 #define KI_7    16
00302 #define KI_8    22
00303 #define KI_9     1
00304 #define KI_10    7
00305 #define KI_11   13
00306 #define KI_12   19
00307 #define KI_13   20
00308 #define KI_14    4
00309 #define KI_15    5
00310 #define KI_16   11
00311 #define KI_17   17
00312 #define KI_18   23
00313 #define KI_19    2
00314 #define KI_20    8
00315 #define KI_21   14
00316 #define KI_22   15
00317 #define KI_23   21
00318 
00319 /* Number of bits to rotate in swap and rotate operation. */
00320 #define KR_0    44
00321 #define KR_1    43
00322 #define KR_2    21
00323 #define KR_3    14
00324 #define KR_4    28
00325 #define KR_5    20
00326 #define KR_6     3
00327 #define KR_7    45
00328 #define KR_8    61
00329 #define KR_9     1
00330 #define KR_10    6
00331 #define KR_11   25
00332 #define KR_12    8
00333 #define KR_13   18
00334 #define KR_14   27
00335 #define KR_15   36
00336 #define KR_16   10
00337 #define KR_17   15
00338 #define KR_18   56
00339 #define KR_19   62
00340 #define KR_20   55
00341 #define KR_21   39
00342 #define KR_22   41
00343 #define KR_23    2
00344 
00345 /* Mix the XOR of the column's values into each number by column.
00346  *
00347  * s  The state.
00348  * b  Temporary array of XORed column values.
00349  * x  The index of the column.
00350  * t  Temporary variable.
00351  */
00352 #define COL_MIX(s, b, x, t)                                     \
00353 do                                                              \
00354 {                                                               \
00355     b[0] = s[0] ^ s[5] ^ s[10] ^ s[15] ^ s[20];                 \
00356     b[1] = s[1] ^ s[6] ^ s[11] ^ s[16] ^ s[21];                 \
00357     b[2] = s[2] ^ s[7] ^ s[12] ^ s[17] ^ s[22];                 \
00358     b[3] = s[3] ^ s[8] ^ s[13] ^ s[18] ^ s[23];                 \
00359     b[4] = s[4] ^ s[9] ^ s[14] ^ s[19] ^ s[24];                 \
00360     t = b[(0 + 4) % 5] ^ ROTL64(b[(0 + 1) % 5], 1);             \
00361     s[ 0] ^= t; s[ 5] ^= t; s[10] ^= t; s[15] ^= t; s[20] ^= t; \
00362     t = b[(1 + 4) % 5] ^ ROTL64(b[(1 + 1) % 5], 1);             \
00363     s[ 1] ^= t; s[ 6] ^= t; s[11] ^= t; s[16] ^= t; s[21] ^= t; \
00364     t = b[(2 + 4) % 5] ^ ROTL64(b[(2 + 1) % 5], 1);             \
00365     s[ 2] ^= t; s[ 7] ^= t; s[12] ^= t; s[17] ^= t; s[22] ^= t; \
00366     t = b[(3 + 4) % 5] ^ ROTL64(b[(3 + 1) % 5], 1);             \
00367     s[ 3] ^= t; s[ 8] ^= t; s[13] ^= t; s[18] ^= t; s[23] ^= t; \
00368     t = b[(4 + 4) % 5] ^ ROTL64(b[(4 + 1) % 5], 1);             \
00369     s[ 4] ^= t; s[ 9] ^= t; s[14] ^= t; s[19] ^= t; s[24] ^= t; \
00370 }                                                               \
00371 while (0)
00372 
00373 #define S(s1, i) ROTL64(s1[KI_##i], KR_##i)
00374 
00375 #ifdef SHA3_BY_SPEC
00376 /* Mix the row values.
00377  * BMI1 has ANDN instruction ((~a) & b) - Haswell and above.
00378  *
00379  * s2  The new state.
00380  * s1  The current state.
00381  * b   Temporary array of XORed row values.
00382  * t0  Temporary variable. (Unused)
00383  * t1  Temporary variable. (Unused)
00384  */
00385 #define ROW_MIX(s2, s1, b, t0, t1)            \
00386 do                                            \
00387 {                                             \
00388     b[0] = s1[0];                             \
00389     b[1] = S(s1, 0);                          \
00390     b[2] = S(s1, 1);                          \
00391     b[3] = S(s1, 2);                          \
00392     b[4] = S(s1, 3);                          \
00393     s2[0] = b[0] ^ (~b[1] & b[2]);            \
00394     s2[1] = b[1] ^ (~b[2] & b[3]);            \
00395     s2[2] = b[2] ^ (~b[3] & b[4]);            \
00396     s2[3] = b[3] ^ (~b[4] & b[0]);            \
00397     s2[4] = b[4] ^ (~b[0] & b[1]);            \
00398     b[0] = S(s1, 4);                          \
00399     b[1] = S(s1, 5);                          \
00400     b[2] = S(s1, 6);                          \
00401     b[3] = S(s1, 7);                          \
00402     b[4] = S(s1, 8);                          \
00403     s2[5] = b[0] ^ (~b[1] & b[2]);            \
00404     s2[6] = b[1] ^ (~b[2] & b[3]);            \
00405     s2[7] = b[2] ^ (~b[3] & b[4]);            \
00406     s2[8] = b[3] ^ (~b[4] & b[0]);            \
00407     s2[9] = b[4] ^ (~b[0] & b[1]);            \
00408     b[0] = S(s1, 9);                          \
00409     b[1] = S(s1, 10);                         \
00410     b[2] = S(s1, 11);                         \
00411     b[3] = S(s1, 12);                         \
00412     b[4] = S(s1, 13);                         \
00413     s2[10] = b[0] ^ (~b[1] & b[2]);           \
00414     s2[11] = b[1] ^ (~b[2] & b[3]);           \
00415     s2[12] = b[2] ^ (~b[3] & b[4]);           \
00416     s2[13] = b[3] ^ (~b[4] & b[0]);           \
00417     s2[14] = b[4] ^ (~b[0] & b[1]);           \
00418     b[0] = S(s1, 14);                         \
00419     b[1] = S(s1, 15);                         \
00420     b[2] = S(s1, 16);                         \
00421     b[3] = S(s1, 17);                         \
00422     b[4] = S(s1, 18);                         \
00423     s2[15] = b[0] ^ (~b[1] & b[2]);           \
00424     s2[16] = b[1] ^ (~b[2] & b[3]);           \
00425     s2[17] = b[2] ^ (~b[3] & b[4]);           \
00426     s2[18] = b[3] ^ (~b[4] & b[0]);           \
00427     s2[19] = b[4] ^ (~b[0] & b[1]);           \
00428     b[0] = S(s1, 19);                         \
00429     b[1] = S(s1, 20);                         \
00430     b[2] = S(s1, 21);                         \
00431     b[3] = S(s1, 22);                         \
00432     b[4] = S(s1, 23);                         \
00433     s2[20] = b[0] ^ (~b[1] & b[2]);           \
00434     s2[21] = b[1] ^ (~b[2] & b[3]);           \
00435     s2[22] = b[2] ^ (~b[3] & b[4]);           \
00436     s2[23] = b[3] ^ (~b[4] & b[0]);           \
00437     s2[24] = b[4] ^ (~b[0] & b[1]);           \
00438 }                                             \
00439 while (0)
00440 #else
00441 /* Mix the row values.
00442  * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)
00443  *
00444  * s2  The new state.
00445  * s1  The current state.
00446  * b   Temporary array of XORed row values.
00447  * t12 Temporary variable.
00448  * t34 Temporary variable.
00449  */
00450 #define ROW_MIX(s2, s1, b, t12, t34)          \
00451 do                                            \
00452 {                                             \
00453     b[0] = s1[0];                             \
00454     b[1] = S(s1, 0);                          \
00455     b[2] = S(s1, 1);                          \
00456     b[3] = S(s1, 2);                          \
00457     b[4] = S(s1, 3);                          \
00458     t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
00459     s2[0] = b[0] ^ (b[2] &  t12);             \
00460     s2[1] =  t12 ^ (b[2] | b[3]);             \
00461     s2[2] = b[2] ^ (b[4] &  t34);             \
00462     s2[3] =  t34 ^ (b[4] | b[0]);             \
00463     s2[4] = b[4] ^ (b[1] & (b[0] ^ b[1]));    \
00464     b[0] = S(s1, 4);                          \
00465     b[1] = S(s1, 5);                          \
00466     b[2] = S(s1, 6);                          \
00467     b[3] = S(s1, 7);                          \
00468     b[4] = S(s1, 8);                          \
00469     t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
00470     s2[5] = b[0] ^ (b[2] &  t12);             \
00471     s2[6] =  t12 ^ (b[2] | b[3]);             \
00472     s2[7] = b[2] ^ (b[4] &  t34);             \
00473     s2[8] =  t34 ^ (b[4] | b[0]);             \
00474     s2[9] = b[4] ^ (b[1] & (b[0] ^ b[1]));    \
00475     b[0] = S(s1, 9);                          \
00476     b[1] = S(s1, 10);                         \
00477     b[2] = S(s1, 11);                         \
00478     b[3] = S(s1, 12);                         \
00479     b[4] = S(s1, 13);                         \
00480     t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
00481     s2[10] = b[0] ^ (b[2] &  t12);            \
00482     s2[11] =  t12 ^ (b[2] | b[3]);            \
00483     s2[12] = b[2] ^ (b[4] &  t34);            \
00484     s2[13] =  t34 ^ (b[4] | b[0]);            \
00485     s2[14] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \
00486     b[0] = S(s1, 14);                         \
00487     b[1] = S(s1, 15);                         \
00488     b[2] = S(s1, 16);                         \
00489     b[3] = S(s1, 17);                         \
00490     b[4] = S(s1, 18);                         \
00491     t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
00492     s2[15] = b[0] ^ (b[2] &  t12);            \
00493     s2[16] =  t12 ^ (b[2] | b[3]);            \
00494     s2[17] = b[2] ^ (b[4] &  t34);            \
00495     s2[18] =  t34 ^ (b[4] | b[0]);            \
00496     s2[19] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \
00497     b[0] = S(s1, 19);                         \
00498     b[1] = S(s1, 20);                         \
00499     b[2] = S(s1, 21);                         \
00500     b[3] = S(s1, 22);                         \
00501     b[4] = S(s1, 23);                         \
00502     t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]); \
00503     s2[20] = b[0] ^ (b[2] &  t12);            \
00504     s2[21] =  t12 ^ (b[2] | b[3]);            \
00505     s2[22] = b[2] ^ (b[4] &  t34);            \
00506     s2[23] =  t34 ^ (b[4] | b[0]);            \
00507     s2[24] = b[4] ^ (b[1] & (b[0] ^ b[1]));   \
00508 }                                             \
00509 while (0)
00510 #endif /* SHA3_BY_SPEC */
00511 
00512 /* The block operation performed on the state.
00513  *
00514  * s  The state.
00515  */
00516 static void BlockSha3(word64 *s)
00517 {
00518     word64 n[25];
00519     word64 b[5];
00520     word64 t0;
00521 #ifndef SHA3_BY_SPEC
00522     word64 t1;
00523 #endif
00524     byte i;
00525 
00526     for (i = 0; i < 24; i += 2)
00527     {
00528         COL_MIX(s, b, x, t0);
00529         ROW_MIX(n, s, b, t0, t1);
00530         n[0] ^= hash_keccak_r[i];
00531 
00532         COL_MIX(n, b, x, t0);
00533         ROW_MIX(s, n, b, t0, t1);
00534         s[0] ^= hash_keccak_r[i+1];
00535     }
00536 }
00537 #endif /* WOLFSSL_SHA3_SMALL */
00538 
00539 /* Convert the array of bytes, in little-endian order, to a 64-bit integer.
00540  *
00541  * a  Array of bytes.
00542  * returns a 64-bit integer.
00543  */
00544 static word64 Load64BitBigEndian(const byte* a)
00545 {
00546 #ifdef BIG_ENDIAN_ORDER
00547     word64 n = 0;
00548     int i;
00549 
00550     for (i = 0; i < 8; i++)
00551         n |= (word64)a[i] << (8 * i);
00552 
00553     return n;
00554 #else
00555     return *(word64*)a;
00556 #endif
00557 }
00558 
00559 /* Initialize the state for a SHA3-224 hash operation.
00560  *
00561  * sha3   wc_Sha3 object holding state.
00562  * returns 0 on success.
00563  */
00564 static int InitSha3(wc_Sha3* sha3)
00565 {
00566     int i;
00567 
00568     for (i = 0; i < 25; i++)
00569         sha3->s[i] = 0;
00570     sha3->i = 0;
00571 
00572     return 0;
00573 }
00574 
00575 /* Update the SHA-3 hash state with message data.
00576  *
00577  * sha3  wc_Sha3 object holding state.
00578  * data  Message data to be hashed.
00579  * len   Length of the message data.
00580  * p     Number of 64-bit numbers in a block of data to process.
00581  * returns 0 on success.
00582  */
00583 static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
00584 {
00585     byte i;
00586     byte l;
00587     byte *t;
00588 
00589     if (sha3->i > 0)
00590     {
00591         l = p * 8 - sha3->i;
00592         if (l > len) {
00593             l = (byte)len;
00594         }
00595 
00596         t = &sha3->t[sha3->i];
00597         for (i = 0; i < l; i++)
00598             t[i] = data[i];
00599         data += i;
00600         len -= i;
00601         sha3->i += i;
00602 
00603         if (sha3->i == p * 8)
00604         {
00605             for (i = 0; i < p; i++)
00606                 sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
00607             BlockSha3(sha3->s);
00608             sha3->i = 0;
00609         }
00610     }
00611     while (len >= ((word32)(p * 8)))
00612     {
00613         for (i = 0; i < p; i++)
00614             sha3->s[i] ^= Load64BitBigEndian(data + 8 * i);
00615         BlockSha3(sha3->s);
00616         len -= p * 8;
00617         data += p * 8;
00618     }
00619     for (i = 0; i < len; i++)
00620         sha3->t[i] = data[i];
00621     sha3->i += i;
00622 
00623     return 0;
00624 }
00625 
00626 /* Calculate the SHA-3 hash based on all the message data seen.
00627  *
00628  * sha3  wc_Sha3 object holding state.
00629  * hash  Buffer to hold the hash result.
00630  * p     Number of 64-bit numbers in a block of data to process.
00631  * len   Number of bytes in output.
00632  * returns 0 on success.
00633  */
00634 static int Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte l)
00635 {
00636     byte i;
00637     byte *s8 = (byte *)sha3->s;
00638 
00639     sha3->t[p * 8 - 1]  = 0x00;
00640     sha3->t[  sha3->i]  = 0x06;
00641     sha3->t[p * 8 - 1] |= 0x80;
00642     for (i=sha3->i + 1; i < p * 8 - 1; i++)
00643         sha3->t[i] = 0;
00644     for (i = 0; i < p; i++)
00645         sha3->s[i] ^= Load64BitBigEndian(sha3->t + 8 * i);
00646     BlockSha3(sha3->s);
00647 #if defined(BIG_ENDIAN_ORDER)
00648     ByteReverseWords64(sha3->s, sha3->s, ((l+7)/8)*8);
00649 #endif
00650     for (i = 0; i < l; i++)
00651         hash[i] = s8[i];
00652 
00653     return 0;
00654 }
00655 
00656 /* Initialize the state for a SHA-3 hash operation.
00657  *
00658  * sha3   wc_Sha3 object holding state.
00659  * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
00660  * devId  Device identifier for asynchronous operation.
00661  * returns 0 on success.
00662  */
00663 static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)
00664 {
00665     int ret = 0;
00666 
00667     if (sha3 == NULL)
00668         return BAD_FUNC_ARG;
00669 
00670     sha3->heap = heap;
00671     ret = InitSha3(sha3);
00672     if (ret != 0)
00673         return ret;
00674 
00675 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
00676     ret = wolfAsync_DevCtxInit(&sha3->asyncDev,
00677                         WOLFSSL_ASYNC_MARKER_SHA3, sha3->heap, devId);
00678 #else
00679     (void)devId;
00680 #endif /* WOLFSSL_ASYNC_CRYPT */
00681 
00682     return ret;
00683 }
00684 
00685 /* Update the SHA-3 hash state with message data.
00686  *
00687  * sha3  wc_Sha3 object holding state.
00688  * data  Message data to be hashed.
00689  * len   Length of the message data.
00690  * p     Number of 64-bit numbers in a block of data to process.
00691  * returns 0 on success.
00692  */
00693 static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
00694 {
00695     int ret = 0;
00696 
00697     if (sha3 == NULL || (data == NULL && len > 0)) {
00698         return BAD_FUNC_ARG;
00699     }
00700 
00701 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
00702     if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {
00703     #if defined(HAVE_INTEL_QA)
00704         return IntelQaSymSha3(&sha3->asyncDev, NULL, data, len);
00705     #endif
00706     }
00707 #endif /* WOLFSSL_ASYNC_CRYPT */
00708 
00709     Sha3Update(sha3, data, len, p);
00710 
00711     return ret;
00712 }
00713 
00714 /* Calculate the SHA-3 hash based on all the message data seen.
00715  *
00716  * sha3  wc_Sha3 object holding state.
00717  * hash  Buffer to hold the hash result.
00718  * p     Number of 64-bit numbers in a block of data to process.
00719  * len   Number of bytes in output.
00720  * returns 0 on success.
00721  */
00722 static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)
00723 {
00724     int ret;
00725 
00726     if (sha3 == NULL || hash == NULL) {
00727         return BAD_FUNC_ARG;
00728     }
00729 
00730 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
00731     if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {
00732     #if defined(HAVE_INTEL_QA)
00733         return IntelQaSymSha3(&sha3->asyncDev, hash, NULL,
00734                               SHA3_DIGEST_SIZE);
00735     #endif
00736     }
00737 #endif /* WOLFSSL_ASYNC_CRYPT */
00738 
00739     ret = Sha3Final(sha3, hash, p, len);
00740     if (ret != 0)
00741         return ret;
00742 
00743     return InitSha3(sha3);  /* reset state */
00744 }
00745 
00746 /* Dispose of any dynamically allocated data from the SHA3-384 operation.
00747  * (Required for async ops.)
00748  *
00749  * sha3  wc_Sha3 object holding state.
00750  * returns 0 on success.
00751  */
00752 static void wc_Sha3Free(wc_Sha3* sha3)
00753 {
00754     (void)sha3;
00755 
00756 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
00757     if (sha3 == NULL)
00758         return;
00759 
00760     wolfAsync_DevCtxFree(&sha3->asyncDev, WOLFSSL_ASYNC_MARKER_SHA3);
00761 #endif /* WOLFSSL_ASYNC_CRYPT */
00762 }
00763 
00764 
00765 /* Copy the state of the SHA3 operation.
00766  *
00767  * src  wc_Sha3 object holding state top copy.
00768  * dst  wc_Sha3 object to copy into.
00769  * returns 0 on success.
00770  */
00771 static int wc_Sha3Copy(wc_Sha3* src, wc_Sha3* dst)
00772 {
00773     int ret = 0;
00774 
00775     if (src == NULL || dst == NULL)
00776         return BAD_FUNC_ARG;
00777 
00778     XMEMCPY(dst, src, sizeof(wc_Sha3));
00779 
00780 #ifdef WOLFSSL_ASYNC_CRYPT
00781     ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
00782 #endif
00783 
00784     return ret;
00785 }
00786 
00787 /* Calculate the SHA3-224 hash based on all the message data so far.
00788  * More message data can be added, after this operation, using the current
00789  * state.
00790  *
00791  * sha3  wc_Sha3 object holding state.
00792  * hash  Buffer to hold the hash result. Must be at least 28 bytes.
00793  * p     Number of 64-bit numbers in a block of data to process.
00794  * len   Number of bytes in output.
00795  * returns 0 on success.
00796  */
00797 static int wc_Sha3GetHash(wc_Sha3* sha3, byte* hash, byte p, byte len)
00798 {
00799     int ret;
00800     wc_Sha3 tmpSha3;
00801 
00802     if (sha3 == NULL || hash == NULL)
00803         return BAD_FUNC_ARG;
00804 
00805     ret = wc_Sha3Copy(sha3, &tmpSha3);
00806     if (ret == 0) {
00807         ret = wc_Sha3Final(&tmpSha3, hash, p, len);
00808     }
00809     return ret;
00810 }
00811 
00812 
00813 /* Initialize the state for a SHA3-224 hash operation.
00814  *
00815  * sha3   wc_Sha3 object holding state.
00816  * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
00817  * devId  Device identifier for asynchronous operation.
00818  * returns 0 on success.
00819  */
00820 WOLFSSL_API int wc_InitSha3_224(wc_Sha3* sha3, void* heap, int devId)
00821 {
00822     return wc_InitSha3(sha3, heap, devId);
00823 }
00824 
00825 /* Update the SHA3-224 hash state with message data.
00826  *
00827  * sha3  wc_Sha3 object holding state.
00828  * data  Message data to be hashed.
00829  * len   Length of the message data.
00830  * returns 0 on success.
00831  */
00832 WOLFSSL_API int wc_Sha3_224_Update(wc_Sha3* sha3, const byte* data, word32 len)
00833 {
00834     return wc_Sha3Update(sha3, data, len, WC_SHA3_224_COUNT);
00835 }
00836 
00837 /* Calculate the SHA3-224 hash based on all the message data seen.
00838  * The state is initialized ready for a new message to hash.
00839  *
00840  * sha3  wc_Sha3 object holding state.
00841  * hash  Buffer to hold the hash result. Must be at least 28 bytes.
00842  * returns 0 on success.
00843  */
00844 WOLFSSL_API int wc_Sha3_224_Final(wc_Sha3* sha3, byte* hash)
00845 {
00846     return wc_Sha3Final(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE);
00847 }
00848 
00849 /* Dispose of any dynamically allocated data from the SHA3-224 operation.
00850  * (Required for async ops.)
00851  *
00852  * sha3  wc_Sha3 object holding state.
00853  * returns 0 on success.
00854  */
00855 WOLFSSL_API void wc_Sha3_224_Free(wc_Sha3* sha3)
00856 {
00857     wc_Sha3Free(sha3);
00858 }
00859 
00860 /* Calculate the SHA3-224 hash based on all the message data so far.
00861  * More message data can be added, after this operation, using the current
00862  * state.
00863  *
00864  * sha3  wc_Sha3 object holding state.
00865  * hash  Buffer to hold the hash result. Must be at least 28 bytes.
00866  * returns 0 on success.
00867  */
00868 WOLFSSL_API int wc_Sha3_224_GetHash(wc_Sha3* sha3, byte* hash)
00869 {
00870     return wc_Sha3GetHash(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE);
00871 }
00872 
00873 /* Copy the state of the SHA3-224 operation.
00874  *
00875  * src  wc_Sha3 object holding state top copy.
00876  * dst  wc_Sha3 object to copy into.
00877  * returns 0 on success.
00878  */
00879 WOLFSSL_API int wc_Sha3_224_Copy(wc_Sha3* src, wc_Sha3* dst)
00880 {
00881     return wc_Sha3Copy(src, dst);
00882 }
00883 
00884 
00885 /* Initialize the state for a SHA3-256 hash operation.
00886  *
00887  * sha3   wc_Sha3 object holding state.
00888  * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
00889  * devId  Device identifier for asynchronous operation.
00890  * returns 0 on success.
00891  */
00892 WOLFSSL_API int wc_InitSha3_256(wc_Sha3* sha3, void* heap, int devId)
00893 {
00894     return wc_InitSha3(sha3, heap, devId);
00895 }
00896 
00897 /* Update the SHA3-256 hash state with message data.
00898  *
00899  * sha3  wc_Sha3 object holding state.
00900  * data  Message data to be hashed.
00901  * len   Length of the message data.
00902  * returns 0 on success.
00903  */
00904 WOLFSSL_API int wc_Sha3_256_Update(wc_Sha3* sha3, const byte* data, word32 len)
00905 {
00906     return wc_Sha3Update(sha3, data, len, WC_SHA3_256_COUNT);
00907 }
00908 
00909 /* Calculate the SHA3-256 hash based on all the message data seen.
00910  * The state is initialized ready for a new message to hash.
00911  *
00912  * sha3  wc_Sha3 object holding state.
00913  * hash  Buffer to hold the hash result. Must be at least 32 bytes.
00914  * returns 0 on success.
00915  */
00916 WOLFSSL_API int wc_Sha3_256_Final(wc_Sha3* sha3, byte* hash)
00917 {
00918     return wc_Sha3Final(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE);
00919 }
00920 
00921 /* Dispose of any dynamically allocated data from the SHA3-256 operation.
00922  * (Required for async ops.)
00923  *
00924  * sha3  wc_Sha3 object holding state.
00925  * returns 0 on success.
00926  */
00927 WOLFSSL_API void wc_Sha3_256_Free(wc_Sha3* sha3)
00928 {
00929     wc_Sha3Free(sha3);
00930 }
00931 
00932 /* Calculate the SHA3-256 hash based on all the message data so far.
00933  * More message data can be added, after this operation, using the current
00934  * state.
00935  *
00936  * sha3  wc_Sha3 object holding state.
00937  * hash  Buffer to hold the hash result. Must be at least 32 bytes.
00938  * returns 0 on success.
00939  */
00940 WOLFSSL_API int wc_Sha3_256_GetHash(wc_Sha3* sha3, byte* hash)
00941 {
00942     return wc_Sha3GetHash(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE);
00943 }
00944 
00945 /* Copy the state of the SHA3-256 operation.
00946  *
00947  * src  wc_Sha3 object holding state top copy.
00948  * dst  wc_Sha3 object to copy into.
00949  * returns 0 on success.
00950  */
00951 WOLFSSL_API int wc_Sha3_256_Copy(wc_Sha3* src, wc_Sha3* dst)
00952 {
00953     return wc_Sha3Copy(src, dst);
00954 }
00955 
00956 
00957 /* Initialize the state for a SHA3-384 hash operation.
00958  *
00959  * sha3   wc_Sha3 object holding state.
00960  * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
00961  * devId  Device identifier for asynchronous operation.
00962  * returns 0 on success.
00963  */
00964 WOLFSSL_API int wc_InitSha3_384(wc_Sha3* sha3, void* heap, int devId)
00965 {
00966     return wc_InitSha3(sha3, heap, devId);
00967 }
00968 
00969 /* Update the SHA3-384 hash state with message data.
00970  *
00971  * sha3  wc_Sha3 object holding state.
00972  * data  Message data to be hashed.
00973  * len   Length of the message data.
00974  * returns 0 on success.
00975  */
00976 WOLFSSL_API int wc_Sha3_384_Update(wc_Sha3* sha3, const byte* data, word32 len)
00977 {
00978     return wc_Sha3Update(sha3, data, len, WC_SHA3_384_COUNT);
00979 }
00980 
00981 /* Calculate the SHA3-384 hash based on all the message data seen.
00982  * The state is initialized ready for a new message to hash.
00983  *
00984  * sha3  wc_Sha3 object holding state.
00985  * hash  Buffer to hold the hash result. Must be at least 48 bytes.
00986  * returns 0 on success.
00987  */
00988 WOLFSSL_API int wc_Sha3_384_Final(wc_Sha3* sha3, byte* hash)
00989 {
00990     return wc_Sha3Final(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE);
00991 }
00992 
00993 /* Dispose of any dynamically allocated data from the SHA3-384 operation.
00994  * (Required for async ops.)
00995  *
00996  * sha3  wc_Sha3 object holding state.
00997  * returns 0 on success.
00998  */
00999 WOLFSSL_API void wc_Sha3_384_Free(wc_Sha3* sha3)
01000 {
01001     wc_Sha3Free(sha3);
01002 }
01003 
01004 /* Calculate the SHA3-384 hash based on all the message data so far.
01005  * More message data can be added, after this operation, using the current
01006  * state.
01007  *
01008  * sha3  wc_Sha3 object holding state.
01009  * hash  Buffer to hold the hash result. Must be at least 48 bytes.
01010  * returns 0 on success.
01011  */
01012 WOLFSSL_API int wc_Sha3_384_GetHash(wc_Sha3* sha3, byte* hash)
01013 {
01014     return wc_Sha3GetHash(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE);
01015 }
01016 
01017 /* Copy the state of the SHA3-384 operation.
01018  *
01019  * src  wc_Sha3 object holding state top copy.
01020  * dst  wc_Sha3 object to copy into.
01021  * returns 0 on success.
01022  */
01023 WOLFSSL_API int wc_Sha3_384_Copy(wc_Sha3* src, wc_Sha3* dst)
01024 {
01025     return wc_Sha3Copy(src, dst);
01026 }
01027 
01028 
01029 /* Initialize the state for a SHA3-512 hash operation.
01030  *
01031  * sha3   wc_Sha3 object holding state.
01032  * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
01033  * devId  Device identifier for asynchronous operation.
01034  * returns 0 on success.
01035  */
01036 WOLFSSL_API int wc_InitSha3_512(wc_Sha3* sha3, void* heap, int devId)
01037 {
01038     return wc_InitSha3(sha3, heap, devId);
01039 }
01040 
01041 /* Update the SHA3-512 hash state with message data.
01042  *
01043  * sha3  wc_Sha3 object holding state.
01044  * data  Message data to be hashed.
01045  * len   Length of the message data.
01046  * returns 0 on success.
01047  */
01048 WOLFSSL_API int wc_Sha3_512_Update(wc_Sha3* sha3, const byte* data, word32 len)
01049 {
01050     return wc_Sha3Update(sha3, data, len, WC_SHA3_512_COUNT);
01051 }
01052 
01053 /* Calculate the SHA3-512 hash based on all the message data seen.
01054  * The state is initialized ready for a new message to hash.
01055  *
01056  * sha3  wc_Sha3 object holding state.
01057  * hash  Buffer to hold the hash result. Must be at least 64 bytes.
01058  * returns 0 on success.
01059  */
01060 WOLFSSL_API int wc_Sha3_512_Final(wc_Sha3* sha3, byte* hash)
01061 {
01062     return wc_Sha3Final(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE);
01063 }
01064 
01065 /* Dispose of any dynamically allocated data from the SHA3-512 operation.
01066  * (Required for async ops.)
01067  *
01068  * sha3  wc_Sha3 object holding state.
01069  * returns 0 on success.
01070  */
01071 WOLFSSL_API void wc_Sha3_512_Free(wc_Sha3* sha3)
01072 {
01073     wc_Sha3Free(sha3);
01074 }
01075 
01076 /* Calculate the SHA3-512 hash based on all the message data so far.
01077  * More message data can be added, after this operation, using the current
01078  * state.
01079  *
01080  * sha3  wc_Sha3 object holding state.
01081  * hash  Buffer to hold the hash result. Must be at least 64 bytes.
01082  * returns 0 on success.
01083  */
01084 WOLFSSL_API int wc_Sha3_512_GetHash(wc_Sha3* sha3, byte* hash)
01085 {
01086     return wc_Sha3GetHash(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE);
01087 }
01088 
01089 /* Copy the state of the SHA3-512 operation.
01090  *
01091  * src  wc_Sha3 object holding state top copy.
01092  * dst  wc_Sha3 object to copy into.
01093  * returns 0 on success.
01094  */
01095 WOLFSSL_API int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst)
01096 {
01097     return wc_Sha3Copy(src, dst);
01098 }
01099 
01100 #endif /* WOLFSSL_SHA3 */
01101