Coverage Report

Created: 2026-09-20 06:33

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.10M
        #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
981k
    #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
286k
{
310
286k
    XMEMSET(sha256->digest, 0, sizeof(sha256->digest));
311
286k
    sha256->digest[0] = 0x6A09E667L;
312
286k
    sha256->digest[1] = 0xBB67AE85L;
313
286k
    sha256->digest[2] = 0x3C6EF372L;
314
286k
    sha256->digest[3] = 0xA54FF53AL;
315
286k
    sha256->digest[4] = 0x510E527FL;
316
286k
    sha256->digest[5] = 0x9B05688CL;
317
286k
    sha256->digest[6] = 0x1F83D9ABL;
318
286k
    sha256->digest[7] = 0x5BE0CD19L;
319
320
286k
    sha256->buffLen = 0;
321
286k
    XMEMSET(sha256->buffer, 0, sizeof(sha256->buffer));
322
286k
    sha256->loLen   = 0;
323
286k
    sha256->hiLen   = 0;
324
286k
#ifdef WOLFSSL_HASH_FLAGS
325
286k
    sha256->flags = 0;
326
286k
#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
286k
    return 0;
350
286k
}
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
164k
    {
1621
164k
        int ret = 0;
1622
164k
        if (sha256 == NULL)
1623
0
            return BAD_FUNC_ARG;
1624
164k
        ret = InitSha256(sha256);
1625
164k
        if (ret != 0)
1626
0
            return ret;
1627
1628
164k
        sha256->heap = heap;
1629
164k
    #ifdef WOLF_CRYPTO_CB
1630
164k
        sha256->devId = devId;
1631
164k
        sha256->devCtx = NULL;
1632
164k
    #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
164k
        (void)devId;
1645
164k
    #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
164k
        return ret;
1651
164k
    }
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
59.9M
    #define Ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
1677
59.9M
    #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
89.9M
    #define R(x, n)         (((x) & 0xFFFFFFFFU) >> (n))
1684
1685
539M
    #define S(x, n)         rotrFixed(x, n)
1686
59.9M
    #define Sigma0(x)       (S(x, 2)  ^ S(x, 13) ^ S(x, 22))
1687
59.9M
    #define Sigma1(x)       (S(x, 6)  ^ S(x, 11) ^ S(x, 25))
1688
44.9M
    #define Gamma0(x)       (S(x, 7)  ^ S(x, 18) ^ R(x, 3))
1689
44.9M
    #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
59.9M
    #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
119M
    #define h(i) S[(7-(i)) & 7]
1699
1700
    #ifndef XTRANSFORM
1701
981k
         #define XTRANSFORM(S, D)         Transform_Sha256(S, D)
1702
    #endif
1703
1704
#ifndef SHA256_MANY_REGISTERS
1705
    #define RND(j) \
1706
59.9M
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+(j)] + W[i+(j)]; \
1707
59.9M
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
1708
59.9M
         d(j) += t0; \
1709
59.9M
         h(j)  = t0 + t1
1710
1711
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
1712
938k
    {
1713
938k
        word32 S[8], t0, t1;
1714
938k
        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
938k
        W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
1723
938k
                             sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);
1724
938k
        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
8.42M
        for (i = 0; i < 8; i++)
1732
7.49M
            S[i] = sha256->digest[i];
1733
1734
15.9M
        for (i = 0; i < 16; i++) {
1735
#ifdef WOLFSSL_WIDE_BYTE
1736
            W[i] = *((const word32*)&data[i*(int)sizeof(word32)]);
1737
#else
1738
14.9M
            W[i] = readUnalignedWord32(&data[i*(int)sizeof(word32)]);
1739
14.9M
#endif
1740
14.9M
        }
1741
1742
45.8M
        for (i = 16; i < WC_SHA256_BLOCK_SIZE; i++)
1743
44.9M
            W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];
1744
1745
    #ifdef USE_SLOW_SHA256
1746
        /* not unrolled - ~2k smaller and ~25% slower */
1747
        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {
1748
            int j;
1749
            for (j = 0; j < 8; j++) { /* braces needed here for macros {} */
1750
                RND(j);
1751
            }
1752
        }
1753
    #else
1754
        /* partially loop unrolled */
1755
8.42M
        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {
1756
7.49M
            RND(0); RND(1); RND(2); RND(3);
1757
7.49M
            RND(4); RND(5); RND(6); RND(7);
1758
7.49M
        }
1759
936k
    #endif /* USE_SLOW_SHA256 */
1760
1761
        /* Add the working vars back into digest state[] */
1762
8.42M
        for (i = 0; i < 8; i++) {
1763
7.49M
            sha256->digest[i] += S[i];
1764
7.49M
        }
1765
1766
936k
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE) &&\
1767
936k
        !defined(WOLFSSL_NO_MALLOC)
1768
936k
        ForceZero(W, sizeof(word32) * WC_SHA256_BLOCK_SIZE);
1769
936k
        XFREE(W, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);
1770
936k
    #endif
1771
936k
        return 0;
1772
938k
    }
1773
#else
1774
    /* SHA256 version that keeps all data in registers */
1775
    #define SCHED1(j) (W[j] = *((word32*)&data[j*sizeof(word32)]))
1776
    #define SCHED(j) (               \
1777
                   W[ j     & 15] += \
1778
            Gamma1(W[(j-2)  & 15])+  \
1779
                   W[(j-7)  & 15] +  \
1780
            Gamma0(W[(j-15) & 15])   \
1781
        )
1782
1783
    #define RND1(j) \
1784
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED1(j); \
1785
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
1786
         d(j) += t0; \
1787
         h(j)  = t0 + t1
1788
    #define RNDN(j) \
1789
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED(j); \
1790
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
1791
         d(j) += t0; \
1792
         h(j)  = t0 + t1
1793
1794
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
1795
    {
1796
        word32 S[8], t0, t1;
1797
        int i;
1798
    #ifdef USE_SLOW_SHA256
1799
        int j;
1800
    #endif
1801
        word32 W[WC_SHA256_BLOCK_SIZE/sizeof(word32)];
1802
1803
        /* Copy digest to working vars */
1804
        S[0] = sha256->digest[0];
1805
        S[1] = sha256->digest[1];
1806
        S[2] = sha256->digest[2];
1807
        S[3] = sha256->digest[3];
1808
        S[4] = sha256->digest[4];
1809
        S[5] = sha256->digest[5];
1810
        S[6] = sha256->digest[6];
1811
        S[7] = sha256->digest[7];
1812
1813
        i = 0;
1814
    #ifdef USE_SLOW_SHA256
1815
        for (j = 0; j < 16; j++) {
1816
            RND1(j);
1817
        }
1818
        for (i = 16; i < 64; i += 16) {
1819
            for (j = 0; j < 16; j++) {
1820
                RNDN(j);
1821
            }
1822
        }
1823
    #else
1824
        RND1( 0); RND1( 1); RND1( 2); RND1( 3);
1825
        RND1( 4); RND1( 5); RND1( 6); RND1( 7);
1826
        RND1( 8); RND1( 9); RND1(10); RND1(11);
1827
        RND1(12); RND1(13); RND1(14); RND1(15);
1828
        /* 64 operations, partially loop unrolled */
1829
        for (i = 16; i < 64; i += 16) {
1830
            RNDN( 0); RNDN( 1); RNDN( 2); RNDN( 3);
1831
            RNDN( 4); RNDN( 5); RNDN( 6); RNDN( 7);
1832
            RNDN( 8); RNDN( 9); RNDN(10); RNDN(11);
1833
            RNDN(12); RNDN(13); RNDN(14); RNDN(15);
1834
        }
1835
    #endif
1836
1837
        /* Add the working vars back into digest */
1838
        sha256->digest[0] += S[0];
1839
        sha256->digest[1] += S[1];
1840
        sha256->digest[2] += S[2];
1841
        sha256->digest[3] += S[3];
1842
        sha256->digest[4] += S[4];
1843
        sha256->digest[5] += S[5];
1844
        sha256->digest[6] += S[6];
1845
        sha256->digest[7] += S[7];
1846
1847
        return 0;
1848
    }
1849
#endif /* SHA256_MANY_REGISTERS */
1850
#endif
1851
/* End wc_ software implementation */
1852
1853
#ifdef XTRANSFORM
1854
1855
    static WC_INLINE void AddLength(wc_Sha256* sha256, word32 len)
1856
498k
    {
1857
498k
        word32 tmp = sha256->loLen;
1858
498k
        if ((sha256->loLen += len) < tmp) {
1859
0
            sha256->hiLen++;                       /* carry low to high */
1860
0
        }
1861
498k
    }
1862
1863
    /* do block size increments/updates */
1864
    static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data,
1865
        word32 len)
1866
498k
    {
1867
498k
        int ret = 0;
1868
498k
        word32 blocksLen;
1869
498k
        byte* local;
1870
1871
        /* check that internal buffLen is valid */
1872
498k
        if (sha256->buffLen >= WC_SHA256_BLOCK_SIZE) {
1873
399
            return BUFFER_E;
1874
399
        }
1875
1876
        /* add length for final */
1877
498k
        AddLength(sha256, len);
1878
1879
498k
        local = (byte*)sha256->buffer;
1880
1881
        /* process any remainder from previous operation */
1882
498k
        if (sha256->buffLen > 0) {
1883
254k
            blocksLen = min(len, WC_SHA256_BLOCK_SIZE - sha256->buffLen);
1884
254k
            XMEMCPY(&local[sha256->buffLen], data, blocksLen);
1885
1886
254k
            sha256->buffLen += blocksLen;
1887
254k
            data            += blocksLen;
1888
254k
            len             -= blocksLen;
1889
1890
254k
            if (sha256->buffLen == WC_SHA256_BLOCK_SIZE) {
1891
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1892
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1893
                if (sha256->ctx.mode == ESP32_SHA_INIT) {
1894
                    ESP_LOGV(TAG, "Sha256Update try hardware");
1895
                    esp_sha_try_hw_lock(&sha256->ctx);
1896
                }
1897
            #endif
1898
1899
79.2k
            if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
1900
            #ifdef WOLFSSL_WIDE_BYTE
1901
                /* CHAR_BIT != 8: pack 16 big-endian schedule words octet-wise */
1902
                WordsFromBytesBE32(sha256->buffer, (const byte*)sha256->buffer,
1903
                    WC_SHA256_BLOCK_SIZE / 4);
1904
            #else
1905
79.2k
                ByteReverseWords(sha256->buffer, sha256->buffer,
1906
79.2k
                    WC_SHA256_BLOCK_SIZE);
1907
79.2k
            #endif
1908
79.2k
            }
1909
1910
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1911
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1912
                if (sha256->ctx.mode == ESP32_SHA_SW) {
1913
                    #if defined(WOLFSSL_DEBUG_MUTEX)
1914
                    {
1915
                        ESP_LOGI(TAG, "Sha256Update process software");
1916
                    }
1917
                    #endif
1918
                    #ifdef WOLFSSL_HW_METRICS
1919
                    {
1920
                        /* Track of # SW during transforms during active HW */
1921
                        esp_sw_sha256_count_add();
1922
                    }
1923
                    #endif /* WOLFSSL_HW_METRICS */
1924
                    ret = XTRANSFORM(sha256, (const byte*)local);
1925
                }
1926
                else {
1927
                    #if defined(WOLFSSL_DEBUG_MUTEX)
1928
                    {
1929
                        ESP_LOGI(TAG, "Sha256Update process hardware");
1930
                    }
1931
                    #endif
1932
                    esp_sha256_process(sha256, (const byte*)local);
1933
                }
1934
            #else
1935
                /* Always SW */
1936
79.2k
                ret = XTRANSFORM(sha256, (const byte*)local);
1937
79.2k
            #endif
1938
79.2k
                if (ret == 0)
1939
78.4k
                    sha256->buffLen = 0;
1940
870
                else
1941
870
                    len = 0; /* error */
1942
79.2k
            }
1943
254k
        }
1944
1945
        /* process blocks */
1946
    #ifdef XTRANSFORM_LEN
1947
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1948
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1949
1950
        #ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
1951
        if (sha_method != SHA256_C)
1952
        #else
1953
        if (Transform_Sha256_Len_p != NULL)
1954
        #endif
1955
1956
        #endif
1957
        {
1958
            if (len >= WC_SHA256_BLOCK_SIZE) {
1959
                /* get number of blocks */
1960
                /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */
1961
                /* len (masked by 0xFFFFFFC0) returns block aligned length */
1962
                blocksLen = len & ~((word32)WC_SHA256_BLOCK_SIZE-1);
1963
                /* Byte reversal and alignment handled in function if required
1964
                 */
1965
                ret = XTRANSFORM_LEN(sha256, data, blocksLen);
1966
                if (ret == 0) {
1967
                    data += blocksLen;
1968
                    len  -= blocksLen;
1969
                }
1970
            }
1971
        }
1972
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1973
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1974
        else
1975
        #endif
1976
    #endif /* XTRANSFORM_LEN */
1977
498k
    #if !defined(XTRANSFORM_LEN) || \
1978
498k
        (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1979
498k
         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
1980
498k
        {
1981
1.27M
            while (len >= WC_SHA256_BLOCK_SIZE) {
1982
776k
                word32* local32 = sha256->buffer;
1983
                /* optimization to avoid memcpy if data pointer is properly aligned */
1984
                /* Intel transform function requires use of sha256->buffer */
1985
                /* Little Endian requires byte swap, so can't use data directly */
1986
            #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(LITTLE_ENDIAN_ORDER) && \
1987
                !(defined(WOLFSSL_X86_64_BUILD) && \
1988
                         defined(USE_INTEL_SPEEDUP) && \
1989
                         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
1990
                if (((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {
1991
                    local32 = (word32*)data;
1992
                }
1993
                else
1994
            #endif
1995
776k
                {
1996
776k
                    XMEMCPY(local32, data, WC_SHA256_BLOCK_SIZE);
1997
776k
                }
1998
1999
776k
                data += WC_SHA256_BLOCK_SIZE;
2000
776k
                len  -= WC_SHA256_BLOCK_SIZE;
2001
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2002
               !defined( NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2003
                if (sha256->ctx.mode == ESP32_SHA_INIT){
2004
                    ESP_LOGV(TAG, "Sha256Update try hardware loop");
2005
                    esp_sha_try_hw_lock(&sha256->ctx);
2006
                }
2007
            #endif
2008
2009
776k
            if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
2010
            #ifdef WOLFSSL_WIDE_BYTE
2011
                WordsFromBytesBE32(local32, (const byte*)local32,
2012
                    WC_SHA256_BLOCK_SIZE / 4);
2013
            #else
2014
776k
                ByteReverseWords(local32, local32, WC_SHA256_BLOCK_SIZE);
2015
776k
            #endif
2016
776k
            }
2017
2018
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2019
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2020
                if (sha256->ctx.mode == ESP32_SHA_SW) {
2021
                    ESP_LOGV(TAG, "Sha256Update process software loop");
2022
                    ret = XTRANSFORM(sha256, (const byte*)local32);
2023
                }
2024
                else {
2025
                    ESP_LOGV(TAG, "Sha256Update process hardware");
2026
                    esp_sha256_process(sha256, (const byte*)local32);
2027
                }
2028
            #else
2029
776k
                ret = XTRANSFORM(sha256, (const byte*)local32);
2030
776k
            #endif
2031
2032
776k
                if (ret != 0)
2033
809
                    break;
2034
776k
            }
2035
498k
        }
2036
498k
    #endif
2037
2038
        /* save remainder */
2039
498k
        if (ret == 0 && len > 0) {
2040
216k
            XMEMCPY(local, data, len);
2041
216k
            sha256->buffLen = len;
2042
216k
        }
2043
2044
498k
        return ret;
2045
498k
    }
2046
2047
#if defined(WOLFSSL_KCAPI_HASH)
2048
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2049
2050
#else
2051
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
2052
493k
    {
2053
493k
        if (sha256 == NULL) {
2054
0
            return BAD_FUNC_ARG;
2055
0
        }
2056
493k
        if (len == 0) {
2057
            /* valid, but do nothing */
2058
6.00k
            return 0;
2059
6.00k
        }
2060
487k
        if (data == NULL) {
2061
0
            return BAD_FUNC_ARG;
2062
0
        }
2063
2064
487k
    #ifdef WOLF_CRYPTO_CB
2065
487k
        #ifndef WOLF_CRYPTO_CB_FIND
2066
487k
        if (sha256->devId != INVALID_DEVID)
2067
127
        #endif
2068
127
        {
2069
127
            int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL);
2070
127
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2071
0
                return ret;
2072
            /* fall-through when unavailable */
2073
127
        }
2074
487k
    #endif
2075
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
2076
        if (sha256->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA256) {
2077
        #if defined(HAVE_INTEL_QA)
2078
            return IntelQaSymSha256(&sha256->asyncDev, NULL, data, len);
2079
        #endif
2080
        }
2081
    #endif /* WOLFSSL_ASYNC_CRYPT */
2082
2083
487k
        return Sha256Update(sha256, data, len);
2084
487k
    }
2085
#endif
2086
2087
    static WC_INLINE int Sha256Final(wc_Sha256* sha256)
2088
123k
    {
2089
123k
        int ret;
2090
123k
        byte* local;
2091
2092
        /* we'll add a 0x80 byte at the end,
2093
        ** so make sure we have appropriate buffer length. */
2094
123k
        if (sha256->buffLen > WC_SHA256_BLOCK_SIZE - 1) {
2095
            /* exit with error code if there's a bad buffer size in buffLen */
2096
0
            return BAD_STATE_E;
2097
0
        } /* buffLen check */
2098
2099
123k
        local = (byte*)sha256->buffer;
2100
123k
        local[sha256->buffLen++] = 0x80; /* add 1 */
2101
2102
        /* pad with zeros */
2103
123k
        if (sha256->buffLen > WC_SHA256_PAD_SIZE) {
2104
1.90k
            if (sha256->buffLen < WC_SHA256_BLOCK_SIZE) {
2105
1.78k
                XMEMSET(&local[sha256->buffLen], 0,
2106
1.78k
                    WC_SHA256_BLOCK_SIZE - sha256->buffLen);
2107
1.78k
            }
2108
2109
        #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2110
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2111
            if (sha256->ctx.mode == ESP32_SHA_INIT) {
2112
                esp_sha_try_hw_lock(&sha256->ctx);
2113
            }
2114
        #endif
2115
2116
1.90k
        if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
2117
        #ifdef WOLFSSL_WIDE_BYTE
2118
            WordsFromBytesBE32(sha256->buffer, (const byte*)sha256->buffer,
2119
                WC_SHA256_BLOCK_SIZE / 4);
2120
        #else
2121
1.90k
            ByteReverseWords(sha256->buffer, sha256->buffer,
2122
1.90k
                WC_SHA256_BLOCK_SIZE);
2123
1.90k
        #endif
2124
1.90k
        }
2125
2126
        #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2127
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2128
            if (sha256->ctx.mode == ESP32_SHA_INIT) {
2129
                esp_sha_try_hw_lock(&sha256->ctx);
2130
            }
2131
            if (sha256->ctx.mode == ESP32_SHA_SW) {
2132
                ret = XTRANSFORM(sha256, (const byte*)local);
2133
            }
2134
            else {
2135
                ret = esp_sha256_process(sha256, (const byte*)local);
2136
            }
2137
        #else
2138
1.90k
            ret = XTRANSFORM(sha256, (const byte*)local);
2139
1.90k
        #endif
2140
1.90k
            if (ret != 0)
2141
2
                return ret;
2142
2143
1.89k
            sha256->buffLen = 0;
2144
1.89k
        }
2145
123k
        XMEMSET(&local[sha256->buffLen], 0,
2146
123k
            WC_SHA256_PAD_SIZE - sha256->buffLen);
2147
2148
        /* put 64 bit length in separate 32 bit parts */
2149
123k
        sha256->hiLen = (sha256->loLen >>
2150
123k
                            (CHAR_BIT * sizeof(sha256->loLen) - 3)) +
2151
123k
                                                         (sha256->hiLen << 3);
2152
123k
        sha256->loLen = sha256->loLen << 3;
2153
2154
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2155
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2156
        if (sha256->ctx.mode == ESP32_SHA_INIT) {
2157
            esp_sha_try_hw_lock(&sha256->ctx);
2158
        }
2159
    #endif
2160
2161
        /* store lengths */
2162
#ifdef WOLFSSL_WIDE_BYTE
2163
        /* CHAR_BIT != 8: 'local' indexes octet cells, so place the 64-bit
2164
         * bit-length as 8 big-endian octets (W[14]=hiLen, W[15]=loLen). */
2165
        local[WC_SHA256_PAD_SIZE + 0] = (byte)((sha256->hiLen >> 24) & 0xFF);
2166
        local[WC_SHA256_PAD_SIZE + 1] = (byte)((sha256->hiLen >> 16) & 0xFF);
2167
        local[WC_SHA256_PAD_SIZE + 2] = (byte)((sha256->hiLen >>  8) & 0xFF);
2168
        local[WC_SHA256_PAD_SIZE + 3] = (byte)((sha256->hiLen      ) & 0xFF);
2169
        local[WC_SHA256_PAD_SIZE + 4] = (byte)((sha256->loLen >> 24) & 0xFF);
2170
        local[WC_SHA256_PAD_SIZE + 5] = (byte)((sha256->loLen >> 16) & 0xFF);
2171
        local[WC_SHA256_PAD_SIZE + 6] = (byte)((sha256->loLen >>  8) & 0xFF);
2172
        local[WC_SHA256_PAD_SIZE + 7] = (byte)((sha256->loLen      ) & 0xFF);
2173
#endif
2174
123k
        if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
2175
        #ifdef WOLFSSL_WIDE_BYTE
2176
            /* pack all 16 big-endian schedule words octet-wise (incl. length) */
2177
            WordsFromBytesBE32(sha256->buffer, (const byte*)sha256->buffer,
2178
                WC_SHA256_BLOCK_SIZE / 4);
2179
        #else
2180
123k
            ByteReverseWords(sha256->buffer, sha256->buffer,
2181
123k
                WC_SHA256_PAD_SIZE);
2182
123k
        #endif
2183
123k
        }
2184
123k
#ifndef WOLFSSL_WIDE_BYTE
2185
        /* ! 64-bit length ordering dependent on digest endian type ! */
2186
123k
        XMEMCPY(&local[WC_SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32));
2187
123k
        XMEMCPY(&local[WC_SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
2188
123k
                sizeof(word32));
2189
123k
#endif
2190
2191
    /* Only the ESP32-C3 with HW enabled may need pad size byte order reversal
2192
     * depending on HW or SW mode */
2193
    #if ( defined(CONFIG_IDF_TARGET_ESP32C2) || \
2194
          defined(CONFIG_IDF_TARGET_ESP8684) || \
2195
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
2196
          defined(CONFIG_IDF_TARGET_ESP32C6)    \
2197
        ) && \
2198
        defined(WOLFSSL_ESP32_CRYPT) &&         \
2199
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
2200
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2201
        /* For Espressif RISC-V Targets, we *may* need to reverse bytes
2202
         * depending on if HW is active or not. */
2203
        if (sha256->ctx.mode == ESP32_SHA_HW) {
2204
        #if defined(WOLFSSL_SUPER_VERBOSE_DEBUG)
2205
            ESP_LOGV(TAG, "Start: Reverse PAD SIZE Endianness.");
2206
        #endif
2207
            ByteReverseWords(
2208
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)], /* out */
2209
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)], /* in  */
2210
                2 * sizeof(word32) /* byte count to reverse */
2211
            );
2212
        #if defined(WOLFSSL_SUPER_VERBOSE_DEBUG)
2213
            ESP_LOGV(TAG, "End: Reverse PAD SIZE Endianness.");
2214
        #endif
2215
        } /* end if (sha256->ctx.mode == ESP32_SHA_HW) */
2216
    #endif
2217
2218
    #if defined(FREESCALE_MMCAU_SHA) || \
2219
        (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2220
                         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
2221
        /* Kinetis requires only these bytes reversed */
2222
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2223
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2224
        #ifdef WC_SHA256_RAW_BE_BUFFER
2225
        /* raw-buffer convention -- the length words must be big-endian in the
2226
         * stream regardless of which transform consumes the final block. */
2227
        #else
2228
        if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags) ||
2229
            IS_INTEL_SHA(intel_flags))
2230
        #endif
2231
        #endif
2232
        {
2233
            ByteReverseWords(
2234
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2235
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2236
                2 * sizeof(word32));
2237
        }
2238
    #endif
2239
    #if (defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM)) && \
2240
        !defined(FREESCALE_MMCAU_SHA)
2241
        ByteReverseWords( &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2242
            &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2243
            2 * sizeof(word32));
2244
    #endif
2245
    #if defined(WOLFSSL_PPC64_ASM) && defined(LITTLE_ENDIAN_ORDER)
2246
        /* The PPC64 assembly loads the message with byte-reversed loads on
2247
         * little-endian, treating the whole block as a big-endian byte stream.
2248
         * The 64-bit length above is stored in native (little-endian) word
2249
         * order, so reverse it here to keep the block a consistent big-endian
2250
         * stream. */
2251
        ByteReverseWords( &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2252
            &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
2253
            2 * sizeof(word32));
2254
    #endif
2255
2256
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2257
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2258
        if (sha256->ctx.mode == ESP32_SHA_INIT) {
2259
            esp_sha_try_hw_lock(&sha256->ctx);
2260
        }
2261
        /* depending on architecture and ctx.mode value
2262
         * we may or may not need default digest */
2263
        if (sha256->ctx.mode == ESP32_SHA_SW) {
2264
            ret = XTRANSFORM(sha256, (const byte*)local);
2265
        }
2266
        else {
2267
            ret = esp_sha256_digest_process(sha256, 1);
2268
        }
2269
    #else
2270
123k
        ret = XTRANSFORM(sha256, (const byte*)local);
2271
123k
    #endif
2272
2273
123k
        return ret;
2274
123k
    }
2275
2276
#if !defined(WOLFSSL_KCAPI_HASH)
2277
2278
#ifndef WOLF_CRYPTO_CB_ONLY_SHA256
2279
    int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
2280
49
    {
2281
49
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_WIDE_BYTE)
2282
49
        word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)];
2283
49
        XMEMSET(digest, 0, sizeof(digest));
2284
49
    #endif
2285
2286
49
        if (sha256 == NULL || hash == NULL) {
2287
0
            return BAD_FUNC_ARG;
2288
0
        }
2289
2290
    #if defined(WOLFSSL_WIDE_BYTE)
2291
        /* CHAR_BIT != 8: store digest words as big-endian octets. */
2292
        BytesFromWordsBE32(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2293
    #elif defined(LITTLE_ENDIAN_ORDER)
2294
49
        if (SHA256_REV_BYTES(&sha256->ctx)) {
2295
49
            ByteReverseWords((word32*)digest, (word32*)sha256->digest,
2296
49
                              WC_SHA256_DIGEST_SIZE);
2297
49
        }
2298
49
        XMEMCPY(hash, digest, WC_SHA256_DIGEST_SIZE);
2299
    #else
2300
        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2301
    #endif
2302
2303
49
        return 0;
2304
49
    }
2305
#endif /* !WOLF_CRYPTO_CB_ONLY_SHA256 */
2306
2307
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
2308
121k
    {
2309
121k
        int ret;
2310
2311
121k
        if (sha256 == NULL || hash == NULL) {
2312
0
            return BAD_FUNC_ARG;
2313
0
        }
2314
2315
121k
    #ifdef WOLF_CRYPTO_CB
2316
121k
        #ifndef WOLF_CRYPTO_CB_FIND
2317
121k
        if (sha256->devId != INVALID_DEVID)
2318
46
        #endif
2319
46
        {
2320
46
            ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash);
2321
46
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2322
0
                return ret;
2323
            /* fall-through when unavailable */
2324
46
        }
2325
121k
    #endif
2326
2327
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
2328
        if (sha256->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA256) {
2329
        #if defined(HAVE_INTEL_QA)
2330
            return IntelQaSymSha256(&sha256->asyncDev, hash, NULL,
2331
                                            WC_SHA256_DIGEST_SIZE);
2332
        #endif
2333
        }
2334
    #endif /* WOLFSSL_ASYNC_CRYPT */
2335
2336
121k
        ret = Sha256Final(sha256);
2337
121k
        if (ret != 0) {
2338
76
            return ret;
2339
76
        }
2340
2341
    #if defined(WOLFSSL_WIDE_BYTE)
2342
        /* CHAR_BIT != 8: store digest words as big-endian octets. */
2343
        BytesFromWordsBE32(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2344
    #else
2345
121k
    #if defined(LITTLE_ENDIAN_ORDER)
2346
121k
        if (SHA256_REV_BYTES(&sha256->ctx)) {
2347
121k
            ByteReverseWords(sha256->digest, sha256->digest,
2348
121k
                WC_SHA256_DIGEST_SIZE);
2349
121k
        }
2350
121k
    #endif
2351
121k
        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2352
121k
    #endif
2353
2354
121k
        return InitSha256(sha256);  /* reset state */
2355
121k
    }
2356
2357
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
2358
/* Apply SHA256 transformation to the data                */
2359
/* @param sha  a pointer to wc_Sha256 structure           */
2360
/* @param data data to be applied SHA256 transformation   */
2361
/* @return 0 on successful, otherwise non-zero on failure */
2362
    int wc_Sha256Transform(wc_Sha256* sha256, const unsigned char* data)
2363
    {
2364
        if (sha256 == NULL || data == NULL) {
2365
            return BAD_FUNC_ARG;
2366
        }
2367
2368
    #if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM)
2369
        #ifdef __aarch64__
2370
        if (Transform_Sha256_Len_p == Transform_Sha256_Len) {
2371
            return Transform_Sha256(sha256, data);
2372
        }
2373
        else
2374
        #endif
2375
        {
2376
            byte buffer[WC_SHA256_BLOCK_SIZE];
2377
            ByteReverseWords((word32*)buffer, (word32*)data,
2378
                WC_SHA256_BLOCK_SIZE);
2379
        #ifdef __aarch64__
2380
            return Transform_Sha256_aarch64(sha256, buffer);
2381
        #else
2382
            return Transform_Sha256(sha256, buffer);
2383
        #endif
2384
        }
2385
    #else
2386
        return Transform_Sha256(sha256, data);
2387
    #endif
2388
    }
2389
#endif /* OPENSSL_EXTRA || HAVE_CURL */
2390
2391
#if defined(WOLFSSL_HAVE_LMS) && !defined(WOLFSSL_LMS_FULL_HASH)
2392
    /* One block will be used from data.
2393
     * hash must be big enough to hold all of digest output.
2394
     */
2395
    int wc_Sha256HashBlock(wc_Sha256* sha256, const unsigned char* data,
2396
        unsigned char* hash)
2397
    {
2398
        int ret;
2399
2400
        if ((sha256 == NULL) || (data == NULL)) {
2401
            return BAD_FUNC_ARG;
2402
        }
2403
2404
        if (SHA256_UPDATE_REV_BYTES(&sha256->ctx)) {
2405
        #ifdef WOLFSSL_WIDE_BYTE
2406
            /* CHAR_BIT != 8: pack 16 big-endian schedule words octet-wise */
2407
            WordsFromBytesBE32(sha256->buffer, data,
2408
                WC_SHA256_BLOCK_SIZE / 4);
2409
        #else
2410
            /* Reverse in place. Stage first only when data is the caller's
2411
             * own buffer, which may be unaligned - LMS hands us
2412
             * sha256->buffer itself, and copying that onto itself is UB. */
2413
            if (data != (const unsigned char*)sha256->buffer) {
2414
                XMEMCPY(sha256->buffer, data, WC_SHA256_BLOCK_SIZE);
2415
            }
2416
            ByteReverseWords(sha256->buffer, sha256->buffer,
2417
                WC_SHA256_BLOCK_SIZE);
2418
        #endif
2419
            data = (const unsigned char*)sha256->buffer;
2420
        }
2421
        ret = XTRANSFORM(sha256, data);
2422
2423
        if ((ret == 0) && (hash != NULL)) {
2424
            if (!SHA256_REV_BYTES(&sha256->ctx)) {
2425
                XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
2426
            }
2427
            else {
2428
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP)
2429
                __asm__ __volatile__ (
2430
                    "mov    0x00(%[d]), %%esi\n\t"
2431
                    "movbe  %%esi, 0x00(%[h])\n\t"
2432
                    "mov    0x04(%[d]), %%esi\n\t"
2433
                    "movbe  %%esi, 0x04(%[h])\n\t"
2434
                    "mov    0x08(%[d]), %%esi\n\t"
2435
                    "movbe  %%esi, 0x08(%[h])\n\t"
2436
                    "mov    0x0c(%[d]), %%esi\n\t"
2437
                    "movbe  %%esi, 0x0c(%[h])\n\t"
2438
                    "mov    0x10(%[d]), %%esi\n\t"
2439
                    "movbe  %%esi, 0x10(%[h])\n\t"
2440
                    "mov    0x14(%[d]), %%esi\n\t"
2441
                    "movbe  %%esi, 0x14(%[h])\n\t"
2442
                    "mov    0x18(%[d]), %%esi\n\t"
2443
                    "movbe  %%esi, 0x18(%[h])\n\t"
2444
                    "mov    0x1c(%[d]), %%esi\n\t"
2445
                    "movbe  %%esi, 0x1c(%[h])\n\t"
2446
                    :
2447
                    : [d] "r" (sha256->digest), [h] "r" (hash)
2448
                    : "memory", "esi"
2449
                );
2450
        #else
2451
                word32* hash32 = (word32*)hash;
2452
                word32* digest = (word32*)sha256->digest;
2453
            #if WOLFSSL_GENERAL_ALIGNMENT < 4
2454
                ALIGN16 word32 buf[WC_SHA256_DIGEST_SIZE / sizeof(word32)];
2455
2456
                if (((size_t)digest & 0x3) != 0) {
2457
                    if (((size_t)hash32 & 0x3) != 0) {
2458
                        XMEMCPY(buf, digest, WC_SHA256_DIGEST_SIZE);
2459
                        hash32 = buf;
2460
                        digest = buf;
2461
                    }
2462
                    else {
2463
                        XMEMCPY(hash, digest, WC_SHA256_DIGEST_SIZE);
2464
                        digest = hash32;
2465
                    }
2466
                }
2467
                else if (((size_t)hash32 & 0x3) != 0) {
2468
                    hash32 = digest;
2469
                }
2470
            #endif
2471
                ByteReverseWords(hash32, digest, (word32)(sizeof(word32) * 8));
2472
            #if WOLFSSL_GENERAL_ALIGNMENT < 4
2473
                if (hash != (byte*)hash32) {
2474
                    XMEMCPY(hash, hash32, WC_SHA256_DIGEST_SIZE);
2475
                }
2476
            #endif
2477
        #endif /* WOLFSSL_X86_64_BUILD && USE_INTEL_SPEEDUP */
2478
            }
2479
            sha256->digest[0] = 0x6A09E667L;
2480
            sha256->digest[1] = 0xBB67AE85L;
2481
            sha256->digest[2] = 0x3C6EF372L;
2482
            sha256->digest[3] = 0xA54FF53AL;
2483
            sha256->digest[4] = 0x510E527FL;
2484
            sha256->digest[5] = 0x9B05688CL;
2485
            sha256->digest[6] = 0x1F83D9ABL;
2486
            sha256->digest[7] = 0x5BE0CD19L;
2487
        }
2488
2489
        return ret;
2490
    }
2491
#endif /* WOLFSSL_HAVE_LMS && !WOLFSSL_LMS_FULL_HASH */
2492
#endif /* !WOLFSSL_KCAPI_HASH */
2493
2494
#endif /* XTRANSFORM */
2495
2496
#ifdef WOLF_CRYPTO_CB_ONLY_SHA256
2497
2498
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
2499
    {
2500
        if (sha256 == NULL) {
2501
            return BAD_FUNC_ARG;
2502
        }
2503
        if (data == NULL && len == 0) {
2504
            /* valid, but do nothing */
2505
            return 0;
2506
        }
2507
        if (data == NULL) {
2508
            return BAD_FUNC_ARG;
2509
        }
2510
2511
        #ifndef WOLF_CRYPTO_CB_FIND
2512
        if (sha256->devId != INVALID_DEVID)
2513
        #endif
2514
        {
2515
            int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL);
2516
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2517
                return ret;
2518
        }
2519
2520
        return NO_VALID_DEVID;
2521
    }
2522
2523
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
2524
    {
2525
        int ret;
2526
2527
        if (sha256 == NULL || hash == NULL) {
2528
            return BAD_FUNC_ARG;
2529
        }
2530
2531
        #ifndef WOLF_CRYPTO_CB_FIND
2532
        if (sha256->devId != INVALID_DEVID)
2533
        #endif
2534
        {
2535
            ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash);
2536
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2537
                return ret;
2538
        }
2539
2540
        return NO_VALID_DEVID;
2541
    }
2542
2543
#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */
2544
2545
2546
#ifdef WOLFSSL_SHA224
2547
2548
#ifdef STM32_HASH_SHA2
2549
2550
    /* Supports CubeMX HAL or Standard Peripheral Library */
2551
2552
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
2553
    {
2554
        if (sha224 == NULL)
2555
            return BAD_FUNC_ARG;
2556
        (void)devId;
2557
        (void)heap;
2558
2559
        XMEMSET(sha224, 0, sizeof(wc_Sha224));
2560
        wc_Stm32_Hash_Init(&sha224->stmCtx);
2561
        return 0;
2562
    }
2563
2564
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
2565
    {
2566
        int ret = 0;
2567
2568
        if (sha224 == NULL || (data == NULL && len > 0)) {
2569
            return BAD_FUNC_ARG;
2570
        }
2571
2572
        ret = wolfSSL_CryptHwMutexLock();
2573
        if (ret == 0) {
2574
            ret = wc_Stm32_Hash_Update(&sha224->stmCtx,
2575
                HASH_AlgoSelection_SHA224, data, len, WC_SHA224_BLOCK_SIZE);
2576
            wolfSSL_CryptHwMutexUnLock();
2577
        }
2578
        return ret;
2579
    }
2580
2581
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
2582
    {
2583
        int ret = 0;
2584
2585
        if (sha224 == NULL || hash == NULL) {
2586
            return BAD_FUNC_ARG;
2587
        }
2588
2589
        ret = wolfSSL_CryptHwMutexLock();
2590
        if (ret == 0) {
2591
            ret = wc_Stm32_Hash_Final(&sha224->stmCtx,
2592
                HASH_AlgoSelection_SHA224, hash, WC_SHA224_DIGEST_SIZE);
2593
            wolfSSL_CryptHwMutexUnLock();
2594
        }
2595
2596
        (void)wc_InitSha224(sha224); /* reset state */
2597
2598
        return ret;
2599
    }
2600
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2601
2602
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
2603
    {
2604
        if (sha224 == NULL) {
2605
            return BAD_FUNC_ARG;
2606
        }
2607
        (void)devId;
2608
2609
        return se050_hash_init(&sha224->se050Ctx, heap);
2610
    }
2611
2612
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
2613
    {
2614
        return se050_hash_update(&sha224->se050Ctx, data, len);
2615
    }
2616
2617
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
2618
    {
2619
        int ret = 0;
2620
        ret = se050_hash_final(&sha224->se050Ctx, hash, WC_SHA224_DIGEST_SIZE,
2621
                               kAlgorithm_SSS_SHA224);
2622
        (void)wc_InitSha224(sha224);
2623
        return ret;
2624
    }
2625
2626
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
2627
    !defined(WOLFSSL_QNX_CAAM)
2628
    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
2629
2630
#elif defined(WOLFSSL_AFALG_HASH)
2631
    #error SHA224 currently not supported with AF_ALG enabled
2632
2633
#elif defined(WOLFSSL_DEVCRYPTO_HASH)
2634
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
2635
2636
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
2637
    /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
2638
2639
#elif defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224)
2640
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2641
2642
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
2643
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
2644
2645
#elif defined(MAX3266X_SHA)
2646
    /* implemented in wolfcrypt/src/port/maxim/max3266x.c */
2647
2648
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
2649
2650
/* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
2651
2652
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2653
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2654
2655
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2656
#elif defined(PSOC6_HASH_SHA2)
2657
    /* Implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */
2658
2659
#elif defined(WOLF_CRYPTO_CB_ONLY_SHA256)
2660
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
2661
    {
2662
        int ret;
2663
        if (sha224 == NULL)
2664
            return BAD_FUNC_ARG;
2665
        ret = InitSha256((wc_Sha256*)sha224);
2666
        if (ret != 0)
2667
            return ret;
2668
        sha224->digest[0] = 0xc1059ed8;
2669
        sha224->digest[1] = 0x367cd507;
2670
        sha224->digest[2] = 0x3070dd17;
2671
        sha224->digest[3] = 0xf70e5939;
2672
        sha224->digest[4] = 0xffc00b31;
2673
        sha224->digest[5] = 0x68581511;
2674
        sha224->digest[6] = 0x64f98fa7;
2675
        sha224->digest[7] = 0xbefa4fa4;
2676
        sha224->heap   = heap;
2677
        sha224->devId  = devId;
2678
        sha224->devCtx = NULL;
2679
    #ifdef WOLFSSL_SMALL_STACK_CACHE
2680
        sha224->W = NULL;
2681
    #endif
2682
    #ifdef WOLFSSL_ASYNC_CRYPT
2683
        XMEMSET(&sha224->asyncDev, 0, sizeof(sha224->asyncDev));
2684
    #endif
2685
        return ret;
2686
    }
2687
2688
#else
2689
2690
    #define NEED_SOFT_SHA224
2691
2692
2693
    static int InitSha224(wc_Sha224* sha224)
2694
3.17k
    {
2695
3.17k
        int ret = 0;
2696
2697
#ifdef WOLFSSL_SMALL_STACK_CACHE
2698
    if (sha224->W == NULL) {
2699
        sha224->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
2700
                                     sha224->heap, DYNAMIC_TYPE_DIGEST);
2701
        if (sha224->W == NULL)
2702
            return MEMORY_E;
2703
    }
2704
#endif
2705
2706
3.17k
        sha224->digest[0] = 0xc1059ed8;
2707
3.17k
        sha224->digest[1] = 0x367cd507;
2708
3.17k
        sha224->digest[2] = 0x3070dd17;
2709
3.17k
        sha224->digest[3] = 0xf70e5939;
2710
3.17k
        sha224->digest[4] = 0xffc00b31;
2711
3.17k
        sha224->digest[5] = 0x68581511;
2712
3.17k
        sha224->digest[6] = 0x64f98fa7;
2713
3.17k
        sha224->digest[7] = 0xbefa4fa4;
2714
2715
3.17k
        sha224->buffLen = 0;
2716
3.17k
        XMEMSET(sha224->buffer, 0, sizeof(sha224->buffer));
2717
3.17k
        sha224->loLen   = 0;
2718
3.17k
        sha224->hiLen   = 0;
2719
2720
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2721
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2722
        /* choose best Transform function under this runtime environment */
2723
        Sha256_SetTransform();
2724
    #elif defined(WOLFSSL_ARMASM_SHA256_TRANSFORM)
2725
        /* SHA-224 shares the SHA-256 transform, on AArch32 as well as AArch64;
2726
         * a no-op in builds that compile a single variant.  Keyed off the
2727
         * marker so the call cannot outlive its definition when a hardware
2728
         * hash port wins the implementation chain. */
2729
        Sha256_SetTransform();
2730
    #endif
2731
    #if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
2732
        /* SHA-224 shares the SHA-256 transform; select the base/vector-crypto
2733
         * implementation at run time (sets sha256_use_crypto). */
2734
        Sha256_SetTransform();
2735
    #endif
2736
3.17k
    #ifdef WOLFSSL_HASH_FLAGS
2737
3.17k
        sha224->flags = 0;
2738
3.17k
    #endif
2739
    #ifdef WOLFSSL_HASH_KEEP
2740
        sha224->msg  = NULL;
2741
        sha224->len  = 0;
2742
        sha224->used = 0;
2743
    #endif
2744
2745
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2746
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2747
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
2748
        /* not to be confused with SHAS512_224 */
2749
        ret = esp_sha_init(&(sha224->ctx), WC_HASH_TYPE_SHA224);
2750
    #endif
2751
2752
3.17k
        return ret;
2753
3.17k
    }
2754
2755
#endif
2756
2757
#ifdef NEED_SOFT_SHA224
2758
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
2759
1.26k
    {
2760
1.26k
        int ret = 0;
2761
2762
1.26k
        if (sha224 == NULL)
2763
0
            return BAD_FUNC_ARG;
2764
2765
1.26k
        sha224->heap = heap;
2766
    #ifdef WOLFSSL_SMALL_STACK_CACHE
2767
        sha224->W = NULL;
2768
    #endif
2769
1.26k
    #ifdef WOLF_CRYPTO_CB
2770
1.26k
        sha224->devId = devId;
2771
1.26k
        sha224->devCtx = NULL;
2772
1.26k
    #endif
2773
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
2774
        #if defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224)
2775
        /* We know this is a fresh, uninitialized item, so set to INIT */
2776
        if (sha224->ctx.mode != ESP32_SHA_SW) {
2777
            ESP_LOGV(TAG, "Set sha224 ctx mode init to ESP32_SHA_SW. "
2778
                          "Prior value: %d", sha224->ctx.mode);
2779
        }
2780
        /* no sha224 HW support is available, set to SW */
2781
            sha224->ctx.mode = ESP32_SHA_SW;
2782
        #else
2783
            /* We know this is a fresh, uninitialized item, so set to INIT */
2784
            sha224->ctx.mode = ESP32_SHA_INIT;
2785
        #endif
2786
    #endif
2787
2788
1.26k
        ret = InitSha224(sha224);
2789
1.26k
        if (ret != 0) {
2790
0
            return ret;
2791
0
        }
2792
2793
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
2794
        ret = wolfAsync_DevCtxInit(&sha224->asyncDev,
2795
                            WOLFSSL_ASYNC_MARKER_SHA224, sha224->heap, devId);
2796
    #else
2797
1.26k
        (void)devId;
2798
1.26k
    #endif /* WOLFSSL_ASYNC_CRYPT */
2799
#ifdef WOLFSSL_IMXRT1170_CAAM
2800
     ret = wc_CAAM_HashInit(&sha224->hndl, &sha224->ctx, WC_HASH_TYPE_SHA224);
2801
#endif
2802
2803
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2804
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2805
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
2806
        if (sha224->ctx.mode != ESP32_SHA_INIT) {
2807
            ESP_LOGV("SHA224", "Set ctx mode from prior value: "
2808
                               "%d", sha224->ctx.mode);
2809
        }
2810
        /* We know this is a fresh, uninitialized item, so set to INIT */
2811
        sha224->ctx.mode = ESP32_SHA_INIT;
2812
    #endif
2813
2814
1.26k
        return ret;
2815
1.26k
    }
2816
2817
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
2818
8.69k
    {
2819
8.69k
        int ret;
2820
2821
8.69k
        if (sha224 == NULL) {
2822
0
            return BAD_FUNC_ARG;
2823
0
        }
2824
8.69k
        if (len == 0) {
2825
            /* valid, but do nothing */
2826
4.70k
            return 0;
2827
4.70k
        }
2828
3.98k
        if (data == NULL) {
2829
0
            return BAD_FUNC_ARG;
2830
0
        }
2831
3.98k
    #ifdef WOLF_CRYPTO_CB
2832
3.98k
        #ifndef WOLF_CRYPTO_CB_FIND
2833
3.98k
        if (sha224->devId != INVALID_DEVID)
2834
163
        #endif
2835
163
        {
2836
163
            ret = wc_CryptoCb_Sha224Hash(sha224, data, len, NULL);
2837
163
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2838
0
                return ret;
2839
            /* fall-through when unavailable */
2840
163
        }
2841
3.98k
    #endif
2842
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
2843
        if (sha224->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA224) {
2844
        #if defined(HAVE_INTEL_QA)
2845
            return IntelQaSymSha224(&sha224->asyncDev, NULL, data, len);
2846
        #endif
2847
        }
2848
    #endif /* WOLFSSL_ASYNC_CRYPT */
2849
2850
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2851
       (defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2852
        defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
2853
        sha224->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
2854
    #endif
2855
2856
3.98k
        ret = Sha256Update((wc_Sha256*)sha224, data, len);
2857
2858
3.98k
        return ret;
2859
3.98k
    }
2860
2861
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
2862
1.91k
    {
2863
1.91k
        int ret;
2864
2865
1.91k
        if (sha224 == NULL || hash == NULL) {
2866
0
            return BAD_FUNC_ARG;
2867
0
        }
2868
1.91k
    #ifdef WOLF_CRYPTO_CB
2869
1.91k
        #ifndef WOLF_CRYPTO_CB_FIND
2870
1.91k
        if (sha224->devId != INVALID_DEVID)
2871
71
        #endif
2872
71
        {
2873
71
            ret = wc_CryptoCb_Sha224Hash(sha224, NULL, 0, hash);
2874
71
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2875
0
                return ret;
2876
            /* fall-through when unavailable */
2877
71
        }
2878
1.91k
    #endif
2879
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
2880
        if (sha224->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA224) {
2881
        #if defined(HAVE_INTEL_QA)
2882
            return IntelQaSymSha224(&sha224->asyncDev, hash, NULL,
2883
                                            WC_SHA224_DIGEST_SIZE);
2884
        #endif
2885
        }
2886
    #endif /* WOLFSSL_ASYNC_CRYPT */
2887
2888
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) &&      \
2889
       ( !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2890
         !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224) )
2891
2892
        /* nothing enabled here for RISC-V C2/C3/C6 success */
2893
    #endif
2894
2895
1.91k
        ret = Sha256Final((wc_Sha256*)sha224);
2896
1.91k
        if (ret != 0)
2897
0
            return ret;
2898
2899
    #if defined(WOLFSSL_WIDE_BYTE)
2900
        /* CHAR_BIT != 8: store digest words as big-endian octets. */
2901
        BytesFromWordsBE32(hash, sha224->digest, WC_SHA224_DIGEST_SIZE);
2902
    #else
2903
1.91k
    #if defined(LITTLE_ENDIAN_ORDER)
2904
1.91k
        if (SHA256_REV_BYTES(&sha224->ctx)) {
2905
1.91k
            ByteReverseWords(sha224->digest,
2906
1.91k
                             sha224->digest,
2907
1.91k
                             WC_SHA224_DIGEST_SIZE);
2908
1.91k
        }
2909
1.91k
    #endif
2910
1.91k
        XMEMCPY(hash, sha224->digest, WC_SHA224_DIGEST_SIZE);
2911
1.91k
    #endif
2912
2913
1.91k
        return InitSha224(sha224);  /* reset state */
2914
1.91k
    }
2915
#endif /* end of SHA224 software implementation */
2916
2917
#ifdef WOLF_CRYPTO_CB_ONLY_SHA256
2918
2919
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
2920
    {
2921
        if (sha224 == NULL)
2922
            return BAD_FUNC_ARG;
2923
        if (data == NULL && len == 0)
2924
            return 0;
2925
        if (data == NULL)
2926
            return BAD_FUNC_ARG;
2927
2928
        #ifndef WOLF_CRYPTO_CB_FIND
2929
        if (sha224->devId != INVALID_DEVID)
2930
        #endif
2931
        {
2932
            int ret = wc_CryptoCb_Sha224Hash(sha224, data, len, NULL);
2933
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2934
                return ret;
2935
        }
2936
2937
        return NO_VALID_DEVID;
2938
    }
2939
2940
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
2941
    {
2942
        int ret;
2943
2944
        if (sha224 == NULL || hash == NULL)
2945
            return BAD_FUNC_ARG;
2946
2947
        #ifndef WOLF_CRYPTO_CB_FIND
2948
        if (sha224->devId != INVALID_DEVID)
2949
        #endif
2950
        {
2951
            ret = wc_CryptoCb_Sha224Hash(sha224, NULL, 0, hash);
2952
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2953
                return ret;
2954
        }
2955
2956
        return NO_VALID_DEVID;
2957
    }
2958
2959
#endif /* WOLF_CRYPTO_CB_ONLY_SHA256 */
2960
2961
    int wc_InitSha224(wc_Sha224* sha224)
2962
71
    {
2963
71
        int devId = INVALID_DEVID;
2964
2965
71
    #ifdef WOLF_CRYPTO_CB
2966
71
        devId = wc_CryptoCb_DefaultDevID();
2967
71
    #endif
2968
71
        return wc_InitSha224_ex(sha224, NULL, devId);
2969
71
    }
2970
2971
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
2972
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
2973
2974
    void wc_Sha224Free(wc_Sha224* sha224)
2975
1.42k
    {
2976
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
2977
        int ret = 0;
2978
#endif
2979
2980
1.42k
        if (sha224 == NULL)
2981
0
            return;
2982
2983
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
2984
    #ifndef WOLF_CRYPTO_CB_FIND
2985
        if (sha224->devId != INVALID_DEVID)
2986
    #endif
2987
        {
2988
            ret = wc_CryptoCb_Free(sha224->devId, WC_ALGO_TYPE_HASH,
2989
                             WC_HASH_TYPE_SHA224, 0, (void*)sha224);
2990
            /* If they want the standard free, they can call it themselves */
2991
            /* via their callback setting devId to INVALID_DEVID */
2992
            /* otherwise assume the callback handled it */
2993
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2994
                return;
2995
            /* fall-through when unavailable */
2996
        }
2997
2998
        /* silence compiler warning */
2999
        (void)ret;
3000
3001
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
3002
3003
#ifdef WOLFSSL_SMALL_STACK_CACHE
3004
        if (sha224->W != NULL) {
3005
            ForceZero(sha224->W, sizeof(word32) * WC_SHA224_BLOCK_SIZE);
3006
            XFREE(sha224->W, sha224->heap, DYNAMIC_TYPE_DIGEST);
3007
            sha224->W = NULL;
3008
        }
3009
#endif
3010
3011
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
3012
        wolfAsync_DevCtxFree(&sha224->asyncDev, WOLFSSL_ASYNC_MARKER_SHA224);
3013
    #endif /* WOLFSSL_ASYNC_CRYPT */
3014
3015
    #ifdef WOLFSSL_PIC32MZ_HASH
3016
        wc_Sha256Pic32Free(sha224);
3017
    #endif
3018
    #if defined(WOLFSSL_KCAPI_HASH)
3019
        KcapiHashFree(&sha224->kcapi);
3020
    #endif
3021
    #if defined(WOLFSSL_RENESAS_RX64_HASH)
3022
        if (sha224->msg != NULL) {
3023
            ForceZero(sha224->msg, sha224->len);
3024
            XFREE(sha224->msg, sha224->heap, DYNAMIC_TYPE_TMP_BUFFER);
3025
            sha224->msg = NULL;
3026
        }
3027
    #endif
3028
    #if defined(PSOC6_HASH_SHA2)
3029
        wc_Psoc6_Sha_Free();
3030
    #endif
3031
1.42k
        ForceZero(sha224, sizeof(*sha224));
3032
1.42k
    }
3033
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)  */
3034
#endif /*  WOLFSSL_SHA224 */
3035
3036
3037
int wc_InitSha256(wc_Sha256* sha256)
3038
245
{
3039
245
    int devId = INVALID_DEVID;
3040
3041
245
#ifdef WOLF_CRYPTO_CB
3042
245
    devId = wc_CryptoCb_DefaultDevID();
3043
245
#endif
3044
245
    return wc_InitSha256_ex(sha256, NULL, devId);
3045
245
}
3046
3047
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
3048
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
3049
3050
void wc_Sha256Free(wc_Sha256* sha256)
3051
177k
{
3052
3053
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
3054
    int ret = 0;
3055
#endif
3056
3057
177k
    if (sha256 == NULL)
3058
0
        return;
3059
3060
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
3061
    #ifndef WOLF_CRYPTO_CB_FIND
3062
    if (sha256->devId != INVALID_DEVID)
3063
    #endif
3064
    {
3065
        ret = wc_CryptoCb_Free(sha256->devId, WC_ALGO_TYPE_HASH,
3066
                         WC_HASH_TYPE_SHA256, 0, (void*)sha256);
3067
        /* If they want the standard free, they can call it themselves */
3068
        /* via their callback setting devId to INVALID_DEVID */
3069
        /* otherwise assume the callback handled it */
3070
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3071
            return;
3072
        /* fall-through when unavailable */
3073
    }
3074
3075
    /* silence compiler warning */
3076
    (void)ret;
3077
3078
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
3079
3080
#if defined(WOLFSSL_ESP32) && \
3081
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
3082
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
3083
    esp_sha_release_unfinished_lock(&sha256->ctx);
3084
#endif
3085
3086
#ifdef WOLFSSL_SMALL_STACK_CACHE
3087
    if (sha256->W != NULL) {
3088
        ForceZero(sha256->W, sizeof(word32) * WC_SHA256_BLOCK_SIZE);
3089
        XFREE(sha256->W, sha256->heap, DYNAMIC_TYPE_DIGEST);
3090
        sha256->W = NULL;
3091
    }
3092
#endif
3093
3094
3095
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
3096
    wolfAsync_DevCtxFree(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256);
3097
#endif /* WOLFSSL_ASYNC_CRYPT */
3098
#ifdef WOLFSSL_PIC32MZ_HASH
3099
    wc_Sha256Pic32Free(sha256);
3100
#endif
3101
#if defined(WOLFSSL_AFALG_HASH)
3102
    if (sha256->alFd > 0) {
3103
        close(sha256->alFd);
3104
        sha256->alFd = -1; /* avoid possible double close on socket */
3105
    }
3106
    if (sha256->rdFd > 0) {
3107
        close(sha256->rdFd);
3108
        sha256->rdFd = -1; /* avoid possible double close on socket */
3109
    }
3110
#endif /* WOLFSSL_AFALG_HASH */
3111
#ifdef WOLFSSL_DEVCRYPTO_HASH
3112
    wc_DevCryptoFree(&sha256->ctx);
3113
#endif /* WOLFSSL_DEVCRYPTO */
3114
#if (defined(WOLFSSL_AFALG_HASH) && defined(WOLFSSL_AFALG_HASH_KEEP)) || \
3115
    (defined(WOLFSSL_DEVCRYPTO_HASH) && defined(WOLFSSL_DEVCRYPTO_HASH_KEEP)) || \
3116
    ((defined(WOLFSSL_RENESAS_TSIP_TLS) || \
3117
      defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
3118
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) || \
3119
    ((defined(WOLFSSL_RENESAS_SCEPROTECT) || \
3120
    (defined(WOLFSSL_RENESAS_RSIP) && (WOLFSSL_RENESAS_RZFSP_VER >= 220))) && \
3121
    !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)) || \
3122
    defined(WOLFSSL_RENESAS_RX64_HASH) || \
3123
    defined(WOLFSSL_HASH_KEEP)
3124
3125
    if (sha256->msg != NULL) {
3126
        ForceZero(sha256->msg, sha256->len);
3127
        XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);
3128
        sha256->msg = NULL;
3129
    }
3130
#endif
3131
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3132
    se050_hash_free(&sha256->se050Ctx);
3133
#endif
3134
#if defined(WOLFSSL_KCAPI_HASH)
3135
    KcapiHashFree(&sha256->kcapi);
3136
#endif
3137
#ifdef WOLFSSL_IMXRT_DCP
3138
    DCPSha256Free(sha256);
3139
#endif
3140
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
3141
    wc_MAXQ10XX_Sha256Free(sha256);
3142
#endif
3143
3144
#ifdef HAVE_ARIA
3145
    if (sha256->hSession != NULL) {
3146
        MC_CloseSession(sha256->hSession);
3147
        sha256->hSession = NULL;
3148
    }
3149
#endif
3150
3151
/* Espressif embedded hardware acceleration specific: */
3152
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3153
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
3154
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
3155
    if (sha256->ctx.lockDepth > 0) {
3156
        /* probably due to unclean shutdown, error, or other problem.
3157
         *
3158
         * if you find yourself here, code needs to be cleaned up to
3159
         * properly release hardware. this init is only for handling
3160
         * the unexpected. by the time free is called, the hardware
3161
         * should have already been released (lockDepth = 0)
3162
         */
3163
        (void)InitSha256(sha256); /* unlock mutex, set mode to ESP32_SHA_INIT */
3164
        ESP_LOGV(TAG, "Alert: hardware unlock needed in wc_Sha256Free.");
3165
    }
3166
    else {
3167
        ESP_LOGV(TAG, "Hardware unlock not needed in wc_Sha256Free.");
3168
    }
3169
#endif
3170
3171
#if defined(PSOC6_HASH_SHA2)
3172
    wc_Psoc6_Sha_Free();
3173
#endif
3174
3175
177k
    ForceZero(sha256, sizeof(*sha256));
3176
177k
} /* wc_Sha256Free */
3177
3178
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */
3179
#ifdef WOLFSSL_HASH_KEEP
3180
/* Some hardware have issues with update, this function stores the data to be
3181
 * hashed into an array. Once ready, the Final operation is called on all of the
3182
 * data to be hashed at once.
3183
 * returns 0 on success
3184
 */
3185
int wc_Sha256_Grow(wc_Sha256* sha256, const byte* in, int inSz)
3186
{
3187
    return _wc_Hash_Grow(&(sha256->msg), &(sha256->used), &(sha256->len), in,
3188
                        inSz, sha256->heap);
3189
}
3190
#ifdef WOLFSSL_SHA224
3191
int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz)
3192
{
3193
    return _wc_Hash_Grow(&(sha224->msg), &(sha224->used), &(sha224->len), in,
3194
                        inSz, sha224->heap);
3195
}
3196
#endif /* WOLFSSL_SHA224 */
3197
#endif /* WOLFSSL_HASH_KEEP */
3198
3199
#endif /* !WOLFSSL_TI_HASH */
3200
3201
3202
#ifndef WOLFSSL_TI_HASH
3203
#if !defined(WOLFSSL_RENESAS_RX64_HASH) && \
3204
    (!defined(WOLFSSL_RENESAS_RSIP) || \
3205
      defined(NO_WOLFSSL_RENESAS_FSPSM_HASH))
3206
#ifdef WOLFSSL_SHA224
3207
3208
#if defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224)
3209
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3210
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
3211
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
3212
3213
#elif defined(MAX3266X_SHA)
3214
    /* implemented in wolfcrypt/src/port/maxim/max3266x.c */
3215
3216
#else
3217
3218
    int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash)
3219
0
    {
3220
0
        int ret;
3221
0
        WC_DECLARE_VAR(tmpSha224, wc_Sha224, 1, 0);
3222
3223
0
        if (sha224 == NULL || hash == NULL) {
3224
0
            return BAD_FUNC_ARG;
3225
0
        }
3226
3227
0
        WC_CALLOC_VAR_EX(tmpSha224, wc_Sha224, 1, NULL,
3228
0
            DYNAMIC_TYPE_TMP_BUFFER, return MEMORY_E);
3229
3230
0
        ret = wc_Sha224Copy(sha224, tmpSha224);
3231
0
        if (ret == 0) {
3232
0
            ret = wc_Sha224Final(tmpSha224, hash);
3233
0
            wc_Sha224Free(tmpSha224);
3234
0
        }
3235
3236
0
        WC_FREE_VAR_EX(tmpSha224, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3237
0
        return ret;
3238
0
    }
3239
3240
    int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst)
3241
47
    {
3242
47
        int ret = 0; /* assume success unless proven otherwise */
3243
3244
47
        if (src == NULL || dst == NULL) {
3245
0
            return BAD_FUNC_ARG;
3246
0
        }
3247
3248
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
3249
    #ifndef WOLF_CRYPTO_CB_FIND
3250
        if (src->devId != INVALID_DEVID)
3251
    #endif
3252
        {
3253
            /* Cast the source and destination to be void to keep the abstraction */
3254
            ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
3255
                                   WC_HASH_TYPE_SHA224, (void*)src, (void*)dst);
3256
            if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3257
                return ret;
3258
            /* fall-through when unavailable */
3259
        }
3260
        ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
3261
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
3262
3263
        /* Free dst resources before copy to prevent memory leaks (e.g., msg
3264
         * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
3265
47
        wc_Sha224Free(dst);
3266
47
        XMEMCPY(dst, src, sizeof(wc_Sha224));
3267
3268
    #ifdef WOLFSSL_SMALL_STACK_CACHE
3269
        dst->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
3270
                                  dst->heap, DYNAMIC_TYPE_DIGEST);
3271
        if (dst->W == NULL) {
3272
            XMEMSET(dst, 0, sizeof(wc_Sha224));
3273
            return MEMORY_E;
3274
        }
3275
    #endif
3276
3277
    #if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3)
3278
        dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
3279
        dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
3280
    #endif
3281
3282
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
3283
        ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
3284
    #endif
3285
3286
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3287
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
3288
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
3289
        /* regardless of any other settings, there's no SHA-224 HW on ESP32 */
3290
        #ifndef CONFIG_IDF_TARGET_ESP32
3291
            ret = esp_sha224_ctx_copy(src, dst);
3292
        #endif
3293
    #endif
3294
3295
47
    #ifdef WOLFSSL_HASH_FLAGS
3296
47
        dst->flags |= WC_HASH_FLAG_ISCOPY;
3297
47
    #endif
3298
3299
    #if defined(WOLFSSL_HASH_KEEP)
3300
        if (src->msg != NULL) {
3301
            dst->msg = (byte*)XMALLOC(src->len, dst->heap,
3302
                                      DYNAMIC_TYPE_TMP_BUFFER);
3303
            if (dst->msg == NULL)
3304
                return MEMORY_E;
3305
            XMEMCPY(dst->msg, src->msg, src->len);
3306
        }
3307
    #endif
3308
3309
    #if defined(PSOC6_HASH_SHA2)
3310
        wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA224, 0);
3311
    #endif
3312
47
        return ret;
3313
47
    }
3314
3315
#endif /* WOLFSSL_KCAPI_HASH && !WOLFSSL_NO_KCAPI_SHA224 */
3316
3317
#ifdef WOLFSSL_HASH_FLAGS
3318
    int wc_Sha224SetFlags(wc_Sha224* sha224, word32 flags)
3319
0
    {
3320
0
        if (sha224) {
3321
0
            sha224->flags = flags;
3322
0
        }
3323
0
        return 0;
3324
0
    }
3325
    int wc_Sha224GetFlags(wc_Sha224* sha224, word32* flags)
3326
0
    {
3327
0
        if (sha224 && flags) {
3328
0
            *flags = sha224->flags;
3329
0
        }
3330
0
        return 0;
3331
0
    }
3332
#endif
3333
3334
#endif /* WOLFSSL_SHA224 */
3335
#endif /* WOLFSSL_RENESAS_RX64_HASH */
3336
3337
#ifdef WOLFSSL_AFALG_HASH
3338
    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
3339
3340
#elif defined(WOLFSSL_DEVCRYPTO_HASH)
3341
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
3342
3343
#elif (defined(WOLFSSL_RENESAS_TSIP_TLS) || \
3344
       defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
3345
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)
3346
3347
    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */
3348
3349
#elif (defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_RSIP))\
3350
     && !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3351
3352
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3353
#elif defined(WOLFSSL_IMXRT_DCP)
3354
    /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */
3355
#elif defined(WOLFSSL_KCAPI_HASH)
3356
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3357
3358
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
3359
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
3360
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
3361
    /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
3362
#elif defined(MAX3266X_SHA)
3363
    /* Implemented in wolfcrypt/src/port/maxim/max3266x.c */
3364
#else
3365
3366
int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
3367
6.09k
{
3368
6.09k
    int ret;
3369
6.09k
    WC_DECLARE_VAR(tmpSha256, wc_Sha256, 1, 0);
3370
3371
6.09k
    if (sha256 == NULL || hash == NULL) {
3372
0
        return BAD_FUNC_ARG;
3373
0
    }
3374
3375
6.09k
    WC_CALLOC_VAR_EX(tmpSha256, wc_Sha256, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
3376
6.09k
        return MEMORY_E);
3377
3378
6.08k
    ret = wc_Sha256Copy(sha256, tmpSha256);
3379
6.08k
    if (ret == 0) {
3380
6.08k
        ret = wc_Sha256Final(tmpSha256, hash);
3381
6.08k
        wc_Sha256Free(tmpSha256);
3382
6.08k
    }
3383
3384
3385
6.08k
    WC_FREE_VAR_EX(tmpSha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3386
3387
6.08k
    return ret;
3388
6.09k
}
3389
int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
3390
6.12k
{
3391
6.12k
    int ret = 0;
3392
3393
6.12k
    if (src == NULL || dst == NULL) {
3394
0
        return BAD_FUNC_ARG;
3395
0
    }
3396
3397
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
3398
    #ifndef WOLF_CRYPTO_CB_FIND
3399
    if (src->devId != INVALID_DEVID)
3400
    #endif
3401
    {
3402
        /* Cast the source and destination to be void to keep the abstraction */
3403
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
3404
                               WC_HASH_TYPE_SHA256, (void*)src, (void*)dst);
3405
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3406
            return ret;
3407
        /* fall-through when unavailable */
3408
    }
3409
    ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
3410
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
3411
3412
    /* Free dst resources before copy to prevent memory leaks (e.g., msg
3413
     * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
3414
6.12k
    wc_Sha256Free(dst);
3415
6.12k
    XMEMCPY(dst, src, sizeof(wc_Sha256));
3416
3417
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
3418
    wc_MAXQ10XX_Sha256Copy(src);
3419
#endif
3420
3421
3422
#ifdef WOLFSSL_SMALL_STACK_CACHE
3423
    dst->W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE,
3424
                              dst->heap, DYNAMIC_TYPE_DIGEST);
3425
    if (dst->W == NULL) {
3426
        XMEMSET(dst, 0, sizeof(wc_Sha256));
3427
        return MEMORY_E;
3428
    }
3429
#endif
3430
3431
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3)
3432
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
3433
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
3434
#endif
3435
3436
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
3437
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
3438
#endif
3439
3440
#ifdef WOLFSSL_PIC32MZ_HASH
3441
    ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
3442
#endif
3443
3444
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3445
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
3446
    esp_sha256_ctx_copy(src, dst);
3447
#endif
3448
3449
#ifdef HAVE_ARIA
3450
    dst->hSession = NULL;
3451
    if((src->hSession != NULL) && (MC_CopySession(src->hSession, &(dst->hSession)) != MC_OK)) {
3452
        return MEMORY_E;
3453
    }
3454
#endif
3455
3456
6.12k
#ifdef WOLFSSL_HASH_FLAGS
3457
6.12k
    dst->flags |= WC_HASH_FLAG_ISCOPY;
3458
6.12k
#endif
3459
3460
#if defined(WOLFSSL_HASH_KEEP)
3461
    if (src->msg != NULL) {
3462
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
3463
        if (dst->msg == NULL)
3464
            return MEMORY_E;
3465
        XMEMCPY(dst->msg, src->msg, src->len);
3466
    }
3467
#endif
3468
3469
6.12k
    return ret;
3470
6.12k
}
3471
#endif
3472
3473
#ifdef WOLFSSL_HASH_FLAGS
3474
int wc_Sha256SetFlags(wc_Sha256* sha256, word32 flags)
3475
101k
{
3476
101k
    if (sha256) {
3477
101k
        sha256->flags = flags;
3478
101k
    }
3479
101k
    return 0;
3480
101k
}
3481
int wc_Sha256GetFlags(wc_Sha256* sha256, word32* flags)
3482
0
{
3483
0
    if (sha256 && flags) {
3484
0
        *flags = sha256->flags;
3485
0
    }
3486
0
    return 0;
3487
0
}
3488
#endif
3489
#endif /* !WOLFSSL_TI_HASH */
3490
3491
#endif /* NO_SHA256 */