Coverage Report

Created: 2026-04-05 07:22

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-fastmath/wolfcrypt/src/sha3.c
Line
Count
Source
1
/* sha3.c
2
 *
3
 * Copyright (C) 2006-2026 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
/*
23
 * SHA-3 Build Options:
24
 *
25
 * Core:
26
 * WOLFSSL_SHA3:             Enable SHA-3 support                  default: off
27
 * WOLFSSL_SHA3_SMALL:       Use smaller SHA-3 implementation      default: off
28
 * WOLFSSL_SHAKE128:         Enable SHAKE128 XOF                   default: off
29
 * WOLFSSL_SHAKE256:         Enable SHAKE256 XOF                   default: off
30
 * SHA3_BY_SPEC:             Use specification Keccak-f order      default: off
31
 * WC_SHA3_NO_ASM:           Disable SHA-3 assembly optimizations  default: off
32
 * WC_SHA3_FAULT_HARDEN:     Harden SHA-3 against fault attacks    default: off
33
 *
34
 * Hardware Acceleration (SHA-3-specific):
35
 * WC_ASYNC_ENABLE_SHA3:     Enable async SHA-3 operations         default: off
36
 * WOLFSSL_ARMASM_CRYPTO_SHA3: ARM crypto SHA-3 instructions       default: off
37
 * STM32_HASH_SHA3:          STM32 hardware SHA-3                  default: off
38
 * PSOC6_HASH_SHA3:          PSoC6 hardware SHA-3                  default: off
39
 */
40
41
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
42
43
#ifdef WC_SHA3_NO_ASM
44
    #undef USE_INTEL_SPEEDUP
45
    #undef WOLFSSL_ARMASM
46
    #undef WOLFSSL_RISCV_ASM
47
#endif
48
49
#if defined(WOLFSSL_PSOC6_CRYPTO)
50
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
51
#endif
52
53
#if defined(WOLFSSL_SHA3) && !defined(WOLFSSL_XILINX_CRYPT) && \
54
   !defined(WOLFSSL_AFALG_XILINX_SHA3)
55
56
#if FIPS_VERSION3_GE(2,0,0)
57
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
58
    #define FIPS_NO_WRAPPERS
59
60
    #ifdef USE_WINDOWS_API
61
        #pragma code_seg(".fipsA$n")
62
        #pragma const_seg(".fipsB$n")
63
    #endif
64
#endif
65
66
#include <wolfssl/wolfcrypt/sha3.h>
67
#include <wolfssl/wolfcrypt/hash.h>
68
69
#ifdef WOLF_CRYPTO_CB
70
    #include <wolfssl/wolfcrypt/cryptocb.h>
71
#endif
72
#ifdef NO_INLINE
73
    #include <wolfssl/wolfcrypt/misc.h>
74
#else
75
    #define WOLFSSL_MISC_INCLUDED
76
    #include <wolfcrypt/src/misc.c>
77
#endif
78
79
#if FIPS_VERSION3_GE(6,0,0)
80
    const unsigned int wolfCrypt_FIPS_sha3_ro_sanity[2] =
81
                                                     { 0x1a2b3c4d, 0x00000016 };
82
    int wolfCrypt_FIPS_SHA3_sanity(void)
83
    {
84
        return 0;
85
    }
86
#endif
87
88
89
#if defined(USE_INTEL_SPEEDUP) || (defined(__aarch64__) && \
90
        defined(WOLFSSL_ARMASM))
91
    #include <wolfssl/wolfcrypt/cpuid.h>
92
93
    static cpuid_flags_t cpuid_flags = WC_CPUID_INITIALIZER;
94
#ifdef WC_C_DYNAMIC_FALLBACK
95
    #define SHA3_BLOCK (sha3->sha3_block)
96
    #define SHA3_BLOCK_N (sha3->sha3_block_n)
97
#else
98
    void (*sha3_block)(word64 *s) = NULL;
99
    void (*sha3_block_n)(word64 *s, const byte* data, word32 n,
100
        word64 c) = NULL;
101
    #define SHA3_BLOCK sha3_block
102
    #define SHA3_BLOCK_N sha3_block_n
103
#endif
104
#endif
105
106
#if !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_RISCV_ASM)
107
108
#ifdef WOLFSSL_SHA3_SMALL
109
/* Rotate a 64-bit value left.
110
 *
111
 * a  Number to rotate left.
112
 * r  Number od bits to rotate left.
113
 * returns the rotated number.
114
 */
115
#define ROTL64(a, n)    (((a)<<(n))|((a)>>(64-(n))))
116
117
/* An array of values to XOR for block operation. */
118
static const word64 hash_keccak_r[24] =
119
{
120
    0x0000000000000001UL, 0x0000000000008082UL,
121
    0x800000000000808aUL, 0x8000000080008000UL,
122
    0x000000000000808bUL, 0x0000000080000001UL,
123
    0x8000000080008081UL, 0x8000000000008009UL,
124
    0x000000000000008aUL, 0x0000000000000088UL,
125
    0x0000000080008009UL, 0x000000008000000aUL,
126
    0x000000008000808bUL, 0x800000000000008bUL,
127
    0x8000000000008089UL, 0x8000000000008003UL,
128
    0x8000000000008002UL, 0x8000000000000080UL,
129
    0x000000000000800aUL, 0x800000008000000aUL,
130
    0x8000000080008081UL, 0x8000000000008080UL,
131
    0x0000000080000001UL, 0x8000000080008008UL
132
};
133
134
/* Indices used in swap and rotate operation. */
135
#define K_I_0   10
136
#define K_I_1    7
137
#define K_I_2   11
138
#define K_I_3   17
139
#define K_I_4   18
140
#define K_I_5    3
141
#define K_I_6    5
142
#define K_I_7   16
143
#define K_I_8    8
144
#define K_I_9   21
145
#define K_I_10  24
146
#define K_I_11   4
147
#define K_I_12  15
148
#define K_I_13  23
149
#define K_I_14  19
150
#define K_I_15  13
151
#define K_I_16  12
152
#define K_I_17   2
153
#define K_I_18  20
154
#define K_I_19  14
155
#define K_I_20  22
156
#define K_I_21   9
157
#define K_I_22   6
158
#define K_I_23   1
159
160
/* Number of bits to rotate in swap and rotate operation. */
161
#define K_R_0    1
162
#define K_R_1    3
163
#define K_R_2    6
164
#define K_R_3   10
165
#define K_R_4   15
166
#define K_R_5   21
167
#define K_R_6   28
168
#define K_R_7   36
169
#define K_R_8   45
170
#define K_R_9   55
171
#define K_R_10   2
172
#define K_R_11  14
173
#define K_R_12  27
174
#define K_R_13  41
175
#define K_R_14  56
176
#define K_R_15   8
177
#define K_R_16  25
178
#define K_R_17  43
179
#define K_R_18  62
180
#define K_R_19  18
181
#define K_R_20  39
182
#define K_R_21  61
183
#define K_R_22  20
184
#define K_R_23  44
185
186
/* Swap and rotate left operation.
187
 *
188
 * s   The state.
189
 * t1  Temporary value.
190
 * t2  Second temporary value.
191
 * i   The index of the loop.
192
 */
193
#define SWAP_ROTL(s, t1, t2, i)                                         \
194
do {                                                                    \
195
    t2 = s[K_I_##i]; s[K_I_##i] = ROTL64(t1, K_R_##i);                  \
196
}                                                                       \
197
while (0)
198
199
/* Mix the XOR of the column's values into each number by column.
200
 *
201
 * s  The state.
202
 * b  Temporary array of XORed column values.
203
 * x  The index of the column.
204
 * t  Temporary variable.
205
 */
206
#define COL_MIX(s, b, x, t)                                             \
207
do {                                                                    \
208
    for (x = 0; x < 5; x++)                                             \
209
        b[x] = s[x + 0] ^ s[x + 5] ^ s[x + 10] ^ s[x + 15] ^ s[x + 20]; \
210
    for (x = 0; x < 5; x++) {                                           \
211
        t = b[(x + 4) % 5] ^ ROTL64(b[(x + 1) % 5], 1);                 \
212
        s[x +  0] ^= t;                                                 \
213
        s[x +  5] ^= t;                                                 \
214
        s[x + 10] ^= t;                                                 \
215
        s[x + 15] ^= t;                                                 \
216
        s[x + 20] ^= t;                                                 \
217
    }                                                                   \
218
}                                                                       \
219
while (0)
220
221
#ifdef SHA3_BY_SPEC
222
/* Mix the row values.
223
 * BMI1 has ANDN instruction ((~a) & b) - Haswell and above.
224
 *
225
 * s   The state.
226
 * b   Temporary array of XORed row values.
227
 * y   The index of the row to work on.
228
 * x   The index of the column.
229
 * t0  Temporary variable.
230
 * t1  Temporary variable.
231
 */
232
#define ROW_MIX(s, b, y, x, t0, t1)                                     \
233
do {                                                                    \
234
    for (y = 0; y < 5; y++) {                                           \
235
        for (x = 0; x < 5; x++)                                         \
236
            b[x] = s[y * 5 + x];                                        \
237
        for (x = 0; x < 5; x++)                                         \
238
            s[y * 5 + x] = b[x] ^ (~b[(x + 1) % 5] & b[(x + 2) % 5]);   \
239
    }                                                                   \
240
}                                                                       \
241
while (0)
242
#else
243
/* Mix the row values.
244
 * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)
245
 *
246
 * s   The state.
247
 * b   Temporary array of XORed row values.
248
 * y   The index of the row to work on.
249
 * x   The index of the column.
250
 * t0  Temporary variable.
251
 * t1  Temporary variable.
252
 */
253
#define ROW_MIX(s, b, y, x, t12, t34)                                   \
254
do {                                                                    \
255
    for (y = 0; y < 5; y++) {                                           \
256
        for (x = 0; x < 5; x++)                                         \
257
            b[x] = s[y * 5 + x];                                        \
258
        t12 = (b[1] ^ b[2]); t34 = (b[3] ^ b[4]);                       \
259
        s[y * 5 + 0] = b[0] ^ (b[2] &  t12);                            \
260
        s[y * 5 + 1] =  t12 ^ (b[2] | b[3]);                            \
261
        s[y * 5 + 2] = b[2] ^ (b[4] &  t34);                            \
262
        s[y * 5 + 3] =  t34 ^ (b[4] | b[0]);                            \
263
        s[y * 5 + 4] = b[4] ^ (b[1] & (b[0] ^ b[1]));                   \
264
    }                                                                   \
265
}                                                                       \
266
while (0)
267
#endif /* SHA3_BY_SPEC */
268
269
/* The block operation performed on the state.
270
 *
271
 * s  The state.
272
 */
273
void BlockSha3(word64* s)
274
{
275
    byte i, x, y;
276
    word64 t0, t1;
277
    word64 b[5];
278
279
    for (i = 0; i < 24; i++)
280
    {
281
        COL_MIX(s, b, x, t0);
282
283
        t0 = s[1];
284
        SWAP_ROTL(s, t0, t1,  0);
285
        SWAP_ROTL(s, t1, t0,  1);
286
        SWAP_ROTL(s, t0, t1,  2);
287
        SWAP_ROTL(s, t1, t0,  3);
288
        SWAP_ROTL(s, t0, t1,  4);
289
        SWAP_ROTL(s, t1, t0,  5);
290
        SWAP_ROTL(s, t0, t1,  6);
291
        SWAP_ROTL(s, t1, t0,  7);
292
        SWAP_ROTL(s, t0, t1,  8);
293
        SWAP_ROTL(s, t1, t0,  9);
294
        SWAP_ROTL(s, t0, t1, 10);
295
        SWAP_ROTL(s, t1, t0, 11);
296
        SWAP_ROTL(s, t0, t1, 12);
297
        SWAP_ROTL(s, t1, t0, 13);
298
        SWAP_ROTL(s, t0, t1, 14);
299
        SWAP_ROTL(s, t1, t0, 15);
300
        SWAP_ROTL(s, t0, t1, 16);
301
        SWAP_ROTL(s, t1, t0, 17);
302
        SWAP_ROTL(s, t0, t1, 18);
303
        SWAP_ROTL(s, t1, t0, 19);
304
        SWAP_ROTL(s, t0, t1, 20);
305
        SWAP_ROTL(s, t1, t0, 21);
306
        SWAP_ROTL(s, t0, t1, 22);
307
        SWAP_ROTL(s, t1, t0, 23);
308
309
        ROW_MIX(s, b, y, x, t0, t1);
310
311
        s[0] ^= hash_keccak_r[i];
312
    }
313
}
314
#else
315
/* Rotate a 64-bit value left.
316
 *
317
 * a  Number to rotate left.
318
 * r  Number od bits to rotate left.
319
 * returns the rotated number.
320
 */
321
122M
#define ROTL64(a, n)    (((a)<<(n))|((a)>>(64-(n))))
322
323
#if !defined(STM32_HASH_SHA3) && !defined(PSOC6_HASH_SHA3)
324
/* An array of values to XOR for block operation. */
325
static const word64 hash_keccak_r[24] =
326
{
327
    W64LIT(0x0000000000000001), W64LIT(0x0000000000008082),
328
    W64LIT(0x800000000000808a), W64LIT(0x8000000080008000),
329
    W64LIT(0x000000000000808b), W64LIT(0x0000000080000001),
330
    W64LIT(0x8000000080008081), W64LIT(0x8000000000008009),
331
    W64LIT(0x000000000000008a), W64LIT(0x0000000000000088),
332
    W64LIT(0x0000000080008009), W64LIT(0x000000008000000a),
333
    W64LIT(0x000000008000808b), W64LIT(0x800000000000008b),
334
    W64LIT(0x8000000000008089), W64LIT(0x8000000000008003),
335
    W64LIT(0x8000000000008002), W64LIT(0x8000000000000080),
336
    W64LIT(0x000000000000800a), W64LIT(0x800000008000000a),
337
    W64LIT(0x8000000080008081), W64LIT(0x8000000000008080),
338
    W64LIT(0x0000000080000001), W64LIT(0x8000000080008008)
339
};
340
#endif
341
342
/* Indices used in swap and rotate operation. */
343
#define KI_0     6
344
#define KI_1    12
345
#define KI_2    18
346
#define KI_3    24
347
#define KI_4     3
348
#define KI_5     9
349
#define KI_6    10
350
#define KI_7    16
351
#define KI_8    22
352
#define KI_9     1
353
#define KI_10    7
354
#define KI_11   13
355
#define KI_12   19
356
#define KI_13   20
357
#define KI_14    4
358
#define KI_15    5
359
#define KI_16   11
360
#define KI_17   17
361
#define KI_18   23
362
#define KI_19    2
363
#define KI_20    8
364
#define KI_21   14
365
#define KI_22   15
366
#define KI_23   21
367
368
/* Number of bits to rotate in swap and rotate operation. */
369
#define KR_0    44
370
#define KR_1    43
371
#define KR_2    21
372
#define KR_3    14
373
#define KR_4    28
374
#define KR_5    20
375
#define KR_6     3
376
#define KR_7    45
377
#define KR_8    61
378
#define KR_9     1
379
#define KR_10    6
380
#define KR_11   25
381
#define KR_12    8
382
#define KR_13   18
383
#define KR_14   27
384
#define KR_15   36
385
#define KR_16   10
386
#define KR_17   15
387
#define KR_18   56
388
#define KR_19   62
389
#define KR_20   55
390
#define KR_21   39
391
#define KR_22   41
392
#define KR_23    2
393
394
/* Mix the XOR of the column's values into each number by column.
395
 *
396
 * s  The state.
397
 * b  Temporary array of XORed column values.
398
 * x  The index of the column.
399
 * t  Temporary variable.
400
 */
401
4.23M
#define COL_MIX(s, b, x, t)                                                         \
402
4.23M
do {                                                                                \
403
4.23M
    (b)[0] = (s)[0] ^ (s)[5] ^ (s)[10] ^ (s)[15] ^ (s)[20];                         \
404
4.23M
    (b)[1] = (s)[1] ^ (s)[6] ^ (s)[11] ^ (s)[16] ^ (s)[21];                         \
405
4.23M
    (b)[2] = (s)[2] ^ (s)[7] ^ (s)[12] ^ (s)[17] ^ (s)[22];                         \
406
4.23M
    (b)[3] = (s)[3] ^ (s)[8] ^ (s)[13] ^ (s)[18] ^ (s)[23];                         \
407
4.23M
    (b)[4] = (s)[4] ^ (s)[9] ^ (s)[14] ^ (s)[19] ^ (s)[24];                         \
408
4.23M
    (t) = (b)[(0 + 4) % 5] ^ ROTL64((b)[(0 + 1) % 5], 1);                           \
409
4.23M
    (s)[ 0] ^= (t); (s)[ 5] ^= (t); (s)[10] ^= (t); (s)[15] ^= (t); (s)[20] ^= (t); \
410
4.23M
    (t) = (b)[(1 + 4) % 5] ^ ROTL64((b)[(1 + 1) % 5], 1);                           \
411
4.23M
    (s)[ 1] ^= (t); (s)[ 6] ^= (t); (s)[11] ^= (t); (s)[16] ^= (t); (s)[21] ^= (t); \
412
4.23M
    (t) = (b)[(2 + 4) % 5] ^ ROTL64((b)[(2 + 1) % 5], 1);                           \
413
4.23M
    (s)[ 2] ^= (t); (s)[ 7] ^= (t); (s)[12] ^= (t); (s)[17] ^= (t); (s)[22] ^= (t); \
414
4.23M
    (t) = (b)[(3 + 4) % 5] ^ ROTL64((b)[(3 + 1) % 5], 1);                           \
415
4.23M
    (s)[ 3] ^= (t); (s)[ 8] ^= (t); (s)[13] ^= (t); (s)[18] ^= (t); (s)[23] ^= (t); \
416
4.23M
    (t) = (b)[(4 + 4) % 5] ^ ROTL64((b)[(4 + 1) % 5], 1);                           \
417
4.23M
    (s)[ 4] ^= (t); (s)[ 9] ^= (t); (s)[14] ^= (t); (s)[19] ^= (t); (s)[24] ^= (t); \
418
4.23M
}                                                                                   \
419
4.23M
while (0)
420
421
101M
#define S(s1, i) ROTL64((s1)[KI_##i], KR_##i)
422
423
#ifdef SHA3_BY_SPEC
424
/* Mix the row values.
425
 * BMI1 has ANDN instruction ((~a) & b) - Haswell and above.
426
 *
427
 * s2  The new state.
428
 * s1  The current state.
429
 * b   Temporary array of XORed row values.
430
 * t0  Temporary variable. (Unused)
431
 * t1  Temporary variable. (Unused)
432
 */
433
#define ROW_MIX(s2, s1, b, t0, t1)                    \
434
do {                                                  \
435
    (b)[0] = (s1)[0];                                 \
436
    (b)[1] = S((s1), 0);                              \
437
    (b)[2] = S((s1), 1);                              \
438
    (b)[3] = S((s1), 2);                              \
439
    (b)[4] = S((s1), 3);                              \
440
    (s2)[0] = (b)[0] ^ (~(b)[1] & (b)[2]);            \
441
    (s2)[1] = (b)[1] ^ (~(b)[2] & (b)[3]);            \
442
    (s2)[2] = (b)[2] ^ (~(b)[3] & (b)[4]);            \
443
    (s2)[3] = (b)[3] ^ (~(b)[4] & (b)[0]);            \
444
    (s2)[4] = (b)[4] ^ (~(b)[0] & (b)[1]);            \
445
    (b)[0] = S((s1), 4);                              \
446
    (b)[1] = S((s1), 5);                              \
447
    (b)[2] = S((s1), 6);                              \
448
    (b)[3] = S((s1), 7);                              \
449
    (b)[4] = S((s1), 8);                              \
450
    (s2)[5] = (b)[0] ^ (~(b)[1] & (b)[2]);            \
451
    (s2)[6] = (b)[1] ^ (~(b)[2] & (b)[3]);            \
452
    (s2)[7] = (b)[2] ^ (~(b)[3] & (b)[4]);            \
453
    (s2)[8] = (b)[3] ^ (~(b)[4] & (b)[0]);            \
454
    (s2)[9] = (b)[4] ^ (~(b)[0] & (b)[1]);            \
455
    (b)[0] = S((s1), 9);                              \
456
    (b)[1] = S((s1), 10);                             \
457
    (b)[2] = S((s1), 11);                             \
458
    (b)[3] = S((s1), 12);                             \
459
    (b)[4] = S((s1), 13);                             \
460
    (s2)[10] = (b)[0] ^ (~(b)[1] & (b)[2]);           \
461
    (s2)[11] = (b)[1] ^ (~(b)[2] & (b)[3]);           \
462
    (s2)[12] = (b)[2] ^ (~(b)[3] & (b)[4]);           \
463
    (s2)[13] = (b)[3] ^ (~(b)[4] & (b)[0]);           \
464
    (s2)[14] = (b)[4] ^ (~(b)[0] & (b)[1]);           \
465
    (b)[0] = S((s1), 14);                             \
466
    (b)[1] = S((s1), 15);                             \
467
    (b)[2] = S((s1), 16);                             \
468
    (b)[3] = S((s1), 17);                             \
469
    (b)[4] = S((s1), 18);                             \
470
    (s2)[15] = (b)[0] ^ (~(b)[1] & (b)[2]);           \
471
    (s2)[16] = (b)[1] ^ (~(b)[2] & (b)[3]);           \
472
    (s2)[17] = (b)[2] ^ (~(b)[3] & (b)[4]);           \
473
    (s2)[18] = (b)[3] ^ (~(b)[4] & (b)[0]);           \
474
    (s2)[19] = (b)[4] ^ (~(b)[0] & (b)[1]);           \
475
    (b)[0] = S((s1), 19);                             \
476
    (b)[1] = S((s1), 20);                             \
477
    (b)[2] = S((s1), 21);                             \
478
    (b)[3] = S((s1), 22);                             \
479
    (b)[4] = S((s1), 23);                             \
480
    (s2)[20] = (b)[0] ^ (~(b)[1] & (b)[2]);           \
481
    (s2)[21] = (b)[1] ^ (~(b)[2] & (b)[3]);           \
482
    (s2)[22] = (b)[2] ^ (~(b)[3] & (b)[4]);           \
483
    (s2)[23] = (b)[3] ^ (~(b)[4] & (b)[0]);           \
484
    (s2)[24] = (b)[4] ^ (~(b)[0] & (b)[1]);           \
485
}                                                     \
486
while (0)
487
#else
488
/* Mix the row values.
489
 * a ^ (~b & c) == a ^ (c & (b ^ c)) == (a ^ b) ^ (b | c)
490
 *
491
 * s2  The new state.
492
 * s1  The current state.
493
 * b   Temporary array of XORed row values.
494
 * t12 Temporary variable.
495
 * t34 Temporary variable.
496
 */
497
4.23M
#define ROW_MIX(s2, s1, b, t12, t34)                      \
498
4.23M
do {                                                      \
499
4.23M
    (b)[0] = (s1)[0];                                     \
500
4.23M
    (b)[1] = S((s1), 0);                                  \
501
4.23M
    (b)[2] = S((s1), 1);                                  \
502
4.23M
    (b)[3] = S((s1), 2);                                  \
503
4.23M
    (b)[4] = S((s1), 3);                                  \
504
4.23M
    (t12) = ((b)[1] ^ (b)[2]); (t34) = ((b)[3] ^ (b)[4]); \
505
4.23M
    (s2)[0] = (b)[0] ^ ((b)[2] &  (t12));                 \
506
4.23M
    (s2)[1] =  (t12) ^ ((b)[2] | (b)[3]);                 \
507
4.23M
    (s2)[2] = (b)[2] ^ ((b)[4] &  (t34));                 \
508
4.23M
    (s2)[3] =  (t34) ^ ((b)[4] | (b)[0]);                 \
509
4.23M
    (s2)[4] = (b)[4] ^ ((b)[1] & ((b)[0] ^ (b)[1]));      \
510
4.23M
    (b)[0] = S((s1), 4);                                  \
511
4.23M
    (b)[1] = S((s1), 5);                                  \
512
4.23M
    (b)[2] = S((s1), 6);                                  \
513
4.23M
    (b)[3] = S((s1), 7);                                  \
514
4.23M
    (b)[4] = S((s1), 8);                                  \
515
4.23M
    (t12) = ((b)[1] ^ (b)[2]); (t34) = ((b)[3] ^ (b)[4]); \
516
4.23M
    (s2)[5] = (b)[0] ^ ((b)[2] &  (t12));                 \
517
4.23M
    (s2)[6] =  (t12) ^ ((b)[2] | (b)[3]);                 \
518
4.23M
    (s2)[7] = (b)[2] ^ ((b)[4] &  (t34));                 \
519
4.23M
    (s2)[8] =  (t34) ^ ((b)[4] | (b)[0]);                 \
520
4.23M
    (s2)[9] = (b)[4] ^ ((b)[1] & ((b)[0] ^ (b)[1]));      \
521
4.23M
    (b)[0] = S((s1), 9);                                  \
522
4.23M
    (b)[1] = S((s1), 10);                                 \
523
4.23M
    (b)[2] = S((s1), 11);                                 \
524
4.23M
    (b)[3] = S((s1), 12);                                 \
525
4.23M
    (b)[4] = S((s1), 13);                                 \
526
4.23M
    (t12) = ((b)[1] ^ (b)[2]); (t34) = ((b)[3] ^ (b)[4]); \
527
4.23M
    (s2)[10] = (b)[0] ^ ((b)[2] &  (t12));                \
528
4.23M
    (s2)[11] =  (t12) ^ ((b)[2] | (b)[3]);                \
529
4.23M
    (s2)[12] = (b)[2] ^ ((b)[4] &  (t34));                \
530
4.23M
    (s2)[13] =  (t34) ^ ((b)[4] | (b)[0]);                \
531
4.23M
    (s2)[14] = (b)[4] ^ ((b)[1] & ((b)[0] ^ (b)[1]));     \
532
4.23M
    (b)[0] = S((s1), 14);                                 \
533
4.23M
    (b)[1] = S((s1), 15);                                 \
534
4.23M
    (b)[2] = S((s1), 16);                                 \
535
4.23M
    (b)[3] = S((s1), 17);                                 \
536
4.23M
    (b)[4] = S((s1), 18);                                 \
537
4.23M
    (t12) = ((b)[1] ^ (b)[2]); (t34) = ((b)[3] ^ (b)[4]); \
538
4.23M
    (s2)[15] = (b)[0] ^ ((b)[2] &  (t12));                \
539
4.23M
    (s2)[16] =  (t12) ^ ((b)[2] | (b)[3]);                \
540
4.23M
    (s2)[17] = (b)[2] ^ ((b)[4] &  (t34));                \
541
4.23M
    (s2)[18] =  (t34) ^ ((b)[4] | (b)[0]);                \
542
4.23M
    (s2)[19] = (b)[4] ^ ((b)[1] & ((b)[0] ^ (b)[1]));     \
543
4.23M
    (b)[0] = S((s1), 19);                                 \
544
4.23M
    (b)[1] = S((s1), 20);                                 \
545
4.23M
    (b)[2] = S((s1), 21);                                 \
546
4.23M
    (b)[3] = S((s1), 22);                                 \
547
4.23M
    (b)[4] = S((s1), 23);                                 \
548
4.23M
    (t12) = ((b)[1] ^ (b)[2]); (t34) = ((b)[3] ^ (b)[4]); \
549
4.23M
    (s2)[20] = (b)[0] ^ ((b)[2] &  (t12));                \
550
4.23M
    (s2)[21] =  (t12) ^ ((b)[2] | (b)[3]);                \
551
4.23M
    (s2)[22] = (b)[2] ^ ((b)[4] &  (t34));                \
552
4.23M
    (s2)[23] =  (t34) ^ ((b)[4] | (b)[0]);                \
553
4.23M
    (s2)[24] = (b)[4] ^ ((b)[1] & ((b)[0] ^ (b)[1]));     \
554
4.23M
}                                                         \
555
4.23M
while (0)
556
#endif /* SHA3_BY_SPEC */
557
558
#if !defined(STM32_HASH_SHA3) && !defined(PSOC6_HASH_SHA3)
559
/* The block operation performed on the state.
560
 *
561
 * s  The state.
562
 */
563
void BlockSha3(word64* s)
564
176k
{
565
176k
    word64 n[25];
566
176k
    word64 b[5];
567
176k
    word64 t0;
568
176k
#ifndef SHA3_BY_SPEC
569
176k
    word64 t1;
570
176k
#endif
571
176k
    word32 i;
572
573
2.29M
    for (i = 0; i < 24; i += 2)
574
2.11M
    {
575
2.11M
        COL_MIX(s, b, x, t0);
576
2.11M
        ROW_MIX(n, s, b, t0, t1);
577
2.11M
        n[0] ^= hash_keccak_r[i];
578
579
2.11M
        COL_MIX(n, b, x, t0);
580
2.11M
        ROW_MIX(s, n, b, t0, t1);
581
2.11M
        s[0] ^= hash_keccak_r[i+1];
582
2.11M
    }
583
176k
}
584
#endif /* WOLFSSL_SHA3_SMALL */
585
#endif /* STM32_HASH_SHA3 */
586
#endif /* !WOLFSSL_ARMASM && !WOLFSSL_RISCV_ASM */
587
588
#if !defined(STM32_HASH_SHA3) && !defined(PSOC6_HASH_SHA3)
589
#if defined(BIG_ENDIAN_ORDER)
590
static WC_INLINE word64 Load64Unaligned(const unsigned char *a)
591
{
592
    return ((word64)a[0] <<  0) |
593
           ((word64)a[1] <<  8) |
594
           ((word64)a[2] << 16) |
595
           ((word64)a[3] << 24) |
596
           ((word64)a[4] << 32) |
597
           ((word64)a[5] << 40) |
598
           ((word64)a[6] << 48) |
599
           ((word64)a[7] << 56);
600
}
601
602
/* Convert the array of bytes, in little-endian order, to a 64-bit integer.
603
 *
604
 * a  Array of bytes.
605
 * returns a 64-bit integer.
606
 */
607
static word64 Load64BitLittleEndian(const byte* a)
608
{
609
    word64 n = 0;
610
    int i;
611
612
    for (i = 0; i < 8; i++)
613
        n |= (word64)a[i] << (8 * i);
614
615
    return n;
616
}
617
#elif defined(WC_SHA3_FAULT_HARDEN)
618
static WC_INLINE word64 Load64Unaligned(const unsigned char *a)
619
{
620
#ifdef WC_64BIT_CPU
621
    return *(word64*)a;
622
#elif defined(WC_32BIT_CPU)
623
    return (((word64)((word32*)a)[1]) << 32) |
624
                     ((word32*)a)[0];
625
#else
626
    return (((word64)((word16*)a)[3]) << 48) |
627
           (((word64)((word16*)a)[2]) << 32) |
628
           (((word64)((word16*)a)[1]) << 16) |
629
                     ((word16*)a)[0];
630
#endif
631
}
632
633
/* Convert the array of bytes, in little-endian order, to a 64-bit integer.
634
 *
635
 * a  Array of bytes.
636
 * returns a 64-bit integer.
637
 */
638
static word64 Load64BitLittleEndian(const byte* a)
639
{
640
    return Load64Unaligned(a);
641
}
642
#endif
643
644
/* Initialize the state for a SHA3-224 hash operation.
645
 *
646
 * sha3   wc_Sha3 object holding state.
647
 * returns 0 on success.
648
 */
649
650
static int InitSha3(wc_Sha3* sha3)
651
87.4k
{
652
87.4k
    int i;
653
654
2.27M
    for (i = 0; i < 25; i++)
655
2.18M
        sha3->s[i] = 0;
656
87.4k
    sha3->i = 0;
657
87.4k
#ifdef WOLFSSL_HASH_FLAGS
658
87.4k
    sha3->flags = 0;
659
87.4k
#endif
660
661
#ifdef USE_INTEL_SPEEDUP
662
    {
663
        int cpuid_flags_were_updated = cpuid_get_flags_ex(&cpuid_flags);
664
#ifdef WC_C_DYNAMIC_FALLBACK
665
        (void)cpuid_flags_were_updated;
666
        if (! CAN_SAVE_VECTOR_REGISTERS()) {
667
            SHA3_BLOCK = BlockSha3;
668
            SHA3_BLOCK_N = NULL;
669
        }
670
        else
671
#else
672
        if ((! cpuid_flags_were_updated) && (SHA3_BLOCK != NULL)) {
673
        }
674
        else
675
#endif
676
        if (IS_INTEL_AVX2(cpuid_flags)) {
677
            SHA3_BLOCK = sha3_block_avx2;
678
            SHA3_BLOCK_N = sha3_block_n_avx2;
679
        }
680
        else if (IS_INTEL_BMI1(cpuid_flags) && IS_INTEL_BMI2(cpuid_flags)) {
681
            SHA3_BLOCK = sha3_block_bmi2;
682
            SHA3_BLOCK_N = sha3_block_n_bmi2;
683
        }
684
        else {
685
            SHA3_BLOCK = BlockSha3;
686
            SHA3_BLOCK_N = NULL;
687
        }
688
    }
689
#define SHA3_FUNC_PTR
690
#endif /* USE_INTEL_SPEEDUP */
691
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM)
692
    {
693
        int cpuid_flags_were_updated = cpuid_get_flags_ex(&cpuid_flags);
694
        if ((! cpuid_flags_were_updated) && (SHA3_BLOCK != NULL)) {
695
        }
696
        else
697
    #ifdef WOLFSSL_ARMASM_CRYPTO_SHA3
698
        if (IS_AARCH64_SHA3(cpuid_flags)) {
699
            SHA3_BLOCK = BlockSha3_crypto;
700
            SHA3_BLOCK_N = NULL;
701
        }
702
        else
703
    #endif
704
        {
705
            SHA3_BLOCK = BlockSha3_base;
706
            SHA3_BLOCK_N = NULL;
707
        }
708
    }
709
#define SHA3_FUNC_PTR
710
#endif
711
712
87.4k
    return 0;
713
87.4k
}
714
715
#if defined(__aarch64__) && defined(WOLFSSL_ARMASM)
716
void BlockSha3(word64* s)
717
{
718
    (*SHA3_BLOCK)(s);
719
}
720
#endif
721
722
/* Update the SHA-3 hash state with message data.
723
 *
724
 * sha3  wc_Sha3 object holding state.
725
 * data  Message data to be hashed.
726
 * len   Length of the message data.
727
 * p     Number of 64-bit numbers in a block of data to process.
728
 * returns 0 on success.
729
 */
730
static int Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
731
327k
{
732
327k
    word32 i;
733
327k
    word32 blocks;
734
#ifdef WC_SHA3_FAULT_HARDEN
735
    word32 check = 0;
736
    word32 total_check = 0;
737
#endif
738
739
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
740
    if (SHA3_BLOCK == sha3_block_avx2) {
741
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
742
    }
743
#endif
744
327k
    if (sha3->i > 0) {
745
210k
        byte *t;
746
210k
        byte l = (byte)(p * 8 - sha3->i);
747
210k
        if (l > len) {
748
208k
            l = (byte)len;
749
208k
        }
750
751
210k
        t = &sha3->t[sha3->i];
752
929k
        for (i = 0; i < l; i++) {
753
718k
            t[i] = data[i];
754
    #ifdef WC_SHA3_FAULT_HARDEN
755
            check++;
756
    #endif
757
718k
        }
758
    #ifdef WC_SHA3_FAULT_HARDEN
759
        if (check != l) {
760
            return BAD_COND_E;
761
        }
762
        total_check += l;
763
    #endif
764
210k
        data += i;
765
210k
        len -= i;
766
210k
        sha3->i = (byte)(sha3->i + i);
767
768
210k
        if (sha3->i == p * 8) {
769
2.16k
    #if !defined(BIG_ENDIAN_ORDER) && !defined(WC_SHA3_FAULT_HARDEN)
770
2.16k
            xorbuf(sha3->s, sha3->t, (word32)(p * 8));
771
    #else
772
            for (i = 0; i < p; i++) {
773
                sha3->s[i] ^= Load64BitLittleEndian(sha3->t + 8 * i);
774
            #ifdef WC_SHA3_FAULT_HARDEN
775
                check++;
776
            #endif
777
            }
778
        #ifdef WC_SHA3_FAULT_HARDEN
779
            if (check != p + l) {
780
                return BAD_COND_E;
781
            }
782
            total_check += p;
783
        #endif
784
    #endif
785
        #ifdef SHA3_FUNC_PTR
786
            (*SHA3_BLOCK)(sha3->s);
787
        #else
788
2.16k
            BlockSha3(sha3->s);
789
2.16k
        #endif
790
2.16k
            sha3->i = 0;
791
2.16k
        }
792
210k
    }
793
327k
    blocks = len / (p * 8U);
794
    #ifdef SHA3_FUNC_PTR
795
    if ((SHA3_BLOCK_N != NULL) && (blocks > 0)) {
796
        (*SHA3_BLOCK_N)(sha3->s, data, blocks, p * 8U);
797
        len -= blocks * (p * 8U);
798
        data += blocks * (p * 8U);
799
        blocks = 0;
800
    }
801
    #endif
802
#ifdef WC_SHA3_FAULT_HARDEN
803
    total_check += blocks * p;
804
#endif
805
368k
    for (; blocks > 0; blocks--) {
806
41.3k
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_SHA3_FAULT_HARDEN)
807
41.3k
        xorbuf(sha3->s, data, (word32)(p * 8));
808
#else
809
        for (i = 0; i < p; i++) {
810
            sha3->s[i] ^= Load64Unaligned(data + 8 * i);
811
        #ifdef WC_SHA3_FAULT_HARDEN
812
            check++;
813
        #endif
814
        }
815
    #ifdef WC_SHA3_FAULT_HARDEN
816
        if (check != total_check - ((blocks - 1) * p)) {
817
            return BAD_COND_E;
818
        }
819
    #endif
820
#endif
821
    #ifdef SHA3_FUNC_PTR
822
        (*SHA3_BLOCK)(sha3->s);
823
    #else
824
41.3k
        BlockSha3(sha3->s);
825
41.3k
    #endif
826
41.3k
        len -= p * 8U;
827
41.3k
        data += p * 8U;
828
41.3k
    }
829
#ifdef WC_SHA3_FAULT_HARDEN
830
    if (check != total_check) {
831
        return BAD_COND_E;
832
    }
833
#endif
834
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
835
    if (SHA3_BLOCK == sha3_block_avx2) {
836
        RESTORE_VECTOR_REGISTERS();
837
    }
838
#endif
839
327k
    if (len > 0) {
840
73.2k
        XMEMCPY(sha3->t, data, len);
841
73.2k
    }
842
327k
    sha3->i = (byte)(sha3->i + len);
843
844
327k
    return 0;
845
327k
}
846
847
/* Calculate the SHA-3 hash based on all the message data seen.
848
 *
849
 * sha3  wc_Sha3 object holding state.
850
 * hash  Buffer to hold the hash result.
851
 * p     Number of 64-bit numbers in a block of data to process.
852
 * len   Number of bytes in output.
853
 * returns 0 on success.
854
 */
855
static int Sha3Final(wc_Sha3* sha3, byte padChar, byte* hash, byte p, word32 l)
856
69.5k
{
857
69.5k
    word32 rate = p * 8U;
858
69.5k
    word32 j;
859
#if defined(BIG_ENDIAN_ORDER) || defined(WC_SHA3_FAULT_HARDEN)
860
    word32 i;
861
#endif
862
#ifdef WC_SHA3_FAULT_HARDEN
863
    int check = 0;
864
#endif
865
866
69.5k
#if !defined(BIG_ENDIAN_ORDER) && !defined(WC_SHA3_FAULT_HARDEN)
867
69.5k
    xorbuf(sha3->s, sha3->t, sha3->i);
868
69.5k
#ifdef WOLFSSL_HASH_FLAGS
869
69.5k
    if ((p == WC_SHA3_256_COUNT) && (sha3->flags & WC_HASH_SHA3_KECCAK256)) {
870
0
        padChar = 0x01;
871
0
    }
872
69.5k
#endif
873
69.5k
    ((byte*)sha3->s)[sha3->i ] ^= padChar;
874
69.5k
    ((byte*)sha3->s)[rate - 1] ^= 0x80;
875
#else
876
    sha3->t[rate - 1]  = 0x00;
877
#ifdef WOLFSSL_HASH_FLAGS
878
    if ((p == WC_SHA3_256_COUNT) && (sha3->flags & WC_HASH_SHA3_KECCAK256)) {
879
        padChar = 0x01;
880
    }
881
#endif
882
    sha3->t[sha3->i ]  = padChar;
883
    sha3->t[rate - 1] |= 0x80;
884
    if (rate - 1 > (word32)sha3->i + 1) {
885
        XMEMSET(sha3->t + sha3->i + 1, 0, rate - 1U - (sha3->i + 1U));
886
    }
887
    for (i = 0; i < p; i++) {
888
        sha3->s[i] ^= Load64BitLittleEndian(sha3->t + 8 * i);
889
    #ifdef WC_SHA3_FAULT_HARDEN
890
        check++;
891
    #endif
892
    }
893
#ifdef WC_SHA3_FAULT_HARDEN
894
    if (check != p) {
895
        return BAD_COND_E;
896
    }
897
#endif
898
#endif
899
900
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
901
    if (SHA3_BLOCK == sha3_block_avx2)
902
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
903
#endif
904
905
69.5k
    for (j = 0; l - j >= rate; j += rate) {
906
    #ifdef SHA3_FUNC_PTR
907
        (*SHA3_BLOCK)(sha3->s);
908
    #else
909
0
        BlockSha3(sha3->s);
910
0
    #endif
911
    #if defined(BIG_ENDIAN_ORDER)
912
        ByteReverseWords64((word64*)(hash + j), sha3->s, rate);
913
    #else
914
0
        XMEMCPY(hash + j, sha3->s, rate);
915
0
    #endif
916
0
    }
917
69.5k
    if (j != l) {
918
    #ifdef SHA3_FUNC_PTR
919
        (*SHA3_BLOCK)(sha3->s);
920
    #else
921
39.6k
        BlockSha3(sha3->s);
922
39.6k
    #endif
923
    #if defined(BIG_ENDIAN_ORDER)
924
        ByteReverseWords64(sha3->s, sha3->s, rate);
925
    #endif
926
39.6k
        XMEMCPY(hash + j, sha3->s, l - j);
927
39.6k
    }
928
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
929
    if (SHA3_BLOCK == sha3_block_avx2) {
930
        RESTORE_VECTOR_REGISTERS();
931
    }
932
#endif
933
934
69.5k
    return 0;
935
69.5k
}
936
#endif
937
#if defined(STM32_HASH_SHA3)
938
939
/* Supports CubeMX HAL or Standard Peripheral Library */
940
941
static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)
942
{
943
    if (sha3 == NULL)
944
        return BAD_FUNC_ARG;
945
946
    (void)devId;
947
    (void)heap;
948
949
    XMEMSET(sha3, 0, sizeof(wc_Sha3));
950
    wc_Stm32_Hash_Init(&sha3->stmCtx);
951
    return 0;
952
}
953
954
static int Stm32GetAlgo(byte p)
955
{
956
    switch(p) {
957
        case WC_SHA3_224_COUNT:
958
            return HASH_ALGOSELECTION_SHA3_224;
959
        case WC_SHA3_256_COUNT:
960
            return HASH_ALGOSELECTION_SHA3_256;
961
        case WC_SHA3_384_COUNT:
962
            return HASH_ALGOSELECTION_SHA3_384;
963
        case WC_SHA3_512_COUNT:
964
            return HASH_ALGOSELECTION_SHA3_512;
965
    }
966
    /* Should never get here */
967
    return WC_SHA3_224_COUNT;
968
}
969
970
static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
971
{
972
    int ret = 0;
973
974
    if (sha3 == NULL) {
975
        return BAD_FUNC_ARG;
976
    }
977
    if (data == NULL && len == 0) {
978
        /* valid, but do nothing */
979
        return 0;
980
    }
981
    if (data == NULL) {
982
        return BAD_FUNC_ARG;
983
    }
984
985
    ret = wolfSSL_CryptHwMutexLock();
986
    if (ret == 0) {
987
        ret = wc_Stm32_Hash_Update(&sha3->stmCtx, Stm32GetAlgo(p), data, len,
988
            p * 8);
989
        wolfSSL_CryptHwMutexUnLock();
990
    }
991
    return ret;
992
}
993
994
static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)
995
{
996
    int ret = 0;
997
998
    if (sha3 == NULL || hash == NULL) {
999
        return BAD_FUNC_ARG;
1000
    }
1001
1002
    ret = wolfSSL_CryptHwMutexLock();
1003
    if (ret == 0) {
1004
        ret = wc_Stm32_Hash_Final(&sha3->stmCtx, Stm32GetAlgo(p), hash, len);
1005
        wolfSSL_CryptHwMutexUnLock();
1006
    }
1007
1008
    (void)wc_InitSha3(sha3, NULL, 0); /* reset state */
1009
1010
    return ret;
1011
}
1012
#elif defined(PSOC6_HASH_SHA3)
1013
1014
static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)
1015
{
1016
    int ret;
1017
    if (sha3 == NULL) {
1018
        return BAD_FUNC_ARG;
1019
    }
1020
    (void)devId;
1021
    (void)heap;
1022
1023
    /* Lock the mutex to perform crypto operations */
1024
    ret = wolfSSL_CryptHwMutexLock();
1025
    if (ret == 0) {
1026
        /* Initialize hash state for SHA-3 operation */
1027
        ret = wc_Psoc6_Sha3_Init(sha3);
1028
        /* Release the lock */
1029
        wolfSSL_CryptHwMutexUnLock();
1030
    }
1031
1032
    return ret;
1033
}
1034
1035
static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
1036
{
1037
    int ret;
1038
1039
    if (sha3 == NULL || (data == NULL && len > 0)) {
1040
        return BAD_FUNC_ARG;
1041
    }
1042
1043
    if (data == NULL && len == 0) {
1044
        /* valid, but do nothing */
1045
        return 0;
1046
    }
1047
1048
    /* Lock the mutex to perform crypto operations */
1049
    ret = wolfSSL_CryptHwMutexLock();
1050
    if (ret == 0) {
1051
        /* Perform SHA3 on the input data and update the hash state */
1052
        ret = wc_Psoc6_Sha3_Update(sha3, data, len, p);
1053
        /* Release the lock */
1054
        wolfSSL_CryptHwMutexUnLock();
1055
    }
1056
1057
    return ret;
1058
}
1059
1060
static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)
1061
{
1062
    int ret;
1063
1064
    if (sha3 == NULL || hash == NULL) {
1065
        return BAD_FUNC_ARG;
1066
    }
1067
1068
    /* Lock the mutex to perform crypto operations */
1069
    ret = wolfSSL_CryptHwMutexLock();
1070
    if (ret == 0) {
1071
        /* Finalize SHA3 operations and produce digest */
1072
        ret = wc_Psoc6_Sha3_Final(sha3, 0x06, hash, p, len);
1073
        if (ret == 0) {
1074
            /* Initialize hash state for SHA-3 operation */
1075
            ret = wc_Psoc6_Sha3_Init(sha3);
1076
        }
1077
        /* Release the lock */
1078
        wolfSSL_CryptHwMutexUnLock();
1079
    }
1080
1081
    return ret;
1082
}
1083
1084
#else
1085
1086
/* Initialize the state for a SHA-3 hash operation.
1087
 *
1088
 * sha3   wc_Sha3 object holding state.
1089
 * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
1090
 * devId  Device identifier for asynchronous operation.
1091
 * returns 0 on success.
1092
 */
1093
static int wc_InitSha3(wc_Sha3* sha3, void* heap, int devId)
1094
47.2k
{
1095
47.2k
    int ret = 0;
1096
1097
47.2k
    if (sha3 == NULL)
1098
0
        return BAD_FUNC_ARG;
1099
1100
47.2k
    sha3->heap = heap;
1101
47.2k
    ret = InitSha3(sha3);
1102
47.2k
    if (ret != 0)
1103
0
        return ret;
1104
1105
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
1106
    ret = wolfAsync_DevCtxInit(&sha3->asyncDev,
1107
                        WOLFSSL_ASYNC_MARKER_SHA3, sha3->heap, devId);
1108
#endif
1109
47.2k
#if defined(WOLF_CRYPTO_CB)
1110
47.2k
    sha3->devId = devId;
1111
    /* Set to none to determine the hash type later */
1112
    /* in the update/final functions based on the p value */
1113
47.2k
    sha3->hashType = WC_HASH_TYPE_NONE;
1114
47.2k
#endif
1115
47.2k
    (void)devId;
1116
1117
47.2k
    return ret;
1118
47.2k
}
1119
1120
/* Update the SHA-3 hash state with message data.
1121
 *
1122
 * sha3  wc_Sha3 object holding state.
1123
 * data  Message data to be hashed.
1124
 * len   Length of the message data.
1125
 * p     Number of 64-bit numbers in a block of data to process.
1126
 * returns 0 on success.
1127
 */
1128
static int wc_Sha3Update(wc_Sha3* sha3, const byte* data, word32 len, byte p)
1129
10.1k
{
1130
10.1k
    int ret;
1131
1132
10.1k
    if (sha3 == NULL || (data == NULL && len > 0)) {
1133
0
        return BAD_FUNC_ARG;
1134
0
    }
1135
1136
10.1k
    if (data == NULL && len == 0) {
1137
        /* valid, but do nothing */
1138
55
        return 0;
1139
55
    }
1140
1141
10.0k
#ifdef WOLF_CRYPTO_CB
1142
10.0k
    #ifndef WOLF_CRYPTO_CB_FIND
1143
10.0k
    if (sha3->devId != INVALID_DEVID)
1144
0
    #endif
1145
0
    {
1146
        /* If the hash type is not set, determine it based on the p value */
1147
        /* We can skip the switch statement if the hash type set already */
1148
0
        if (sha3->hashType == WC_HASH_TYPE_NONE) {
1149
0
            switch (p) {
1150
0
                case WC_SHA3_224_COUNT:
1151
0
                    sha3->hashType = WC_HASH_TYPE_SHA3_224; break;
1152
0
                case WC_SHA3_256_COUNT:
1153
0
                    sha3->hashType = WC_HASH_TYPE_SHA3_256; break;
1154
0
                case WC_SHA3_384_COUNT:
1155
0
                    sha3->hashType = WC_HASH_TYPE_SHA3_384; break;
1156
0
                case WC_SHA3_512_COUNT:
1157
0
                    sha3->hashType = WC_HASH_TYPE_SHA3_512; break;
1158
0
                default: return BAD_FUNC_ARG;
1159
0
            }
1160
0
        }
1161
0
        ret = wc_CryptoCb_Sha3Hash(sha3, sha3->hashType, data, len, NULL);
1162
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1163
0
            return ret;
1164
        /* fall-through when unavailable */
1165
0
    }
1166
10.0k
#endif
1167
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
1168
    if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {
1169
    #if defined(HAVE_INTEL_QA) && defined(QAT_V2)
1170
        /* QAT only supports SHA3_256 */
1171
        if (p == WC_SHA3_256_COUNT) {
1172
            ret = IntelQaSymSha3(&sha3->asyncDev, NULL, data, len);
1173
            if (ret != WC_NO_ERR_TRACE(NOT_COMPILED_IN))
1174
                return ret;
1175
            /* fall-through when unavailable */
1176
        }
1177
    #endif
1178
    }
1179
#endif /* WOLFSSL_ASYNC_CRYPT */
1180
1181
10.0k
    ret = Sha3Update(sha3, data, len, p);
1182
1183
10.0k
    return ret;
1184
10.0k
}
1185
1186
/* Calculate the SHA-3 hash based on all the message data seen.
1187
 *
1188
 * sha3  wc_Sha3 object holding state.
1189
 * hash  Buffer to hold the hash result.
1190
 * p     Number of 64-bit numbers in a block of data to process.
1191
 * len   Number of bytes in output.
1192
 * returns 0 on success.
1193
 */
1194
static int wc_Sha3Final(wc_Sha3* sha3, byte* hash, byte p, byte len)
1195
6.79k
{
1196
6.79k
    int ret;
1197
1198
6.79k
    if (sha3 == NULL || hash == NULL) {
1199
0
        return BAD_FUNC_ARG;
1200
0
    }
1201
1202
6.79k
#ifdef WOLF_CRYPTO_CB
1203
6.79k
    #ifndef WOLF_CRYPTO_CB_FIND
1204
6.79k
    if (sha3->devId != INVALID_DEVID)
1205
0
    #endif
1206
0
    {
1207
        /* If the hash type is not set, determine it based on the p value */
1208
        /* We can skip the switch statement if the hash type is set already */
1209
0
        if (sha3->hashType == WC_HASH_TYPE_NONE) {
1210
0
            switch (p) {
1211
0
                case WC_SHA3_224_COUNT:
1212
0
                    sha3->hashType = WC_HASH_TYPE_SHA3_224; break;
1213
0
                case WC_SHA3_256_COUNT:
1214
0
                    sha3->hashType = WC_HASH_TYPE_SHA3_256; break;
1215
0
                case WC_SHA3_384_COUNT:
1216
0
                    sha3->hashType = WC_HASH_TYPE_SHA3_384; break;
1217
0
                case WC_SHA3_512_COUNT:
1218
0
                    sha3->hashType = WC_HASH_TYPE_SHA3_512; break;
1219
0
                default: return BAD_FUNC_ARG;
1220
0
            }
1221
0
        }
1222
0
        ret = wc_CryptoCb_Sha3Hash(sha3, sha3->hashType, NULL, 0, hash);
1223
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1224
0
            return ret;
1225
        /* fall-through when unavailable */
1226
0
    }
1227
6.79k
#endif
1228
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
1229
    if (sha3->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA3) {
1230
    #if defined(HAVE_INTEL_QA) && defined(QAT_V2)
1231
        /* QAT only supports SHA3_256 */
1232
        /* QAT SHA-3 only supported on v2 (8970 or later cards) */
1233
        if (len == WC_SHA3_256_DIGEST_SIZE) {
1234
            ret = IntelQaSymSha3(&sha3->asyncDev, hash, NULL, len);
1235
            if (ret != WC_NO_ERR_TRACE(NOT_COMPILED_IN))
1236
                return ret;
1237
            /* fall-through when unavailable */
1238
        }
1239
    #endif
1240
    }
1241
#endif /* WOLFSSL_ASYNC_CRYPT */
1242
1243
6.79k
    ret = Sha3Final(sha3, 0x06, hash, p, (word32)len);
1244
6.79k
    if (ret != 0)
1245
0
        return ret;
1246
1247
6.79k
    return InitSha3(sha3);  /* reset state */
1248
6.79k
}
1249
#endif
1250
1251
/* Dispose of any dynamically allocated data from the SHA3-384 operation.
1252
 * (Required for async ops.)
1253
 *
1254
 * sha3  wc_Sha3 object holding state.
1255
 * returns 0 on success.
1256
 */
1257
static void wc_Sha3Free(wc_Sha3* sha3)
1258
13.1k
{
1259
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
1260
    int ret = 0;
1261
#endif
1262
1263
13.1k
    (void)sha3;
1264
1265
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
1266
    if (sha3 == NULL)
1267
        return;
1268
1269
    #ifndef WOLF_CRYPTO_CB_FIND
1270
    if (sha3->devId != INVALID_DEVID)
1271
    #endif
1272
    {
1273
        ret = wc_CryptoCb_Free(sha3->devId, WC_ALGO_TYPE_HASH,
1274
                         sha3->hashType, 0, (void*)sha3);
1275
        /* If they want the standard free, they can call it themselves */
1276
        /* via their callback setting devId to INVALID_DEVID */
1277
        /* otherwise assume the callback handled it */
1278
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1279
            return;
1280
        /* fall-through when unavailable */
1281
    }
1282
1283
    /* silence compiler warning */
1284
    (void)ret;
1285
1286
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
1287
1288
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
1289
    if (sha3 == NULL)
1290
        return;
1291
1292
    wolfAsync_DevCtxFree(&sha3->asyncDev, WOLFSSL_ASYNC_MARKER_SHA3);
1293
#endif /* WOLFSSL_ASYNC_CRYPT */
1294
1295
#if defined(PSOC6_HASH_SHA3)
1296
    wc_Psoc6_Sha_Free();
1297
#endif
1298
13.1k
}
1299
1300
/* Copy the state of the SHA3 operation.
1301
 *
1302
 * src  wc_Sha3 object holding state top copy.
1303
 * dst  wc_Sha3 object to copy into.
1304
 * returns 0 on success.
1305
 */
1306
static int wc_Sha3Copy(wc_Sha3* src, wc_Sha3* dst)
1307
0
{
1308
0
    int ret = 0;
1309
1310
0
    if (src == NULL || dst == NULL)
1311
0
        return BAD_FUNC_ARG;
1312
1313
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
1314
    #ifndef WOLF_CRYPTO_CB_FIND
1315
    if (src->devId != INVALID_DEVID)
1316
    #endif
1317
    {
1318
        /* Cast the source and destination to be void to keep the abstraction */
1319
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
1320
                               src->hashType, (void*)src, (void*)dst);
1321
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1322
            return ret;
1323
        /* fall-through when unavailable */
1324
    }
1325
    ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
1326
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
1327
1328
    /* Free dst resources before copy to prevent memory leaks (e.g.,
1329
     * hardware contexts). XMEMCPY overwrites dst. */
1330
0
    wc_Sha3Free(dst);
1331
0
    XMEMCPY(dst, src, sizeof(wc_Sha3));
1332
1333
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA3)
1334
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
1335
#endif
1336
1337
#if defined(PSOC6_HASH_SHA3)
1338
    /* Re-initialize internal pointers in hash_state that point inside sha_buffers */
1339
    dst->hash_state.hash = (uint8_t*)((cy_stc_crypto_v2_sha3_buffers_t *)&dst->sha_buffers)->hash;
1340
#endif
1341
1342
0
#ifdef WOLFSSL_HASH_FLAGS
1343
0
     dst->flags |= WC_HASH_FLAG_ISCOPY;
1344
0
#endif
1345
1346
0
    return ret;
1347
0
}
1348
1349
/* Calculate the SHA3-224 hash based on all the message data so far.
1350
 * More message data can be added, after this operation, using the current
1351
 * state.
1352
 *
1353
 * sha3  wc_Sha3 object holding state.
1354
 * hash  Buffer to hold the hash result. Must be at least 28 bytes.
1355
 * p     Number of 64-bit numbers in a block of data to process.
1356
 * len   Number of bytes in output.
1357
 * returns 0 on success.
1358
 */
1359
static int wc_Sha3GetHash(wc_Sha3* sha3, byte* hash, byte p, byte len)
1360
0
{
1361
0
    int ret;
1362
0
    wc_Sha3 tmpSha3;
1363
1364
0
    if (sha3 == NULL || hash == NULL)
1365
0
        return BAD_FUNC_ARG;
1366
1367
0
    XMEMSET(&tmpSha3, 0, sizeof(tmpSha3));
1368
0
    ret = wc_Sha3Copy(sha3, &tmpSha3);
1369
0
    if (ret == 0) {
1370
0
        ret = wc_Sha3Final(&tmpSha3, hash, p, len);
1371
0
    }
1372
0
    return ret;
1373
0
}
1374
1375
/* Initialize the state for a SHA3-224 hash operation.
1376
 *
1377
 * sha3   wc_Sha3 object holding state.
1378
 * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
1379
 * devId  Device identifier for asynchronous operation.
1380
 * returns 0 on success.
1381
 */
1382
int wc_InitSha3_224(wc_Sha3* sha3, void* heap, int devId)
1383
20
{
1384
20
    return wc_InitSha3(sha3, heap, devId);
1385
20
}
1386
1387
/* Update the SHA3-224 hash state with message data.
1388
 *
1389
 * sha3  wc_Sha3 object holding state.
1390
 * data  Message data to be hashed.
1391
 * len   Length of the message data.
1392
 * returns 0 on success.
1393
 */
1394
int wc_Sha3_224_Update(wc_Sha3* sha3, const byte* data, word32 len)
1395
20
{
1396
20
    return wc_Sha3Update(sha3, data, len, WC_SHA3_224_COUNT);
1397
20
}
1398
1399
/* Calculate the SHA3-224 hash based on all the message data seen.
1400
 * The state is initialized ready for a new message to hash.
1401
 *
1402
 * sha3  wc_Sha3 object holding state.
1403
 * hash  Buffer to hold the hash result. Must be at least 28 bytes.
1404
 * returns 0 on success.
1405
 */
1406
int wc_Sha3_224_Final(wc_Sha3* sha3, byte* hash)
1407
20
{
1408
20
    return wc_Sha3Final(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE);
1409
20
}
1410
1411
/* Dispose of any dynamically allocated data from the SHA3-224 operation.
1412
 * (Required for async ops.)
1413
 *
1414
 * sha3  wc_Sha3 object holding state.
1415
 * returns 0 on success.
1416
 */
1417
void wc_Sha3_224_Free(wc_Sha3* sha3)
1418
20
{
1419
20
    wc_Sha3Free(sha3);
1420
20
}
1421
1422
/* Calculate the SHA3-224 hash based on all the message data so far.
1423
 * More message data can be added, after this operation, using the current
1424
 * state.
1425
 *
1426
 * sha3  wc_Sha3 object holding state.
1427
 * hash  Buffer to hold the hash result. Must be at least 28 bytes.
1428
 * returns 0 on success.
1429
 */
1430
int wc_Sha3_224_GetHash(wc_Sha3* sha3, byte* hash)
1431
0
{
1432
0
    return wc_Sha3GetHash(sha3, hash, WC_SHA3_224_COUNT, WC_SHA3_224_DIGEST_SIZE);
1433
0
}
1434
1435
/* Copy the state of the SHA3-224 operation.
1436
 *
1437
 * src  wc_Sha3 object holding state top copy.
1438
 * dst  wc_Sha3 object to copy into.
1439
 * returns 0 on success.
1440
 */
1441
int wc_Sha3_224_Copy(wc_Sha3* src, wc_Sha3* dst)
1442
0
{
1443
0
    return wc_Sha3Copy(src, dst);
1444
0
}
1445
1446
1447
/* Initialize the state for a SHA3-256 hash operation.
1448
 *
1449
 * sha3   wc_Sha3 object holding state.
1450
 * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
1451
 * devId  Device identifier for asynchronous operation.
1452
 * returns 0 on success.
1453
 */
1454
int wc_InitSha3_256(wc_Sha3* sha3, void* heap, int devId)
1455
3.43k
{
1456
3.43k
    return wc_InitSha3(sha3, heap, devId);
1457
3.43k
}
1458
1459
/* Update the SHA3-256 hash state with message data.
1460
 *
1461
 * sha3  wc_Sha3 object holding state.
1462
 * data  Message data to be hashed.
1463
 * len   Length of the message data.
1464
 * returns 0 on success.
1465
 */
1466
int wc_Sha3_256_Update(wc_Sha3* sha3, const byte* data, word32 len)
1467
3.41k
{
1468
3.41k
    return wc_Sha3Update(sha3, data, len, WC_SHA3_256_COUNT);
1469
3.41k
}
1470
1471
/* Calculate the SHA3-256 hash based on all the message data seen.
1472
 * The state is initialized ready for a new message to hash.
1473
 *
1474
 * sha3  wc_Sha3 object holding state.
1475
 * hash  Buffer to hold the hash result. Must be at least 32 bytes.
1476
 * returns 0 on success.
1477
 */
1478
int wc_Sha3_256_Final(wc_Sha3* sha3, byte* hash)
1479
3.41k
{
1480
3.41k
    return wc_Sha3Final(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE);
1481
3.41k
}
1482
1483
/* Dispose of any dynamically allocated data from the SHA3-256 operation.
1484
 * (Required for async ops.)
1485
 *
1486
 * sha3  wc_Sha3 object holding state.
1487
 * returns 0 on success.
1488
 */
1489
void wc_Sha3_256_Free(wc_Sha3* sha3)
1490
3.43k
{
1491
3.43k
    wc_Sha3Free(sha3);
1492
3.43k
}
1493
1494
/* Calculate the SHA3-256 hash based on all the message data so far.
1495
 * More message data can be added, after this operation, using the current
1496
 * state.
1497
 *
1498
 * sha3  wc_Sha3 object holding state.
1499
 * hash  Buffer to hold the hash result. Must be at least 32 bytes.
1500
 * returns 0 on success.
1501
 */
1502
int wc_Sha3_256_GetHash(wc_Sha3* sha3, byte* hash)
1503
0
{
1504
0
    return wc_Sha3GetHash(sha3, hash, WC_SHA3_256_COUNT, WC_SHA3_256_DIGEST_SIZE);
1505
0
}
1506
1507
/* Copy the state of the SHA3-256 operation.
1508
 *
1509
 * src  wc_Sha3 object holding state top copy.
1510
 * dst  wc_Sha3 object to copy into.
1511
 * returns 0 on success.
1512
 */
1513
int wc_Sha3_256_Copy(wc_Sha3* src, wc_Sha3* dst)
1514
0
{
1515
0
    return wc_Sha3Copy(src, dst);
1516
0
}
1517
1518
1519
/* Initialize the state for a SHA3-384 hash operation.
1520
 *
1521
 * sha3   wc_Sha3 object holding state.
1522
 * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
1523
 * devId  Device identifier for asynchronous operation.
1524
 * returns 0 on success.
1525
 */
1526
int wc_InitSha3_384(wc_Sha3* sha3, void* heap, int devId)
1527
22
{
1528
22
    return wc_InitSha3(sha3, heap, devId);
1529
22
}
1530
1531
/* Update the SHA3-384 hash state with message data.
1532
 *
1533
 * sha3  wc_Sha3 object holding state.
1534
 * data  Message data to be hashed.
1535
 * len   Length of the message data.
1536
 * returns 0 on success.
1537
 */
1538
int wc_Sha3_384_Update(wc_Sha3* sha3, const byte* data, word32 len)
1539
22
{
1540
22
    return wc_Sha3Update(sha3, data, len, WC_SHA3_384_COUNT);
1541
22
}
1542
1543
/* Calculate the SHA3-384 hash based on all the message data seen.
1544
 * The state is initialized ready for a new message to hash.
1545
 *
1546
 * sha3  wc_Sha3 object holding state.
1547
 * hash  Buffer to hold the hash result. Must be at least 48 bytes.
1548
 * returns 0 on success.
1549
 */
1550
int wc_Sha3_384_Final(wc_Sha3* sha3, byte* hash)
1551
22
{
1552
22
    return wc_Sha3Final(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE);
1553
22
}
1554
1555
/* Dispose of any dynamically allocated data from the SHA3-384 operation.
1556
 * (Required for async ops.)
1557
 *
1558
 * sha3  wc_Sha3 object holding state.
1559
 * returns 0 on success.
1560
 */
1561
void wc_Sha3_384_Free(wc_Sha3* sha3)
1562
22
{
1563
22
    wc_Sha3Free(sha3);
1564
22
}
1565
1566
/* Calculate the SHA3-384 hash based on all the message data so far.
1567
 * More message data can be added, after this operation, using the current
1568
 * state.
1569
 *
1570
 * sha3  wc_Sha3 object holding state.
1571
 * hash  Buffer to hold the hash result. Must be at least 48 bytes.
1572
 * returns 0 on success.
1573
 */
1574
int wc_Sha3_384_GetHash(wc_Sha3* sha3, byte* hash)
1575
0
{
1576
0
    return wc_Sha3GetHash(sha3, hash, WC_SHA3_384_COUNT, WC_SHA3_384_DIGEST_SIZE);
1577
0
}
1578
1579
/* Copy the state of the SHA3-384 operation.
1580
 *
1581
 * src  wc_Sha3 object holding state top copy.
1582
 * dst  wc_Sha3 object to copy into.
1583
 * returns 0 on success.
1584
 */
1585
int wc_Sha3_384_Copy(wc_Sha3* src, wc_Sha3* dst)
1586
0
{
1587
0
    return wc_Sha3Copy(src, dst);
1588
0
}
1589
1590
1591
/* Initialize the state for a SHA3-512 hash operation.
1592
 *
1593
 * sha3   wc_Sha3 object holding state.
1594
 * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
1595
 * devId  Device identifier for asynchronous operation.
1596
 * returns 0 on success.
1597
 */
1598
int wc_InitSha3_512(wc_Sha3* sha3, void* heap, int devId)
1599
70
{
1600
70
    return wc_InitSha3(sha3, heap, devId);
1601
70
}
1602
1603
/* Update the SHA3-512 hash state with message data.
1604
 *
1605
 * sha3  wc_Sha3 object holding state.
1606
 * data  Message data to be hashed.
1607
 * len   Length of the message data.
1608
 * returns 0 on success.
1609
 */
1610
int wc_Sha3_512_Update(wc_Sha3* sha3, const byte* data, word32 len)
1611
6.84k
{
1612
6.84k
    return wc_Sha3Update(sha3, data, len, WC_SHA3_512_COUNT);
1613
6.84k
}
1614
1615
/* Calculate the SHA3-512 hash based on all the message data seen.
1616
 * The state is initialized ready for a new message to hash.
1617
 *
1618
 * sha3  wc_Sha3 object holding state.
1619
 * hash  Buffer to hold the hash result. Must be at least 64 bytes.
1620
 * returns 0 on success.
1621
 */
1622
int wc_Sha3_512_Final(wc_Sha3* sha3, byte* hash)
1623
3.45k
{
1624
3.45k
    return wc_Sha3Final(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE);
1625
3.45k
}
1626
1627
/* Dispose of any dynamically allocated data from the SHA3-512 operation.
1628
 * (Required for async ops.)
1629
 *
1630
 * sha3  wc_Sha3 object holding state.
1631
 * returns 0 on success.
1632
 */
1633
void wc_Sha3_512_Free(wc_Sha3* sha3)
1634
70
{
1635
70
    wc_Sha3Free(sha3);
1636
70
}
1637
1638
/* Calculate the SHA3-512 hash based on all the message data so far.
1639
 * More message data can be added, after this operation, using the current
1640
 * state.
1641
 *
1642
 * sha3  wc_Sha3 object holding state.
1643
 * hash  Buffer to hold the hash result. Must be at least 64 bytes.
1644
 * returns 0 on success.
1645
 */
1646
int wc_Sha3_512_GetHash(wc_Sha3* sha3, byte* hash)
1647
0
{
1648
0
    return wc_Sha3GetHash(sha3, hash, WC_SHA3_512_COUNT, WC_SHA3_512_DIGEST_SIZE);
1649
0
}
1650
1651
/* Copy the state of the SHA3-512 operation.
1652
 *
1653
 * src  wc_Sha3 object holding state top copy.
1654
 * dst  wc_Sha3 object to copy into.
1655
 * returns 0 on success.
1656
 */
1657
int wc_Sha3_512_Copy(wc_Sha3* src, wc_Sha3* dst)
1658
0
{
1659
0
    return wc_Sha3Copy(src, dst);
1660
0
}
1661
1662
#ifdef WOLFSSL_HASH_FLAGS
1663
int wc_Sha3_SetFlags(wc_Sha3* sha3, word32 flags)
1664
0
{
1665
0
    if (sha3) {
1666
0
        sha3->flags = flags;
1667
0
    }
1668
0
    return 0;
1669
0
}
1670
int wc_Sha3_GetFlags(wc_Sha3* sha3, word32* flags)
1671
0
{
1672
0
    if (sha3 && flags) {
1673
0
        *flags = sha3->flags;
1674
0
    }
1675
0
    return 0;
1676
0
}
1677
#endif
1678
1679
#ifdef WOLFSSL_SHAKE128
1680
/* Initialize the state for a Shake128 hash operation.
1681
 *
1682
 * shake  wc_Shake object holding state.
1683
 * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
1684
 * devId  Device identifier for asynchronous operation.
1685
 * returns 0 on success.
1686
 */
1687
int wc_InitShake128(wc_Shake* shake, void* heap, int devId)
1688
30.7k
{
1689
30.7k
    return wc_InitSha3(shake, heap, devId);
1690
30.7k
}
1691
1692
#if defined(PSOC6_HASH_SHA3)
1693
1694
int wc_Shake128_Update(wc_Shake* shake, const byte* data, word32 len)
1695
{
1696
    int ret;
1697
    if (shake == NULL || (data == NULL && len > 0)) {
1698
         return BAD_FUNC_ARG;
1699
    }
1700
1701
    if (data == NULL && len == 0) {
1702
        /* valid, but do nothing */
1703
        return 0;
1704
    }
1705
1706
    /* Lock the mutex to perform crypto operations */
1707
    ret = wolfSSL_CryptHwMutexLock();
1708
    if (ret == 0) {
1709
        /* Perform SHA3 on the input data and update the hash state */
1710
        ret = wc_Psoc6_Sha3_Update(shake, data, len, WC_SHA3_128_COUNT);
1711
        /* Release the lock */
1712
        wolfSSL_CryptHwMutexUnLock();
1713
    }
1714
1715
    return ret;
1716
}
1717
1718
int wc_Shake128_Final(wc_Shake* shake, byte* hash, word32 hashLen)
1719
{
1720
    int ret;
1721
1722
    if (shake == NULL || hash == NULL) {
1723
        return BAD_FUNC_ARG;
1724
    }
1725
1726
    /* Lock the mutex to perform crypto operations */
1727
    ret = wolfSSL_CryptHwMutexLock();
1728
    if (ret == 0) {
1729
        /* Finalize SHA3 operations and produce digest */
1730
        ret = wc_Psoc6_Sha3_Final(shake, 0x1f, hash, WC_SHA3_128_COUNT, hashLen);
1731
        if (ret == 0) {
1732
            /* Initialize hash state for SHA-3 operation */
1733
            ret = wc_Psoc6_Sha3_Init(shake);
1734
        }
1735
        /* Release the lock */
1736
        wolfSSL_CryptHwMutexUnLock();
1737
    }
1738
1739
    return ret;
1740
1741
}
1742
1743
int wc_Shake128_Absorb(wc_Shake* shake, const byte* data, word32 len)
1744
{
1745
    int ret;
1746
1747
    if ((shake == NULL) || (data == NULL && len != 0)) {
1748
        return BAD_FUNC_ARG;
1749
    }
1750
1751
    /* Lock the mutex to perform crypto operations */
1752
    ret = wolfSSL_CryptHwMutexLock();
1753
    if (ret == 0) {
1754
        /* Perform SHA3 on the input data and update the hash state */
1755
        ret = wc_Psoc6_Sha3_Update(shake, data, len, WC_SHA3_128_COUNT);
1756
        if (ret == 0) {
1757
            /* Finalize SHA3 operations and produce digest */
1758
            ret = wc_Psoc6_Sha3_Final(shake, 0x1f, NULL, WC_SHA3_128_COUNT, 0);
1759
        }
1760
        /* Release the lock */
1761
        wolfSSL_CryptHwMutexUnLock();
1762
    }
1763
1764
    return ret;
1765
}
1766
1767
1768
int wc_Shake128_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt)
1769
{
1770
    int ret;
1771
    if ((shake == NULL) || (out == NULL && blockCnt != 0)) {
1772
        return BAD_FUNC_ARG;
1773
    }
1774
1775
    /* Lock the mutex to perform crypto operations */
1776
    ret = wolfSSL_CryptHwMutexLock();
1777
    if (ret == 0) {
1778
        /* Squeeze output blocks from current hash state */
1779
        ret = wc_Psoc6_Shake_SqueezeBlocks(shake, out, blockCnt);
1780
        /* Release the lock */
1781
        wolfSSL_CryptHwMutexUnLock();
1782
    }
1783
1784
    return ret;
1785
}
1786
#else
1787
/* Update the SHAKE128 hash state with message data.
1788
 *
1789
 * shake  wc_Shake object holding state.
1790
 * data  Message data to be hashed.
1791
 * len   Length of the message data.
1792
 * returns 0 on success.
1793
 */
1794
int wc_Shake128_Update(wc_Shake* shake, const byte* data, word32 len)
1795
0
{
1796
0
    if (shake == NULL || (data == NULL && len > 0)) {
1797
0
         return BAD_FUNC_ARG;
1798
0
    }
1799
1800
0
    if (data == NULL && len == 0) {
1801
        /* valid, but do nothing */
1802
0
        return 0;
1803
0
    }
1804
1805
0
    return Sha3Update(shake, data, len, WC_SHA3_128_COUNT);
1806
0
}
1807
1808
/* Calculate the SHAKE128 hash based on all the message data seen.
1809
 * The state is initialized ready for a new message to hash.
1810
 *
1811
 * shake  wc_Shake object holding state.
1812
 * hash  Buffer to hold the hash result. Must be at least 64 bytes.
1813
 * returns 0 on success.
1814
 */
1815
int wc_Shake128_Final(wc_Shake* shake, byte* hash, word32 hashLen)
1816
0
{
1817
0
    int ret;
1818
1819
0
    if (shake == NULL || hash == NULL) {
1820
0
        return BAD_FUNC_ARG;
1821
0
    }
1822
1823
0
    ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_128_COUNT, hashLen);
1824
0
    if (ret != 0)
1825
0
        return ret;
1826
1827
0
    return InitSha3(shake);  /* reset state */
1828
0
}
1829
1830
/* Absorb the data for squeezing.
1831
 *
1832
 * Update and final with data but no output and no reset
1833
 *
1834
 * shake  wc_Shake object holding state.
1835
 * data  Data to absorb.
1836
 * len  Length of d to absorb in bytes.
1837
 * returns 0 on success.
1838
 */
1839
int wc_Shake128_Absorb(wc_Shake* shake, const byte* data, word32 len)
1840
30.7k
{
1841
30.7k
    int ret;
1842
1843
30.7k
    if ((shake == NULL) || (data == NULL && len != 0)) {
1844
0
        return BAD_FUNC_ARG;
1845
0
    }
1846
1847
30.7k
    ret = Sha3Update(shake, data, len, WC_SHA3_128_COUNT);
1848
30.7k
    if (ret == 0) {
1849
30.7k
        byte hash[1];
1850
30.7k
        ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_128_COUNT, 0);
1851
30.7k
    }
1852
    /* No partial data. */
1853
30.7k
    shake->i = 0;
1854
1855
30.7k
    return ret;
1856
30.7k
}
1857
1858
#ifdef WC_C_DYNAMIC_FALLBACK
1859
    #undef SHA3_BLOCK
1860
    #undef SHA3_BLOCK_N
1861
    #define SHA3_BLOCK (shake->sha3_block)
1862
    #define SHA3_BLOCK_N (shake->sha3_block_n)
1863
#endif
1864
1865
/* Squeeze the state to produce pseudo-random output.
1866
 *
1867
 * shake  wc_Shake object holding state.
1868
 * out  Output buffer.
1869
 * blockCnt  Number of blocks to write.
1870
 * returns 0 on success.
1871
 */
1872
int wc_Shake128_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt)
1873
31.0k
{
1874
31.0k
    if ((shake == NULL) || (out == NULL && blockCnt != 0)) {
1875
0
        return BAD_FUNC_ARG;
1876
0
    }
1877
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
1878
    if (SHA3_BLOCK == sha3_block_avx2)
1879
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
1880
#endif
1881
123k
    for (; (blockCnt > 0); blockCnt--) {
1882
    #ifdef SHA3_FUNC_PTR
1883
        (*SHA3_BLOCK)(shake->s);
1884
    #else
1885
92.6k
        BlockSha3(shake->s);
1886
92.6k
    #endif
1887
    #if defined(BIG_ENDIAN_ORDER)
1888
        ByteReverseWords64((word64*)out, shake->s, WC_SHA3_128_COUNT * 8);
1889
    #else
1890
92.6k
        XMEMCPY(out, shake->s, WC_SHA3_128_COUNT * 8);
1891
92.6k
    #endif
1892
92.6k
        out += WC_SHA3_128_COUNT * 8;
1893
92.6k
    }
1894
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
1895
    if (SHA3_BLOCK == sha3_block_avx2)
1896
        RESTORE_VECTOR_REGISTERS();
1897
#endif
1898
1899
31.0k
    return 0;
1900
31.0k
}
1901
#endif
1902
1903
1904
/* Dispose of any dynamically allocated data from the SHAKE128 operation.
1905
 * (Required for async ops.)
1906
 *
1907
 * shake  wc_Shake object holding state.
1908
 * returns 0 on success.
1909
 */
1910
void wc_Shake128_Free(wc_Shake* shake)
1911
0
{
1912
0
    wc_Sha3Free(shake);
1913
0
}
1914
1915
/* Copy the state of the SHA3-512 operation.
1916
 *
1917
 * src  wc_Shake object holding state top copy.
1918
 * dst  wc_Shake object to copy into.
1919
 * returns 0 on success.
1920
 */
1921
int wc_Shake128_Copy(wc_Shake* src, wc_Shake* dst)
1922
0
{
1923
0
    return wc_Sha3Copy(src, dst);
1924
0
}
1925
#endif
1926
1927
#ifdef WOLFSSL_SHAKE256
1928
/* Initialize the state for a Shake256 hash operation.
1929
 *
1930
 * shake  wc_Shake object holding state.
1931
 * heap   Heap reference for dynamic memory allocation. (Used in async ops.)
1932
 * devId  Device identifier for asynchronous operation.
1933
 * returns 0 on success.
1934
 */
1935
int wc_InitShake256(wc_Shake* shake, void* heap, int devId)
1936
12.9k
{
1937
12.9k
    return wc_InitSha3(shake, heap, devId);
1938
12.9k
}
1939
1940
1941
#ifdef PSOC6_HASH_SHA3
1942
1943
int wc_Shake256_Update(wc_Shake* shake, const byte* data, word32 len)
1944
{
1945
    int ret;
1946
    if (shake == NULL || (data == NULL && len > 0)) {
1947
         return BAD_FUNC_ARG;
1948
    }
1949
1950
    if (data == NULL && len == 0) {
1951
        /* valid, but do nothing */
1952
        return 0;
1953
    }
1954
1955
    /* Lock the mutex to perform crypto operations */
1956
    ret = wolfSSL_CryptHwMutexLock();
1957
    if (ret == 0) {
1958
        /* Perform SHA3 on the input data and update the hash state */
1959
        ret = wc_Psoc6_Sha3_Update(shake, data, len, WC_SHA3_256_COUNT);
1960
        /* Release the lock */
1961
        wolfSSL_CryptHwMutexUnLock();
1962
    }
1963
1964
    return ret;
1965
}
1966
1967
int wc_Shake256_Final(wc_Shake* shake, byte* hash, word32 hashLen)
1968
{
1969
    int ret;
1970
    if (shake == NULL || hash == NULL) {
1971
        return BAD_FUNC_ARG;
1972
    }
1973
1974
    /* Lock the mutex to perform crypto operations */
1975
    ret = wolfSSL_CryptHwMutexLock();
1976
    if (ret == 0) {
1977
        /* Finalize SHA3 operations and produce digest */
1978
        ret = wc_Psoc6_Sha3_Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, hashLen);
1979
        if (ret == 0) {
1980
            /* Initialize hash state for SHA-3 operation */
1981
            ret = wc_Psoc6_Sha3_Init(shake);
1982
        }
1983
        /* Release the lock */
1984
        wolfSSL_CryptHwMutexUnLock();
1985
    }
1986
1987
    return ret;
1988
}
1989
1990
int wc_Shake256_Absorb(wc_Shake* shake, const byte* data, word32 len)
1991
{
1992
    int ret;
1993
1994
    if ((shake == NULL) || (data == NULL && len != 0)) {
1995
        return BAD_FUNC_ARG;
1996
    }
1997
1998
    /* Lock the mutex to perform crypto operations */
1999
    ret = wolfSSL_CryptHwMutexLock();
2000
    if (ret == 0) {
2001
        /* Perform SHA3 on the input data and update the hash state */
2002
        ret = wc_Psoc6_Sha3_Update(shake, data, len, WC_SHA3_256_COUNT);
2003
        if (ret == 0) {
2004
            /* Finalize SHA3 operations and produce digest */
2005
            ret = wc_Psoc6_Sha3_Final(shake, 0x1f, NULL, WC_SHA3_256_COUNT, 0);
2006
        }
2007
        /* Release the lock */
2008
        wolfSSL_CryptHwMutexUnLock();
2009
    }
2010
2011
    return ret;
2012
}
2013
2014
int wc_Shake256_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt)
2015
{
2016
    int ret;
2017
    if ((shake == NULL) || (out == NULL && blockCnt != 0)) {
2018
        return BAD_FUNC_ARG;
2019
    }
2020
2021
    /* Lock the mutex to perform crypto operations */
2022
    ret = wolfSSL_CryptHwMutexLock();
2023
    if (ret == 0) {
2024
        /* Squeeze output blocks from current hash state */
2025
        ret = wc_Psoc6_Shake_SqueezeBlocks(shake, out, blockCnt);
2026
        /* Release the lock */
2027
        wolfSSL_CryptHwMutexUnLock();
2028
    }
2029
2030
    return ret;
2031
}
2032
2033
#else
2034
/* Update the SHAKE256 hash state with message data.
2035
 *
2036
 * shake  wc_Shake object holding state.
2037
 * data  Message data to be hashed.
2038
 * len   Length of the message data.
2039
 * returns 0 on success.
2040
 */
2041
int wc_Shake256_Update(wc_Shake* shake, const byte* data, word32 len)
2042
285k
{
2043
285k
    if (shake == NULL || (data == NULL && len > 0)) {
2044
0
         return BAD_FUNC_ARG;
2045
0
    }
2046
2047
285k
    if (data == NULL && len == 0) {
2048
        /* valid, but do nothing */
2049
0
        return 0;
2050
0
    }
2051
2052
285k
    return Sha3Update(shake, data, len, WC_SHA3_256_COUNT);
2053
285k
}
2054
2055
/* Calculate the SHAKE256 hash based on all the message data seen.
2056
 * The state is initialized ready for a new message to hash.
2057
 *
2058
 * shake  wc_Shake object holding state.
2059
 * hash  Buffer to hold the hash result. Must be at least 64 bytes.
2060
 * hashLen Size of hash in bytes.
2061
 * returns 0 on success.
2062
 */
2063
int wc_Shake256_Final(wc_Shake* shake, byte* hash, word32 hashLen)
2064
33.2k
{
2065
33.2k
    int ret;
2066
2067
33.2k
    if (shake == NULL || hash == NULL) {
2068
0
        return BAD_FUNC_ARG;
2069
0
    }
2070
2071
33.2k
    ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, hashLen);
2072
33.2k
    if (ret != 0)
2073
0
        return ret;
2074
2075
33.2k
    return InitSha3(shake);  /* reset state */
2076
33.2k
}
2077
2078
/* Absorb the data for squeezing.
2079
 *
2080
 * Update and final with data but no output and no reset
2081
 *
2082
 * shake  wc_Shake object holding state.
2083
 * data  Data to absorb.
2084
 * len  Length of d to absorb in bytes.
2085
 * returns 0 on success.
2086
 */
2087
int wc_Shake256_Absorb(wc_Shake* shake, const byte* data, word32 len)
2088
0
{
2089
0
    int ret;
2090
2091
0
    if ((shake == NULL) || (data == NULL && len != 0)) {
2092
0
        return BAD_FUNC_ARG;
2093
0
    }
2094
2095
0
    ret = Sha3Update(shake, data, len, WC_SHA3_256_COUNT);
2096
0
    if (ret == 0) {
2097
0
        byte hash[1];
2098
0
        ret = Sha3Final(shake, 0x1f, hash, WC_SHA3_256_COUNT, 0);
2099
0
    }
2100
    /* No partial data. */
2101
0
    shake->i = 0;
2102
2103
0
    return ret;
2104
0
}
2105
2106
/* Squeeze the state to produce pseudo-random output.
2107
 *
2108
 * shake  wc_Shake object holding state.
2109
 * out  Output buffer.
2110
 * blockCnt  Number of blocks to write.
2111
 * returns 0 on success.
2112
 */
2113
int wc_Shake256_SqueezeBlocks(wc_Shake* shake, byte* out, word32 blockCnt)
2114
0
{
2115
0
    if ((shake == NULL) || (out == NULL && blockCnt != 0)) {
2116
0
        return BAD_FUNC_ARG;
2117
0
    }
2118
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
2119
    if (SHA3_BLOCK == sha3_block_avx2)
2120
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
2121
#endif
2122
0
    for (; (blockCnt > 0); blockCnt--) {
2123
    #ifdef SHA3_FUNC_PTR
2124
        (*SHA3_BLOCK)(shake->s);
2125
    #else
2126
0
        BlockSha3(shake->s);
2127
0
    #endif
2128
    #if defined(BIG_ENDIAN_ORDER)
2129
        ByteReverseWords64((word64*)out, shake->s, WC_SHA3_256_COUNT * 8);
2130
    #else
2131
0
        XMEMCPY(out, shake->s, WC_SHA3_256_COUNT * 8);
2132
0
    #endif
2133
0
        out += WC_SHA3_256_COUNT * 8;
2134
0
    }
2135
#if defined(WOLFSSL_USE_SAVE_VECTOR_REGISTERS) && defined(USE_INTEL_SPEEDUP)
2136
    if (SHA3_BLOCK == sha3_block_avx2)
2137
        RESTORE_VECTOR_REGISTERS();
2138
#endif
2139
2140
0
    return 0;
2141
0
}
2142
#endif
2143
2144
/* Dispose of any dynamically allocated data from the SHAKE256 operation.
2145
 * (Required for async ops.)
2146
 *
2147
 * shake  wc_Shake object holding state.
2148
 * returns 0 on success.
2149
 */
2150
void wc_Shake256_Free(wc_Shake* shake)
2151
9.56k
{
2152
9.56k
    wc_Sha3Free(shake);
2153
9.56k
}
2154
2155
/* Copy the state of the SHA3-512 operation.
2156
 *
2157
 * src  wc_Shake object holding state top copy.
2158
 * dst  wc_Shake object to copy into.
2159
 * returns 0 on success.
2160
 */
2161
int wc_Shake256_Copy(wc_Shake* src, wc_Shake* dst)
2162
0
{
2163
0
    return wc_Sha3Copy(src, dst);
2164
0
}
2165
#endif
2166
2167
#endif /* WOLFSSL_SHA3 */