Coverage Report

Created: 2026-08-15 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/wolfcrypt/src/sha256.c
Line
Count
Source
1
/* sha256.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
/* For more info on the algorithm, see https://tools.ietf.org/html/rfc6234
23
 *
24
 * For more information on NIST FIPS PUB 180-4, see
25
 * https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
26
 */
27
28
/*
29
30
DESCRIPTION
31
This library provides the interface to SHA-256 secure hash algorithms.
32
SHA-256 performs processing on message blocks to produce a final hash digest
33
output. It can be used to hash a message, M, having a length of L bits,
34
where 0 <= L < 2^64.
35
36
Note that in some cases, hardware acceleration may be enabled, depending
37
on the specific device platform.
38
39
*/
40
41
#define WC_FIPS_LL_CRYPTO
42
#define _WC_BUILDING_SHA256_C
43
44
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
45
46
/*
47
 * SHA256 Build Options:
48
 * USE_SLOW_SHA256:            Reduces code size by not partially unrolling
49
                                (~2KB smaller and ~25% slower) (default OFF)
50
 * WOLFSSL_SHA256_BY_SPEC:     Uses the Ch/Maj based on SHA256 specification
51
                                (default ON)
52
 * WOLFSSL_SHA256_ALT_CH_MAJ:  Alternate Ch/Maj that is easier for compilers to
53
                                optimize and recognize as SHA256 (default OFF)
54
 * SHA256_MANY_REGISTERS:      A SHA256 version that keeps all data in registers
55
                                and partial unrolled (default OFF)
56
 */
57
58
/* Default SHA256 to use Ch/Maj based on specification */
59
#if !defined(WOLFSSL_SHA256_BY_SPEC) && !defined(WOLFSSL_SHA256_ALT_CH_MAJ)
60
    #define WOLFSSL_SHA256_BY_SPEC
61
#endif
62
63
64
#if !defined(NO_SHA256)
65
66
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
67
    #ifdef USE_WINDOWS_API
68
        #pragma code_seg(".fipsA$l")
69
        #pragma const_seg(".fipsB$l")
70
    #endif
71
#endif
72
73
#include <wolfssl/wolfcrypt/sha256.h>
74
#include <wolfssl/wolfcrypt/cpuid.h>
75
#include <wolfssl/wolfcrypt/hash.h>
76
77
#ifdef WOLF_CRYPTO_CB
78
    #include <wolfssl/wolfcrypt/cryptocb.h>
79
#endif
80
81
#ifdef WOLFSSL_IMXRT1170_CAAM
82
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h>
83
#endif
84
85
86
/* determine if we are using Espressif SHA hardware acceleration */
87
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
88
#if defined(WOLFSSL_ESP32_CRYPT) && \
89
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
90
    /* define a single keyword for simplicity & readability
91
     *
92
     * by default the HW acceleration is on for ESP32-WROOM32
93
     * but individual components can be turned off.
94
     */
95
    #define WOLFSSL_USE_ESP32_CRYPT_HASH_HW
96
#else
97
    #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
98
#endif
99
100
/* WOLF_CRYPTO_CB_ONLY_SHA256 strips the software SHA-256 implementation and
101
 * routes every operation through the crypto callback. It is mutually exclusive
102
 * with any in-tree SHA-256 hardware/asm backend below: keep this list in sync
103
 * with the #elif chain at the start of the "Hardware Acceleration" section. */
104
#if defined(WOLF_CRYPTO_CB_ONLY_SHA256) && ( \
105
        defined(WOLFSSL_TI_HASH) || \
106
        defined(WOLFSSL_CRYPTOCELL) || \
107
        defined(MAX3266X_SHA) || \
108
        defined(FREESCALE_LTC_SHA) || \
109
        defined(FREESCALE_MMCAU_SHA) || \
110
        defined(WOLFSSL_PIC32MZ_HASH) || \
111
        defined(STM32_HASH_SHA2) || \
112
        (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)) || \
113
        (defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)) || \
114
        defined(WOLFSSL_AFALG_HASH) || \
115
        defined(WOLFSSL_DEVCRYPTO_HASH) || \
116
        (defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_HASH)) || \
117
        defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) || \
118
        defined(WOLFSSL_RENESAS_TSIP_TLS) || \
119
        defined(WOLFSSL_RENESAS_SCEPROTECT) || \
120
        defined(WOLFSSL_RENESAS_RSIP) || \
121
        defined(PSOC6_HASH_SHA2) || \
122
        defined(WOLFSSL_IMXRT_DCP) || \
123
        defined(WOLFSSL_NXP_HASHCRYPT_SHA) || \
124
        defined(WOLFSSL_SILABS_SE_ACCEL) || \
125
        defined(WOLFSSL_KCAPI_HASH) || \
126
        (defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)) || \
127
        defined(WOLFSSL_RENESAS_RX64_HASH) || \
128
        defined(WOLFSSL_PPC32_ASM) || \
129
        defined(WOLFSSL_PPC64_ASM) || \
130
        defined(WOLFSSL_ARMASM) || \
131
        defined(WOLFSSL_RISCV_ASM) || \
132
        (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
133
            (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))))
134
    #error "WOLF_CRYPTO_CB_ONLY_SHA256 is incompatible with SHA-256 hardware" \
135
           " acceleration backends"
136
#endif
137
138
#ifdef WOLFSSL_ESPIDF
139
    /* Define the ESP_LOGx(TAG,  WOLFSSL_ESPIDF_BLANKLINE_MESSAGE value for output messages here.
140
    **
141
    ** Beware of possible conflict in test.c (that one now named TEST_TAG)
142
    */
143
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
144
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
145
        static const char* TAG = "wc_sha256";
146
    #endif
147
#endif
148
149
#if defined(WOLFSSL_TI_HASH)
150
    /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */
151
#elif defined(WOLFSSL_CRYPTOCELL)
152
    /* wc_port.c includes wolfcrypt/src/port/arm/cryptoCellHash.c */
153
154
155
#elif defined(MAX3266X_SHA)
156
    /* Already brought in by sha256.h */
157
    /* #include <wolfssl/wolfcrypt/port/maxim/max3266x.h> */
158
#else
159
160
#ifdef NO_INLINE
161
    #include <wolfssl/wolfcrypt/misc.h>
162
#else
163
    #define WOLFSSL_MISC_INCLUDED
164
    #include <wolfcrypt/src/misc.c>
165
#endif
166
167
#ifdef WOLFSSL_DEVCRYPTO_HASH
168
    #include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
169
#endif
170
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
171
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
172
#endif
173
174
#if FIPS_VERSION3_GE(6,0,0)
175
    const unsigned int wolfCrypt_FIPS_sha256_ro_sanity[2] =
176
                                                     { 0x1a2b3c4d, 0x00000014 };
177
    int wolfCrypt_FIPS_SHA256_sanity(void)
178
    {
179
        return 0;
180
    }
181
#endif
182
183
#if defined(WC_C_DYNAMIC_FALLBACK) && \
184
        defined(WOLFSSL_AESNI) && !defined(USE_INTEL_SPEEDUP)
185
    /* AES-NI can be enabled with WC_C_DYNAMIC_FALLBACK, but without the rest of
186
     * USE_INTEL_SPEEDUP, in which case we need to disable the dynamic
187
     * fallback.
188
     */
189
    #undef WC_C_DYNAMIC_FALLBACK
190
#endif
191
192
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP)
193
    #if defined(__GNUC__) && ((__GNUC__ < 4) || \
194
                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
195
        #undef  NO_AVX2_SUPPORT
196
        #define NO_AVX2_SUPPORT
197
    #endif
198
    #if defined(__clang__) && ((__clang_major__ < 3) || \
199
                               (__clang_major__ == 3 && __clang_minor__ <= 5))
200
        #define NO_AVX2_SUPPORT
201
    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)
202
        #undef NO_AVX2_SUPPORT
203
    #endif
204
205
    #define HAVE_INTEL_AVX1
206
    #ifndef NO_AVX2_SUPPORT
207
        #define HAVE_INTEL_AVX2
208
    #endif
209
#else
210
    #undef HAVE_INTEL_AVX1
211
    #undef HAVE_INTEL_AVX2
212
#endif /* WOLFSSL_X86_64_BUILD && USE_INTEL_SPEEDUP */
213
214
#if defined(HAVE_INTEL_AVX2)
215
    #define HAVE_INTEL_RORX
216
#endif
217
218
#if defined(LITTLE_ENDIAN_ORDER)
219
    #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
220
          defined(CONFIG_IDF_TARGET_ESP8684) || \
221
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
222
          defined(CONFIG_IDF_TARGET_ESP32C6)    \
223
        ) && \
224
        defined(WOLFSSL_ESP32_CRYPT) &&         \
225
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
226
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
227
        /* For Espressif RISC-V Targets, we *may* need to reverse bytes
228
         * depending on if HW is active or not. */
229
        #define SHA256_REV_BYTES(ctx) \
230
            (esp_sha_need_byte_reversal(ctx))
231
    #elif defined(FREESCALE_MMCAU_SHA)
232
        #define SHA256_REV_BYTES(ctx)       1 /* reverse needed on final */
233
    #endif
234
#endif
235
#ifndef SHA256_REV_BYTES
236
    #if defined(LITTLE_ENDIAN_ORDER) || defined(WOLFSSL_WIDE_BYTE)
237
1.03M
        #define SHA256_REV_BYTES(ctx)       1
238
    #else
239
        #define SHA256_REV_BYTES(ctx)       0
240
    #endif
241
#endif
242
#if defined(LITTLE_ENDIAN_ORDER) && \
243
        defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
244
        (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
245
246
    #if defined(WC_C_DYNAMIC_FALLBACK) && !defined(WC_NO_INTERNAL_FUNCTION_POINTERS)
247
        /* With the AVX backend, wc_Sha256.buffer is in big endian even though
248
         * the host is little endian.  For WC_C_DYNAMIC_FALLBACK, which requires
249
         * alternating between AVX and C, we activate
250
         * WC_NO_INTERNAL_FUNCTION_POINTERS, which arranges for just-in-time
251
         * byte swapping on each call to the C back end.  This keeps the buffers
252
         * big endian at all times.
253
         */
254
        #define WC_NO_INTERNAL_FUNCTION_POINTERS
255
    #endif
256
257
    #ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
258
        /* With WC_NO_INTERNAL_FUNCTION_POINTERS every transform is dispatched
259
         * through inline_XTRANSFORM{,_LEN}(), whose C arm is
260
         * Transform_Sha256{,_Len}_C_from_raw() -- those byte-reverse the block
261
         * themselves, just in time.
262
         */
263
        #define WC_SHA256_RAW_BE_BUFFER
264
        #define SHA256_UPDATE_REV_BYTES(ctx) 0
265
    #else
266
        #define SHA256_UPDATE_REV_BYTES(ctx) \
267
            (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags) && \
268
             !IS_INTEL_SHA(intel_flags))
269
    #endif
270
#elif defined(FREESCALE_MMCAU_SHA)
271
    #define SHA256_UPDATE_REV_BYTES(ctx)    0 /* reverse not needed on update */
272
#elif defined(WOLFSSL_PPC32_ASM)
273
    #define SHA256_UPDATE_REV_BYTES(ctx)    0
274
#elif defined(WOLFSSL_PPC64_ASM)
275
    #define SHA256_UPDATE_REV_BYTES(ctx)    0
276
#elif defined(WOLFSSL_ARMASM)
277
    #define SHA256_UPDATE_REV_BYTES(ctx)    0
278
#elif defined(WOLFSSL_RISCV_ASM)
279
    #define SHA256_UPDATE_REV_BYTES(ctx)    0
280
#else
281
918k
    #define SHA256_UPDATE_REV_BYTES(ctx)    SHA256_REV_BYTES(ctx)
282
#endif
283
284
#if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH_SHA2) && \
285
    (!defined(WOLFSSL_IMX6_CAAM) || defined(NO_IMX6_CAAM_HASH) || \
286
     defined(WOLFSSL_QNX_CAAM)) && \
287
    !defined(WOLFSSL_AFALG_HASH) && !defined(WOLFSSL_DEVCRYPTO_HASH) && \
288
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_HASH)) && \
289
    ((!defined(WOLFSSL_RENESAS_TSIP_TLS) && \
290
      !defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) || \
291
     defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) && \
292
    !defined(PSOC6_HASH_SHA2) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
293
    !defined(WOLFSSL_NXP_HASHCRYPT_SHA) && \
294
    !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050_HASH) && \
295
    ((!defined(WOLFSSL_RENESAS_SCEPROTECT) && \
296
      !defined(WOLFSSL_RENESAS_RSIP)) \
297
      || defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)) && \
298
    (!defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)) && \
299
    !defined(WOLFSSL_RENESAS_RX64_HASH)
300
301
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
302
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
303
    (defined(WOLFSSL_ARMASM) && defined(__aarch64__) && \
304
     !defined(WOLF_CRYPTO_CB_ONLY_SHA256))
305
static void Sha256_SetTransform(void);
306
#endif
307
308
static int InitSha256(wc_Sha256* sha256)
309
277k
{
310
277k
    XMEMSET(sha256->digest, 0, sizeof(sha256->digest));
311
277k
    sha256->digest[0] = 0x6A09E667L;
312
277k
    sha256->digest[1] = 0xBB67AE85L;
313
277k
    sha256->digest[2] = 0x3C6EF372L;
314
277k
    sha256->digest[3] = 0xA54FF53AL;
315
277k
    sha256->digest[4] = 0x510E527FL;
316
277k
    sha256->digest[5] = 0x9B05688CL;
317
277k
    sha256->digest[6] = 0x1F83D9ABL;
318
277k
    sha256->digest[7] = 0x5BE0CD19L;
319
320
277k
    sha256->buffLen = 0;
321
277k
    XMEMSET(sha256->buffer, 0, sizeof(sha256->buffer));
322
277k
    sha256->loLen   = 0;
323
277k
    sha256->hiLen   = 0;
324
277k
#ifdef WOLFSSL_HASH_FLAGS
325
277k
    sha256->flags = 0;
326
277k
#endif
327
#ifdef WOLFSSL_HASH_KEEP
328
    sha256->msg  = NULL;
329
    sha256->len  = 0;
330
    sha256->used = 0;
331
#endif
332
333
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
334
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
335
    (defined(WOLFSSL_ARMASM) && defined(__aarch64__) && \
336
     !defined(WOLF_CRYPTO_CB_ONLY_SHA256))
337
    /* choose best Transform function under this runtime environment */
338
    Sha256_SetTransform();
339
#endif
340
341
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
342
    XMEMSET(&sha256->maxq_ctx, 0, sizeof(sha256->maxq_ctx));
343
#endif
344
345
#ifdef HAVE_ARIA
346
    sha256->hSession = NULL;
347
#endif
348
349
277k
    return 0;
350
277k
}
351
#endif
352
353
354
/* Hardware Acceleration */
355
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
356
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) && \
357
    !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
358
359
    /* in case intel instructions aren't available, plus we need the K[] global */
360
    #define NEED_SOFT_SHA256
361
362
    /*****
363
    Intel AVX1/AVX2 Macro Control Structure
364
365
    #define HAVE_INTEL_AVX1
366
    #define HAVE_INTEL_AVX2
367
368
    #define HAVE_INTEL_RORX
369
370
371
    int InitSha256(wc_Sha256* sha256) {
372
         Save/Recover XMM, YMM
373
         ...
374
    }
375
376
    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
377
      Transform_Sha256(); Function prototype
378
    #else
379
      Transform_Sha256() {   }
380
      int Sha256Final() {
381
         Save/Recover XMM, YMM
382
         ...
383
      }
384
    #endif
385
386
    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
387
        #if defined(HAVE_INTEL_RORX
388
             #define RND with rorx instruction
389
        #else
390
            #define RND
391
        #endif
392
    #endif
393
394
    #if defined(HAVE_INTEL_AVX1)
395
396
       #define XMM Instructions/inline asm
397
398
       int Transform_Sha256() {
399
           Stitched Message Sched/Round
400
        }
401
402
    #elif defined(HAVE_INTEL_AVX2)
403
404
      #define YMM Instructions/inline asm
405
406
      int Transform_Sha256() {
407
          More granular Stitched Message Sched/Round
408
      }
409
410
    #endif
411
412
    */
413
414
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
415
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
416
     */
417
418
    /* #if defined(HAVE_INTEL_AVX1/2) at the tail of sha256 */
419
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data);
420
421
#ifdef __cplusplus
422
    extern "C" {
423
#endif
424
425
        extern int Transform_Sha256_SSE2_Sha(wc_Sha256 *sha256,
426
                                             const byte* data);
427
        extern int Transform_Sha256_SSE2_Sha_Len(wc_Sha256* sha256,
428
                                                 const byte* data, word32 len);
429
    #if defined(HAVE_INTEL_AVX1)
430
        extern int Transform_Sha256_AVX1_Sha(wc_Sha256 *sha256,
431
                                             const byte* data);
432
        extern int Transform_Sha256_AVX1_Sha_Len(wc_Sha256* sha256,
433
                                                 const byte* data, word32 len);
434
        extern int Transform_Sha256_AVX1(wc_Sha256 *sha256, const byte* data);
435
        extern int Transform_Sha256_AVX1_Len(wc_Sha256* sha256,
436
                                             const byte* data, word32 len);
437
    #endif
438
    #if defined(HAVE_INTEL_AVX2)
439
        extern int Transform_Sha256_AVX2(wc_Sha256 *sha256, const byte* data);
440
        extern int Transform_Sha256_AVX2_Len(wc_Sha256* sha256,
441
                                             const byte* data, word32 len);
442
        #ifdef HAVE_INTEL_RORX
443
        extern int Transform_Sha256_AVX1_RORX(wc_Sha256 *sha256, const byte* data);
444
        extern int Transform_Sha256_AVX1_RORX_Len(wc_Sha256* sha256,
445
                                                  const byte* data, word32 len);
446
        extern int Transform_Sha256_AVX2_RORX(wc_Sha256 *sha256, const byte* data);
447
        extern int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256,
448
                                                  const byte* data, word32 len);
449
        #endif /* HAVE_INTEL_RORX */
450
    #endif /* HAVE_INTEL_AVX2 */
451
452
#ifdef __cplusplus
453
    }  /* extern "C" */
454
#endif
455
456
    static cpuid_flags_atomic_t intel_flags = WC_CPUID_ATOMIC_INITIALIZER;
457
458
#ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
459
460
    enum sha_methods { SHA256_UNSET = 0, SHA256_AVX1_SHA, SHA256_AVX2,
461
                       SHA256_AVX1_RORX, SHA256_AVX1_NOSHA, SHA256_AVX2_RORX,
462
                       SHA256_SSE2, SHA256_C };
463
464
    /* note that all write access to this static variable must be idempotent,
465
     * as arranged by Sha256_SetTransform(), else it will be susceptible to
466
     * data races.
467
     */
468
    static enum sha_methods sha_method = SHA256_UNSET;
469
470
    static void Sha256_SetTransform(void)
471
    {
472
        if (sha_method != SHA256_UNSET)
473
            return;
474
475
        /* Note, with WC_C_DYNAMIC_FALLBACK, sha_method records CPU capability
476
         * only.  Whether vector registers are actually usable is determined
477
         * independently at each transform via SAVE_VECTOR_REGISTERS2(),
478
         * allowing a context to move freely between vectorized and C transforms
479
         * call by call.
480
         */
481
482
        cpuid_get_flags_atomic(&intel_flags);
483
484
        if (IS_INTEL_SHA(intel_flags)) {
485
        #ifdef HAVE_INTEL_AVX1
486
            if (IS_INTEL_AVX1(intel_flags)) {
487
                sha_method = SHA256_AVX1_SHA;
488
            }
489
            else
490
        #endif
491
            {
492
                sha_method = SHA256_SSE2;
493
            }
494
        }
495
        else
496
    #ifdef HAVE_INTEL_AVX2
497
        if (IS_INTEL_AVX2(intel_flags)) {
498
        #ifdef HAVE_INTEL_RORX
499
            if (IS_INTEL_BMI2(intel_flags)) {
500
                sha_method = SHA256_AVX2_RORX;
501
            }
502
            else
503
        #endif
504
            {
505
                sha_method = SHA256_AVX2;
506
            }
507
        }
508
        else
509
    #endif
510
    #ifdef HAVE_INTEL_AVX1
511
        if (IS_INTEL_AVX1(intel_flags)) {
512
        #ifdef HAVE_INTEL_RORX
513
            if (IS_INTEL_BMI2(intel_flags)) {
514
                sha_method = SHA256_AVX1_RORX;
515
            }
516
            else
517
        #endif
518
            {
519
                sha_method = SHA256_AVX1_NOSHA;
520
            }
521
        }
522
        else
523
    #endif
524
        {
525
            sha_method = SHA256_C;
526
        }
527
    }
528
529
    #ifdef WC_SHA256_RAW_BE_BUFFER
530
531
    static WC_INLINE int Transform_Sha256_C_from_raw(wc_Sha256* S,
532
                                                     const byte* D)
533
    {
534
        if (D != (const byte*)S->buffer)
535
            XMEMCPY(S->buffer, D, WC_SHA256_BLOCK_SIZE);
536
    #ifdef LITTLE_ENDIAN_ORDER
537
        ByteReverseWords(S->buffer, S->buffer, WC_SHA256_BLOCK_SIZE);
538
    #endif
539
        return Transform_Sha256(S, (const byte*)S->buffer);
540
    }
541
542
    static WC_INLINE int Transform_Sha256_Len_C_from_raw(wc_Sha256* S,
543
                                                         const byte* D,
544
                                                         word32 L)
545
    {
546
        int ret = 0;
547
548
        while (L >= WC_SHA256_BLOCK_SIZE) {
549
            ret = Transform_Sha256_C_from_raw(S, D);
550
            if (ret != 0)
551
                break;
552
            D += WC_SHA256_BLOCK_SIZE;
553
            L -= WC_SHA256_BLOCK_SIZE;
554
        }
555
556
        return ret;
557
    }
558
559
    #endif /* WC_SHA256_RAW_BE_BUFFER */
560
561
    static WC_INLINE int inline_XTRANSFORM(wc_Sha256* S, const byte* D) {
562
        int ret;
563
564
    #ifdef WC_C_DYNAMIC_FALLBACK
565
        if ((sha_method == SHA256_C) ||
566
            (SAVE_VECTOR_REGISTERS2() != 0))
567
        {
568
            return Transform_Sha256_C_from_raw(S, D);
569
        }
570
    #else
571
        if (sha_method == SHA256_C) {
572
            #ifdef WC_SHA256_RAW_BE_BUFFER
573
            /* not currently reachable */
574
            return Transform_Sha256_C_from_raw(S, D);
575
            #else
576
            return Transform_Sha256(S, D);
577
            #endif
578
        }
579
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
580
    #endif
581
        switch (sha_method) {
582
        case SHA256_AVX2:
583
            ret = Transform_Sha256_AVX2(S, D);
584
            break;
585
        case SHA256_AVX2_RORX:
586
            ret = Transform_Sha256_AVX2_RORX(S, D);
587
            break;
588
        case SHA256_AVX1_SHA:
589
            ret = Transform_Sha256_AVX1_Sha(S, D);
590
            break;
591
        case SHA256_AVX1_NOSHA:
592
            ret = Transform_Sha256_AVX1(S, D);
593
            break;
594
        case SHA256_AVX1_RORX:
595
            ret = Transform_Sha256_AVX1_RORX(S, D);
596
            break;
597
        case SHA256_SSE2:
598
            ret = Transform_Sha256_SSE2_Sha(S, D);
599
            break;
600
        case SHA256_C:
601
        case SHA256_UNSET:
602
        default:
603
            /* not reachable -- the C path exits above, before vector register
604
             * save -- but must stay layout-correct. */
605
            #ifdef WC_SHA256_RAW_BE_BUFFER
606
            ret = Transform_Sha256_C_from_raw(S, D);
607
            #else
608
            ret = Transform_Sha256(S, D);
609
            #endif
610
            break;
611
        }
612
        RESTORE_VECTOR_REGISTERS();
613
        return ret;
614
    }
615
#define XTRANSFORM(...) inline_XTRANSFORM(__VA_ARGS__)
616
617
    static WC_INLINE int inline_XTRANSFORM_LEN(wc_Sha256* S, const byte* D, word32 L) {
618
        int ret;
619
    #ifdef WC_C_DYNAMIC_FALLBACK
620
        if ((sha_method == SHA256_C) ||
621
            (SAVE_VECTOR_REGISTERS2() != 0))
622
        {
623
            return Transform_Sha256_Len_C_from_raw(S, D, L);
624
        }
625
    #else
626
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
627
    #endif
628
        switch (sha_method) {
629
        case SHA256_AVX2:
630
            ret = Transform_Sha256_AVX2_Len(S, D, L);
631
            break;
632
        case SHA256_AVX2_RORX:
633
            ret = Transform_Sha256_AVX2_RORX_Len(S, D, L);
634
            break;
635
        case SHA256_AVX1_SHA:
636
            ret = Transform_Sha256_AVX1_Sha_Len(S, D, L);
637
            break;
638
        case SHA256_AVX1_NOSHA:
639
            ret = Transform_Sha256_AVX1_Len(S, D, L);
640
            break;
641
        case SHA256_AVX1_RORX:
642
            ret = Transform_Sha256_AVX1_RORX_Len(S, D, L);
643
            break;
644
        case SHA256_SSE2:
645
            ret = Transform_Sha256_SSE2_Sha_Len(S, D, L);
646
            break;
647
        case SHA256_C:
648
        case SHA256_UNSET:
649
        default:
650
            #ifdef WC_SHA256_RAW_BE_BUFFER
651
            ret = Transform_Sha256_Len_C_from_raw(S, D, L);
652
            #else
653
            ret = 0;
654
            #endif
655
            break;
656
        }
657
        RESTORE_VECTOR_REGISTERS();
658
        return ret;
659
    }
660
#define XTRANSFORM_LEN(...) inline_XTRANSFORM_LEN(__VA_ARGS__)
661
662
#else /* !WC_NO_INTERNAL_FUNCTION_POINTERS */
663
664
    static int (*Transform_Sha256_p)(wc_Sha256* sha256, const byte* data);
665
                                                       /* = _Transform_Sha256 */
666
    static int (*Transform_Sha256_Len_p)(wc_Sha256* sha256, const byte* data,
667
                                         word32 len);
668
                                                                    /* = NULL */
669
    static int transform_check = 0;
670
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
671
    static int Transform_Sha256_is_vectorized = 0;
672
    #endif
673
674
    static WC_INLINE int inline_XTRANSFORM(wc_Sha256* S, const byte* D) {
675
        int ret;
676
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
677
        if (Transform_Sha256_is_vectorized)
678
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
679
    #endif
680
        ret = (*Transform_Sha256_p)(S, D);
681
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
682
        if (Transform_Sha256_is_vectorized)
683
            RESTORE_VECTOR_REGISTERS();
684
    #endif
685
        return ret;
686
    }
687
#define XTRANSFORM(...) inline_XTRANSFORM(__VA_ARGS__)
688
689
    static WC_INLINE int inline_XTRANSFORM_LEN(wc_Sha256* S, const byte* D, word32 L) {
690
        int ret;
691
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
692
        if (Transform_Sha256_is_vectorized)
693
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
694
    #endif
695
        ret = (*Transform_Sha256_Len_p)(S, D, L);
696
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
697
        if (Transform_Sha256_is_vectorized)
698
            RESTORE_VECTOR_REGISTERS();
699
    #endif
700
        return ret;
701
    }
702
#define XTRANSFORM_LEN(...) inline_XTRANSFORM_LEN(__VA_ARGS__)
703
704
    static void Sha256_SetTransform(void)
705
    {
706
707
        if (transform_check)
708
            return;
709
710
        cpuid_get_flags_atomic(&intel_flags);
711
712
        if (IS_INTEL_SHA(intel_flags)) {
713
        #ifdef HAVE_INTEL_AVX1
714
            if (IS_INTEL_AVX1(intel_flags)) {
715
                Transform_Sha256_p = Transform_Sha256_AVX1_Sha;
716
                Transform_Sha256_Len_p = Transform_Sha256_AVX1_Sha_Len;
717
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
718
                Transform_Sha256_is_vectorized = 1;
719
            #endif
720
            }
721
            else
722
        #endif
723
            {
724
                Transform_Sha256_p = Transform_Sha256_SSE2_Sha;
725
                Transform_Sha256_Len_p = Transform_Sha256_SSE2_Sha_Len;
726
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
727
                Transform_Sha256_is_vectorized = 1;
728
            #endif
729
            }
730
        }
731
        else
732
    #ifdef HAVE_INTEL_AVX2
733
        if (IS_INTEL_AVX2(intel_flags)) {
734
        #ifdef HAVE_INTEL_RORX
735
            if (IS_INTEL_BMI2(intel_flags)) {
736
                Transform_Sha256_p = Transform_Sha256_AVX2_RORX;
737
                Transform_Sha256_Len_p = Transform_Sha256_AVX2_RORX_Len;
738
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
739
                Transform_Sha256_is_vectorized = 1;
740
            #endif
741
            }
742
            else
743
        #endif
744
            {
745
                Transform_Sha256_p = Transform_Sha256_AVX2;
746
                Transform_Sha256_Len_p = Transform_Sha256_AVX2_Len;
747
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
748
                Transform_Sha256_is_vectorized = 1;
749
            #endif
750
            }
751
        }
752
        else
753
    #endif
754
    #ifdef HAVE_INTEL_AVX1
755
        if (IS_INTEL_AVX1(intel_flags)) {
756
        #ifdef HAVE_INTEL_RORX
757
            if (IS_INTEL_BMI2(intel_flags)) {
758
                Transform_Sha256_p = Transform_Sha256_AVX1_RORX;
759
                Transform_Sha256_Len_p = Transform_Sha256_AVX1_RORX_Len;
760
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
761
                Transform_Sha256_is_vectorized = 1;
762
            #endif
763
            }
764
            else
765
        #endif
766
            {
767
                Transform_Sha256_p = Transform_Sha256_AVX1;
768
                Transform_Sha256_Len_p = Transform_Sha256_AVX1_Len;
769
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
770
                Transform_Sha256_is_vectorized = 1;
771
            #endif
772
            }
773
        }
774
        else
775
    #endif
776
        {
777
            Transform_Sha256_p = Transform_Sha256;
778
            Transform_Sha256_Len_p = NULL;
779
        #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
780
            Transform_Sha256_is_vectorized = 0;
781
        #endif
782
        }
783
784
        transform_check = 1;
785
    }
786
787
#endif /* !WC_NO_INTERNAL_FUNCTION_POINTERS */
788
789
#if !defined(WOLFSSL_KCAPI_HASH)
790
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
791
    {
792
        int ret = 0;
793
        if (sha256 == NULL)
794
            return BAD_FUNC_ARG;
795
796
        sha256->heap = heap;
797
    #ifdef WOLF_CRYPTO_CB
798
        sha256->devId = devId;
799
        sha256->devCtx = NULL;
800
    #endif
801
    #ifdef WOLFSSL_SMALL_STACK_CACHE
802
        sha256->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
803
                                     sha256->heap, DYNAMIC_TYPE_DIGEST);
804
        if (sha256->W == NULL)
805
            return MEMORY_E;
806
    #endif
807
808
        ret = InitSha256(sha256);
809
        if (ret != 0)
810
            return ret;
811
812
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
813
        ret = wolfAsync_DevCtxInit(&sha256->asyncDev,
814
                            WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId);
815
    #else
816
        (void)devId;
817
    #endif /* WOLFSSL_ASYNC_CRYPT */
818
819
        return ret;
820
    }
821
#endif /* !WOLFSSL_KCAPI_HASH */
822
823
#elif defined(FREESCALE_LTC_SHA)
824
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
825
    {
826
        (void)heap;
827
        (void)devId;
828
829
        LTC_HASH_Init(LTC_BASE, &sha256->ctx, kLTC_Sha256, NULL, 0);
830
831
        return 0;
832
    }
833
834
#elif defined(FREESCALE_MMCAU_SHA)
835
836
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
837
        #include "cau_api.h"
838
    #else
839
        #include "fsl_mmcau.h"
840
    #endif
841
842
    #define XTRANSFORM(S, D)         Transform_Sha256(S, D)
843
    #define XTRANSFORM_LEN(S, D, L)  Transform_Sha256_Len(S, D, L)
844
845
    #ifndef WC_HASH_DATA_ALIGNMENT
846
        /* these hardware API's require 4 byte (word32) alignment */
847
        #define WC_HASH_DATA_ALIGNMENT 4
848
    #endif
849
850
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
851
    {
852
        int ret = 0;
853
854
        (void)heap;
855
        (void)devId;
856
857
        ret = wolfSSL_CryptHwMutexLock();
858
        if (ret != 0) {
859
            return ret;
860
        }
861
862
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
863
        cau_sha256_initialize_output(sha256->digest);
864
    #else
865
        MMCAU_SHA256_InitializeOutput((uint32_t*)sha256->digest);
866
    #endif
867
        wolfSSL_CryptHwMutexUnLock();
868
869
        sha256->buffLen = 0;
870
        sha256->loLen   = 0;
871
        sha256->hiLen   = 0;
872
    #ifdef WOLFSSL_SMALL_STACK_CACHE
873
        sha256->W = NULL;
874
    #endif
875
876
        return ret;
877
    }
878
879
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
880
    {
881
        int ret = wolfSSL_CryptHwMutexLock();
882
        if (ret == 0) {
883
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
884
            cau_sha256_hash_n((byte*)data, 1, sha256->digest);
885
    #else
886
            MMCAU_SHA256_HashN((byte*)data, 1, (uint32_t*)sha256->digest);
887
    #endif
888
            wolfSSL_CryptHwMutexUnLock();
889
        }
890
        return ret;
891
    }
892
893
    static int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
894
        word32 len)
895
    {
896
        int ret = wolfSSL_CryptHwMutexLock();
897
        if (ret == 0) {
898
        #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0
899
            if ((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) {
900
                /* data pointer is NOT aligned,
901
                 * so copy and perform one block at a time */
902
                byte* local = (byte*)sha256->buffer;
903
                while (len >= WC_SHA256_BLOCK_SIZE) {
904
                    XMEMCPY(local, data, WC_SHA256_BLOCK_SIZE);
905
                #ifdef FREESCALE_MMCAU_CLASSIC_SHA
906
                    cau_sha256_hash_n(local, 1, sha256->digest);
907
                #else
908
                    MMCAU_SHA256_HashN(local, 1, (uint32_t*)sha256->digest);
909
                #endif
910
                    data += WC_SHA256_BLOCK_SIZE;
911
                    len  -= WC_SHA256_BLOCK_SIZE;
912
                }
913
            }
914
            else
915
        #endif
916
            {
917
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
918
            cau_sha256_hash_n((byte*)data, len/WC_SHA256_BLOCK_SIZE,
919
                sha256->digest);
920
    #else
921
            MMCAU_SHA256_HashN((byte*)data, len/WC_SHA256_BLOCK_SIZE,
922
                (uint32_t*)sha256->digest);
923
    #endif
924
            }
925
            wolfSSL_CryptHwMutexUnLock();
926
        }
927
        return ret;
928
    }
929
930
#elif defined(WOLFSSL_PIC32MZ_HASH)
931
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
932
933
#elif defined(STM32_HASH_SHA2)
934
935
    /* Supports CubeMX HAL or Standard Peripheral Library */
936
937
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
938
    {
939
        if (sha256 == NULL)
940
            return BAD_FUNC_ARG;
941
942
        (void)devId;
943
        (void)heap;
944
945
        XMEMSET(sha256, 0, sizeof(wc_Sha256));
946
        wc_Stm32_Hash_Init(&sha256->stmCtx);
947
        return 0;
948
    }
949
950
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
951
    {
952
        int ret = 0;
953
954
        if (sha256 == NULL) {
955
            return BAD_FUNC_ARG;
956
        }
957
        if (data == NULL && len == 0) {
958
            /* valid, but do nothing */
959
            return 0;
960
        }
961
        if (data == NULL) {
962
            return BAD_FUNC_ARG;
963
        }
964
965
        ret = wolfSSL_CryptHwMutexLock();
966
        if (ret == 0) {
967
            ret = wc_Stm32_Hash_Update(&sha256->stmCtx,
968
                HASH_AlgoSelection_SHA256, data, len, WC_SHA256_BLOCK_SIZE);
969
            wolfSSL_CryptHwMutexUnLock();
970
        }
971
        return ret;
972
    }
973
974
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
975
    {
976
        int ret = 0;
977
978
        if (sha256 == NULL || hash == NULL) {
979
            return BAD_FUNC_ARG;
980
        }
981
982
        ret = wolfSSL_CryptHwMutexLock();
983
        if (ret == 0) {
984
            ret = wc_Stm32_Hash_Final(&sha256->stmCtx,
985
                HASH_AlgoSelection_SHA256, hash, WC_SHA256_DIGEST_SIZE);
986
            wolfSSL_CryptHwMutexUnLock();
987
        }
988
989
        (void)wc_InitSha256(sha256); /* reset state */
990
991
        return ret;
992
    }
993
994
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
995
    !defined(WOLFSSL_QNX_CAAM)
996
    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
997
998
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
999
1000
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1001
    {
1002
        if (sha256 == NULL) {
1003
            return BAD_FUNC_ARG;
1004
        }
1005
        (void)devId;
1006
1007
        return se050_hash_init(&sha256->se050Ctx, heap);
1008
    }
1009
1010
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
1011
    {
1012
        if (sha256 == NULL) {
1013
            return BAD_FUNC_ARG;
1014
        }
1015
        if (data == NULL && len == 0) {
1016
            /* valid, but do nothing */
1017
            return 0;
1018
        }
1019
        if (data == NULL) {
1020
            return BAD_FUNC_ARG;
1021
        }
1022
1023
        return se050_hash_update(&sha256->se050Ctx, data, len);
1024
    }
1025
1026
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
1027
    {
1028
        int ret = 0;
1029
        ret = se050_hash_final(&sha256->se050Ctx, hash, WC_SHA256_DIGEST_SIZE,
1030
                               kAlgorithm_SSS_SHA256);
1031
        return ret;
1032
    }
1033
1034
#elif defined(WOLFSSL_AFALG_HASH)
1035
    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
1036
1037
#elif defined(WOLFSSL_DEVCRYPTO_HASH)
1038
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
1039
1040
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_HASH)
1041
    #include "hal_data.h"
1042
1043
    #ifndef WOLFSSL_SCE_SHA256_HANDLE
1044
        #define WOLFSSL_SCE_SHA256_HANDLE g_sce_hash_0
1045
    #endif
1046
1047
    #define WC_SHA256_DIGEST_WORD_SIZE 16
1048
    #define XTRANSFORM(S, D) wc_Sha256SCE_XTRANSFORM(S, D)
1049
    static int wc_Sha256SCE_XTRANSFORM(wc_Sha256* sha256, const byte* data)
1050
    {
1051
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1052
                CRYPTO_WORD_ENDIAN_LITTLE)
1053
        {
1054
            ByteReverseWords((word32*)data, (word32*)data,
1055
                    WC_SHA256_BLOCK_SIZE);
1056
            ByteReverseWords(sha256->digest, sha256->digest,
1057
                    WC_SHA256_DIGEST_SIZE);
1058
        }
1059
1060
        if (WOLFSSL_SCE_SHA256_HANDLE.p_api->hashUpdate(
1061
                    WOLFSSL_SCE_SHA256_HANDLE.p_ctrl, (word32*)data,
1062
                    WC_SHA256_DIGEST_WORD_SIZE, sha256->digest) != SSP_SUCCESS){
1063
            WOLFSSL_MSG("Unexpected hardware return value");
1064
            return WC_HW_E;
1065
        }
1066
1067
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
1068
                CRYPTO_WORD_ENDIAN_LITTLE)
1069
        {
1070
            ByteReverseWords((word32*)data, (word32*)data,
1071
                    WC_SHA256_BLOCK_SIZE);
1072
            ByteReverseWords(sha256->digest, sha256->digest,
1073
                    WC_SHA256_DIGEST_SIZE);
1074
        }
1075
1076
        return 0;
1077
    }
1078
1079
1080
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1081
    {
1082
        int ret = 0;
1083
        if (sha256 == NULL)
1084
            return BAD_FUNC_ARG;
1085
1086
        sha256->heap = heap;
1087
1088
        ret = InitSha256(sha256);
1089
        if (ret != 0)
1090
            return ret;
1091
1092
        (void)devId;
1093
1094
        return ret;
1095
    }
1096
1097
#elif defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1098
1099
    /* HW may fail since there's only one, so we still need SW */
1100
    #define NEED_SOFT_SHA256
1101
1102
    /*
1103
    ** An Espressif-specific InitSha256()
1104
    **
1105
    ** soft SHA needs initialization digest, but HW does not.
1106
    */
1107
    static int InitSha256(wc_Sha256* sha256)
1108
    {
1109
        int ret = 0; /* zero = success */
1110
1111
        /* We may or may not need initial digest for HW.
1112
         * Always needed for SW-only. */
1113
        sha256->digest[0] = 0x6A09E667L;
1114
        sha256->digest[1] = 0xBB67AE85L;
1115
        sha256->digest[2] = 0x3C6EF372L;
1116
        sha256->digest[3] = 0xA54FF53AL;
1117
        sha256->digest[4] = 0x510E527FL;
1118
        sha256->digest[5] = 0x9B05688CL;
1119
        sha256->digest[6] = 0x1F83D9ABL;
1120
        sha256->digest[7] = 0x5BE0CD19L;
1121
1122
        sha256->buffLen = 0;
1123
        sha256->loLen   = 0;
1124
        sha256->hiLen   = 0;
1125
1126
#ifndef NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256
1127
        ret = esp_sha_init((WC_ESP32SHA*)&(sha256->ctx), WC_HASH_TYPE_SHA256);
1128
#endif
1129
        return ret;
1130
    }
1131
1132
    /*
1133
    ** An Espressif-specific wolfCrypt InitSha256 external wrapper.
1134
    **
1135
    ** we'll assume this is ALWAYS for a new, uninitialized sha256
1136
    */
1137
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1138
    {
1139
        (void)devId;
1140
        if (sha256 == NULL) {
1141
            return BAD_FUNC_ARG;
1142
        }
1143
1144
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1145
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1146
        /* We know this is a fresh, uninitialized item, so set to INIT */
1147
        if (sha256->ctx.mode != ESP32_SHA_INIT) {
1148
            ESP_LOGV(TAG, "Set ctx mode from prior value: "
1149
                               "%d", sha256->ctx.mode);
1150
        }
1151
        sha256->ctx.mode = ESP32_SHA_INIT;
1152
    #endif
1153
1154
        return InitSha256(sha256);
1155
    }
1156
1157
#elif (defined(WOLFSSL_RENESAS_TSIP_TLS) || \
1158
       defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
1159
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)
1160
1161
    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */
1162
1163
#elif (defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_RSIP)) \
1164
     && !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
1165
1166
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
1167
1168
#elif defined(PSOC6_HASH_SHA2)
1169
    /* implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */
1170
1171
#elif defined(WOLFSSL_IMXRT_DCP)
1172
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
1173
    /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */
1174
1175
#elif defined(WOLFSSL_NXP_HASHCRYPT_SHA)
1176
    /* implemented in wolfcrypt/src/port/nxp/hashcrypt_port.c */
1177
1178
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1179
    /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
1180
1181
#elif defined(WOLFSSL_KCAPI_HASH)
1182
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
1183
1184
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
1185
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
1186
1187
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
1188
1189
    /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
1190
#elif (defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_PPC64_ASM)) && \
1191
    !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
1192
1193
extern void Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
1194
    word32 len);
1195
1196
#if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
1197
/* POWER8+ has a vector SHA-256 sigma instruction (vshasigmaw).  When built
1198
 * in, select that implementation at run time if the CPU supports it.
1199
 *
1200
 * A run-time flag with direct calls is used rather than a function pointer:
1201
 * an indirect call would require an ELFv1 function descriptor, whereas direct
1202
 * calls work under both the ELFv1 and ELFv2 ABIs. */
1203
extern void Transform_Sha256_Len_crypto(wc_Sha256* sha256, const byte* data,
1204
    word32 len);
1205
1206
/* -1 = not yet determined, 0 = base, 1 = vector-crypto */
1207
/* Resolved dispatch decision (0 = base, 1 = vector-crypto), accessed with the
1208
 * wolfSSL atomic APIs so the one-time detection is free of data races.  The
1209
 * write is idempotent (all callers compute the same value from the atomic
1210
 * master flags), so a benign concurrent double-write is harmless. */
1211
static wolfSSL_Atomic_Uint sha256_use_crypto = WOLFSSL_ATOMIC_INITIALIZER(0);
1212
1213
/* Detect CPU support via the central cpuid module. */
1214
static void Sha256_SetTransform(void)
1215
{
1216
    WOLFSSL_ATOMIC_STORE(sha256_use_crypto,
1217
        (unsigned int)(IS_PPC64_VEC_CRYPTO(cpuid_get_flags()) != 0));
1218
}
1219
1220
static WC_INLINE int SHA256_TRANSFORM_LEN(wc_Sha256* sha256, const byte* data,
1221
    word32 len)
1222
{
1223
    if (WOLFSSL_ATOMIC_LOAD(sha256_use_crypto))
1224
        Transform_Sha256_Len_crypto(sha256, data, len);
1225
    else
1226
        Transform_Sha256_Len(sha256, data, len);
1227
    return 0;
1228
}
1229
#else
1230
#define Sha256_SetTransform()           WC_DO_NOTHING
1231
static WC_INLINE int SHA256_TRANSFORM_LEN(wc_Sha256* sha256, const byte* data,
1232
    word32 len)
1233
{
1234
    Transform_Sha256_Len(sha256, data, len);
1235
    return 0;
1236
}
1237
#endif
1238
1239
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1240
{
1241
    int ret = 0;
1242
1243
    if (sha256 == NULL)
1244
        return BAD_FUNC_ARG;
1245
    ret = InitSha256(sha256);
1246
    if (ret != 0)
1247
        return ret;
1248
1249
    Sha256_SetTransform();
1250
1251
    sha256->heap = heap;
1252
#ifdef WOLF_CRYPTO_CB
1253
    sha256->devId = devId;
1254
    sha256->devCtx = NULL;
1255
#else
1256
    (void)devId;
1257
#endif
1258
1259
#ifdef WOLFSSL_SMALL_STACK_CACHE
1260
    sha256->W = NULL;
1261
#endif
1262
1263
    return ret;
1264
}
1265
1266
static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
1267
{
1268
    SHA256_TRANSFORM_LEN(sha256, data, WC_SHA256_BLOCK_SIZE);
1269
    return 0;
1270
}
1271
1272
#define XTRANSFORM Transform_Sha256
1273
#define XTRANSFORM_LEN(s, d, l)         SHA256_TRANSFORM_LEN(s, d, l)
1274
1275
#elif defined(WOLFSSL_ARMASM) && defined(__aarch64__) && \
1276
      !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
1277
1278
/* This arm of the chain provides Sha256_SetTransform() - marks it available to
1279
 * the SHA-224 initializer, which shares the SHA-256 transform.  Earlier arms
1280
 * (hardware hash ports) win the chain and provide no such selection. */
1281
#define WOLFSSL_ARMASM_SHA256_TRANSFORM
1282
1283
static int transform_check = 0;
1284
static cpuid_flags_atomic_t cpuid_flags = WC_CPUID_ATOMIC_INITIALIZER;
1285
1286
static int Transform_Sha256(wc_Sha256* sha256, const byte* data);
1287
static int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
1288
     word32 len);
1289
1290
/* Initialize to the software fallback so the pointer is never NULL if it is
1291
 * read before Sha256_SetTransform() has published the selected variant. */
1292
static int (*Transform_Sha256_Len_p)(wc_Sha256* sha256, const byte* data,
1293
     word32 len) = Transform_Sha256_Len;
1294
1295
static WC_INLINE int Transform_Sha256_aarch64(wc_Sha256* sha256,
1296
     const byte* data)
1297
{
1298
    return (*Transform_Sha256_Len_p)(sha256, data, WC_SHA256_BLOCK_SIZE);
1299
}
1300
1301
static WC_INLINE int Transform_Sha256_Len_aarch64(wc_Sha256* sha256,
1302
    const byte* data, word32 len)
1303
{
1304
    return (*Transform_Sha256_Len_p)(sha256, data, len);
1305
}
1306
1307
#if !defined(WOLFSSL_ARMASM_NO_NEON)
1308
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1309
static int Transform_Sha256_Len_crypto_aarch64(wc_Sha256* sha256,
1310
    const byte* data, word32 len)
1311
{
1312
    Transform_Sha256_Len_crypto(sha256, data, len);
1313
    return 0;
1314
}
1315
#endif
1316
1317
static int Transform_Sha256_Len_neon_aarch64(wc_Sha256* sha256,
1318
    const byte* data, word32 len)
1319
{
1320
    Transform_Sha256_Len_neon(sha256, data, len);
1321
    return 0;
1322
}
1323
#endif
1324
1325
static int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
1326
    word32 len)
1327
{
1328
    int ret = 0;
1329
1330
    while (len >= WC_SHA256_BLOCK_SIZE) {
1331
        word32 buffer[WC_SHA256_BLOCK_SIZE / sizeof(word32)];
1332
1333
        XMEMCPY(buffer, data, WC_SHA256_BLOCK_SIZE);
1334
    #ifdef LITTLE_ENDIAN_ORDER
1335
        ByteReverseWords(buffer, buffer, WC_SHA256_BLOCK_SIZE);
1336
    #endif
1337
        ret = Transform_Sha256(sha256, (const byte*)buffer);
1338
        if (ret != 0)
1339
            break;
1340
        data += WC_SHA256_BLOCK_SIZE;
1341
        len  -= WC_SHA256_BLOCK_SIZE;
1342
    }
1343
1344
    return ret;
1345
}
1346
1347
static void Sha256_SetTransform(void)
1348
{
1349
    if (transform_check)
1350
        return;
1351
1352
    cpuid_get_flags_atomic(&cpuid_flags);
1353
1354
#if !defined(WOLFSSL_ARMASM_NO_NEON)
1355
#if !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1356
    if (IS_AARCH64_SHA256(cpuid_flags)) {
1357
        Transform_Sha256_Len_p = Transform_Sha256_Len_crypto_aarch64;
1358
    }
1359
    else
1360
#endif
1361
    if (IS_AARCH64_ASIMD(cpuid_flags)) {
1362
        Transform_Sha256_Len_p = Transform_Sha256_Len_neon_aarch64;
1363
    }
1364
    else
1365
#endif
1366
    {
1367
        Transform_Sha256_Len_p = Transform_Sha256_Len;
1368
    }
1369
1370
    transform_check = 1;
1371
}
1372
1373
#define XTRANSFORM      Transform_Sha256_aarch64
1374
#define XTRANSFORM_LEN  Transform_Sha256_Len_aarch64
1375
1376
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1377
{
1378
    int ret = 0;
1379
1380
    if (sha256 == NULL)
1381
        return BAD_FUNC_ARG;
1382
    ret = InitSha256(sha256);
1383
    if (ret != 0)
1384
        return ret;
1385
1386
    sha256->heap = heap;
1387
#ifdef WOLF_CRYPTO_CB
1388
    sha256->devId = devId;
1389
    sha256->devCtx = NULL;
1390
#else
1391
    (void)devId;
1392
#endif
1393
1394
#ifdef WOLFSSL_SMALL_STACK_CACHE
1395
    sha256->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
1396
                                 sha256->heap, DYNAMIC_TYPE_DIGEST);
1397
    if (sha256->W == NULL)
1398
        return MEMORY_E;
1399
#endif
1400
1401
    return ret;
1402
}
1403
1404
#define NEED_SOFT_SHA256
1405
1406
#elif defined(WOLFSSL_ARMASM) && !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
1407
1408
/* As in the AArch64 arm above: this arm provides Sha256_SetTransform(). */
1409
#define WOLFSSL_ARMASM_SHA256_TRANSFORM
1410
1411
/* On 32-bit Arm a NEON build compiles in the base and NEON and (unless
1412
 * disabled) the Armv8 crypto-extension block transforms, so the best supported
1413
 * one is chosen at run time - mirroring the AArch64 path.  Thumb-2, no-NEON,
1414
 * no-crypto (NO_HW_CRYPTO) and crypto-only (NO_NEON_IMPL) builds compile a
1415
 * single variant and call it directly, as does a build with no run-time
1416
 * detection to dispatch on (HAVE_CPUID_ARM32). */
1417
#if !defined(WOLFSSL_ARMASM_THUMB2) && !defined(WOLFSSL_ARMASM_NO_NEON) && \
1418
    !defined(WOLFSSL_ARMASM_NO_HW_CRYPTO) && \
1419
    !(defined(WOLFSSL_ARMASM_NO_NEON_IMPL) && \
1420
      defined(WOLFSSL_ARMASM_NO_BASE_IMPL)) && defined(HAVE_CPUID_ARM32)
1421
    #define SHA256_ARM32_DISPATCH
1422
#endif
1423
1424
#ifdef SHA256_ARM32_DISPATCH
1425
1426
static int sha256_transform_check = 0;
1427
static cpuid_flags_atomic_t sha256_cpuid_flags = WC_CPUID_ATOMIC_INITIALIZER;
1428
1429
/* Initialize to the transform that needs the least of the CPU - the base one
1430
 * requires no extension at all - so the pointer is safe to use even if read
1431
 * before Sha256_SetTransform() runs. */
1432
#ifndef WOLFSSL_ARMASM_NO_BASE_IMPL
1433
    #define SHA256_ARM32_TRANSFORM_INIT     Transform_Sha256_Len_base
1434
#else
1435
    #define SHA256_ARM32_TRANSFORM_INIT     Transform_Sha256_Len_neon
1436
#endif
1437
1438
static void (*Transform_Sha256_Len_p)(wc_Sha256* sha256, const byte* data,
1439
    word32 len) = SHA256_ARM32_TRANSFORM_INIT;
1440
1441
/* Select the crypto-extension transform when the CPU implements FEAT_SHA256,
1442
 * otherwise the best fallback this build kept: NEON when the CPU implements
1443
 * Advanced SIMD, else the base transform.  Either fallback can be dropped
1444
 * (WOLFSSL_ARMASM_NO_NEON_IMPL / WOLFSSL_ARMASM_NO_BASE_IMPL) - dropping both
1445
 * is what turns dispatch off above. */
1446
static void Sha256_SetTransform(void)
1447
{
1448
    if (sha256_transform_check)
1449
        return;
1450
1451
    cpuid_get_flags_atomic(&sha256_cpuid_flags);
1452
1453
    if (IS_ARM32_SHA256(sha256_cpuid_flags)) {
1454
        Transform_Sha256_Len_p = Transform_Sha256_Len_crypto;
1455
    }
1456
#if !defined(WOLFSSL_ARMASM_NO_NEON_IMPL) && \
1457
    !defined(WOLFSSL_ARMASM_NO_BASE_IMPL)
1458
    else if (IS_ARM32_ASIMD(sha256_cpuid_flags)) {
1459
        Transform_Sha256_Len_p = Transform_Sha256_Len_neon;
1460
    }
1461
    else {
1462
        Transform_Sha256_Len_p = Transform_Sha256_Len_base;
1463
    }
1464
#elif !defined(WOLFSSL_ARMASM_NO_NEON_IMPL)
1465
    /* Base dropped - a NEON build always implements Advanced SIMD. */
1466
    else {
1467
        Transform_Sha256_Len_p = Transform_Sha256_Len_neon;
1468
    }
1469
#else
1470
    /* NEON implementation dropped - the base transform needs no extension. */
1471
    else {
1472
        Transform_Sha256_Len_p = Transform_Sha256_Len_base;
1473
    }
1474
#endif
1475
1476
    sha256_transform_check = 1;
1477
}
1478
1479
#else
1480
#define Sha256_SetTransform()   WC_DO_NOTHING
1481
#endif /* SHA256_ARM32_DISPATCH */
1482
1483
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1484
{
1485
    int ret = 0;
1486
1487
    if (sha256 == NULL)
1488
        return BAD_FUNC_ARG;
1489
    ret = InitSha256(sha256);
1490
    if (ret != 0)
1491
        return ret;
1492
1493
    Sha256_SetTransform();
1494
1495
    sha256->heap = heap;
1496
#ifdef WOLF_CRYPTO_CB
1497
    sha256->devId = devId;
1498
    sha256->devCtx = NULL;
1499
#else
1500
    (void)devId;
1501
#endif
1502
1503
    #ifdef WOLFSSL_SMALL_STACK_CACHE
1504
    sha256->W = NULL;
1505
    #endif
1506
1507
    return ret;
1508
}
1509
1510
/* Call the transform selected at run time, or - when only one variant is
1511
 * compiled in - the single one this build has.  The base transform is the
1512
 * choice for Thumb-2 and no-NEON builds, NEON when the crypto extension is off,
1513
 * and otherwise the crypto-extension transform the build was configured for. */
1514
static WC_INLINE int Transform_Sha256(wc_Sha256* sha256, const byte* data)
1515
{
1516
#ifdef SHA256_ARM32_DISPATCH
1517
    (*Transform_Sha256_Len_p)(sha256, data, WC_SHA256_BLOCK_SIZE);
1518
#elif defined(WOLFSSL_ARMASM_THUMB2) || defined(WOLFSSL_ARMASM_NO_NEON)
1519
    Transform_Sha256_Len_base(sha256, data, WC_SHA256_BLOCK_SIZE);
1520
#elif defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1521
    Transform_Sha256_Len_neon(sha256, data, WC_SHA256_BLOCK_SIZE);
1522
#else
1523
    Transform_Sha256_Len_crypto(sha256, data, WC_SHA256_BLOCK_SIZE);
1524
#endif
1525
    return 0;
1526
}
1527
1528
/* Multi-block form of Transform_Sha256() - see there for the selection. */
1529
static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
1530
    word32 len)
1531
{
1532
#ifdef SHA256_ARM32_DISPATCH
1533
    (*Transform_Sha256_Len_p)(sha256, data, len);
1534
#elif defined(WOLFSSL_ARMASM_THUMB2) || defined(WOLFSSL_ARMASM_NO_NEON)
1535
    Transform_Sha256_Len_base(sha256, data, len);
1536
#elif defined(WOLFSSL_ARMASM_NO_HW_CRYPTO)
1537
    Transform_Sha256_Len_neon(sha256, data, len);
1538
#else
1539
    Transform_Sha256_Len_crypto(sha256, data, len);
1540
#endif
1541
    return 0;
1542
}
1543
1544
#define XTRANSFORM      Transform_Sha256
1545
#define XTRANSFORM_LEN  Transform_Sha256_Len
1546
1547
#elif defined(WOLFSSL_RISCV_ASM) && !defined(WOLF_CRYPTO_CB_ONLY_SHA256)
1548
1549
int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1550
{
1551
    int ret = 0;
1552
1553
    if (sha256 == NULL)
1554
        return BAD_FUNC_ARG;
1555
    ret = InitSha256(sha256);
1556
    if (ret != 0)
1557
        return ret;
1558
1559
    sha256->heap = heap;
1560
#ifdef WOLF_CRYPTO_CB
1561
    sha256->devId = devId;
1562
    sha256->devCtx = NULL;
1563
#else
1564
    (void)devId;
1565
#endif
1566
1567
#ifdef WOLFSSL_SMALL_STACK_CACHE
1568
    sha256->W = NULL;
1569
#endif
1570
1571
    return ret;
1572
}
1573
1574
static WC_INLINE int Transform_Sha256(wc_Sha256* sha256, const byte* data)
1575
{
1576
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
1577
    Transform_Sha256_Len_riscv_vector(sha256, data, WC_SHA256_BLOCK_SIZE);
1578
#elif defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
1579
    Transform_Sha256_Len_riscv_crypto(sha256, data, WC_SHA256_BLOCK_SIZE);
1580
#else
1581
    Transform_Sha256_Len_riscv(sha256, data, WC_SHA256_BLOCK_SIZE);
1582
#endif
1583
    return 0;
1584
}
1585
1586
static WC_INLINE int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
1587
    word32 len)
1588
{
1589
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
1590
    Transform_Sha256_Len_riscv_vector(sha256, data, len);
1591
#elif defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
1592
    Transform_Sha256_Len_riscv_crypto(sha256, data, len);
1593
#else
1594
    Transform_Sha256_Len_riscv(sha256, data, len);
1595
#endif
1596
    return 0;
1597
}
1598
#define XTRANSFORM      Transform_Sha256
1599
#define XTRANSFORM_LEN  Transform_Sha256_Len
1600
1601
#elif defined(WOLF_CRYPTO_CB_ONLY_SHA256)
1602
    /* Software SHA-256 stripped; every op dispatches via cryptocb. */
1603
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1604
    {
1605
        int ret;
1606
        if (sha256 == NULL)
1607
            return BAD_FUNC_ARG;
1608
        ret = InitSha256(sha256);
1609
        if (ret != 0)
1610
            return ret;
1611
        sha256->heap   = heap;
1612
        sha256->devId  = devId;
1613
        sha256->devCtx = NULL;
1614
        return ret;
1615
    }
1616
#else
1617
    #define NEED_SOFT_SHA256
1618
1619
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
1620
160k
    {
1621
160k
        int ret = 0;
1622
160k
        if (sha256 == NULL)
1623
0
            return BAD_FUNC_ARG;
1624
160k
        ret = InitSha256(sha256);
1625
160k
        if (ret != 0)
1626
0
            return ret;
1627
1628
160k
        sha256->heap = heap;
1629
160k
    #ifdef WOLF_CRYPTO_CB
1630
160k
        sha256->devId = devId;
1631
160k
        sha256->devCtx = NULL;
1632
160k
    #endif
1633
    #ifdef WOLFSSL_SMALL_STACK_CACHE
1634
        sha256->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
1635
                                     sha256->heap, DYNAMIC_TYPE_DIGEST);
1636
        if (sha256->W == NULL)
1637
            return MEMORY_E;
1638
    #endif
1639
1640
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
1641
        ret = wolfAsync_DevCtxInit(&sha256->asyncDev,
1642
                            WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId);
1643
    #else
1644
160k
        (void)devId;
1645
160k
    #endif /* WOLFSSL_ASYNC_CRYPT */
1646
    #ifdef WOLFSSL_IMXRT1170_CAAM
1647
         ret = wc_CAAM_HashInit(&sha256->hndl, &sha256->ctx, WC_HASH_TYPE_SHA256);
1648
    #endif
1649
1650
160k
        return ret;
1651
160k
    }
1652
#endif /* End Hardware Acceleration */
1653
1654
#ifdef NEED_SOFT_SHA256
1655
1656
    static const FLASH_QUALIFIER ALIGN32 word32 K[64] = {
1657
        0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
1658
        0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
1659
        0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L,
1660
        0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
1661
        0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L,
1662
        0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L,
1663
        0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL,
1664
        0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
1665
        0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L,
1666
        0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L,
1667
        0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL,
1668
        0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
1669
        0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L
1670
    };
1671
1672
/* Both versions of Ch and Maj are logically the same, but with the second set
1673
    the compilers can recognize them better for optimization */
1674
#ifdef WOLFSSL_SHA256_BY_SPEC
1675
    /* SHA256 math based on specification */
1676
55.6M
    #define Ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
1677
55.6M
    #define Maj(x,y,z)      ((((x) | (y)) & (z)) | ((x) & (y)))
1678
#else
1679
    /* SHA256 math reworked for easier compiler optimization */
1680
    #define Ch(x,y,z)       ((((y) ^ (z)) & (x)) ^ (z))
1681
    #define Maj(x,y,z)      ((((x) ^ (y)) & ((y) ^ (z))) ^ (y))
1682
#endif
1683
83.4M
    #define R(x, n)         (((x) & 0xFFFFFFFFU) >> (n))
1684
1685
500M
    #define S(x, n)         rotrFixed(x, n)
1686
55.6M
    #define Sigma0(x)       (S(x, 2)  ^ S(x, 13) ^ S(x, 22))
1687
55.6M
    #define Sigma1(x)       (S(x, 6)  ^ S(x, 11) ^ S(x, 25))
1688
41.7M
    #define Gamma0(x)       (S(x, 7)  ^ S(x, 18) ^ R(x, 3))
1689
41.7M
    #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
1690
1691
    #define a(i) S[(0-(i)) & 7]
1692
    #define b(i) S[(1-(i)) & 7]
1693
    #define c(i) S[(2-(i)) & 7]
1694
55.6M
    #define d(i) S[(3-(i)) & 7]
1695
    #define e(i) S[(4-(i)) & 7]
1696
    #define f(i) S[(5-(i)) & 7]
1697
    #define g(i) S[(6-(i)) & 7]
1698
111M
    #define h(i) S[(7-(i)) & 7]
1699
1700
    #ifndef XTRANSFORM
1701
918k
         #define XTRANSFORM(S, D)         Transform_Sha256(S, D)
1702
    #endif
1703
1704
#ifndef SHA256_MANY_REGISTERS
1705
    #define RND(j) \
1706
55.6M
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+(j)] + W[i+(j)]; \
1707
55.6M
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
1708
55.6M
         d(j) += t0; \
1709
55.6M
         h(j)  = t0 + t1
1710
1711
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
1712
871k
    {
1713
871k
        word32 S[8], t0, t1;
1714
871k
        int i;
1715
1716
    #if defined(WOLFSSL_SMALL_STACK_CACHE) && !defined(WOLFSSL_NO_MALLOC)
1717
        word32* W = sha256->W;
1718
        if (W == NULL)
1719
            return BAD_FUNC_ARG;
1720
    #elif defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_NO_MALLOC)
1721
        word32* W;
1722
871k
        W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
1723
871k
                             sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);
1724
871k
        if (W == NULL)
1725
1.75k
            return MEMORY_E;
1726
    #else
1727
        word32 W[WC_SHA256_BLOCK_SIZE];
1728
    #endif
1729
1730
        /* Copy context->state[] to working vars */
1731
7.82M
        for (i = 0; i < 8; i++)
1732
6.95M
            S[i] = sha256->digest[i];
1733
1734
14.7M
        for (i = 0; i < 16; i++)
1735
13.9M
            W[i] = *((const word32*)&data[i*(int)sizeof(word32)]);
1736
1737
42.5M
        for (i = 16; i < WC_SHA256_BLOCK_SIZE; i++)
1738
41.7M
            W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];
1739
1740
    #ifdef USE_SLOW_SHA256
1741
        /* not unrolled - ~2k smaller and ~25% slower */
1742
        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {
1743
            int j;
1744
            for (j = 0; j < 8; j++) { /* braces needed here for macros {} */
1745
                RND(j);
1746
            }
1747
        }
1748
    #else
1749
        /* partially loop unrolled */
1750
7.82M
        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {
1751
6.95M
            RND(0); RND(1); RND(2); RND(3);
1752
6.95M
            RND(4); RND(5); RND(6); RND(7);
1753
6.95M
        }
1754
869k
    #endif /* USE_SLOW_SHA256 */
1755
1756
        /* Add the working vars back into digest state[] */
1757
7.82M
        for (i = 0; i < 8; i++) {
1758
6.95M
            sha256->digest[i] += S[i];
1759
6.95M
        }
1760
1761
869k
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE) &&\
1762
869k
        !defined(WOLFSSL_NO_MALLOC)
1763
869k
        ForceZero(W, sizeof(word32) * WC_SHA256_BLOCK_SIZE);
1764
869k
        XFREE(W, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);
1765
869k
    #endif
1766
869k
        return 0;
1767
871k
    }
1768
#else
1769
    /* SHA256 version that keeps all data in registers */
1770
    #define SCHED1(j) (W[j] = *((word32*)&data[j*sizeof(word32)]))
1771
    #define SCHED(j) (               \
1772
                   W[ j     & 15] += \
1773
            Gamma1(W[(j-2)  & 15])+  \
1774
                   W[(j-7)  & 15] +  \
1775
            Gamma0(W[(j-15) & 15])   \
1776
        )
1777
1778
    #define RND1(j) \
1779
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED1(j); \
1780
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
1781
         d(j) += t0; \
1782
         h(j)  = t0 + t1
1783
    #define RNDN(j) \
1784
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED(j); \
1785
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
1786
         d(j) += t0; \
1787
         h(j)  = t0 + t1
1788
1789
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
1790
    {
1791
        word32 S[8], t0, t1;
1792
        int i;
1793
    #ifdef USE_SLOW_SHA256
1794
        int j;
1795
    #endif
1796
        word32 W[WC_SHA256_BLOCK_SIZE/sizeof(word32)];
1797
1798
        /* Copy digest to working vars */
1799
        S[0] = sha256->digest[0];
1800
        S[1] = sha256->digest[1];
1801
        S[2] = sha256->digest[2];
1802
        S[3] = sha256->digest[3];
1803
        S[4] = sha256->digest[4];
1804
        S[5] = sha256->digest[5];
1805
        S[6] = sha256->digest[6];
1806
        S[7] = sha256->digest[7];
1807
1808
        i = 0;
1809
    #ifdef USE_SLOW_SHA256
1810
        for (j = 0; j < 16; j++) {
1811
            RND1(j);
1812
        }
1813
        for (i = 16; i < 64; i += 16) {
1814
            for (j = 0; j < 16; j++) {
1815
                RNDN(j);
1816
            }
1817
        }
1818
    #else
1819
        RND1( 0); RND1( 1); RND1( 2); RND1( 3);
1820
        RND1( 4); RND1( 5); RND1( 6); RND1( 7);
1821
        RND1( 8); RND1( 9); RND1(10); RND1(11);
1822
        RND1(12); RND1(13); RND1(14); RND1(15);
1823
        /* 64 operations, partially loop unrolled */
1824
        for (i = 16; i < 64; i += 16) {
1825
            RNDN( 0); RNDN( 1); RNDN( 2); RNDN( 3);
1826
            RNDN( 4); RNDN( 5); RNDN( 6); RNDN( 7);
1827
            RNDN( 8); RNDN( 9); RNDN(10); RNDN(11);
1828
            RNDN(12); RNDN(13); RNDN(14); RNDN(15);
1829
        }
1830
    #endif
1831
1832
        /* Add the working vars back into digest */
1833
        sha256->digest[0] += S[0];
1834
        sha256->digest[1] += S[1];
1835
        sha256->digest[2] += S[2];
1836
        sha256->digest[3] += S[3];
1837
        sha256->digest[4] += S[4];
1838
        sha256->digest[5] += S[5];
1839
        sha256->digest[6] += S[6];
1840
        sha256->digest[7] += S[7];
1841
1842
        return 0;
1843
    }
1844
#endif /* SHA256_MANY_REGISTERS */
1845
#endif
1846
/* End wc_ software implementation */
1847
1848
#ifdef XTRANSFORM
1849
1850
    static WC_INLINE void AddLength(wc_Sha256* sha256, word32 len)
1851
477k
    {
1852
477k
        word32 tmp = sha256->loLen;
1853
477k
        if ((sha256->loLen += len) < tmp) {
1854
0
            sha256->hiLen++;                       /* carry low to high */
1855
0
        }
1856
477k
    }
1857
1858
    /* do block size increments/updates */
1859
    static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data,
1860
        word32 len)
1861
478k
    {
1862
478k
        int ret = 0;
1863
478k
        word32 blocksLen;
1864
478k
        byte* local;
1865
1866
        /* check that internal buffLen is valid */
1867
478k
        if (sha256->buffLen >= WC_SHA256_BLOCK_SIZE) {
1868
389
            return BUFFER_E;
1869
389
        }
1870
1871
        /* add length for final */
1872
477k
        AddLength(sha256, len);
1873
1874
477k
        local = (byte*)sha256->buffer;
1875
1876
        /* process any remainder from previous operation */
1877
477k
        if (sha256->buffLen > 0) {
1878
240k
            blocksLen = min(len, WC_SHA256_BLOCK_SIZE - sha256->buffLen);
1879
240k
            XMEMCPY(&local[sha256->buffLen], data, blocksLen);
1880
1881
240k
            sha256->buffLen += blocksLen;
1882
240k
            data            += blocksLen;
1883
240k
            len             -= blocksLen;
1884
1885
240k
            if (sha256->buffLen == WC_SHA256_BLOCK_SIZE) {
1886
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1887
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1888
                if (sha256->ctx.mode == ESP32_SHA_INIT) {
1889
                    ESP_LOGV(TAG, "Sha256Update try hardware");
1890
                    esp_sha_try_hw_lock(&sha256->ctx);
1891
                }
1892
            #endif
1893
1894
77.1k
            if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
1895
            #ifdef WOLFSSL_WIDE_BYTE
1896
                /* CHAR_BIT != 8: pack 16 big-endian schedule words octet-wise */
1897
                WordsFromBytesBE32(sha256->buffer, (const byte*)sha256->buffer,
1898
                    WC_SHA256_BLOCK_SIZE / 4);
1899
            #else
1900
77.1k
                ByteReverseWords(sha256->buffer, sha256->buffer,
1901
77.1k
                    WC_SHA256_BLOCK_SIZE);
1902
77.1k
            #endif
1903
77.1k
            }
1904
1905
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1906
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1907
                if (sha256->ctx.mode == ESP32_SHA_SW) {
1908
                    #if defined(WOLFSSL_DEBUG_MUTEX)
1909
                    {
1910
                        ESP_LOGI(TAG, "Sha256Update process software");
1911
                    }
1912
                    #endif
1913
                    #ifdef WOLFSSL_HW_METRICS
1914
                    {
1915
                        /* Track of # SW during transforms during active HW */
1916
                        esp_sw_sha256_count_add();
1917
                    }
1918
                    #endif /* WOLFSSL_HW_METRICS */
1919
                    ret = XTRANSFORM(sha256, (const byte*)local);
1920
                }
1921
                else {
1922
                    #if defined(WOLFSSL_DEBUG_MUTEX)
1923
                    {
1924
                        ESP_LOGI(TAG, "Sha256Update process hardware");
1925
                    }
1926
                    #endif
1927
                    esp_sha256_process(sha256, (const byte*)local);
1928
                }
1929
            #else
1930
                /* Always SW */
1931
77.1k
                ret = XTRANSFORM(sha256, (const byte*)local);
1932
77.1k
            #endif
1933
77.1k
                if (ret == 0)
1934
76.3k
                    sha256->buffLen = 0;
1935
846
                else
1936
846
                    len = 0; /* error */
1937
77.1k
            }
1938
240k
        }
1939
1940
        /* process blocks */
1941
    #ifdef XTRANSFORM_LEN
1942
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1943
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1944
1945
        #ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
1946
        if (sha_method != SHA256_C)
1947
        #else
1948
        if (Transform_Sha256_Len_p != NULL)
1949
        #endif
1950
1951
        #endif
1952
        {
1953
            if (len >= WC_SHA256_BLOCK_SIZE) {
1954
                /* get number of blocks */
1955
                /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */
1956
                /* len (masked by 0xFFFFFFC0) returns block aligned length */
1957
                blocksLen = len & ~((word32)WC_SHA256_BLOCK_SIZE-1);
1958
                /* Byte reversal and alignment handled in function if required
1959
                 */
1960
                ret = XTRANSFORM_LEN(sha256, data, blocksLen);
1961
                if (ret == 0) {
1962
                    data += blocksLen;
1963
                    len  -= blocksLen;
1964
                }
1965
            }
1966
        }
1967
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1968
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1969
        else
1970
        #endif
1971
    #endif /* XTRANSFORM_LEN */
1972
477k
    #if !defined(XTRANSFORM_LEN) || \
1973
477k
        (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1974
477k
         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
1975
477k
        {
1976
1.19M
            while (len >= WC_SHA256_BLOCK_SIZE) {
1977
720k
                word32* local32 = sha256->buffer;
1978
                /* optimization to avoid memcpy if data pointer is properly aligned */
1979
                /* Intel transform function requires use of sha256->buffer */
1980
                /* Little Endian requires byte swap, so can't use data directly */
1981
            #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(LITTLE_ENDIAN_ORDER) && \
1982
                !(defined(WOLFSSL_X86_64_BUILD) && \
1983
                         defined(USE_INTEL_SPEEDUP) && \
1984
                         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
1985
                if (((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {
1986
                    local32 = (word32*)data;
1987
                }
1988
                else
1989
            #endif
1990
720k
                {
1991
720k
                    XMEMCPY(local32, data, WC_SHA256_BLOCK_SIZE);
1992
720k
                }
1993
1994
720k
                data += WC_SHA256_BLOCK_SIZE;
1995
720k
                len  -= WC_SHA256_BLOCK_SIZE;
1996
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1997
               !defined( NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1998
                if (sha256->ctx.mode == ESP32_SHA_INIT){
1999
                    ESP_LOGV(TAG, "Sha256Update try hardware loop");
2000
                    esp_sha_try_hw_lock(&sha256->ctx);
2001
                }
2002
            #endif
2003
2004
720k
            if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
2005
            #ifdef WOLFSSL_WIDE_BYTE
2006
                WordsFromBytesBE32(local32, (const byte*)local32,
2007
                    WC_SHA256_BLOCK_SIZE / 4);
2008
            #else
2009
720k
                ByteReverseWords(local32, local32, WC_SHA256_BLOCK_SIZE);
2010
720k
            #endif
2011
720k
            }
2012
2013
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2014
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2015
                if (sha256->ctx.mode == ESP32_SHA_SW) {
2016
                    ESP_LOGV(TAG, "Sha256Update process software loop");
2017
                    ret = XTRANSFORM(sha256, (const byte*)local32);
2018
                }
2019
                else {
2020
                    ESP_LOGV(TAG, "Sha256Update process hardware");
2021
                    esp_sha256_process(sha256, (const byte*)local32);
2022
                }
2023
            #else
2024
720k
                ret = XTRANSFORM(sha256, (const byte*)local32);
2025
720k
            #endif
2026
2027
720k
                if (ret != 0)
2028
843
                    break;
2029
720k
            }
2030
477k
        }
2031
477k
    #endif
2032
2033
        /* save remainder */
2034
477k
        if (ret == 0 && len > 0) {
2035
211k
            XMEMCPY(local, data, len);
2036
211k
            sha256->buffLen = len;
2037
211k
        }
2038
2039
477k
        return ret;
2040
478k
    }
2041
2042
#if defined(WOLFSSL_KCAPI_HASH)
2043
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2044
2045
#else
2046
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
2047
472k
    {
2048
472k
        if (sha256 == NULL) {
2049
0
            return BAD_FUNC_ARG;
2050
0
        }
2051
472k
        if (len == 0) {
2052
            /* valid, but do nothing */
2053
6.70k
            return 0;
2054
6.70k
        }
2055
466k
        if (data == NULL) {
2056
0
            return BAD_FUNC_ARG;
2057
0
        }
2058
2059
466k
    #ifdef WOLF_CRYPTO_CB
2060
466k
        #ifndef WOLF_CRYPTO_CB_FIND
2061
466k
        if (sha256->devId != INVALID_DEVID)
2062
109
        #endif
2063
109
        {
2064
109
            int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL);
2065
109
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2066
0
                return ret;
2067
            /* fall-through when unavailable */
2068
109
        }
2069
466k
    #endif
2070
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
2071
        if (sha256->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA256) {
2072
        #if defined(HAVE_INTEL_QA)
2073
            return IntelQaSymSha256(&sha256->asyncDev, NULL, data, len);
2074
        #endif
2075
        }
2076
    #endif /* WOLFSSL_ASYNC_CRYPT */
2077
2078
466k
        return Sha256Update(sha256, data, len);
2079
466k
    }
2080
#endif
2081
2082
    static WC_INLINE int Sha256Final(wc_Sha256* sha256)
2083
119k
    {
2084
119k
        int ret;
2085
119k
        byte* local;
2086
2087
        /* we'll add a 0x80 byte at the end,
2088
        ** so make sure we have appropriate buffer length. */
2089
119k
        if (sha256->buffLen > WC_SHA256_BLOCK_SIZE - 1) {
2090
            /* exit with error code if there's a bad buffer size in buffLen */
2091
0
            return BAD_STATE_E;
2092
0
        } /* buffLen check */
2093
2094
119k
        local = (byte*)sha256->buffer;
2095
119k
        local[sha256->buffLen++] = 0x80; /* add 1 */
2096
2097
        /* pad with zeros */
2098
119k
        if (sha256->buffLen > WC_SHA256_PAD_SIZE) {
2099
1.64k
            if (sha256->buffLen < WC_SHA256_BLOCK_SIZE) {
2100
1.53k
                XMEMSET(&local[sha256->buffLen], 0,
2101
1.53k
                    WC_SHA256_BLOCK_SIZE - sha256->buffLen);
2102
1.53k
            }
2103
2104
        #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2105
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2106
            if (sha256->ctx.mode == ESP32_SHA_INIT) {
2107
                esp_sha_try_hw_lock(&sha256->ctx);
2108
            }
2109
        #endif
2110
2111
1.64k
        if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
2112
        #ifdef WOLFSSL_WIDE_BYTE
2113
            WordsFromBytesBE32(sha256->buffer, (const byte*)sha256->buffer,
2114
                WC_SHA256_BLOCK_SIZE / 4);
2115
        #else
2116
1.64k
            ByteReverseWords(sha256->buffer, sha256->buffer,
2117
1.64k
                WC_SHA256_BLOCK_SIZE);
2118
1.64k
        #endif
2119
1.64k
        }
2120
2121
        #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2122
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2123
            if (sha256->ctx.mode == ESP32_SHA_INIT) {
2124
                esp_sha_try_hw_lock(&sha256->ctx);
2125
            }
2126
            if (sha256->ctx.mode == ESP32_SHA_SW) {
2127
                ret = XTRANSFORM(sha256, (const byte*)local);
2128
            }
2129
            else {
2130
                ret = esp_sha256_process(sha256, (const byte*)local);
2131
            }
2132
        #else
2133
1.64k
            ret = XTRANSFORM(sha256, (const byte*)local);
2134
1.64k
        #endif
2135
1.64k
            if (ret != 0)
2136
2
                return ret;
2137
2138
1.64k
            sha256->buffLen = 0;
2139
1.64k
        }
2140
119k
        XMEMSET(&local[sha256->buffLen], 0,
2141
119k
            WC_SHA256_PAD_SIZE - sha256->buffLen);
2142
2143
        /* put 64 bit length in separate 32 bit parts */
2144
119k
        sha256->hiLen = (sha256->loLen >>
2145
119k
                            (CHAR_BIT * sizeof(sha256->loLen) - 3)) +
2146
119k
                                                         (sha256->hiLen << 3);
2147
119k
        sha256->loLen = sha256->loLen << 3;
2148
2149
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2150
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2151
        if (sha256->ctx.mode == ESP32_SHA_INIT) {
2152
            esp_sha_try_hw_lock(&sha256->ctx);
2153
        }
2154
    #endif
2155
2156
        /* store lengths */
2157
#ifdef WOLFSSL_WIDE_BYTE
2158
        /* CHAR_BIT != 8: 'local' indexes octet cells, so place the 64-bit
2159
         * bit-length as 8 big-endian octets (W[14]=hiLen, W[15]=loLen). */
2160
        local[WC_SHA256_PAD_SIZE + 0] = (byte)((sha256->hiLen >> 24) & 0xFF);
2161
        local[WC_SHA256_PAD_SIZE + 1] = (byte)((sha256->hiLen >> 16) & 0xFF);
2162
        local[WC_SHA256_PAD_SIZE + 2] = (byte)((sha256->hiLen >>  8) & 0xFF);
2163
        local[WC_SHA256_PAD_SIZE + 3] = (byte)((sha256->hiLen      ) & 0xFF);
2164
        local[WC_SHA256_PAD_SIZE + 4] = (byte)((sha256->loLen >> 24) & 0xFF);
2165
        local[WC_SHA256_PAD_SIZE + 5] = (byte)((sha256->loLen >> 16) & 0xFF);
2166
        local[WC_SHA256_PAD_SIZE + 6] = (byte)((sha256->loLen >>  8) & 0xFF);
2167
        local[WC_SHA256_PAD_SIZE + 7] = (byte)((sha256->loLen      ) & 0xFF);
2168
#endif
2169
119k
        if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
2170
        #ifdef WOLFSSL_WIDE_BYTE
2171
            /* pack all 16 big-endian schedule words octet-wise (incl. length) */
2172
            WordsFromBytesBE32(sha256->buffer, (const byte*)sha256->buffer,
2173
                WC_SHA256_BLOCK_SIZE / 4);
2174
        #else
2175
119k
            ByteReverseWords(sha256->buffer, sha256->buffer,
2176
119k
                WC_SHA256_PAD_SIZE);
2177
119k
        #endif
2178
119k
        }
2179
119k
#ifndef WOLFSSL_WIDE_BYTE
2180
        /* ! 64-bit length ordering dependent on digest endian type ! */
2181
119k
        XMEMCPY(&local[WC_SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32));
2182
119k
        XMEMCPY(&local[WC_SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
2183
119k
                sizeof(word32));
2184
119k
#endif
2185
2186
    /* Only the ESP32-C3 with HW enabled may need pad size byte order reversal
2187
     * depending on HW or SW mode */
2188
    #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
2189
          defined(CONFIG_IDF_TARGET_ESP8684) || \
2190
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
2191
          defined(CONFIG_IDF_TARGET_ESP32C6)    \
2192
        ) && \
2193
        defined(WOLFSSL_ESP32_CRYPT) &&         \
2194
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
2195
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2196
        /* For Espressif RISC-V Targets, we *may* need to reverse bytes
2197
         * depending on if HW is active or not. */
2198
        if (sha256->ctx.mode == ESP32_SHA_HW) {
2199
        #if defined(WOLFSSL_SUPER_VERBOSE_DEBUG)
2200
            ESP_LOGV(TAG, "Start: Reverse PAD SIZE Endianness.");
2201
        #endif
2202
            ByteReverseWords(
2203
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)], /* out */
2204
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)], /* in  */
2205
                2 * sizeof(word32) /* byte count to reverse */
2206
            );
2207
        #if defined(WOLFSSL_SUPER_VERBOSE_DEBUG)
2208
            ESP_LOGV(TAG, "End: Reverse PAD SIZE Endianness.");
2209
        #endif
2210
        } /* end if (sha256->ctx.mode == ESP32_SHA_HW) */
2211
    #endif
2212
2213
    #if defined(FREESCALE_MMCAU_SHA) || \
2214
        (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2215
                         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
2216
        /* Kinetis requires only these bytes reversed */
2217
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2218
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2219
        #ifdef WC_SHA256_RAW_BE_BUFFER
2220
        /* raw-buffer convention -- the length words must be big-endian in the
2221
         * stream regardless of which transform consumes the final block. */
2222
        #else
2223
        if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags) ||
2224
            IS_INTEL_SHA(intel_flags))
2225
        #endif
2226
        #endif
2227
        {
2228
            ByteReverseWords(
2229
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2230
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2231
                2 * sizeof(word32));
2232
        }
2233
    #endif
2234
    #if (defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM)) && \
2235
        !defined(FREESCALE_MMCAU_SHA)
2236
        ByteReverseWords( &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2237
            &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2238
            2 * sizeof(word32));
2239
    #endif
2240
    #if defined(WOLFSSL_PPC64_ASM) && defined(LITTLE_ENDIAN_ORDER)
2241
        /* The PPC64 assembly loads the message with byte-reversed loads on
2242
         * little-endian, treating the whole block as a big-endian byte stream.
2243
         * The 64-bit length above is stored in native (little-endian) word
2244
         * order, so reverse it here to keep the block a consistent big-endian
2245
         * stream. */
2246
        ByteReverseWords( &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2247
            &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2248
            2 * sizeof(word32));
2249
    #endif
2250
2251
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2252
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2253
        if (sha256->ctx.mode == ESP32_SHA_INIT) {
2254
            esp_sha_try_hw_lock(&sha256->ctx);
2255
        }
2256
        /* depending on architecture and ctx.mode value
2257
         * we may or may not need default digest */
2258
        if (sha256->ctx.mode == ESP32_SHA_SW) {
2259
            ret = XTRANSFORM(sha256, (const byte*)local);
2260
        }
2261
        else {
2262
            ret = esp_sha256_digest_process(sha256, 1);
2263
        }
2264
    #else
2265
119k
        ret = XTRANSFORM(sha256, (const byte*)local);
2266
119k
    #endif
2267
2268
119k
        return ret;
2269
119k
    }
2270
2271
#if !defined(WOLFSSL_KCAPI_HASH)
2272
2273
#ifndef WOLF_CRYPTO_CB_ONLY_SHA256
2274
    int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
2275
55
    {
2276
55
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_WIDE_BYTE)
2277
55
        word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)];
2278
55
        XMEMSET(digest, 0, sizeof(digest));
2279
55
    #endif
2280
2281
55
        if (sha256 == NULL || hash == NULL) {
2282
0
            return BAD_FUNC_ARG;
2283
0
        }
2284
2285
    #if defined(WOLFSSL_WIDE_BYTE)
2286
        /* CHAR_BIT != 8: store digest words as big-endian octets. */
2287
        BytesFromWordsBE32(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2288
    #elif defined(LITTLE_ENDIAN_ORDER)
2289
55
        if (SHA256_REV_BYTES(&sha256->ctx)) {
2290
55
            ByteReverseWords((word32*)digest, (word32*)sha256->digest,
2291
55
                              WC_SHA256_DIGEST_SIZE);
2292
55
        }
2293
55
        XMEMCPY(hash, digest, WC_SHA256_DIGEST_SIZE);
2294
    #else
2295
        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2296
    #endif
2297
2298
55
        return 0;
2299
55
    }
2300
#endif /* !WOLF_CRYPTO_CB_ONLY_SHA256 */
2301
2302
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
2303
117k
    {
2304
117k
        int ret;
2305
2306
117k
        if (sha256 == NULL || hash == NULL) {
2307
0
            return BAD_FUNC_ARG;
2308
0
        }
2309
2310
117k
    #ifdef WOLF_CRYPTO_CB
2311
117k
        #ifndef WOLF_CRYPTO_CB_FIND
2312
117k
        if (sha256->devId != INVALID_DEVID)
2313
44
        #endif
2314
44
        {
2315
44
            ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash);
2316
44
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2317
0
                return ret;
2318
            /* fall-through when unavailable */
2319
44
        }
2320
117k
    #endif
2321
2322
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
2323
        if (sha256->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA256) {
2324
        #if defined(HAVE_INTEL_QA)
2325
            return IntelQaSymSha256(&sha256->asyncDev, hash, NULL,
2326
                                            WC_SHA256_DIGEST_SIZE);
2327
        #endif
2328
        }
2329
    #endif /* WOLFSSL_ASYNC_CRYPT */
2330
2331
117k
        ret = Sha256Final(sha256);
2332
117k
        if (ret != 0) {
2333
70
            return ret;
2334
70
        }
2335
2336
    #if defined(WOLFSSL_WIDE_BYTE)
2337
        /* CHAR_BIT != 8: store digest words as big-endian octets. */
2338
        BytesFromWordsBE32(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2339
    #else
2340
117k
    #if defined(LITTLE_ENDIAN_ORDER)
2341
117k
        if (SHA256_REV_BYTES(&sha256->ctx)) {
2342
117k
            ByteReverseWords(sha256->digest, sha256->digest,
2343
117k
                WC_SHA256_DIGEST_SIZE);
2344
117k
        }
2345
117k
    #endif
2346
117k
        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2347
117k
    #endif
2348
2349
117k
        return InitSha256(sha256);  /* reset state */
2350
117k
    }
2351
2352
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
2353
/* Apply SHA256 transformation to the data                */
2354
/* @param sha  a pointer to wc_Sha256 structure           */
2355
/* @param data data to be applied SHA256 transformation   */
2356
/* @return 0 on successful, otherwise non-zero on failure */
2357
    int wc_Sha256Transform(wc_Sha256* sha256, const unsigned char* data)
2358
    {
2359
        if (sha256 == NULL || data == NULL) {
2360
            return BAD_FUNC_ARG;
2361
        }
2362
2363
    #if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM)
2364
        #ifdef __aarch64__
2365
        if (Transform_Sha256_Len_p == Transform_Sha256_Len) {
2366
            return Transform_Sha256(sha256, data);
2367
        }
2368
        else
2369
        #endif
2370
        {
2371
            byte buffer[WC_SHA256_BLOCK_SIZE];
2372
            ByteReverseWords((word32*)buffer, (word32*)data,
2373
                WC_SHA256_BLOCK_SIZE);
2374
        #ifdef __aarch64__
2375
            return Transform_Sha256_aarch64(sha256, buffer);
2376
        #else
2377
            return Transform_Sha256(sha256, buffer);
2378
        #endif
2379
        }
2380
    #else
2381
        return Transform_Sha256(sha256, data);
2382
    #endif
2383
    }
2384
#endif /* OPENSSL_EXTRA || HAVE_CURL */
2385
2386
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH)
2387
    /* One block will be used from data.
2388
     * hash must be big enough to hold all of digest output.
2389
     */
2390
    int wc_Sha256HashBlock(wc_Sha256* sha256, const unsigned char* data,
2391
        unsigned char* hash)
2392
    {
2393
        int ret;
2394
2395
        if ((sha256 == NULL) || (data == NULL)) {
2396
            return BAD_FUNC_ARG;
2397
        }
2398
2399
        if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
2400
            ByteReverseWords(sha256->buffer, (const word32*)data,
2401
                WC_SHA256_BLOCK_SIZE);
2402
            data = (const unsigned char*)sha256->buffer;
2403
        }
2404
        ret = XTRANSFORM(sha256, data);
2405
2406
        if ((ret == 0) && (hash != NULL)) {
2407
            if (!SHA256_REV_BYTES(&sha256->ctx)) {
2408
                XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2409
            }
2410
            else {
2411
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP)
2412
                __asm__ __volatile__ (
2413
                    "mov    0x00(%[d]), %%esi\n\t"
2414
                    "movbe  %%esi, 0x00(%[h])\n\t"
2415
                    "mov    0x04(%[d]), %%esi\n\t"
2416
                    "movbe  %%esi, 0x04(%[h])\n\t"
2417
                    "mov    0x08(%[d]), %%esi\n\t"
2418
                    "movbe  %%esi, 0x08(%[h])\n\t"
2419
                    "mov    0x0c(%[d]), %%esi\n\t"
2420
                    "movbe  %%esi, 0x0c(%[h])\n\t"
2421
                    "mov    0x10(%[d]), %%esi\n\t"
2422
                    "movbe  %%esi, 0x10(%[h])\n\t"
2423
                    "mov    0x14(%[d]), %%esi\n\t"
2424
                    "movbe  %%esi, 0x14(%[h])\n\t"
2425
                    "mov    0x18(%[d]), %%esi\n\t"
2426
                    "movbe  %%esi, 0x18(%[h])\n\t"
2427
                    "mov    0x1c(%[d]), %%esi\n\t"
2428
                    "movbe  %%esi, 0x1c(%[h])\n\t"
2429
                    :
2430
                    : [d] "r" (sha256->digest), [h] "r" (hash)
2431
                    : "memory", "esi"
2432
                );
2433
        #else
2434
                word32* hash32 = (word32*)hash;
2435
                word32* digest = (word32*)sha256->digest;
2436
            #if WOLFSSL_GENERAL_ALIGNMENT < 4
2437
                ALIGN16 word32 buf[WC_SHA256_DIGEST_SIZE / sizeof(word32)];
2438
2439
                if (((size_t)digest & 0x3) != 0) {
2440
                    if (((size_t)hash32 & 0x3) != 0) {
2441
                        XMEMCPY(buf, digest, WC_SHA256_DIGEST_SIZE);
2442
                        hash32 = buf;
2443
                        digest = buf;
2444
                    }
2445
                    else {
2446
                        XMEMCPY(hash, digest, WC_SHA256_DIGEST_SIZE);
2447
                        digest = hash32;
2448
                    }
2449
                }
2450
                else if (((size_t)hash32 & 0x3) != 0) {
2451
                    hash32 = digest;
2452
                }
2453
            #endif
2454
                ByteReverseWords(hash32, digest, (word32)(sizeof(word32) * 8));
2455
            #if WOLFSSL_GENERAL_ALIGNMENT < 4
2456
                if (hash != (byte*)hash32) {
2457
                    XMEMCPY(hash, hash32, WC_SHA256_DIGEST_SIZE);
2458
                }
2459
            #endif
2460
        #endif /* WOLFSSL_X86_64_BUILD && USE_INTEL_SPEEDUP */
2461
            }
2462
            sha256->digest[0] = 0x6A09E667L;
2463
            sha256->digest[1] = 0xBB67AE85L;
2464
            sha256->digest[2] = 0x3C6EF372L;
2465
            sha256->digest[3] = 0xA54FF53AL;
2466
            sha256->digest[4] = 0x510E527FL;
2467
            sha256->digest[5] = 0x9B05688CL;
2468
            sha256->digest[6] = 0x1F83D9ABL;
2469
            sha256->digest[7] = 0x5BE0CD19L;
2470
        }
2471
2472
        return ret;
2473
    }
2474
#endif /* WOLFSSL_HAVE_LMS && !WOLFSSL_LMS_FULL_HASH */
2475
#endif /* !WOLFSSL_KCAPI_HASH */
2476
2477
#endif /* XTRANSFORM */
2478
2479
#ifdef WOLF_CRYPTO_CB_ONLY_SHA256
2480
2481
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
2482
    {
2483
        if (sha256 == NULL) {
2484
            return BAD_FUNC_ARG;
2485
        }
2486
        if (data == NULL && len == 0) {
2487
            /* valid, but do nothing */
2488
            return 0;
2489
        }
2490
        if (data == NULL) {
2491
            return BAD_FUNC_ARG;
2492
        }
2493
2494
        #ifndef WOLF_CRYPTO_CB_FIND
2495
        if (sha256->devId != INVALID_DEVID)
2496
        #endif
2497
        {
2498
            int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL);
2499
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2500
                return ret;
2501
        }
2502
2503
        return NO_VALID_DEVID;
2504
    }
2505
2506
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
2507
    {
2508
        int ret;
2509
2510
        if (sha256 == NULL || hash == NULL) {
2511
            return BAD_FUNC_ARG;
2512
        }
2513
2514
        #ifndef WOLF_CRYPTO_CB_FIND
2515
        if (sha256->devId != INVALID_DEVID)
2516
        #endif
2517
        {
2518
            ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash);
2519
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2520
                return ret;
2521
        }
2522
2523
        return NO_VALID_DEVID;
2524
    }
2525
2526
#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */
2527
2528
2529
#ifdef WOLFSSL_SHA224
2530
2531
#ifdef STM32_HASH_SHA2
2532
2533
    /* Supports CubeMX HAL or Standard Peripheral Library */
2534
2535
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
2536
    {
2537
        if (sha224 == NULL)
2538
            return BAD_FUNC_ARG;
2539
        (void)devId;
2540
        (void)heap;
2541
2542
        XMEMSET(sha224, 0, sizeof(wc_Sha224));
2543
        wc_Stm32_Hash_Init(&sha224->stmCtx);
2544
        return 0;
2545
    }
2546
2547
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
2548
    {
2549
        int ret = 0;
2550
2551
        if (sha224 == NULL || (data == NULL && len > 0)) {
2552
            return BAD_FUNC_ARG;
2553
        }
2554
2555
        ret = wolfSSL_CryptHwMutexLock();
2556
        if (ret == 0) {
2557
            ret = wc_Stm32_Hash_Update(&sha224->stmCtx,
2558
                HASH_AlgoSelection_SHA224, data, len, WC_SHA224_BLOCK_SIZE);
2559
            wolfSSL_CryptHwMutexUnLock();
2560
        }
2561
        return ret;
2562
    }
2563
2564
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
2565
    {
2566
        int ret = 0;
2567
2568
        if (sha224 == NULL || hash == NULL) {
2569
            return BAD_FUNC_ARG;
2570
        }
2571
2572
        ret = wolfSSL_CryptHwMutexLock();
2573
        if (ret == 0) {
2574
            ret = wc_Stm32_Hash_Final(&sha224->stmCtx,
2575
                HASH_AlgoSelection_SHA224, hash, WC_SHA224_DIGEST_SIZE);
2576
            wolfSSL_CryptHwMutexUnLock();
2577
        }
2578
2579
        (void)wc_InitSha224(sha224); /* reset state */
2580
2581
        return ret;
2582
    }
2583
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2584
2585
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
2586
    {
2587
        if (sha224 == NULL) {
2588
            return BAD_FUNC_ARG;
2589
        }
2590
        (void)devId;
2591
2592
        return se050_hash_init(&sha224->se050Ctx, heap);
2593
    }
2594
2595
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
2596
    {
2597
        return se050_hash_update(&sha224->se050Ctx, data, len);
2598
    }
2599
2600
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
2601
    {
2602
        int ret = 0;
2603
        ret = se050_hash_final(&sha224->se050Ctx, hash, WC_SHA224_DIGEST_SIZE,
2604
                               kAlgorithm_SSS_SHA224);
2605
        (void)wc_InitSha224(sha224);
2606
        return ret;
2607
    }
2608
2609
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
2610
    !defined(WOLFSSL_QNX_CAAM)
2611
    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
2612
2613
#elif defined(WOLFSSL_AFALG_HASH)
2614
    #error SHA224 currently not supported with AF_ALG enabled
2615
2616
#elif defined(WOLFSSL_DEVCRYPTO_HASH)
2617
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
2618
2619
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
2620
    /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
2621
2622
#elif defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224)
2623
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2624
2625
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
2626
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
2627
2628
#elif defined(MAX3266X_SHA)
2629
    /* implemented in wolfcrypt/src/port/maxim/max3266x.c */
2630
2631
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
2632
2633
/* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
2634
2635
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2636
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2637
2638
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2639
#elif defined(PSOC6_HASH_SHA2)
2640
    /* Implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */
2641
2642
#elif defined(WOLF_CRYPTO_CB_ONLY_SHA256)
2643
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
2644
    {
2645
        int ret;
2646
        if (sha224 == NULL)
2647
            return BAD_FUNC_ARG;
2648
        ret = InitSha256((wc_Sha256*)sha224);
2649
        if (ret != 0)
2650
            return ret;
2651
        sha224->digest[0] = 0xc1059ed8;
2652
        sha224->digest[1] = 0x367cd507;
2653
        sha224->digest[2] = 0x3070dd17;
2654
        sha224->digest[3] = 0xf70e5939;
2655
        sha224->digest[4] = 0xffc00b31;
2656
        sha224->digest[5] = 0x68581511;
2657
        sha224->digest[6] = 0x64f98fa7;
2658
        sha224->digest[7] = 0xbefa4fa4;
2659
        sha224->heap   = heap;
2660
        sha224->devId  = devId;
2661
        sha224->devCtx = NULL;
2662
    #ifdef WOLFSSL_SMALL_STACK_CACHE
2663
        sha224->W = NULL;
2664
    #endif
2665
    #ifdef WOLFSSL_ASYNC_CRYPT
2666
        XMEMSET(&sha224->asyncDev, 0, sizeof(sha224->asyncDev));
2667
    #endif
2668
        return ret;
2669
    }
2670
2671
#else
2672
2673
    #define NEED_SOFT_SHA224
2674
2675
2676
    static int InitSha224(wc_Sha224* sha224)
2677
3.46k
    {
2678
3.46k
        int ret = 0;
2679
2680
#ifdef WOLFSSL_SMALL_STACK_CACHE
2681
    if (sha224->W == NULL) {
2682
        sha224->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
2683
                                     sha224->heap, DYNAMIC_TYPE_DIGEST);
2684
        if (sha224->W == NULL)
2685
            return MEMORY_E;
2686
    }
2687
#endif
2688
2689
3.46k
        sha224->digest[0] = 0xc1059ed8;
2690
3.46k
        sha224->digest[1] = 0x367cd507;
2691
3.46k
        sha224->digest[2] = 0x3070dd17;
2692
3.46k
        sha224->digest[3] = 0xf70e5939;
2693
3.46k
        sha224->digest[4] = 0xffc00b31;
2694
3.46k
        sha224->digest[5] = 0x68581511;
2695
3.46k
        sha224->digest[6] = 0x64f98fa7;
2696
3.46k
        sha224->digest[7] = 0xbefa4fa4;
2697
2698
3.46k
        sha224->buffLen = 0;
2699
3.46k
        XMEMSET(sha224->buffer, 0, sizeof(sha224->buffer));
2700
3.46k
        sha224->loLen   = 0;
2701
3.46k
        sha224->hiLen   = 0;
2702
2703
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2704
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2705
        /* choose best Transform function under this runtime environment */
2706
        Sha256_SetTransform();
2707
    #elif defined(WOLFSSL_ARMASM_SHA256_TRANSFORM)
2708
        /* SHA-224 shares the SHA-256 transform, on AArch32 as well as AArch64;
2709
         * a no-op in builds that compile a single variant.  Keyed off the
2710
         * marker so the call cannot outlive its definition when a hardware
2711
         * hash port wins the implementation chain. */
2712
        Sha256_SetTransform();
2713
    #endif
2714
    #if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
2715
        /* SHA-224 shares the SHA-256 transform; select the base/vector-crypto
2716
         * implementation at run time (sets sha256_use_crypto). */
2717
        Sha256_SetTransform();
2718
    #endif
2719
3.46k
    #ifdef WOLFSSL_HASH_FLAGS
2720
3.46k
        sha224->flags = 0;
2721
3.46k
    #endif
2722
    #ifdef WOLFSSL_HASH_KEEP
2723
        sha224->msg  = NULL;
2724
        sha224->len  = 0;
2725
        sha224->used = 0;
2726
    #endif
2727
2728
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2729
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2730
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
2731
        /* not to be confused with SHAS512_224 */
2732
        ret = esp_sha_init(&(sha224->ctx), WC_HASH_TYPE_SHA224);
2733
    #endif
2734
2735
3.46k
        return ret;
2736
3.46k
    }
2737
2738
#endif
2739
2740
#ifdef NEED_SOFT_SHA224
2741
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
2742
1.24k
    {
2743
1.24k
        int ret = 0;
2744
2745
1.24k
        if (sha224 == NULL)
2746
0
            return BAD_FUNC_ARG;
2747
2748
1.24k
        sha224->heap = heap;
2749
    #ifdef WOLFSSL_SMALL_STACK_CACHE
2750
        sha224->W = NULL;
2751
    #endif
2752
1.24k
    #ifdef WOLF_CRYPTO_CB
2753
1.24k
        sha224->devId = devId;
2754
1.24k
        sha224->devCtx = NULL;
2755
1.24k
    #endif
2756
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
2757
        #if defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224)
2758
        /* We know this is a fresh, uninitialized item, so set to INIT */
2759
        if (sha224->ctx.mode != ESP32_SHA_SW) {
2760
            ESP_LOGV(TAG, "Set sha224 ctx mode init to ESP32_SHA_SW. "
2761
                          "Prior value: %d", sha224->ctx.mode);
2762
        }
2763
        /* no sha224 HW support is available, set to SW */
2764
            sha224->ctx.mode = ESP32_SHA_SW;
2765
        #else
2766
            /* We know this is a fresh, uninitialized item, so set to INIT */
2767
            sha224->ctx.mode = ESP32_SHA_INIT;
2768
        #endif
2769
    #endif
2770
2771
1.24k
        ret = InitSha224(sha224);
2772
1.24k
        if (ret != 0) {
2773
0
            return ret;
2774
0
        }
2775
2776
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
2777
        ret = wolfAsync_DevCtxInit(&sha224->asyncDev,
2778
                            WOLFSSL_ASYNC_MARKER_SHA224, sha224->heap, devId);
2779
    #else
2780
1.24k
        (void)devId;
2781
1.24k
    #endif /* WOLFSSL_ASYNC_CRYPT */
2782
#ifdef WOLFSSL_IMXRT1170_CAAM
2783
     ret = wc_CAAM_HashInit(&sha224->hndl, &sha224->ctx, WC_HASH_TYPE_SHA224);
2784
#endif
2785
2786
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2787
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2788
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
2789
        if (sha224->ctx.mode != ESP32_SHA_INIT) {
2790
            ESP_LOGV("SHA224", "Set ctx mode from prior value: "
2791
                               "%d", sha224->ctx.mode);
2792
        }
2793
        /* We know this is a fresh, uninitialized item, so set to INIT */
2794
        sha224->ctx.mode = ESP32_SHA_INIT;
2795
    #endif
2796
2797
1.24k
        return ret;
2798
1.24k
    }
2799
2800
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
2801
6.46k
    {
2802
6.46k
        int ret;
2803
2804
6.46k
        if (sha224 == NULL) {
2805
0
            return BAD_FUNC_ARG;
2806
0
        }
2807
6.46k
        if (len == 0) {
2808
            /* valid, but do nothing */
2809
1.54k
            return 0;
2810
1.54k
        }
2811
4.92k
        if (data == NULL) {
2812
0
            return BAD_FUNC_ARG;
2813
0
        }
2814
4.92k
    #ifdef WOLF_CRYPTO_CB
2815
4.92k
        #ifndef WOLF_CRYPTO_CB_FIND
2816
4.92k
        if (sha224->devId != INVALID_DEVID)
2817
126
        #endif
2818
126
        {
2819
126
            ret = wc_CryptoCb_Sha224Hash(sha224, data, len, NULL);
2820
126
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2821
0
                return ret;
2822
            /* fall-through when unavailable */
2823
126
        }
2824
4.92k
    #endif
2825
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
2826
        if (sha224->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA224) {
2827
        #if defined(HAVE_INTEL_QA)
2828
            return IntelQaSymSha224(&sha224->asyncDev, NULL, data, len);
2829
        #endif
2830
        }
2831
    #endif /* WOLFSSL_ASYNC_CRYPT */
2832
2833
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2834
       (defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2835
        defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
2836
        sha224->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
2837
    #endif
2838
2839
4.92k
        ret = Sha256Update((wc_Sha256*)sha224, data, len);
2840
2841
4.92k
        return ret;
2842
4.92k
    }
2843
2844
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
2845
2.21k
    {
2846
2.21k
        int ret;
2847
2848
2.21k
        if (sha224 == NULL || hash == NULL) {
2849
0
            return BAD_FUNC_ARG;
2850
0
        }
2851
2.21k
    #ifdef WOLF_CRYPTO_CB
2852
2.21k
        #ifndef WOLF_CRYPTO_CB_FIND
2853
2.21k
        if (sha224->devId != INVALID_DEVID)
2854
52
        #endif
2855
52
        {
2856
52
            ret = wc_CryptoCb_Sha224Hash(sha224, NULL, 0, hash);
2857
52
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2858
0
                return ret;
2859
            /* fall-through when unavailable */
2860
52
        }
2861
2.21k
    #endif
2862
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
2863
        if (sha224->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA224) {
2864
        #if defined(HAVE_INTEL_QA)
2865
            return IntelQaSymSha224(&sha224->asyncDev, hash, NULL,
2866
                                            WC_SHA224_DIGEST_SIZE);
2867
        #endif
2868
        }
2869
    #endif /* WOLFSSL_ASYNC_CRYPT */
2870
2871
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) &&      \
2872
       ( !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2873
         !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224) )
2874
2875
        /* nothing enabled here for RISC-V C2/C3/C6 success */
2876
    #endif
2877
2878
2.21k
        ret = Sha256Final((wc_Sha256*)sha224);
2879
2.21k
        if (ret != 0)
2880
0
            return ret;
2881
2882
    #if defined(WOLFSSL_WIDE_BYTE)
2883
        /* CHAR_BIT != 8: store digest words as big-endian octets. */
2884
        BytesFromWordsBE32(hash, sha224->digest, WC_SHA224_DIGEST_SIZE);
2885
    #else
2886
2.21k
    #if defined(LITTLE_ENDIAN_ORDER)
2887
2.21k
        if (SHA256_REV_BYTES(&sha224->ctx)) {
2888
2.21k
            ByteReverseWords(sha224->digest,
2889
2.21k
                             sha224->digest,
2890
2.21k
                             WC_SHA224_DIGEST_SIZE);
2891
2.21k
        }
2892
2.21k
    #endif
2893
2.21k
        XMEMCPY(hash, sha224->digest, WC_SHA224_DIGEST_SIZE);
2894
2.21k
    #endif
2895
2896
2.21k
        return InitSha224(sha224);  /* reset state */
2897
2.21k
    }
2898
#endif /* end of SHA224 software implementation */
2899
2900
#ifdef WOLF_CRYPTO_CB_ONLY_SHA256
2901
2902
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
2903
    {
2904
        if (sha224 == NULL)
2905
            return BAD_FUNC_ARG;
2906
        if (data == NULL && len == 0)
2907
            return 0;
2908
        if (data == NULL)
2909
            return BAD_FUNC_ARG;
2910
2911
        #ifndef WOLF_CRYPTO_CB_FIND
2912
        if (sha224->devId != INVALID_DEVID)
2913
        #endif
2914
        {
2915
            int ret = wc_CryptoCb_Sha224Hash(sha224, data, len, NULL);
2916
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2917
                return ret;
2918
        }
2919
2920
        return NO_VALID_DEVID;
2921
    }
2922
2923
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
2924
    {
2925
        int ret;
2926
2927
        if (sha224 == NULL || hash == NULL)
2928
            return BAD_FUNC_ARG;
2929
2930
        #ifndef WOLF_CRYPTO_CB_FIND
2931
        if (sha224->devId != INVALID_DEVID)
2932
        #endif
2933
        {
2934
            ret = wc_CryptoCb_Sha224Hash(sha224, NULL, 0, hash);
2935
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2936
                return ret;
2937
        }
2938
2939
        return NO_VALID_DEVID;
2940
    }
2941
2942
#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */
2943
2944
    int wc_InitSha224(wc_Sha224* sha224)
2945
52
    {
2946
52
        int devId = INVALID_DEVID;
2947
2948
52
    #ifdef WOLF_CRYPTO_CB
2949
52
        devId = wc_CryptoCb_DefaultDevID();
2950
52
    #endif
2951
52
        return wc_InitSha224_ex(sha224, NULL, devId);
2952
52
    }
2953
2954
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
2955
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
2956
2957
    void wc_Sha224Free(wc_Sha224* sha224)
2958
1.38k
    {
2959
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
2960
        int ret = 0;
2961
#endif
2962
2963
1.38k
        if (sha224 == NULL)
2964
0
            return;
2965
2966
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
2967
    #ifndef WOLF_CRYPTO_CB_FIND
2968
        if (sha224->devId != INVALID_DEVID)
2969
    #endif
2970
        {
2971
            ret = wc_CryptoCb_Free(sha224->devId, WC_ALGO_TYPE_HASH,
2972
                             WC_HASH_TYPE_SHA224, 0, (void*)sha224);
2973
            /* If they want the standard free, they can call it themselves */
2974
            /* via their callback setting devId to INVALID_DEVID */
2975
            /* otherwise assume the callback handled it */
2976
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2977
                return;
2978
            /* fall-through when unavailable */
2979
        }
2980
2981
        /* silence compiler warning */
2982
        (void)ret;
2983
2984
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
2985
2986
#ifdef WOLFSSL_SMALL_STACK_CACHE
2987
        if (sha224->W != NULL) {
2988
            ForceZero(sha224->W, sizeof(word32) * WC_SHA224_BLOCK_SIZE);
2989
            XFREE(sha224->W, sha224->heap, DYNAMIC_TYPE_DIGEST);
2990
            sha224->W = NULL;
2991
        }
2992
#endif
2993
2994
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
2995
        wolfAsync_DevCtxFree(&sha224->asyncDev, WOLFSSL_ASYNC_MARKER_SHA224);
2996
    #endif /* WOLFSSL_ASYNC_CRYPT */
2997
2998
    #ifdef WOLFSSL_PIC32MZ_HASH
2999
        wc_Sha256Pic32Free(sha224);
3000
    #endif
3001
    #if defined(WOLFSSL_KCAPI_HASH)
3002
        KcapiHashFree(&sha224->kcapi);
3003
    #endif
3004
    #if defined(WOLFSSL_RENESAS_RX64_HASH)
3005
        if (sha224->msg != NULL) {
3006
            ForceZero(sha224->msg, sha224->len);
3007
            XFREE(sha224->msg, sha224->heap, DYNAMIC_TYPE_TMP_BUFFER);
3008
            sha224->msg = NULL;
3009
        }
3010
    #endif
3011
    #if defined(PSOC6_HASH_SHA2)
3012
        wc_Psoc6_Sha_Free();
3013
    #endif
3014
1.38k
        ForceZero(sha224, sizeof(*sha224));
3015
1.38k
    }
3016
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)  */
3017
#endif /*  WOLFSSL_SHA224 */
3018
3019
3020
int wc_InitSha256(wc_Sha256* sha256)
3021
244
{
3022
244
    int devId = INVALID_DEVID;
3023
3024
244
#ifdef WOLF_CRYPTO_CB
3025
244
    devId = wc_CryptoCb_DefaultDevID();
3026
244
#endif
3027
244
    return wc_InitSha256_ex(sha256, NULL, devId);
3028
244
}
3029
3030
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
3031
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
3032
3033
void wc_Sha256Free(wc_Sha256* sha256)
3034
172k
{
3035
3036
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
3037
    int ret = 0;
3038
#endif
3039
3040
172k
    if (sha256 == NULL)
3041
0
        return;
3042
3043
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
3044
    #ifndef WOLF_CRYPTO_CB_FIND
3045
    if (sha256->devId != INVALID_DEVID)
3046
    #endif
3047
    {
3048
        ret = wc_CryptoCb_Free(sha256->devId, WC_ALGO_TYPE_HASH,
3049
                         WC_HASH_TYPE_SHA256, 0, (void*)sha256);
3050
        /* If they want the standard free, they can call it themselves */
3051
        /* via their callback setting devId to INVALID_DEVID */
3052
        /* otherwise assume the callback handled it */
3053
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3054
            return;
3055
        /* fall-through when unavailable */
3056
    }
3057
3058
    /* silence compiler warning */
3059
    (void)ret;
3060
3061
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
3062
3063
#if defined(WOLFSSL_ESP32) && \
3064
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
3065
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
3066
    esp_sha_release_unfinished_lock(&sha256->ctx);
3067
#endif
3068
3069
#ifdef WOLFSSL_SMALL_STACK_CACHE
3070
    if (sha256->W != NULL) {
3071
        ForceZero(sha256->W, sizeof(word32) * WC_SHA256_BLOCK_SIZE);
3072
        XFREE(sha256->W, sha256->heap, DYNAMIC_TYPE_DIGEST);
3073
        sha256->W = NULL;
3074
    }
3075
#endif
3076
3077
3078
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
3079
    wolfAsync_DevCtxFree(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256);
3080
#endif /* WOLFSSL_ASYNC_CRYPT */
3081
#ifdef WOLFSSL_PIC32MZ_HASH
3082
    wc_Sha256Pic32Free(sha256);
3083
#endif
3084
#if defined(WOLFSSL_AFALG_HASH)
3085
    if (sha256->alFd > 0) {
3086
        close(sha256->alFd);
3087
        sha256->alFd = -1; /* avoid possible double close on socket */
3088
    }
3089
    if (sha256->rdFd > 0) {
3090
        close(sha256->rdFd);
3091
        sha256->rdFd = -1; /* avoid possible double close on socket */
3092
    }
3093
#endif /* WOLFSSL_AFALG_HASH */
3094
#ifdef WOLFSSL_DEVCRYPTO_HASH
3095
    wc_DevCryptoFree(&sha256->ctx);
3096
#endif /* WOLFSSL_DEVCRYPTO */
3097
#if (defined(WOLFSSL_AFALG_HASH) && defined(WOLFSSL_AFALG_HASH_KEEP)) || \
3098
    (defined(WOLFSSL_DEVCRYPTO_HASH) && defined(WOLFSSL_DEVCRYPTO_HASH_KEEP)) || \
3099
    ((defined(WOLFSSL_RENESAS_TSIP_TLS) || \
3100
      defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
3101
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) || \
3102
    ((defined(WOLFSSL_RENESAS_SCEPROTECT) || \
3103
    (defined(WOLFSSL_RENESAS_RSIP) && (WOLFSSL_RENESAS_RZFSP_VER >= 220))) && \
3104
    !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)) || \
3105
    defined(WOLFSSL_RENESAS_RX64_HASH) || \
3106
    defined(WOLFSSL_HASH_KEEP)
3107
3108
    if (sha256->msg != NULL) {
3109
        ForceZero(sha256->msg, sha256->len);
3110
        XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);
3111
        sha256->msg = NULL;
3112
    }
3113
#endif
3114
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3115
    se050_hash_free(&sha256->se050Ctx);
3116
#endif
3117
#if defined(WOLFSSL_KCAPI_HASH)
3118
    KcapiHashFree(&sha256->kcapi);
3119
#endif
3120
#ifdef WOLFSSL_IMXRT_DCP
3121
    DCPSha256Free(sha256);
3122
#endif
3123
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
3124
    wc_MAXQ10XX_Sha256Free(sha256);
3125
#endif
3126
3127
#ifdef HAVE_ARIA
3128
    if (sha256->hSession != NULL) {
3129
        MC_CloseSession(sha256->hSession);
3130
        sha256->hSession = NULL;
3131
    }
3132
#endif
3133
3134
/* Espressif embedded hardware acceleration specific: */
3135
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3136
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
3137
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
3138
    if (sha256->ctx.lockDepth > 0) {
3139
        /* probably due to unclean shutdown, error, or other problem.
3140
         *
3141
         * if you find yourself here, code needs to be cleaned up to
3142
         * properly release hardware. this init is only for handling
3143
         * the unexpected. by the time free is called, the hardware
3144
         * should have already been released (lockDepth = 0)
3145
         */
3146
        (void)InitSha256(sha256); /* unlock mutex, set mode to ESP32_SHA_INIT */
3147
        ESP_LOGV(TAG, "Alert: hardware unlock needed in wc_Sha256Free.");
3148
    }
3149
    else {
3150
        ESP_LOGV(TAG, "Hardware unlock not needed in wc_Sha256Free.");
3151
    }
3152
#endif
3153
3154
#if defined(PSOC6_HASH_SHA2)
3155
    wc_Psoc6_Sha_Free();
3156
#endif
3157
3158
172k
    ForceZero(sha256, sizeof(*sha256));
3159
172k
} /* wc_Sha256Free */
3160
3161
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */
3162
#ifdef WOLFSSL_HASH_KEEP
3163
/* Some hardware have issues with update, this function stores the data to be
3164
 * hashed into an array. Once ready, the Final operation is called on all of the
3165
 * data to be hashed at once.
3166
 * returns 0 on success
3167
 */
3168
int wc_Sha256_Grow(wc_Sha256* sha256, const byte* in, int inSz)
3169
{
3170
    return _wc_Hash_Grow(&(sha256->msg), &(sha256->used), &(sha256->len), in,
3171
                        inSz, sha256->heap);
3172
}
3173
#ifdef WOLFSSL_SHA224
3174
int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz)
3175
{
3176
    return _wc_Hash_Grow(&(sha224->msg), &(sha224->used), &(sha224->len), in,
3177
                        inSz, sha224->heap);
3178
}
3179
#endif /* WOLFSSL_SHA224 */
3180
#endif /* WOLFSSL_HASH_KEEP */
3181
3182
#endif /* !WOLFSSL_TI_HASH */
3183
3184
3185
#ifndef WOLFSSL_TI_HASH
3186
#if !defined(WOLFSSL_RENESAS_RX64_HASH) && \
3187
    (!defined(WOLFSSL_RENESAS_RSIP) || \
3188
      defined(NO_WOLFSSL_RENESAS_FSPSM_HASH))
3189
#ifdef WOLFSSL_SHA224
3190
3191
#if defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224)
3192
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3193
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
3194
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
3195
3196
#elif defined(MAX3266X_SHA)
3197
    /* implemented in wolfcrypt/src/port/maxim/max3266x.c */
3198
3199
#else
3200
3201
    int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash)
3202
0
    {
3203
0
        int ret;
3204
0
        WC_DECLARE_VAR(tmpSha224, wc_Sha224, 1, 0);
3205
3206
0
        if (sha224 == NULL || hash == NULL) {
3207
0
            return BAD_FUNC_ARG;
3208
0
        }
3209
3210
0
        WC_CALLOC_VAR_EX(tmpSha224, wc_Sha224, 1, NULL,
3211
0
            DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
3212
3213
0
        ret = wc_Sha224Copy(sha224, tmpSha224);
3214
0
        if (ret == 0) {
3215
0
            ret = wc_Sha224Final(tmpSha224, hash);
3216
0
            wc_Sha224Free(tmpSha224);
3217
0
        }
3218
3219
0
        WC_FREE_VAR_EX(tmpSha224, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3220
0
        return ret;
3221
0
    }
3222
3223
    int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst)
3224
43
    {
3225
43
        int ret = 0; /* assume success unless proven otherwise */
3226
3227
43
        if (src == NULL || dst == NULL) {
3228
0
            return BAD_FUNC_ARG;
3229
0
        }
3230
3231
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
3232
    #ifndef WOLF_CRYPTO_CB_FIND
3233
        if (src->devId != INVALID_DEVID)
3234
    #endif
3235
        {
3236
            /* Cast the source and destination to be void to keep the abstraction */
3237
            ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
3238
                                   WC_HASH_TYPE_SHA224, (void*)src, (void*)dst);
3239
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3240
                return ret;
3241
            /* fall-through when unavailable */
3242
        }
3243
        ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
3244
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
3245
3246
        /* Free dst resources before copy to prevent memory leaks (e.g., msg
3247
         * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
3248
43
        wc_Sha224Free(dst);
3249
43
        XMEMCPY(dst, src, sizeof(wc_Sha224));
3250
3251
    #ifdef WOLFSSL_SMALL_STACK_CACHE
3252
        dst->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
3253
                                  dst->heap, DYNAMIC_TYPE_DIGEST);
3254
        if (dst->W == NULL) {
3255
            XMEMSET(dst, 0, sizeof(wc_Sha224));
3256
            return MEMORY_E;
3257
        }
3258
    #endif
3259
3260
    #if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3)
3261
        dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
3262
        dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
3263
    #endif
3264
3265
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
3266
        ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
3267
    #endif
3268
3269
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3270
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
3271
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
3272
        /* regardless of any other settings, there's no SHA-224 HW on ESP32 */
3273
        #ifndef CONFIG_IDF_TARGET_ESP32
3274
            ret = esp_sha224_ctx_copy(src, dst);
3275
        #endif
3276
    #endif
3277
3278
43
    #ifdef WOLFSSL_HASH_FLAGS
3279
43
        dst->flags |= WC_HASH_FLAG_ISCOPY;
3280
43
    #endif
3281
3282
    #if defined(WOLFSSL_HASH_KEEP)
3283
        if (src->msg != NULL) {
3284
            dst->msg = (byte*)XMALLOC(src->len, dst->heap,
3285
                                      DYNAMIC_TYPE_TMP_BUFFER);
3286
            if (dst->msg == NULL)
3287
                return MEMORY_E;
3288
            XMEMCPY(dst->msg, src->msg, src->len);
3289
        }
3290
    #endif
3291
3292
    #if defined(PSOC6_HASH_SHA2)
3293
        wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA224, 0);
3294
    #endif
3295
43
        return ret;
3296
43
    }
3297
3298
#endif /* WOLFSSL_KCAPI_HASH && !WOLFSSL_NO_KCAPI_SHA224 */
3299
3300
#ifdef WOLFSSL_HASH_FLAGS
3301
    int wc_Sha224SetFlags(wc_Sha224* sha224, word32 flags)
3302
0
    {
3303
0
        if (sha224) {
3304
0
            sha224->flags = flags;
3305
0
        }
3306
0
        return 0;
3307
0
    }
3308
    int wc_Sha224GetFlags(wc_Sha224* sha224, word32* flags)
3309
0
    {
3310
0
        if (sha224 && flags) {
3311
0
            *flags = sha224->flags;
3312
0
        }
3313
0
        return 0;
3314
0
    }
3315
#endif
3316
3317
#endif /* WOLFSSL_SHA224 */
3318
#endif /* WOLFSSL_RENESAS_RX64_HASH */
3319
3320
#ifdef WOLFSSL_AFALG_HASH
3321
    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
3322
3323
#elif defined(WOLFSSL_DEVCRYPTO_HASH)
3324
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
3325
3326
#elif (defined(WOLFSSL_RENESAS_TSIP_TLS) || \
3327
       defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
3328
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)
3329
3330
    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */
3331
3332
#elif (defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_RSIP))\
3333
     && !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3334
3335
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3336
#elif defined(WOLFSSL_IMXRT_DCP)
3337
    /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */
3338
#elif defined(WOLFSSL_KCAPI_HASH)
3339
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3340
3341
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
3342
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
3343
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
3344
    /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
3345
#elif defined(MAX3266X_SHA)
3346
    /* Implemented in wolfcrypt/src/port/maxim/max3266x.c */
3347
#else
3348
3349
int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
3350
5.94k
{
3351
5.94k
    int ret;
3352
5.94k
    WC_DECLARE_VAR(tmpSha256, wc_Sha256, 1, 0);
3353
3354
5.94k
    if (sha256 == NULL || hash == NULL) {
3355
0
        return BAD_FUNC_ARG;
3356
0
    }
3357
3358
5.94k
    WC_CALLOC_VAR_EX(tmpSha256, wc_Sha256, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
3359
5.94k
        return MEMORY_E);
3360
3361
5.93k
    ret = wc_Sha256Copy(sha256, tmpSha256);
3362
5.93k
    if (ret == 0) {
3363
5.93k
        ret = wc_Sha256Final(tmpSha256, hash);
3364
5.93k
        wc_Sha256Free(tmpSha256);
3365
5.93k
    }
3366
3367
3368
5.93k
    WC_FREE_VAR_EX(tmpSha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3369
3370
5.93k
    return ret;
3371
5.94k
}
3372
int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
3373
5.97k
{
3374
5.97k
    int ret = 0;
3375
3376
5.97k
    if (src == NULL || dst == NULL) {
3377
0
        return BAD_FUNC_ARG;
3378
0
    }
3379
3380
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
3381
    #ifndef WOLF_CRYPTO_CB_FIND
3382
    if (src->devId != INVALID_DEVID)
3383
    #endif
3384
    {
3385
        /* Cast the source and destination to be void to keep the abstraction */
3386
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
3387
                               WC_HASH_TYPE_SHA256, (void*)src, (void*)dst);
3388
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3389
            return ret;
3390
        /* fall-through when unavailable */
3391
    }
3392
    ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
3393
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
3394
3395
    /* Free dst resources before copy to prevent memory leaks (e.g., msg
3396
     * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
3397
5.97k
    wc_Sha256Free(dst);
3398
5.97k
    XMEMCPY(dst, src, sizeof(wc_Sha256));
3399
3400
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
3401
    wc_MAXQ10XX_Sha256Copy(src);
3402
#endif
3403
3404
3405
#ifdef WOLFSSL_SMALL_STACK_CACHE
3406
    dst->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
3407
                              dst->heap, DYNAMIC_TYPE_DIGEST);
3408
    if (dst->W == NULL) {
3409
        XMEMSET(dst, 0, sizeof(wc_Sha256));
3410
        return MEMORY_E;
3411
    }
3412
#endif
3413
3414
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3)
3415
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
3416
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
3417
#endif
3418
3419
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
3420
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
3421
#endif
3422
3423
#ifdef WOLFSSL_PIC32MZ_HASH
3424
    ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
3425
#endif
3426
3427
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3428
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
3429
    esp_sha256_ctx_copy(src, dst);
3430
#endif
3431
3432
#ifdef HAVE_ARIA
3433
    dst->hSession = NULL;
3434
    if((src->hSession != NULL) && (MC_CopySession(src->hSession, &(dst->hSession)) != MC_OK)) {
3435
        return MEMORY_E;
3436
    }
3437
#endif
3438
3439
5.97k
#ifdef WOLFSSL_HASH_FLAGS
3440
5.97k
    dst->flags |= WC_HASH_FLAG_ISCOPY;
3441
5.97k
#endif
3442
3443
#if defined(WOLFSSL_HASH_KEEP)
3444
    if (src->msg != NULL) {
3445
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
3446
        if (dst->msg == NULL)
3447
            return MEMORY_E;
3448
        XMEMCPY(dst->msg, src->msg, src->len);
3449
    }
3450
#endif
3451
3452
5.97k
    return ret;
3453
5.97k
}
3454
#endif
3455
3456
#ifdef WOLFSSL_HASH_FLAGS
3457
int wc_Sha256SetFlags(wc_Sha256* sha256, word32 flags)
3458
99.4k
{
3459
99.4k
    if (sha256) {
3460
99.4k
        sha256->flags = flags;
3461
99.4k
    }
3462
99.4k
    return 0;
3463
99.4k
}
3464
int wc_Sha256GetFlags(wc_Sha256* sha256, word32* flags)
3465
0
{
3466
0
    if (sha256 && flags) {
3467
0
        *flags = sha256->flags;
3468
0
    }
3469
0
    return 0;
3470
0
}
3471
#endif
3472
#endif /* !WOLFSSL_TI_HASH */
3473
3474
#endif /* NO_SHA256 */