Coverage Report

Created: 2026-11-12 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all-8bit/wolfcrypt/src/sha.c
Line
Count
Source
1
/* sha.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-1 Build Options:
24
 *
25
 * Core:
26
 * NO_SHA:                   Disable SHA-1 support entirely        default: off
27
 * USE_SLOW_SHA:             Disable SHA-1 loop unrolling          default: off
28
 * WC_HASH_DATA_ALIGNMENT:   Required data alignment for hashing   default: off
29
 *
30
 * Hardware Acceleration (SHA-1-specific):
31
 * WC_ASYNC_ENABLE_SHA:      Enable async SHA-1 operations         default: off
32
 * WOLFSSL_PIC32MZ_HASH:     PIC32MZ hardware SHA                  default: off
33
 * WOLFSSL_PSA_NO_HASH:      Disable PSA hash                      default: off
34
 * WOLFSSL_TI_HASH:          TI hardware hash                      default: off
35
 * WOLFSSL_RENESAS_RX64_HASH: Renesas RX64 hardware hash           default: off
36
 * FREESCALE_LTC_SHA:        Freescale LTC SHA acceleration        default: off
37
 * FREESCALE_MMCAU_SHA:      Freescale MMCAU SHA acceleration      default: off
38
 * STM32_HASH:               STM32 hardware hash                   default: off
39
 * PSOC6_HASH_SHA1:          PSoC6 hardware SHA-1                  default: off
40
 *
41
 * AArch64 assembly (WOLFSSL_ARMASM on __aarch64__):
42
 * WOLFSSL_ARMASM:           Use the AArch64 assembly transforms    default: off
43
 * WOLFSSL_ARMASM_NO_NEON:   Drop the NEON and crypto-extension
44
 *                           transforms, leaving only base          default: off
45
 * WOLFSSL_ARMASM_NO_HW_CRYPTO: Drop the crypto-extension transform default: off
46
 * WOLFSSL_ARMASM_NO_NEON_IMPL: Drop the NEON transform             default: off
47
 * WOLFSSL_ARMASM_NO_BASE_IMPL: Drop the base transform             default: off
48
 * WOLFSSL_ARMASM_INLINE:    Take the transforms from the inline
49
 *                           assembly twin rather than the .S file  default: off
50
 */
51
52
#define WC_FIPS_LL_CRYPTO
53
#define _WC_BUILDING_SHA_C
54
55
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
56
57
#ifdef DEBUG_WOLFSSL_VERBOSE
58
    #if defined(WOLFSSL_ESPIDF)
59
        #include <esp_log.h>
60
    #endif
61
#endif
62
63
#if !defined(NO_SHA)
64
65
#if FIPS_VERSION3_GE(2,0,0)
66
    #if defined(USE_WINDOWS_API) && defined(_MSC_VER)
67
        #pragma code_seg(".fipsA$k")
68
        #pragma const_seg(".fipsB$k")
69
    #endif
70
#endif
71
72
#include <wolfssl/wolfcrypt/sha.h>
73
#include <wolfssl/wolfcrypt/hash.h>
74
75
#if defined(WOLFSSL_ARMASM) && defined(__aarch64__)
76
    #include <wolfssl/wolfcrypt/cpuid.h>
77
#endif
78
79
#ifdef WOLF_CRYPTO_CB
80
    #include <wolfssl/wolfcrypt/cryptocb.h>
81
#endif
82
83
#ifdef WOLFSSL_IMXRT1170_CAAM
84
#include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h>
85
#endif
86
87
#if defined(WOLFSSL_PSOC6_CRYPTO)
88
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
89
#endif
90
91
/* Assume no hash HW available until supporting HW found. */
92
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
93
94
#if defined(WOLFSSL_ESP32_CRYPT) && \
95
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
96
    /* define a single keyword for simplicity & readability
97
     *
98
     * by default the HW acceleration is on for ESP32-WROOM32
99
     * but individual components can be turned off.
100
     */
101
    #define WOLFSSL_USE_ESP32_CRYPT_HASH_HW
102
    #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
103
104
    /* Although we have hardware acceleration,
105
    ** we may need to fall back to software */
106
    #define USE_SHA_SOFTWARE_IMPL
107
108
#elif defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
109
    /* The ESP32C3 is different; HW crypto here. Not yet implemented.
110
    ** We'll be using software for RISC-V at this time */
111
#else
112
    #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
113
#endif
114
115
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
116
#if defined(WOLFSSL_ESP32_CRYPT) && \
117
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
118
    /* define a single keyword for simplicity & readability
119
     *
120
     * by default the HW acceleration is on for ESP32-WROOM32
121
     * but individual components can be turned off.
122
     */
123
    #define WOLFSSL_USE_ESP32_CRYPT_HASH_HW
124
    #include "wolfssl/wolfcrypt/port/Espressif/esp32-crypt.h"
125
126
    /* Although we have hardware acceleration,
127
    ** we may need to fall back to software */
128
    #define USE_SHA_SOFTWARE_IMPL
129
    static const char* TAG = "wc_sha";
130
#elif defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
131
    /* The ESP32C3 is different; HW crypto here. Not yet implemented.
132
    ** We'll be using software for RISC-V at this time */
133
    static const char* TAG = "wc_sha-c3";
134
#else
135
    #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
136
#endif
137
138
#if defined(WOLFSSL_TI_HASH)
139
    /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */
140
141
#else
142
143
#ifdef NO_INLINE
144
    #include <wolfssl/wolfcrypt/misc.h>
145
#else
146
    #define WOLFSSL_MISC_INCLUDED
147
    #include <wolfcrypt/src/misc.c>
148
#endif
149
150
#if FIPS_VERSION3_GE(6,0,0)
151
    const unsigned int wolfCrypt_FIPS_sha_ro_sanity[2] =
152
                                                     { 0x1a2b3c4d, 0x00000013 };
153
    int wolfCrypt_FIPS_SHA_sanity(void)
154
    {
155
        return 0;
156
    }
157
#endif
158
159
/* Hardware Acceleration */
160
#if defined(WOLFSSL_PIC32MZ_HASH)
161
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
162
163
#elif defined(STM32_HASH)
164
165
    /* Supports CubeMX HAL or Standard Peripheral Library */
166
    int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
167
    {
168
        if (sha == NULL) {
169
            return BAD_FUNC_ARG;
170
        }
171
172
        WC_SILABS_CLEAR_HASH_CTX(sha);
173
        (void)devId;
174
        (void)heap;
175
176
        wc_Stm32_Hash_Init(&sha->stmCtx);
177
178
        return 0;
179
    }
180
181
    int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
182
    {
183
        int ret;
184
185
        if (sha == NULL || (data == NULL && len > 0)) {
186
            return BAD_FUNC_ARG;
187
        }
188
189
        ret = wolfSSL_CryptHwMutexLock();
190
        if (ret == 0) {
191
            ret = wc_Stm32_Hash_Update(&sha->stmCtx, HASH_AlgoSelection_SHA1,
192
                data, len, WC_SHA_BLOCK_SIZE);
193
            wolfSSL_CryptHwMutexUnLock();
194
        }
195
        return ret;
196
    }
197
198
    int wc_ShaFinal(wc_Sha* sha, byte* hash)
199
    {
200
        int ret;
201
202
        if (sha == NULL || hash == NULL) {
203
            return BAD_FUNC_ARG;
204
        }
205
206
        ret = wolfSSL_CryptHwMutexLock();
207
        if (ret == 0) {
208
            ret = wc_Stm32_Hash_Final(&sha->stmCtx, HASH_AlgoSelection_SHA1,
209
                hash, WC_SHA_DIGEST_SIZE);
210
            wolfSSL_CryptHwMutexUnLock();
211
        }
212
213
        (void)wc_InitSha(sha);  /* reset state */
214
215
        return ret;
216
    }
217
218
219
#elif defined(FREESCALE_LTC_SHA)
220
221
    #include "fsl_ltc.h"
222
    int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
223
    {
224
        if (sha == NULL) {
225
            return BAD_FUNC_ARG;
226
        }
227
228
        WC_SILABS_CLEAR_HASH_CTX(sha);
229
        (void)devId;
230
        (void)heap;
231
232
        LTC_HASH_Init(LTC_BASE, &sha->ctx, kLTC_Sha1, NULL, 0);
233
        return 0;
234
    }
235
236
    int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
237
    {
238
        LTC_HASH_Update(&sha->ctx, data, len);
239
        return 0;
240
    }
241
242
    int wc_ShaFinal(wc_Sha* sha, byte* hash)
243
    {
244
        word32 hashlen = WC_SHA_DIGEST_SIZE;
245
        LTC_HASH_Finish(&sha->ctx, hash, &hashlen);
246
        return wc_InitSha(sha);  /* reset state */
247
    }
248
249
250
#elif defined(FREESCALE_MMCAU_SHA)
251
252
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
253
        #include "cau_api.h"
254
    #else
255
        #include "fsl_mmcau.h"
256
    #endif
257
258
    #define USE_SHA_SOFTWARE_IMPL /* Only for API's, actual transform is here */
259
260
    #define XTRANSFORM(S,B)       Transform((S),(B))
261
    #define XTRANSFORM_LEN(S,B,L) Transform_Len((S),(B),(L))
262
263
    #ifndef WC_HASH_DATA_ALIGNMENT
264
        /* these hardware API's require 4 byte (word32) alignment */
265
        #define WC_HASH_DATA_ALIGNMENT 4
266
    #endif
267
268
    static int InitSha(wc_Sha* sha)
269
    {
270
        int ret = 0;
271
        ret = wolfSSL_CryptHwMutexLock();
272
        if (ret != 0) {
273
            return ret;
274
        }
275
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
276
        cau_sha1_initialize_output(sha->digest);
277
    #else
278
        MMCAU_SHA1_InitializeOutput((word32*)sha->digest);
279
    #endif
280
        wolfSSL_CryptHwMutexUnLock();
281
282
        sha->buffLen = 0;
283
        sha->loLen   = 0;
284
        sha->hiLen   = 0;
285
286
        return ret;
287
    }
288
289
    static int Transform(wc_Sha* sha, const byte* data)
290
    {
291
        int ret = wolfSSL_CryptHwMutexLock();
292
        if (ret == 0) {
293
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
294
            cau_sha1_hash_n((byte*)data, 1, sha->digest);
295
    #else
296
            MMCAU_SHA1_HashN((byte*)data, 1, (word32*)sha->digest);
297
    #endif
298
            wolfSSL_CryptHwMutexUnLock();
299
        }
300
        return ret;
301
    }
302
303
    static int Transform_Len(wc_Sha* sha, const byte* data, word32 len)
304
    {
305
        int ret = wolfSSL_CryptHwMutexLock();
306
        if (ret == 0) {
307
        #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0
308
            if ((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) {
309
                /* data pointer is NOT aligned,
310
                 * so copy and perform one block at a time */
311
                byte* local = (byte*)sha->buffer;
312
                while (len >= WC_SHA_BLOCK_SIZE) {
313
                    XMEMCPY(local, data, WC_SHA_BLOCK_SIZE);
314
                #ifdef FREESCALE_MMCAU_CLASSIC_SHA
315
                    cau_sha1_hash_n(local, 1, sha->digest);
316
                #else
317
                    MMCAU_SHA1_HashN(local, 1, sha->digest);
318
                #endif
319
                    data += WC_SHA_BLOCK_SIZE;
320
                    len  -= WC_SHA_BLOCK_SIZE;
321
                }
322
            }
323
            else
324
        #endif
325
            {
326
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
327
            cau_sha1_hash_n((byte*)data, len/WC_SHA_BLOCK_SIZE, sha->digest);
328
    #else
329
            MMCAU_SHA1_HashN((byte*)data, len/WC_SHA_BLOCK_SIZE,
330
                (word32*)sha->digest);
331
    #endif
332
            }
333
            wolfSSL_CryptHwMutexUnLock();
334
        }
335
        return ret;
336
    }
337
338
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
339
    !defined(WOLFSSL_QNX_CAAM)
340
    /* wolfcrypt/src/port/caam/caam_sha.c */
341
342
#elif defined(MAX3266X_SHA)
343
    /* Already brought in by sha.h */
344
    /* #include <wolfssl/wolfcrypt/port/maxim/max3266x.h> */
345
346
#elif defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) || \
347
      defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
348
349
    /* This function initializes SHA.
350
    ** This is automatically called by wc_ShaHash */
351
    static int InitSha(wc_Sha* sha)
352
    {
353
        int ret = 0;
354
355
        sha->digest[0] = 0x67452301L;
356
        sha->digest[1] = 0xEFCDAB89L;
357
        sha->digest[2] = 0x98BADCFEL;
358
        sha->digest[3] = 0x10325476L;
359
        sha->digest[4] = 0xC3D2E1F0L;
360
361
        sha->buffLen = 0;
362
        sha->loLen   = 0;
363
        sha->hiLen   = 0;
364
365
        /* HW needs to be carefully initialized, taking into account soft copy.
366
        ** If already in use; copy may revert to SW as needed. */
367
        ret = esp_sha_init(&(sha->ctx), WC_HASH_TYPE_SHA);
368
369
        return ret;
370
    }
371
372
#elif (defined(WOLFSSL_RENESAS_TSIP_TLS) || \
373
    defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
374
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)
375
376
    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */
377
378
#elif defined(WOLFSSL_RENESAS_RSIP) && \
379
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
380
381
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
382
383
#elif defined(WOLFSSL_IMXRT_DCP)
384
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
385
    /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */
386
387
#elif defined(WOLFSSL_NXP_HASHCRYPT_SHA)
388
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
389
390
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
391
392
    /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
393
394
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
395
396
/* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
397
398
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
399
400
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
401
    int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
402
    {
403
        if (sha == NULL) {
404
            return BAD_FUNC_ARG;
405
        }
406
        WC_SILABS_CLEAR_HASH_CTX(sha);
407
        (void)devId;
408
409
        return se050_hash_init(&sha->se050Ctx, heap);
410
    }
411
412
    int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
413
    {
414
        return se050_hash_update(&sha->se050Ctx, data, len);
415
416
    }
417
418
    int wc_ShaFinal(wc_Sha* sha, byte* hash)
419
    {
420
        int ret = 0;
421
        ret = se050_hash_final(&sha->se050Ctx, hash, WC_SHA_DIGEST_SIZE,
422
                               kAlgorithm_SSS_SHA1);
423
        return ret;
424
    }
425
    int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
426
    {
427
        int ret = 0;
428
        ret = se050_hash_final(&sha->se050Ctx, hash, WC_SHA_DIGEST_SIZE,
429
                               kAlgorithm_SSS_SHA1);
430
        return ret;
431
    }
432
433
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
434
/* implemented in wolfcrypt/src/port/psa/psa_hash.c */
435
#elif defined(PSOC6_HASH_SHA1)
436
    /* Implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */
437
#else
438
    /* Software implementation */
439
    #define USE_SHA_SOFTWARE_IMPL
440
441
    static int InitSha(wc_Sha* sha)
442
335k
    {
443
335k
        int ret = 0;
444
445
335k
        sha->digest[0] = 0x67452301L;
446
335k
        sha->digest[1] = 0xEFCDAB89L;
447
335k
        sha->digest[2] = 0x98BADCFEL;
448
335k
        sha->digest[3] = 0x10325476L;
449
335k
        sha->digest[4] = 0xC3D2E1F0L;
450
451
335k
        sha->buffLen = 0;
452
335k
        XMEMSET(sha->buffer, 0, sizeof(sha->buffer));
453
335k
        sha->loLen   = 0;
454
335k
        sha->hiLen   = 0;
455
335k
    #ifdef WOLFSSL_HASH_FLAGS
456
335k
        sha->flags = 0;
457
335k
    #endif
458
459
335k
        return ret;
460
335k
    }
461
#endif /* End Hardware Acceleration */
462
463
/* Software implementation */
464
#ifdef USE_SHA_SOFTWARE_IMPL
465
466
static WC_INLINE void AddLength(wc_Sha* sha, word32 len)
467
411k
{
468
411k
    word32 tmp = sha->loLen;
469
411k
    if ((sha->loLen += len) < tmp)
470
0
        sha->hiLen++;                       /* carry low to high */
471
411k
}
472
473
/* AArch64 assembly block transforms - wolfcrypt/src/port/arm/armv8-sha1-asm.S,
474
 * or its inline assembly twin armv8-sha1-asm_c.c.  Reached only when the
475
 * hardware-acceleration chain above selected the software API bodies and did
476
 * not install a transform of its own.
477
 *
478
 * Three implementations are built and the best one the CPU supports is chosen
479
 * on wc_InitSha_ex():
480
 *   crypto - the Armv8 crypto extension (sha1c/sha1p/sha1m/sha1h/sha1su*)
481
 *   neon   - rounds in general-purpose registers, message schedule in NEON
482
 *   base   - general-purpose registers only
483
 * and Transform() below is the last resort if none of them is usable.
484
 *
485
 * The choice follows the CPU id, so cpuid_select_flags() reaches the
486
 * implementations this CPU would not otherwise pick - clearing CPUID_SHA1
487
 * leaves neon, clearing CPUID_ASIMD as well leaves base.  That is how
488
 * sha_armasm_variant_test() in wolfcrypt/test/test.c checks all three on one
489
 * machine, whichever the CPU would have chosen.  Call it
490
 * before wc_InitSha_ex(), not part way through a hash: the selection is read
491
 * again on each init.
492
 *
493
 * Little-endian only.  Every one of the three loads the message with rev/rev32,
494
 * which is what makes a little-endian host read the stream big-endian; on a
495
 * big-endian host the plain loads are already right and the reversal would
496
 * corrupt them.  So a big-endian build does not take this arm and uses the
497
 * software path, unchanged. */
498
#if !defined(XTRANSFORM) && defined(WOLFSSL_ARMASM) && defined(__aarch64__) && \
499
    defined(LITTLE_ENDIAN_ORDER)
500
501
/* The assembly loads the message with rev32, so it consumes the raw big-endian
502
 * byte stream: wc_ShaUpdate()/wc_ShaFinal() must not byte-reverse sha->buffer
503
 * before handing a block over, and must instead put the trailing length words
504
 * into the stream big-endian.  See the uses of this macro below. */
505
#define WOLFSSL_ARMASM_SHA_TRANSFORM
506
/* Build Transform() even though XTRANSFORM is defined here - it is the
507
 * fallback when the CPU has no usable SIMD. */
508
#define NEED_SOFT_SHA
509
510
static int Transform(wc_Sha* sha, const byte* data);
511
static int Transform_Sha_Len(wc_Sha* sha, const byte* data, word32 len);
512
513
/* Which block transform the CPU id selected.
514
 *
515
 * An atomic holding a small enumerator rather than a function pointer.  Three
516
 * reasons.  The store is not a one-time init that could be argued benign:
517
 * cpuid_select_flags() is public, so the id - and with it the selection - can
518
 * change at any point in the process's life, and Sha_SetTransform() redoes it
519
 * on every wc_InitSha_ex().  Concurrent stores are idempotent, every caller
520
 * computing the same value from the same flags, but identical values do not
521
 * make a non-atomic store race-free in C.  And an enumerator plus direct calls
522
 * keeps mutable global function-pointer state out of the picture entirely.
523
 * sha512.c does the same for its PPC64 dispatch. */
524
enum {
525
    WC_SHA_TRANSFORM_C = 0,
526
    WC_SHA_TRANSFORM_BASE,
527
    WC_SHA_TRANSFORM_NEON,
528
    WC_SHA_TRANSFORM_CRYPTO
529
};
530
/* The C fallback until a selection is published, so it is always valid. */
531
static wolfSSL_Atomic_Uint sha_transform =
532
    WOLFSSL_ATOMIC_INITIALIZER(WC_SHA_TRANSFORM_C);
533
534
/* The crypto and NEON transforms work in the vector register file, so a kernel
535
 * module has to bracket them.  (They touch none of the callee-saved v8-v15 -
536
 * see vector_regs_no_stack() in the generator - but that only spares them a
537
 * prologue; the registers still belong to whoever was interrupted.)  The base
538
 * transform and the C fallback use general-purpose registers only. */
539
#ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
540
    #define WC_SHA_ARM64_SVR_BEGIN()                                        \
541
        do { int _svr_ret = SAVE_VECTOR_REGISTERS2();                       \
542
             if (_svr_ret != 0) return _svr_ret; } while (0)
543
    #define WC_SHA_ARM64_SVR_END()  RESTORE_VECTOR_REGISTERS()
544
#else
545
    #define WC_SHA_ARM64_SVR_BEGIN() WC_DO_NOTHING
546
    #define WC_SHA_ARM64_SVR_END()   WC_DO_NOTHING
547
#endif
548
549
/* The assembly entry points return nothing and cannot fail - wrap them so that
550
 * they all have the one type the dispatcher calls through. */
551
#if !defined(WOLFSSL_ARMASM_NO_NEON)
552
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
553
static int Transform_Sha_Len_crypto_aarch64(wc_Sha* sha, const byte* data,
554
    word32 len)
555
{
556
    WC_SHA_ARM64_SVR_BEGIN();
557
    Transform_Sha_Len_crypto(sha, data, len);
558
    WC_SHA_ARM64_SVR_END();
559
    return 0;
560
}
561
#endif
562
#if !defined(WOLFSSL_ARMASM_NO_NEON_IMPL) || \
563
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
564
static int Transform_Sha_Len_neon_aarch64(wc_Sha* sha, const byte* data,
565
    word32 len)
566
{
567
    WC_SHA_ARM64_SVR_BEGIN();
568
    Transform_Sha_Len_neon(sha, data, len);
569
    WC_SHA_ARM64_SVR_END();
570
    return 0;
571
}
572
#endif
573
#endif
574
#if !defined(WOLFSSL_ARMASM_NO_BASE_IMPL) || defined(WOLFSSL_ARMASM_NO_NEON)
575
static int Transform_Sha_Len_base_aarch64(wc_Sha* sha, const byte* data,
576
    word32 len)
577
{
578
    Transform_Sha_Len_base(sha, data, len);
579
    return 0;
580
}
581
#endif
582
583
/* Fallback for a CPU none of the assembly implementations can run on.
584
 * Transform() takes a block already reversed into big-endian words, so the
585
 * reversal the update and final paths skipped happens here. */
586
static int Transform_Sha_Len(wc_Sha* sha, const byte* data, word32 len)
587
{
588
    int ret = 0;
589
590
    while (len >= WC_SHA_BLOCK_SIZE) {
591
        word32 buffer[WC_SHA_BLOCK_SIZE / sizeof(word32)];
592
593
        XMEMCPY(buffer, data, WC_SHA_BLOCK_SIZE);
594
    #ifdef LITTLE_ENDIAN_ORDER
595
        ByteReverseWords(buffer, buffer, WC_SHA_BLOCK_SIZE);
596
    #endif
597
        ret = Transform(sha, (const byte*)buffer);
598
        if (ret != 0)
599
            break;
600
        data += WC_SHA_BLOCK_SIZE;
601
        len  -= WC_SHA_BLOCK_SIZE;
602
    }
603
604
    return ret;
605
}
606
607
/* Call the selected transform.  One atomic read, then a direct call. */
608
static WC_INLINE int Transform_Sha_Len_aarch64(wc_Sha* sha, const byte* data,
609
    word32 len)
610
{
611
    switch (WOLFSSL_ATOMIC_LOAD(sha_transform)) {
612
#if !defined(WOLFSSL_ARMASM_NO_NEON)
613
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
614
    case WC_SHA_TRANSFORM_CRYPTO:
615
        return Transform_Sha_Len_crypto_aarch64(sha, data, len);
616
#endif
617
#if !defined(WOLFSSL_ARMASM_NO_NEON_IMPL) || \
618
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
619
    case WC_SHA_TRANSFORM_NEON:
620
        return Transform_Sha_Len_neon_aarch64(sha, data, len);
621
#endif
622
#endif
623
#if !defined(WOLFSSL_ARMASM_NO_BASE_IMPL) || defined(WOLFSSL_ARMASM_NO_NEON)
624
    case WC_SHA_TRANSFORM_BASE:
625
        return Transform_Sha_Len_base_aarch64(sha, data, len);
626
#endif
627
    default:
628
        return Transform_Sha_Len(sha, data, len);
629
    }
630
}
631
632
static WC_INLINE int Transform_Sha_aarch64(wc_Sha* sha, const byte* data)
633
{
634
    return Transform_Sha_Len_aarch64(sha, data, WC_SHA_BLOCK_SIZE);
635
}
636
637
/* Publish the transform for the CPU features currently selected.
638
 *
639
 * Recomputed on every init rather than cached against the id it was made from:
640
 * the id is a handful of bit tests and init is not a hot path, and it leaves one
641
 * piece of shared state instead of two that could be read out of step with each
642
 * other.  Changing the selection part way through a hash is still the one thing
643
 * that is not safe, because wc_ShaTransform() byte-swaps or not according to
644
 * which implementation is selected. */
645
static void Sha_SetTransform(void)
646
{
647
    cpuid_flags_t cpuid_flags = cpuid_get_flags();
648
    unsigned int transform;
649
650
#if !defined(WOLFSSL_ARMASM_NO_NEON)
651
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
652
    if (IS_AARCH64_SHA1(cpuid_flags)) {
653
        transform = WC_SHA_TRANSFORM_CRYPTO;
654
    }
655
    else
656
#endif
657
#if !defined(WOLFSSL_ARMASM_NO_NEON_IMPL) || \
658
    defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
659
    if (IS_AARCH64_ASIMD(cpuid_flags)) {
660
        transform = WC_SHA_TRANSFORM_NEON;
661
    }
662
    else
663
#endif
664
#endif
665
#if !defined(WOLFSSL_ARMASM_NO_BASE_IMPL) || defined(WOLFSSL_ARMASM_NO_NEON)
666
    {
667
        transform = WC_SHA_TRANSFORM_BASE;
668
    }
669
#else
670
    {
671
        transform = WC_SHA_TRANSFORM_C;
672
    }
673
#endif
674
675
    WOLFSSL_ATOMIC_STORE(sha_transform, transform);
676
    (void)cpuid_flags;
677
}
678
679
#define XTRANSFORM      Transform_Sha_aarch64
680
#define XTRANSFORM_LEN  Transform_Sha_Len_aarch64
681
682
#endif /* !XTRANSFORM && WOLFSSL_ARMASM && __aarch64__ */
683
684
/* Check if custom wc_Sha transform is used.  A backend that supplies its own
685
 * XTRANSFORM can still ask for Transform() to be built - as the AArch64
686
 * assembly does, to fall back on when the CPU has no usable SIMD - by defining
687
 * NEED_SOFT_SHA. */
688
#if !defined(XTRANSFORM) || defined(NEED_SOFT_SHA)
689
    #ifndef XTRANSFORM
690
875k
        #define XTRANSFORM(S,B)   Transform((S),(B))
691
    #endif
692
693
15.0M
    #define blk0(i) (W[i] = *((const word32*)&data[(i)*sizeof(word32)]))
694
60.0M
    #define blk1(i) (W[(i)&15] = \
695
60.0M
        rotlFixed(W[((i)+13)&15]^W[((i)+8)&15]^W[((i)+2)&15]^W[(i)&15],1))
696
697
18.7M
    #define f1(x,y,z) ((z)^((x) &((y)^(z))))
698
18.7M
    #define f2(x,y,z) ((x)^(y)^(z))
699
18.7M
    #define f3(x,y,z) (((x)&(y))|((z)&((x)|(y))))
700
18.7M
    #define f4(x,y,z) ((x)^(y)^(z))
701
702
    #if defined(WOLFSSL_NUCLEUS_1_2) || defined(NUCLEUS_PLUS_2_3)
703
        /* nucleus.h also defines R1-R4 */
704
        #undef R1
705
        #undef R2
706
        #undef R3
707
        #undef R4
708
    #endif
709
710
    /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
711
15.0M
    #define R0(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk0((i)) + 0x5A827999+ \
712
15.0M
        rotlFixed((v),5); (w) = rotlFixed((w),30);
713
3.75M
    #define R1(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk1((i)) + 0x5A827999+ \
714
3.75M
        rotlFixed((v),5); (w) = rotlFixed((w),30);
715
18.7M
    #define R2(v,w,x,y,z,i) (z)+= f2((w),(x),(y)) + blk1((i)) + 0x6ED9EBA1+ \
716
18.7M
        rotlFixed((v),5); (w) = rotlFixed((w),30);
717
18.7M
    #define R3(v,w,x,y,z,i) (z)+= f3((w),(x),(y)) + blk1((i)) + 0x8F1BBCDC+ \
718
18.7M
        rotlFixed((v),5); (w) = rotlFixed((w),30);
719
18.7M
    #define R4(v,w,x,y,z,i) (z)+= f4((w),(x),(y)) + blk1((i)) + 0xCA62C1D6+ \
720
18.7M
        rotlFixed((v),5); (w) = rotlFixed((w),30);
721
722
    static int Transform(wc_Sha* sha, const byte* data)
723
938k
    {
724
938k
        word32 W[WC_SHA_BLOCK_SIZE / sizeof(word32)];
725
726
        /* Copy context->state[] to working vars */
727
938k
        word32 a = sha->digest[0];
728
938k
        word32 b = sha->digest[1];
729
938k
        word32 c = sha->digest[2];
730
938k
        word32 d = sha->digest[3];
731
938k
        word32 e = sha->digest[4];
732
733
    #ifdef USE_SLOW_SHA
734
        word32 t, i;
735
736
    #ifdef WOLFSSL_CHECK_MEM_ZERO
737
        /* Zero first: the registration call takes const void*, and a pointer
738
         * to an uninitialized object trips -Wmaybe-uninitialized under
739
         * -Werror. */
740
        XMEMSET(W, 0, sizeof(W));
741
        wc_MemZero_Add("Sha Transform W", W, sizeof(W));
742
    #endif
743
        for (i = 0; i < 16; i++) {
744
            R0(a, b, c, d, e, i);
745
            t = e; e = d; d = c; c = b; b = a; a = t;
746
        }
747
748
        for (; i < 20; i++) {
749
            R1(a, b, c, d, e, i);
750
            t = e; e = d; d = c; c = b; b = a; a = t;
751
        }
752
753
        for (; i < 40; i++) {
754
            R2(a, b, c, d, e, i);
755
            t = e; e = d; d = c; c = b; b = a; a = t;
756
        }
757
758
        for (; i < 60; i++) {
759
            R3(a, b, c, d, e, i);
760
            t = e; e = d; d = c; c = b; b = a; a = t;
761
        }
762
763
        for (; i < 80; i++) {
764
            R4(a, b, c, d, e, i);
765
            t = e; e = d; d = c; c = b; b = a; a = t;
766
        }
767
    #else
768
        /* nearly 1 K bigger in code size but 25% faster */
769
        /* 4 rounds of 20 operations each. Loop unrolled. */
770
    #ifdef WOLFSSL_CHECK_MEM_ZERO
771
        /* Zero first: the registration call takes const void*, and a pointer
772
         * to an uninitialized object trips -Wmaybe-uninitialized under
773
         * -Werror. */
774
        XMEMSET(W, 0, sizeof(W));
775
        wc_MemZero_Add("Sha Transform W", W, sizeof(W));
776
    #endif
777
938k
        R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
778
938k
        R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
779
938k
        R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
780
938k
        R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
781
782
938k
        R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
783
784
938k
        R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
785
938k
        R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
786
938k
        R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
787
938k
        R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
788
938k
        R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
789
790
938k
        R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
791
938k
        R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
792
938k
        R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
793
938k
        R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
794
938k
        R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
795
796
938k
        R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
797
938k
        R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
798
938k
        R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
799
938k
        R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
800
938k
        R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
801
938k
    #endif
802
803
        /* Add the working vars back into digest state[] */
804
938k
        sha->digest[0] += a;
805
938k
        sha->digest[1] += b;
806
938k
        sha->digest[2] += c;
807
938k
        sha->digest[3] += d;
808
938k
        sha->digest[4] += e;
809
810
938k
        (void)data; /* Not used */
811
812
938k
        ForceZero(W, sizeof(W));
813
    #ifdef WOLFSSL_CHECK_MEM_ZERO
814
        wc_MemZero_Check(W, sizeof(W));
815
    #endif
816
938k
        return 0;
817
938k
    }
818
#endif /* !XTRANSFORM || NEED_SOFT_SHA, when USE_SHA_SOFTWARE_IMPL */
819
820
821
/*
822
** wolfCrypt InitSha external wrapper.
823
**
824
** we'll assume this is ALWAYS for a new, uninitialized sha
825
*/
826
int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
827
201k
{
828
201k
    int ret = 0;
829
201k
    if (sha == NULL) {
830
0
        return BAD_FUNC_ARG;
831
0
    }
832
833
201k
    WC_SILABS_CLEAR_HASH_CTX(sha);
834
835
#ifdef WOLFSSL_ARMASM_SHA_TRANSFORM
836
    Sha_SetTransform();
837
#endif
838
839
201k
    sha->heap = heap;
840
201k
#ifdef WOLF_CRYPTO_CB
841
201k
    sha->devId = devId;
842
201k
    sha->devCtx = NULL;
843
201k
#endif
844
#ifdef WOLFSSL_HASH_KEEP
845
    sha->msg  = NULL;
846
    sha->len  = 0;
847
    sha->used = 0;
848
#endif
849
850
#ifdef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
851
    if (sha->ctx.mode != ESP32_SHA_INIT) {
852
        /* it may be interesting to see old values during debugging */
853
        ESP_LOGV(TAG, "Set ctx mode from prior value: %d", sha->ctx.mode);
854
    }
855
    /* We know this is a fresh, uninitialized item, so set to INIT */
856
    sha->ctx.mode = ESP32_SHA_INIT;
857
#endif
858
859
201k
    ret = InitSha(sha);
860
201k
    if (ret != 0) {
861
0
        return ret;
862
0
    }
863
864
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
865
    ret = wolfAsync_DevCtxInit(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA,
866
                                                            sha->heap, devId);
867
#else
868
201k
    (void)devId;
869
201k
#endif /* WOLFSSL_ASYNC_CRYPT */
870
#ifdef WOLFSSL_IMXRT1170_CAAM
871
   ret = wc_CAAM_HashInit(&sha->hndl, &sha->ctx, WC_HASH_TYPE_SHA);
872
#endif
873
874
201k
    return ret;
875
201k
} /* wc_InitSha_ex */
876
877
/* do block size increments/updates */
878
int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
879
385k
{
880
385k
    int ret = 0;
881
385k
    word32 blocksLen;
882
385k
    byte* local;
883
884
385k
    if (sha == NULL) {
885
0
        return BAD_FUNC_ARG;
886
0
    }
887
888
385k
    if (data == NULL && len == 0) {
889
        /* valid, but do nothing */
890
27
        return 0;
891
27
    }
892
893
385k
    if (data == NULL) {
894
0
        return BAD_FUNC_ARG;
895
0
    }
896
897
385k
#ifdef WOLF_CRYPTO_CB
898
385k
    if (sha->devId != INVALID_DEVID) {
899
0
        ret = wc_CryptoCb_ShaHash(sha, data, len, NULL);
900
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
901
0
            return ret;
902
0
        ret = 0; /* reset ret */
903
        /* fall-through when unavailable */
904
0
    }
905
385k
#endif
906
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
907
    if (sha->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA) {
908
    #if defined(HAVE_INTEL_QA)
909
        return IntelQaSymSha(&sha->asyncDev, NULL, data, len);
910
    #endif
911
    }
912
#endif /* WOLFSSL_ASYNC_CRYPT */
913
914
    /* check that internal buffLen is valid */
915
385k
    if (sha->buffLen >= WC_SHA_BLOCK_SIZE) {
916
0
        return BUFFER_E;
917
0
    }
918
919
    /* add length for final */
920
385k
    AddLength(sha, len);
921
922
385k
    local = (byte*)sha->buffer;
923
924
    /* process any remainder from previous operation */
925
385k
    if (sha->buffLen > 0) {
926
230k
        blocksLen = min(len, WC_SHA_BLOCK_SIZE - sha->buffLen);
927
230k
        XMEMCPY(&local[sha->buffLen], data, blocksLen);
928
929
230k
        sha->buffLen += blocksLen;
930
230k
        data         += blocksLen;
931
230k
        len          -= blocksLen;
932
933
230k
        if (sha->buffLen == WC_SHA_BLOCK_SIZE) {
934
        #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
935
            if (sha->ctx.mode == ESP32_SHA_INIT) {
936
                #if defined(WOLFSSL_DEBUG_MUTEX)
937
                {
938
                    ESP_LOGI(TAG, "wc_ShaUpdate try hardware");
939
                }
940
                #endif
941
                esp_sha_try_hw_lock(&sha->ctx);
942
            }
943
        #endif
944
945
60.3k
        #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) && \
946
60.3k
            !defined(WOLFSSL_ARMASM_SHA_TRANSFORM)
947
            #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
948
                  defined(CONFIG_IDF_TARGET_ESP8684) || \
949
                  defined(CONFIG_IDF_TARGET_ESP32C3) || \
950
                  defined(CONFIG_IDF_TARGET_ESP32C6)    \
951
                ) && \
952
                 defined(WOLFSSL_ESP32_CRYPT) && \
953
                !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
954
                /* For Espressif RISC-V Targets, we *may* need to reverse bytes
955
                 * depending on if HW is active or not. */
956
                if (esp_sha_need_byte_reversal(&sha->ctx))
957
            #endif
958
60.3k
            {
959
            #ifdef WOLFSSL_WIDE_BYTE
960
                /* CHAR_BIT != 8: pack the 16 big-endian schedule words
961
                 * octet-wise rather than reversing whole cells. */
962
                WordsFromBytesBE32(sha->buffer, (const byte*)sha->buffer,
963
                    WC_SHA_BLOCK_SIZE / 4);
964
            #else
965
60.3k
                ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
966
60.3k
            #endif
967
60.3k
            }
968
60.3k
        #endif
969
970
        #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
971
            if (sha->ctx.mode == ESP32_SHA_SW) {
972
                #if defined(WOLFSSL_DEBUG_MUTEX)
973
                {
974
                    ESP_LOGI(TAG, "wc_ShaUpdate process software");
975
                }
976
                #endif
977
                ret = XTRANSFORM(sha, (const byte*)local);
978
            }
979
            else {
980
                #if defined(WOLFSSL_DEBUG_MUTEX)
981
                {
982
                    ESP_LOGI(TAG, "wc_ShaUpdate process hardware");
983
                }
984
                #endif
985
                esp_sha_process(sha, (const byte*)local);
986
            }
987
        #elif defined (WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW)
988
            ESP_LOGI(TAG, "wc_ShaUpdate not implemented for ESP32C3");
989
            ret = XTRANSFORM(sha, (const byte*)local);
990
        #else
991
60.3k
            ret = XTRANSFORM(sha, (const byte*)local);
992
60.3k
        #endif
993
60.3k
            if (ret != 0) {
994
0
                return ret;
995
0
            }
996
997
60.3k
            sha->buffLen = 0; /* Nothing left to do, so set to zero. */
998
60.3k
        } /* (sha->buffLen == WC_SHA_BLOCK_SIZE) */
999
230k
    } /* (sha->buffLen > 0)  Process any remainder from previous operation. */
1000
1001
    /* process blocks */
1002
#ifdef XTRANSFORM_LEN
1003
    /* get number of blocks */
1004
    /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */
1005
    /* len (masked by 0xFFFFFFC0) returns block aligned length */
1006
    blocksLen = len & ~(WC_SHA_BLOCK_SIZE-1);
1007
    if (blocksLen > 0) {
1008
        /* Byte reversal performed in function if required. */
1009
        ret = XTRANSFORM_LEN(sha, data, blocksLen);
1010
        if (ret != 0) {
1011
            return ret;
1012
        }
1013
        data += blocksLen;
1014
        len  -= blocksLen;
1015
    }
1016
#else
1017
1.08M
    while (len >= WC_SHA_BLOCK_SIZE) {
1018
702k
        word32* local32 = sha->buffer;
1019
        /* optimization to avoid memcpy if data pointer is properly aligned */
1020
        /* Little Endian requires byte swap, so can't use data directly */
1021
    #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(LITTLE_ENDIAN_ORDER)
1022
        if (((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {
1023
            local32 = (word32*)data;
1024
        }
1025
        else
1026
    #endif
1027
702k
        {
1028
702k
            XMEMCPY(local32, data, WC_SHA_BLOCK_SIZE);
1029
702k
        }
1030
1031
702k
        data += WC_SHA_BLOCK_SIZE;
1032
702k
        len  -= WC_SHA_BLOCK_SIZE;
1033
1034
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1035
        if (sha->ctx.mode == ESP32_SHA_INIT){
1036
            esp_sha_try_hw_lock(&sha->ctx);
1037
        }
1038
    #endif
1039
1040
702k
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) && \
1041
702k
        !defined(WOLFSSL_ARMASM_SHA_TRANSFORM)
1042
        #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
1043
              defined(CONFIG_IDF_TARGET_ESP8684) || \
1044
              defined(CONFIG_IDF_TARGET_ESP32C3) || \
1045
              defined(CONFIG_IDF_TARGET_ESP32C6)    \
1046
            ) && \
1047
             defined(WOLFSSL_ESP32_CRYPT) && \
1048
            !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
1049
            /* For Espressif RISC-V Targets, we *may* need to reverse bytes
1050
             * depending on if HW is active or not. */
1051
            if (esp_sha_need_byte_reversal(&sha->ctx))
1052
        #endif
1053
702k
        {
1054
        #ifdef WOLFSSL_WIDE_BYTE
1055
            WordsFromBytesBE32(local32, (const byte*)local32,
1056
                WC_SHA_BLOCK_SIZE / 4);
1057
        #else
1058
702k
            ByteReverseWords(local32, local32, WC_SHA_BLOCK_SIZE);
1059
702k
        #endif
1060
702k
        }
1061
702k
    #endif
1062
1063
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1064
        if (sha->ctx.mode == ESP32_SHA_SW){
1065
            ret = XTRANSFORM(sha, (const byte*)local32);
1066
        }
1067
        else {
1068
            esp_sha_process(sha, (const byte*)local32);
1069
        }
1070
    #else
1071
702k
        ret = XTRANSFORM(sha, (const byte*)local32);
1072
702k
    #endif
1073
702k
    }
1074
385k
#endif /* XTRANSFORM_LEN */
1075
1076
    /* save remainder */
1077
385k
    if (len > 0) {
1078
174k
        XMEMCPY(local, data, len);
1079
174k
        sha->buffLen = len;
1080
174k
    }
1081
1082
385k
    return ret;
1083
385k
}
1084
1085
int wc_ShaFinalRaw(wc_Sha* sha, byte* hash)
1086
111
{
1087
111
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_WIDE_BYTE)
1088
111
    word32 digest[WC_SHA_DIGEST_SIZE / sizeof(word32)];
1089
111
    XMEMSET(digest, 0, sizeof(digest));
1090
111
#endif
1091
1092
111
    if (sha == NULL || hash == NULL) {
1093
0
        return BAD_FUNC_ARG;
1094
0
    }
1095
#if defined(WOLFSSL_CHECK_MEM_ZERO) && defined(LITTLE_ENDIAN_ORDER) && \
1096
    !defined(WOLFSSL_WIDE_BYTE)
1097
    wc_MemZero_Add("wc_ShaFinalRaw digest", digest, sizeof(digest));
1098
#endif
1099
1100
#if defined(WOLFSSL_WIDE_BYTE)
1101
    /* CHAR_BIT != 8: write the digest words as big-endian octets. */
1102
    BytesFromWordsBE32(hash, sha->digest, WC_SHA_DIGEST_SIZE);
1103
#elif defined(LITTLE_ENDIAN_ORDER)
1104
    #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
1105
          defined(CONFIG_IDF_TARGET_ESP8684) || \
1106
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
1107
          defined(CONFIG_IDF_TARGET_ESP32C6)    \
1108
        ) && \
1109
         defined(WOLFSSL_ESP32_CRYPT) && \
1110
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
1111
        /* For Espressif RISC-V Targets, we *may* need to reverse bytes
1112
         * depending on if HW is active or not. */
1113
        if (esp_sha_need_byte_reversal(&sha->ctx))
1114
    #endif
1115
111
    {
1116
111
        ByteReverseWords((word32*)digest, (word32*)sha->digest, WC_SHA_DIGEST_SIZE);
1117
111
    }
1118
111
    XMEMCPY(hash, (byte *)&digest[0], WC_SHA_DIGEST_SIZE);
1119
111
    ForceZero(digest, sizeof(digest));
1120
#ifdef WOLFSSL_CHECK_MEM_ZERO
1121
    wc_MemZero_Check(digest, sizeof(digest));
1122
#endif
1123
#else
1124
    XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE);
1125
#endif
1126
1127
111
    return 0;
1128
111
}
1129
1130
/*
1131
** Finalizes hashing of data. Result is placed into hash.
1132
** Resets state of sha struct.
1133
*/
1134
int wc_ShaFinal(wc_Sha* sha, byte* hash)
1135
107k
{
1136
107k
    int ret;
1137
107k
    byte* local;
1138
1139
107k
    if (sha == NULL || hash == NULL) {
1140
0
        return BAD_FUNC_ARG;
1141
0
    }
1142
1143
107k
    local = (byte*)sha->buffer;
1144
1145
107k
#ifdef WOLF_CRYPTO_CB
1146
107k
    if (sha->devId != INVALID_DEVID) {
1147
0
        ret = wc_CryptoCb_ShaHash(sha, NULL, 0, hash);
1148
0
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1149
0
            return ret;
1150
        /* fall-through when unavailable */
1151
0
    }
1152
107k
#endif
1153
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
1154
    if (sha->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA) {
1155
    #if defined(HAVE_INTEL_QA)
1156
        return IntelQaSymSha(&sha->asyncDev, hash, NULL, WC_SHA_DIGEST_SIZE);
1157
    #endif
1158
    }
1159
#endif /* WOLFSSL_ASYNC_CRYPT */
1160
1161
    /* we'll add a 0x80 byte at the end,
1162
    ** so make sure we have appropriate buffer length. */
1163
107k
    if (sha->buffLen > WC_SHA_BLOCK_SIZE - 1) {
1164
        /* exit with error code if there's a bad buffer size in buffLen */
1165
0
        return BAD_STATE_E;
1166
0
    } /* buffLen check */
1167
1168
107k
    local[sha->buffLen++] = 0x80;  /* add 1 */
1169
1170
    /* pad with zeros */
1171
107k
    if (sha->buffLen > WC_SHA_PAD_SIZE) {
1172
4.88k
        if (sha->buffLen < WC_SHA_BLOCK_SIZE) {
1173
4.10k
            XMEMSET(&local[sha->buffLen], 0, WC_SHA_BLOCK_SIZE - sha->buffLen);
1174
4.10k
        }
1175
1176
4.88k
        sha->buffLen += WC_SHA_BLOCK_SIZE - sha->buffLen;
1177
1178
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1179
        /* For a fresh sha.ctx, try to use hardware acceleration */
1180
        if (sha->ctx.mode == ESP32_SHA_INIT) {
1181
            esp_sha_try_hw_lock(&sha->ctx);
1182
        }
1183
    #endif
1184
1185
4.88k
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) && \
1186
4.88k
        !defined(WOLFSSL_ARMASM_SHA_TRANSFORM)
1187
        #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
1188
              defined(CONFIG_IDF_TARGET_ESP8684) || \
1189
              defined(CONFIG_IDF_TARGET_ESP32C3) || \
1190
              defined(CONFIG_IDF_TARGET_ESP32C6)    \
1191
            ) && \
1192
             defined(WOLFSSL_ESP32_CRYPT) && \
1193
            !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
1194
            /* For Espressif RISC-V Targets, we *may* need to reverse bytes
1195
             * depending on if HW is active or not. */
1196
            if (esp_sha_need_byte_reversal(&sha->ctx))
1197
        #endif
1198
4.88k
        {
1199
        #ifdef WOLFSSL_WIDE_BYTE
1200
            WordsFromBytesBE32(sha->buffer, (const byte*)sha->buffer,
1201
                WC_SHA_BLOCK_SIZE / 4);
1202
        #else
1203
4.88k
            ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
1204
4.88k
        #endif
1205
4.88k
        }
1206
4.88k
    #endif
1207
1208
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1209
        /* if HW was busy, we may need to fall back to SW. */
1210
        if (sha->ctx.mode == ESP32_SHA_SW) {
1211
            ret = XTRANSFORM(sha, (const byte*)local);
1212
        }
1213
        else {
1214
            ret = esp_sha_process(sha, (const byte*)local);
1215
        }
1216
    #else
1217
        /*
1218
        ** The #if defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) also falls
1219
        ** though here to SW, as it's not yet implemented for HW.
1220
        */
1221
4.88k
        ret = XTRANSFORM(sha, (const byte*)local);
1222
4.88k
    #endif
1223
4.88k
        if (ret != 0) {
1224
0
            return ret;
1225
0
        }
1226
1227
4.88k
        sha->buffLen = 0;
1228
4.88k
    } /* (sha->buffLen > WC_SHA_PAD_SIZE) */
1229
1230
107k
    XMEMSET(&local[sha->buffLen], 0, WC_SHA_PAD_SIZE - sha->buffLen);
1231
1232
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1233
    if (sha->ctx.mode == ESP32_SHA_INIT) {
1234
        esp_sha_try_hw_lock(&sha->ctx);
1235
    }
1236
#endif
1237
1238
    /* WOLFSSL_WIDE_BYTE packs the whole final block (including the length
1239
     * words) octet-wise below, so skip the in-place word reversal here. */
1240
107k
#if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) && \
1241
107k
    !defined(WOLFSSL_WIDE_BYTE) && \
1242
107k
    !defined(WOLFSSL_ARMASM_SHA_TRANSFORM)
1243
    #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
1244
          defined(CONFIG_IDF_TARGET_ESP8684) || \
1245
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
1246
          defined(CONFIG_IDF_TARGET_ESP32C6)    \
1247
        ) && \
1248
         defined(WOLFSSL_ESP32_CRYPT) && \
1249
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
1250
        /* For Espressif RISC-V Targets, we *may* need to reverse bytes
1251
         * depending on if HW is active or not. */
1252
        if (esp_sha_need_byte_reversal(&sha->ctx))
1253
    #endif
1254
107k
    { /* reminder local also points to sha->buffer  */
1255
107k
        ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE);
1256
107k
    }
1257
107k
#endif
1258
1259
    /* store lengths */
1260
    /* put lengths in bits */
1261
107k
    sha->hiLen = (sha->loLen >> (CHAR_BIT*sizeof(sha->loLen) - 3)) +
1262
107k
                                                            (sha->hiLen << 3);
1263
107k
    sha->loLen = sha->loLen << 3;
1264
1265
    /* ! length ordering dependent on digest endian type ! */
1266
#ifdef WOLFSSL_WIDE_BYTE
1267
    /* CHAR_BIT != 8: place the 64-bit length as 8 big-endian octets, then pack
1268
     * all 16 big-endian schedule words octet-wise (covers the length words). */
1269
    local[WC_SHA_PAD_SIZE + 0] = (byte)((sha->hiLen >> 24) & 0xFF);
1270
    local[WC_SHA_PAD_SIZE + 1] = (byte)((sha->hiLen >> 16) & 0xFF);
1271
    local[WC_SHA_PAD_SIZE + 2] = (byte)((sha->hiLen >>  8) & 0xFF);
1272
    local[WC_SHA_PAD_SIZE + 3] = (byte)((sha->hiLen      ) & 0xFF);
1273
    local[WC_SHA_PAD_SIZE + 4] = (byte)((sha->loLen >> 24) & 0xFF);
1274
    local[WC_SHA_PAD_SIZE + 5] = (byte)((sha->loLen >> 16) & 0xFF);
1275
    local[WC_SHA_PAD_SIZE + 6] = (byte)((sha->loLen >>  8) & 0xFF);
1276
    local[WC_SHA_PAD_SIZE + 7] = (byte)((sha->loLen      ) & 0xFF);
1277
    WordsFromBytesBE32(sha->buffer, (const byte*)sha->buffer,
1278
        WC_SHA_BLOCK_SIZE / 4);
1279
#else
1280
107k
    XMEMCPY(&local[WC_SHA_PAD_SIZE], &sha->hiLen, sizeof(word32));
1281
107k
    XMEMCPY(&local[WC_SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32));
1282
107k
#endif
1283
1284
#if defined(WOLFSSL_ARMASM_SHA_TRANSFORM) && defined(LITTLE_ENDIAN_ORDER) && \
1285
    !defined(WOLFSSL_WIDE_BYTE)
1286
    /* The assembly byte-swaps the block itself, so the rest of this block was
1287
     * never reversed - store the length words big-endian to match.  Only on a
1288
     * little-endian host: on a big-endian one the XMEMCPY above already laid
1289
     * them down big-endian, and reversing would corrupt the final block for the
1290
     * C fallback, which is the transform such a build would select.  (The
1291
     * WOLFSSL_WIDE_BYTE path above already placed them as octets, and cannot
1292
     * occur on AArch64 anyway, where CHAR_BIT is 8.) */
1293
    ByteReverseWords(&sha->buffer[WC_SHA_PAD_SIZE / sizeof(word32)],
1294
                     &sha->buffer[WC_SHA_PAD_SIZE / sizeof(word32)],
1295
                     2 * sizeof(word32));
1296
#endif
1297
1298
#if defined(FREESCALE_MMCAU_SHA)
1299
    /* Kinetis requires only these bytes reversed */
1300
    ByteReverseWords(&sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)],
1301
                     &sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)],
1302
                     2 * sizeof(word32));
1303
#endif
1304
1305
1306
#if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
1307
      defined(CONFIG_IDF_TARGET_ESP8684) || \
1308
      defined(CONFIG_IDF_TARGET_ESP32C3) || \
1309
      defined(CONFIG_IDF_TARGET_ESP32C6)    \
1310
    ) && \
1311
    defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
1312
if (sha->ctx.mode == ESP32_SHA_HW) {
1313
    #if defined(WOLFSSL_SUPER_VERBOSE_DEBUG)
1314
    {
1315
        ESP_LOGV(TAG, "Start: Reverse PAD SIZE Endianness.");
1316
    }
1317
    #endif
1318
    ByteReverseWords(&sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)], /* out */
1319
                     &sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)], /* in  */
1320
                     2 * sizeof(word32) /* byte count to reverse */
1321
                    );
1322
    #if defined(WOLFSSL_SUPER_VERBOSE_DEBUG)
1323
    {
1324
        ESP_LOGV(TAG, "End: Reverse PAD SIZE Endianness.");
1325
    }
1326
    #endif
1327
} /* end if (sha->ctx.mode == ESP32_SHA_HW) */
1328
#endif
1329
1330
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1331
    if (sha->ctx.mode == ESP32_SHA_SW) {
1332
        ret = XTRANSFORM(sha, (const byte*)local);
1333
    }
1334
    else {
1335
        ret = esp_sha_digest_process(sha, 1);
1336
    }
1337
/*
1338
** The #if defined(WOLFSSL_USE_ESP32C3_CRYPT_HASH_HW) also falls
1339
** though here to SW, as it's not yet implemented for HW.
1340
*/
1341
#else
1342
107k
    ret = XTRANSFORM(sha, (const byte*)local);
1343
107k
#endif
1344
1345
#if defined(WOLFSSL_WIDE_BYTE)
1346
    /* CHAR_BIT != 8: write the digest words as big-endian octets. */
1347
    BytesFromWordsBE32(hash, sha->digest, WC_SHA_DIGEST_SIZE);
1348
#else
1349
107k
#ifdef LITTLE_ENDIAN_ORDER
1350
    #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
1351
          defined(CONFIG_IDF_TARGET_ESP8684) || \
1352
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
1353
          defined(CONFIG_IDF_TARGET_ESP32C6)    \
1354
        ) && \
1355
        defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
1356
        /* For Espressif RISC-V Targets, we *may* need to reverse bytes
1357
         * depending on if HW is active or not. */
1358
        if (esp_sha_need_byte_reversal(&sha->ctx))
1359
    #endif
1360
107k
    {
1361
107k
        ByteReverseWords(sha->digest, sha->digest, WC_SHA_DIGEST_SIZE);
1362
107k
    }
1363
107k
#endif
1364
1365
107k
    XMEMCPY(hash, (byte *)&sha->digest[0], WC_SHA_DIGEST_SIZE);
1366
107k
#endif
1367
1368
    /* we'll always reset state upon exit and return the error code from above,
1369
     * which may cause fall back to SW if HW is busy. we do not return result
1370
     * of initSha here */
1371
107k
    (void)InitSha(sha); /* reset state */
1372
107k
    return ret;
1373
107k
}
1374
1375
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
1376
/* Apply SHA1 transformation to the data                  */
1377
/* @param sha  a pointer to wc_Sha structure              */
1378
/* @param data data to be applied SHA1 transformation     */
1379
/* @return 0 on successful, otherwise non-zero on failure */
1380
int wc_ShaTransform(wc_Sha* sha, const unsigned char* data)
1381
{
1382
    /* sanity check */
1383
    if (sha == NULL || data == NULL) {
1384
        return BAD_FUNC_ARG;
1385
    }
1386
#ifdef WOLFSSL_ARMASM_SHA_TRANSFORM
1387
    /* The caller passes a block already in the host's word order, which is what
1388
     * Transform() wants but not what the assembly does - it byte-swaps the
1389
     * block itself.  Undo the swap for the assembly implementations. */
1390
    if (WOLFSSL_ATOMIC_LOAD(sha_transform) != WC_SHA_TRANSFORM_C) {
1391
        word32 buffer[WC_SHA_BLOCK_SIZE / sizeof(word32)];
1392
1393
        XMEMCPY(buffer, data, WC_SHA_BLOCK_SIZE);
1394
    #ifdef LITTLE_ENDIAN_ORDER
1395
        ByteReverseWords(buffer, buffer, WC_SHA_BLOCK_SIZE);
1396
    #endif
1397
        return Transform_Sha_aarch64(sha, (const byte*)buffer);
1398
    }
1399
#endif
1400
    return (Transform(sha, data));
1401
}
1402
#endif
1403
1404
#endif /* USE_SHA_SOFTWARE_IMPL */
1405
1406
/*
1407
** This function initializes SHA. This is automatically called by wc_ShaHash.
1408
*/
1409
int wc_InitSha(wc_Sha* sha)
1410
60
{
1411
60
    return wc_InitSha_ex(sha, NULL, INVALID_DEVID);
1412
60
}
1413
1414
1415
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
1416
1417
#ifndef MAX3266X_SHA
1418
1419
void wc_ShaFree(wc_Sha* sha)
1420
203k
{
1421
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
1422
    int ret = 0;
1423
#endif
1424
1425
203k
    if (sha == NULL)
1426
0
        return;
1427
1428
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
1429
    #ifndef WOLF_CRYPTO_CB_FIND
1430
    if (sha->devId != INVALID_DEVID)
1431
    #endif
1432
    {
1433
        ret = wc_CryptoCb_Free(sha->devId, WC_ALGO_TYPE_HASH,
1434
                         WC_HASH_TYPE_SHA, 0, (void*)sha);
1435
        /* If they want the standard free, they can call it themselves */
1436
        /* via their callback setting devId to INVALID_DEVID */
1437
        /* otherwise assume the callback handled it */
1438
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1439
            return;
1440
        /* fall-through when unavailable */
1441
    }
1442
1443
    /* silence compiler warning */
1444
    (void)ret;
1445
1446
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
1447
1448
#if defined(WOLFSSL_ESP32) &&  !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
1449
    esp_sha_release_unfinished_lock(&sha->ctx);
1450
#endif
1451
1452
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
1453
    wolfAsync_DevCtxFree(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA);
1454
#endif /* WOLFSSL_ASYNC_CRYPT */
1455
1456
#ifdef WOLFSSL_PIC32MZ_HASH
1457
    wc_ShaPic32Free(sha);
1458
#endif
1459
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
1460
    se050_hash_free(&sha->se050Ctx);
1461
#endif
1462
#if (defined(WOLFSSL_RENESAS_TSIP_TLS) || \
1463
     defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
1464
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) || \
1465
    (defined(WOLFSSL_RENESAS_RSIP) && (WOLFSSL_RENESAS_RZFSP_VER >= 220)) ||\
1466
    defined(WOLFSSL_RENESAS_RX64_HASH)
1467
    XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
1468
    sha->msg = NULL;
1469
#endif
1470
#ifdef WOLFSSL_IMXRT_DCP
1471
    DCPShaFree(sha);
1472
#endif
1473
1474
#ifdef WOLFSSL_HASH_KEEP
1475
    if (sha->msg != NULL) {
1476
        ForceZero(sha->msg, sha->len);
1477
        XFREE(sha->msg, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
1478
        sha->msg = NULL;
1479
    }
1480
#endif
1481
1482
#if defined(PSOC6_HASH_SHA1)
1483
    wc_Psoc6_Sha_Free();
1484
#endif
1485
1486
    /* digest and buffer hold keyed material for HMAC-SHA1 and the SSH KDF
1487
     * (ISO/IEC 19790:2012 7.9.7). */
1488
203k
    ForceZero(sha, sizeof(*sha));
1489
203k
}
1490
1491
#endif /* !MAX3266X_SHA */
1492
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */
1493
#endif /* !WOLFSSL_TI_HASH */
1494
1495
#if !defined(WOLFSSL_TI_HASH) && !defined(WOLFSSL_IMXRT_DCP)
1496
1497
#if ((!defined(WOLFSSL_RENESAS_TSIP_TLS) && \
1498
     !defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) || \
1499
    defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) && \
1500
    (!defined(WOLFSSL_RENESAS_RSIP) || \
1501
      defined(NO_WOLFSSL_RENESAS_FSPSM_HASH))
1502
#if !defined(WOLFSSL_RENESAS_RX64_HASH)
1503
1504
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
1505
1506
#ifndef MAX3266X_SHA
1507
1508
/* wc_ShaGetHash get hash value */
1509
int wc_ShaGetHash(wc_Sha* sha, byte* hash)
1510
646
{
1511
646
    int ret;
1512
646
    WC_DECLARE_VAR(tmpSha, wc_Sha, 1, 0);
1513
1514
646
    if (sha == NULL || hash == NULL) {
1515
0
        return BAD_FUNC_ARG;
1516
0
    }
1517
1518
646
    WC_CALLOC_VAR_EX(tmpSha, wc_Sha, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
1519
646
        return MEMORY_E);
1520
#ifdef WOLFSSL_CHECK_MEM_ZERO
1521
    wc_MemZero_Add("wc_ShaGetHash tmpSha", tmpSha, sizeof(*tmpSha));
1522
#endif
1523
1524
646
    ret = wc_ShaCopy(sha, tmpSha);
1525
646
    if (ret == 0) {
1526
646
        ret = wc_ShaFinal(tmpSha, hash);
1527
646
        wc_ShaFree(tmpSha);
1528
646
    }
1529
1530
646
    ForceZero(tmpSha, sizeof(*tmpSha));
1531
#if defined(WOLFSSL_CHECK_MEM_ZERO) && !defined(WOLFSSL_SMALL_STACK)
1532
    wc_MemZero_Check(tmpSha, sizeof(*tmpSha));
1533
#endif
1534
646
    WC_FREE_VAR_EX(tmpSha, NULL, DYNAMIC_TYPE_TMP_BUFFER);
1535
1536
646
    return ret;
1537
646
}
1538
1539
int wc_ShaCopy(wc_Sha* src, wc_Sha* dst)
1540
686
{
1541
686
    int ret = 0;
1542
1543
686
    if (src == NULL || dst == NULL)
1544
0
        return BAD_FUNC_ARG;
1545
1546
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
1547
    #ifndef WOLF_CRYPTO_CB_FIND
1548
    if (src->devId != INVALID_DEVID)
1549
    #endif
1550
    {
1551
        /* Cast the source and destination to be void to keep the abstraction */
1552
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
1553
                               WC_HASH_TYPE_SHA, (void*)src, (void*)dst);
1554
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1555
            return ret;
1556
        /* fall-through when unavailable */
1557
    }
1558
    ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
1559
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
1560
1561
    /* Free dst resources before copy to prevent memory leaks (e.g., msg
1562
     * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
1563
686
    wc_ShaFree(dst);
1564
686
    XMEMCPY(dst, src, sizeof(wc_Sha));
1565
1566
#if defined(WOLFSSL_SILABS_SE_TYPES) && defined(WOLFSSL_SILABS_SE_ACCEL_3)
1567
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
1568
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
1569
#endif
1570
1571
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA)
1572
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
1573
#endif
1574
1575
#ifdef WOLFSSL_PIC32MZ_HASH
1576
    ret = wc_Pic32HashCopy(&src->cache, &dst->cache, (byte*)src->buffer,
1577
        (byte*)dst->buffer, dst->heap);
1578
#endif
1579
1580
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
1581
    ret = se050_hash_copy(&src->se050Ctx, &dst->se050Ctx);
1582
#endif
1583
1584
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1585
    esp_sha_ctx_copy(src, dst);
1586
#endif
1587
1588
1589
#if defined(PSOC6_HASH_SHA1)
1590
    wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA1, 0);
1591
#endif
1592
1593
686
#ifdef WOLFSSL_HASH_FLAGS
1594
686
    dst->flags |= WC_HASH_FLAG_ISCOPY;
1595
686
#endif
1596
1597
#if defined(WOLFSSL_HASH_KEEP)
1598
    if (src->msg != NULL) {
1599
        dst->msg = (byte*)XMALLOC(src->len, dst->heap,
1600
                                  DYNAMIC_TYPE_TMP_BUFFER);
1601
        if (dst->msg == NULL) {
1602
            return MEMORY_E;
1603
        }
1604
        XMEMCPY(dst->msg, src->msg, src->used);
1605
    }
1606
#endif
1607
1608
686
    return ret;
1609
686
}
1610
#endif /* WOLFSSL_RENESAS_RX64_HASH */
1611
#endif /* !MAX3266X_SHA */
1612
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */
1613
#endif /* !defined(WOLFSSL_RENESAS_TSIP_TLS) && \
1614
          !defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY) ||
1615
          defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH) */
1616
#endif /* !defined(WOLFSSL_TI_HASH) && !defined(WOLFSSL_IMXRT_DCP) */
1617
1618
#ifdef WOLFSSL_HASH_FLAGS
1619
int wc_ShaSetFlags(wc_Sha* sha, word32 flags)
1620
75.5k
{
1621
75.5k
    if (sha) {
1622
75.5k
        sha->flags = flags;
1623
75.5k
    }
1624
75.5k
    return 0;
1625
75.5k
}
1626
int wc_ShaGetFlags(wc_Sha* sha, word32* flags)
1627
0
{
1628
0
    if (sha && flags) {
1629
0
        *flags = sha->flags;
1630
0
    }
1631
0
    return 0;
1632
0
}
1633
#endif
1634
1635
#endif /* !NO_SHA */