Coverage Report

Created: 2026-07-16 06:50

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