Coverage Report

Created: 2025-04-11 06:45

/src/wolfssl/wolfcrypt/src/sha256.c
Line
Count
Source (jump to first uncovered line)
1
/* sha256.c
2
 *
3
 * Copyright (C) 2006-2023 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 2 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
#ifdef HAVE_CONFIG_H
42
    #include <config.h>
43
#endif
44
45
#include <wolfssl/wolfcrypt/settings.h>
46
#include <wolfssl/wolfcrypt/types.h>
47
48
/*
49
 * SHA256 Build Options:
50
 * USE_SLOW_SHA256:            Reduces code size by not partially unrolling
51
                                (~2KB smaller and ~25% slower) (default OFF)
52
 * WOLFSSL_SHA256_BY_SPEC:     Uses the Ch/Maj based on SHA256 specification
53
                                (default ON)
54
 * WOLFSSL_SHA256_ALT_CH_MAJ:  Alternate Ch/Maj that is easier for compilers to
55
                                optimize and recognize as SHA256 (default OFF)
56
 * SHA256_MANY_REGISTERS:      A SHA256 version that keeps all data in registers
57
                                and partial unrolled (default OFF)
58
 */
59
60
/* Default SHA256 to use Ch/Maj based on specification */
61
#if !defined(WOLFSSL_SHA256_BY_SPEC) && !defined(WOLFSSL_SHA256_ALT_CH_MAJ)
62
    #define WOLFSSL_SHA256_BY_SPEC
63
#endif
64
65
66
#if !defined(NO_SHA256) && (!defined(WOLFSSL_ARMASM) && \
67
    !defined(WOLFSSL_ARMASM_NO_NEON))
68
69
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
70
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
71
    #define FIPS_NO_WRAPPERS
72
73
    #ifdef USE_WINDOWS_API
74
        #pragma code_seg(".fipsA$d")
75
        #pragma const_seg(".fipsB$d")
76
    #endif
77
#endif
78
79
#include <wolfssl/wolfcrypt/sha256.h>
80
#include <wolfssl/wolfcrypt/error-crypt.h>
81
#include <wolfssl/wolfcrypt/cpuid.h>
82
#include <wolfssl/wolfcrypt/hash.h>
83
84
#ifdef WOLF_CRYPTO_CB
85
    #include <wolfssl/wolfcrypt/cryptocb.h>
86
#endif
87
88
#ifdef WOLFSSL_IMXRT1170_CAAM
89
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h>
90
#endif
91
92
93
/* determine if we are using Espressif SHA hardware acceleration */
94
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
95
#if defined(WOLFSSL_ESP32_CRYPT) && \
96
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
97
    /* define a single keyword for simplicity & readability
98
     *
99
     * by default the HW acceleration is on for ESP32-WROOM32
100
     * but individual components can be turned off.
101
     */
102
    #define WOLFSSL_USE_ESP32_CRYPT_HASH_HW
103
#else
104
    #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
105
#endif
106
107
#ifdef WOLFSSL_ESPIDF
108
    /* Define the ESP_LOGx(TAG, "" value for output messages here.
109
    **
110
    ** Beware of possible conflict in test.c (that one now named TEST_TAG)
111
    */
112
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
113
        static const char* TAG = "wc_sha256";
114
    #endif
115
#endif
116
117
#if defined(WOLFSSL_TI_HASH)
118
    /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */
119
#elif defined(WOLFSSL_CRYPTOCELL)
120
    /* wc_port.c includes wolfcrypt/src/port/arm/cryptoCellHash.c */
121
122
#elif defined(WOLFSSL_PSOC6_CRYPTO)
123
124
125
#else
126
127
#include <wolfssl/wolfcrypt/logging.h>
128
129
#ifdef NO_INLINE
130
    #include <wolfssl/wolfcrypt/misc.h>
131
#else
132
    #define WOLFSSL_MISC_INCLUDED
133
    #include <wolfcrypt/src/misc.c>
134
#endif
135
136
#ifdef WOLFSSL_DEVCRYPTO_HASH
137
    #include <wolfssl/wolfcrypt/port/devcrypto/wc_devcrypto.h>
138
#endif
139
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
140
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
141
#endif
142
143
144
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP)
145
    #if defined(__GNUC__) && ((__GNUC__ < 4) || \
146
                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
147
        #undef  NO_AVX2_SUPPORT
148
        #define NO_AVX2_SUPPORT
149
    #endif
150
    #if defined(__clang__) && ((__clang_major__ < 3) || \
151
                               (__clang_major__ == 3 && __clang_minor__ <= 5))
152
        #define NO_AVX2_SUPPORT
153
    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)
154
        #undef NO_AVX2_SUPPORT
155
    #endif
156
157
    #define HAVE_INTEL_AVX1
158
    #ifndef NO_AVX2_SUPPORT
159
        #define HAVE_INTEL_AVX2
160
    #endif
161
#else
162
    #undef HAVE_INTEL_AVX1
163
    #undef HAVE_INTEL_AVX2
164
#endif /* WOLFSSL_X86_64_BUILD && USE_INTEL_SPEEDUP */
165
166
#if defined(HAVE_INTEL_AVX2)
167
    #define HAVE_INTEL_RORX
168
#endif
169
170
171
#if !defined(WOLFSSL_PIC32MZ_HASH) && !defined(STM32_HASH_SHA2) && \
172
    (!defined(WOLFSSL_IMX6_CAAM) || defined(NO_IMX6_CAAM_HASH) || \
173
     defined(WOLFSSL_QNX_CAAM)) && \
174
    !defined(WOLFSSL_AFALG_HASH) && !defined(WOLFSSL_DEVCRYPTO_HASH) && \
175
    (!defined(WOLFSSL_ESP32_CRYPT) || defined(NO_WOLFSSL_ESP32_CRYPT_HASH)) && \
176
    ((!defined(WOLFSSL_RENESAS_TSIP_TLS) && \
177
      !defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) || \
178
     defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) && \
179
    !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_IMXRT_DCP) && !defined(WOLFSSL_SILABS_SE_ACCEL) && \
180
    !defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_SE050_HASH) && \
181
    ((!defined(WOLFSSL_RENESAS_SCEPROTECT) && \
182
      !defined(WOLFSSL_RENESAS_RSIP)) \
183
      || defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)) && \
184
    (!defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)) && \
185
    !defined(WOLFSSL_RENESAS_RX64_HASH)
186
187
188
static int InitSha256(wc_Sha256* sha256)
189
30.1k
{
190
30.1k
    int ret = 0;
191
192
30.1k
    if (sha256 == NULL)
193
0
        return BAD_FUNC_ARG;
194
195
30.1k
    XMEMSET(sha256->digest, 0, sizeof(sha256->digest));
196
30.1k
    sha256->digest[0] = 0x6A09E667L;
197
30.1k
    sha256->digest[1] = 0xBB67AE85L;
198
30.1k
    sha256->digest[2] = 0x3C6EF372L;
199
30.1k
    sha256->digest[3] = 0xA54FF53AL;
200
30.1k
    sha256->digest[4] = 0x510E527FL;
201
30.1k
    sha256->digest[5] = 0x9B05688CL;
202
30.1k
    sha256->digest[6] = 0x1F83D9ABL;
203
30.1k
    sha256->digest[7] = 0x5BE0CD19L;
204
205
30.1k
    sha256->buffLen = 0;
206
30.1k
    sha256->loLen   = 0;
207
30.1k
    sha256->hiLen   = 0;
208
30.1k
#ifdef WOLFSSL_HASH_FLAGS
209
30.1k
    sha256->flags = 0;
210
30.1k
#endif
211
#ifdef WOLFSSL_HASH_KEEP
212
    sha256->msg  = NULL;
213
    sha256->len  = 0;
214
    sha256->used = 0;
215
#endif
216
217
30.1k
#ifdef WOLF_CRYPTO_CB
218
30.1k
    sha256->devId = wc_CryptoCb_DefaultDevID();
219
30.1k
#endif
220
221
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
222
    XMEMSET(&sha256->maxq_ctx, 0, sizeof(sha256->maxq_ctx));
223
#endif
224
225
#ifdef HAVE_ARIA
226
    sha256->hSession = NULL;
227
#endif
228
229
30.1k
    return ret;
230
30.1k
}
231
#endif
232
233
234
/* Hardware Acceleration */
235
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
236
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
237
238
    /* in case intel instructions aren't available, plus we need the K[] global */
239
    #define NEED_SOFT_SHA256
240
241
    /*****
242
    Intel AVX1/AVX2 Macro Control Structure
243
244
    #define HAVE_INTEL_AVX1
245
    #define HAVE_INTEL_AVX2
246
247
    #define HAVE_INTEL_RORX
248
249
250
    int InitSha256(wc_Sha256* sha256) {
251
         Save/Recover XMM, YMM
252
         ...
253
    }
254
255
    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
256
      Transform_Sha256(); Function prototype
257
    #else
258
      Transform_Sha256() {   }
259
      int Sha256Final() {
260
         Save/Recover XMM, YMM
261
         ...
262
      }
263
    #endif
264
265
    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
266
        #if defined(HAVE_INTEL_RORX
267
             #define RND with rorx instruction
268
        #else
269
            #define RND
270
        #endif
271
    #endif
272
273
    #if defined(HAVE_INTEL_AVX1)
274
275
       #define XMM Instructions/inline asm
276
277
       int Transform_Sha256() {
278
           Stitched Message Sched/Round
279
        }
280
281
    #elif defined(HAVE_INTEL_AVX2)
282
283
      #define YMM Instructions/inline asm
284
285
      int Transform_Sha256() {
286
          More granular Stitched Message Sched/Round
287
      }
288
289
    #endif
290
291
    */
292
293
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
294
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
295
     */
296
297
    /* #if defined(HAVE_INTEL_AVX1/2) at the tail of sha256 */
298
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data);
299
300
#ifdef __cplusplus
301
    extern "C" {
302
#endif
303
304
    #if defined(HAVE_INTEL_AVX1)
305
        extern int Transform_Sha256_AVX1(wc_Sha256 *sha256, const byte* data);
306
        extern int Transform_Sha256_AVX1_Len(wc_Sha256* sha256,
307
                                             const byte* data, word32 len);
308
    #endif
309
    #if defined(HAVE_INTEL_AVX2)
310
        extern int Transform_Sha256_AVX2(wc_Sha256 *sha256, const byte* data);
311
        extern int Transform_Sha256_AVX2_Len(wc_Sha256* sha256,
312
                                             const byte* data, word32 len);
313
        #ifdef HAVE_INTEL_RORX
314
        extern int Transform_Sha256_AVX1_RORX(wc_Sha256 *sha256, const byte* data);
315
        extern int Transform_Sha256_AVX1_RORX_Len(wc_Sha256* sha256,
316
                                                  const byte* data, word32 len);
317
        extern int Transform_Sha256_AVX2_RORX(wc_Sha256 *sha256, const byte* data);
318
        extern int Transform_Sha256_AVX2_RORX_Len(wc_Sha256* sha256,
319
                                                  const byte* data, word32 len);
320
        #endif /* HAVE_INTEL_RORX */
321
    #endif /* HAVE_INTEL_AVX2 */
322
323
#ifdef __cplusplus
324
    }  /* extern "C" */
325
#endif
326
327
    static int (*Transform_Sha256_p)(wc_Sha256* sha256, const byte* data);
328
                                                       /* = _Transform_Sha256 */
329
    static int (*Transform_Sha256_Len_p)(wc_Sha256* sha256, const byte* data,
330
                                         word32 len);
331
                                                                    /* = NULL */
332
    static int transform_check = 0;
333
    static word32 intel_flags;
334
    static int Transform_Sha256_is_vectorized = 0;
335
336
    static WC_INLINE int inline_XTRANSFORM(wc_Sha256* S, const byte* D) {
337
        int ret;
338
        ret = (*Transform_Sha256_p)(S, D);
339
        return ret;
340
    }
341
#define XTRANSFORM(...) inline_XTRANSFORM(__VA_ARGS__)
342
343
    static WC_INLINE int inline_XTRANSFORM_LEN(wc_Sha256* S, const byte* D, word32 L) {
344
        int ret;
345
        ret = (*Transform_Sha256_Len_p)(S, D, L);
346
        return ret;
347
    }
348
#define XTRANSFORM_LEN(...) inline_XTRANSFORM_LEN(__VA_ARGS__)
349
350
    static void Sha256_SetTransform(void)
351
    {
352
353
        if (transform_check)
354
            return;
355
356
        intel_flags = cpuid_get_flags();
357
358
    #ifdef HAVE_INTEL_AVX2
359
        if (1 && IS_INTEL_AVX2(intel_flags)) {
360
        #ifdef HAVE_INTEL_RORX
361
            if (IS_INTEL_BMI2(intel_flags)) {
362
                Transform_Sha256_p = Transform_Sha256_AVX2_RORX;
363
                Transform_Sha256_Len_p = Transform_Sha256_AVX2_RORX_Len;
364
                Transform_Sha256_is_vectorized = 1;
365
            }
366
            else
367
        #endif
368
            if (1)
369
            {
370
                Transform_Sha256_p = Transform_Sha256_AVX2;
371
                Transform_Sha256_Len_p = Transform_Sha256_AVX2_Len;
372
                Transform_Sha256_is_vectorized = 1;
373
            }
374
        #ifdef HAVE_INTEL_RORX
375
            else {
376
                Transform_Sha256_p = Transform_Sha256_AVX1_RORX;
377
                Transform_Sha256_Len_p = Transform_Sha256_AVX1_RORX_Len;
378
                Transform_Sha256_is_vectorized = 1;
379
            }
380
        #endif
381
        }
382
        else
383
    #endif
384
    #ifdef HAVE_INTEL_AVX1
385
        if (IS_INTEL_AVX1(intel_flags)) {
386
            Transform_Sha256_p = Transform_Sha256_AVX1;
387
            Transform_Sha256_Len_p = Transform_Sha256_AVX1_Len;
388
            Transform_Sha256_is_vectorized = 1;
389
        }
390
        else
391
    #endif
392
        {
393
            Transform_Sha256_p = Transform_Sha256;
394
            Transform_Sha256_Len_p = NULL;
395
            Transform_Sha256_is_vectorized = 0;
396
        }
397
398
        transform_check = 1;
399
    }
400
401
#if !defined(WOLFSSL_KCAPI_HASH)
402
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
403
    {
404
        int ret = 0;
405
        if (sha256 == NULL)
406
            return BAD_FUNC_ARG;
407
408
        sha256->heap = heap;
409
    #ifdef WOLF_CRYPTO_CB
410
        sha256->devId = devId;
411
        sha256->devCtx = NULL;
412
    #endif
413
    #ifdef WOLFSSL_SMALL_STACK_CACHE
414
        sha256->W = NULL;
415
    #endif
416
417
        ret = InitSha256(sha256);
418
        if (ret != 0)
419
            return ret;
420
421
        /* choose best Transform function under this runtime environment */
422
        Sha256_SetTransform();
423
424
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
425
        ret = wolfAsync_DevCtxInit(&sha256->asyncDev,
426
                            WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId);
427
    #else
428
        (void)devId;
429
    #endif /* WOLFSSL_ASYNC_CRYPT */
430
431
        return ret;
432
    }
433
#endif /* !WOLFSSL_KCAPI_HASH */
434
435
#elif defined(FREESCALE_LTC_SHA)
436
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
437
    {
438
        (void)heap;
439
        (void)devId;
440
441
        LTC_HASH_Init(LTC_BASE, &sha256->ctx, kLTC_Sha256, NULL, 0);
442
443
        return 0;
444
    }
445
446
#elif defined(FREESCALE_MMCAU_SHA)
447
448
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
449
        #include "cau_api.h"
450
    #else
451
        #include "fsl_mmcau.h"
452
    #endif
453
454
    #define XTRANSFORM(S, D)         Transform_Sha256((S),(D))
455
    #define XTRANSFORM_LEN(S, D, L)  Transform_Sha256_Len((S),(D),(L))
456
457
    #ifndef WC_HASH_DATA_ALIGNMENT
458
        /* these hardware API's require 4 byte (word32) alignment */
459
        #define WC_HASH_DATA_ALIGNMENT 4
460
    #endif
461
462
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
463
    {
464
        int ret = 0;
465
466
        (void)heap;
467
        (void)devId;
468
469
        ret = wolfSSL_CryptHwMutexLock();
470
        if (ret != 0) {
471
            return ret;
472
        }
473
474
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
475
        cau_sha256_initialize_output(sha256->digest);
476
    #else
477
        MMCAU_SHA256_InitializeOutput((uint32_t*)sha256->digest);
478
    #endif
479
        wolfSSL_CryptHwMutexUnLock();
480
481
        sha256->buffLen = 0;
482
        sha256->loLen   = 0;
483
        sha256->hiLen   = 0;
484
    #ifdef WOLFSSL_SMALL_STACK_CACHE
485
        sha256->W = NULL;
486
    #endif
487
488
        return ret;
489
    }
490
491
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
492
    {
493
        int ret = wolfSSL_CryptHwMutexLock();
494
        if (ret == 0) {
495
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
496
            cau_sha256_hash_n((byte*)data, 1, sha256->digest);
497
    #else
498
            MMCAU_SHA256_HashN((byte*)data, 1, (uint32_t*)sha256->digest);
499
    #endif
500
            wolfSSL_CryptHwMutexUnLock();
501
        }
502
        return ret;
503
    }
504
505
    static int Transform_Sha256_Len(wc_Sha256* sha256, const byte* data,
506
        word32 len)
507
    {
508
        int ret = wolfSSL_CryptHwMutexLock();
509
        if (ret == 0) {
510
        #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0
511
            if ((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) {
512
                /* data pointer is NOT aligned,
513
                 * so copy and perform one block at a time */
514
                byte* local = (byte*)sha256->buffer;
515
                while (len >= WC_SHA256_BLOCK_SIZE) {
516
                    XMEMCPY(local, data, WC_SHA256_BLOCK_SIZE);
517
                #ifdef FREESCALE_MMCAU_CLASSIC_SHA
518
                    cau_sha256_hash_n(local, 1, sha256->digest);
519
                #else
520
                    MMCAU_SHA256_HashN(local, 1, (uint32_t*)sha256->digest);
521
                #endif
522
                    data += WC_SHA256_BLOCK_SIZE;
523
                    len  -= WC_SHA256_BLOCK_SIZE;
524
                }
525
            }
526
            else
527
        #endif
528
            {
529
    #ifdef FREESCALE_MMCAU_CLASSIC_SHA
530
            cau_sha256_hash_n((byte*)data, len/WC_SHA256_BLOCK_SIZE,
531
                sha256->digest);
532
    #else
533
            MMCAU_SHA256_HashN((byte*)data, len/WC_SHA256_BLOCK_SIZE,
534
                (uint32_t*)sha256->digest);
535
    #endif
536
            }
537
            wolfSSL_CryptHwMutexUnLock();
538
        }
539
        return ret;
540
    }
541
542
#elif defined(WOLFSSL_PIC32MZ_HASH)
543
    #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
544
545
#elif defined(STM32_HASH_SHA2)
546
547
    /* Supports CubeMX HAL or Standard Peripheral Library */
548
549
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
550
    {
551
        if (sha256 == NULL)
552
            return BAD_FUNC_ARG;
553
554
        (void)devId;
555
        (void)heap;
556
557
        XMEMSET(sha256, 0, sizeof(wc_Sha256));
558
        wc_Stm32_Hash_Init(&sha256->stmCtx);
559
        return 0;
560
    }
561
562
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
563
    {
564
        int ret = 0;
565
566
        if (sha256 == NULL || (data == NULL && len > 0)) {
567
            return BAD_FUNC_ARG;
568
        }
569
570
        ret = wolfSSL_CryptHwMutexLock();
571
        if (ret == 0) {
572
            ret = wc_Stm32_Hash_Update(&sha256->stmCtx,
573
                HASH_AlgoSelection_SHA256, data, len, WC_SHA256_BLOCK_SIZE);
574
            wolfSSL_CryptHwMutexUnLock();
575
        }
576
        return ret;
577
    }
578
579
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
580
    {
581
        int ret = 0;
582
583
        if (sha256 == NULL || hash == NULL) {
584
            return BAD_FUNC_ARG;
585
        }
586
587
        ret = wolfSSL_CryptHwMutexLock();
588
        if (ret == 0) {
589
            ret = wc_Stm32_Hash_Final(&sha256->stmCtx,
590
                HASH_AlgoSelection_SHA256, hash, WC_SHA256_DIGEST_SIZE);
591
            wolfSSL_CryptHwMutexUnLock();
592
        }
593
594
        (void)wc_InitSha256(sha256); /* reset state */
595
596
        return ret;
597
    }
598
599
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
600
    !defined(WOLFSSL_QNX_CAAM)
601
    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
602
603
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
604
605
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
606
    {
607
        if (sha256 == NULL) {
608
            return BAD_FUNC_ARG;
609
        }
610
        (void)devId;
611
612
        return se050_hash_init(&sha256->se050Ctx, heap);
613
    }
614
615
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
616
    {
617
        return se050_hash_update(&sha256->se050Ctx, data, len);
618
    }
619
620
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
621
    {
622
        int ret = 0;
623
        ret = se050_hash_final(&sha256->se050Ctx, hash, WC_SHA256_DIGEST_SIZE,
624
                               kAlgorithm_SSS_SHA256);
625
        return ret;
626
    }
627
    int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
628
    {
629
        int ret = 0;
630
        ret = se050_hash_final(&sha256->se050Ctx, hash, WC_SHA256_DIGEST_SIZE,
631
                               kAlgorithm_SSS_SHA256);
632
        return ret;
633
    }
634
635
#elif defined(WOLFSSL_AFALG_HASH)
636
    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
637
638
#elif defined(WOLFSSL_DEVCRYPTO_HASH)
639
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
640
641
#elif defined(WOLFSSL_SCE) && !defined(WOLFSSL_SCE_NO_HASH)
642
    #include "hal_data.h"
643
644
    #ifndef WOLFSSL_SCE_SHA256_HANDLE
645
        #define WOLFSSL_SCE_SHA256_HANDLE g_sce_hash_0
646
    #endif
647
648
    #define WC_SHA256_DIGEST_WORD_SIZE 16
649
    #define XTRANSFORM(S, D) wc_Sha256SCE_XTRANSFORM((S), (D))
650
    static int wc_Sha256SCE_XTRANSFORM(wc_Sha256* sha256, const byte* data)
651
    {
652
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
653
                CRYPTO_WORD_ENDIAN_LITTLE)
654
        {
655
            ByteReverseWords((word32*)data, (word32*)data,
656
                    WC_SHA256_BLOCK_SIZE);
657
            ByteReverseWords(sha256->digest, sha256->digest,
658
                    WC_SHA256_DIGEST_SIZE);
659
        }
660
661
        if (WOLFSSL_SCE_SHA256_HANDLE.p_api->hashUpdate(
662
                    WOLFSSL_SCE_SHA256_HANDLE.p_ctrl, (word32*)data,
663
                    WC_SHA256_DIGEST_WORD_SIZE, sha256->digest) != SSP_SUCCESS){
664
            WOLFSSL_MSG("Unexpected hardware return value");
665
            return WC_HW_E;
666
        }
667
668
        if (WOLFSSL_SCE_GSCE_HANDLE.p_cfg->endian_flag ==
669
                CRYPTO_WORD_ENDIAN_LITTLE)
670
        {
671
            ByteReverseWords((word32*)data, (word32*)data,
672
                    WC_SHA256_BLOCK_SIZE);
673
            ByteReverseWords(sha256->digest, sha256->digest,
674
                    WC_SHA256_DIGEST_SIZE);
675
        }
676
677
        return 0;
678
    }
679
680
681
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
682
    {
683
        int ret = 0;
684
        if (sha256 == NULL)
685
            return BAD_FUNC_ARG;
686
687
        sha256->heap = heap;
688
689
        ret = InitSha256(sha256);
690
        if (ret != 0)
691
            return ret;
692
693
        (void)devId;
694
695
        return ret;
696
    }
697
698
#elif defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
699
700
    /* HW may fail since there's only one, so we still need SW */
701
    #define NEED_SOFT_SHA256
702
703
    /*
704
    ** An Espressif-specific InitSha256()
705
    **
706
    ** soft SHA needs initialization digest, but HW does not.
707
    */
708
    static int InitSha256(wc_Sha256* sha256)
709
    {
710
        int ret = 0; /* zero = success */
711
712
        if (sha256 == NULL) {
713
            return BAD_FUNC_ARG;
714
        }
715
716
        /* We may or may not need initial digest for HW.
717
         * Always needed for SW-only. */
718
        sha256->digest[0] = 0x6A09E667L;
719
        sha256->digest[1] = 0xBB67AE85L;
720
        sha256->digest[2] = 0x3C6EF372L;
721
        sha256->digest[3] = 0xA54FF53AL;
722
        sha256->digest[4] = 0x510E527FL;
723
        sha256->digest[5] = 0x9B05688CL;
724
        sha256->digest[6] = 0x1F83D9ABL;
725
        sha256->digest[7] = 0x5BE0CD19L;
726
727
        sha256->buffLen = 0;
728
        sha256->loLen   = 0;
729
        sha256->hiLen   = 0;
730
731
#ifndef NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256
732
        ret = esp_sha_init(&(sha256->ctx), WC_HASH_TYPE_SHA256);
733
#endif
734
        return ret;
735
    }
736
737
    /*
738
    ** An Espressif-specific wolfCrypt InitSha256 external wrapper.
739
    **
740
    ** we'll assume this is ALWAYS for a new, uninitialized sha256
741
    */
742
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
743
    {
744
        (void)devId;
745
        if (sha256 == NULL) {
746
            return BAD_FUNC_ARG;
747
        }
748
749
    #ifdef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
750
#ifndef NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256
751
        /* We know this is a fresh, uninitialized item, so set to INIT */
752
        if (sha256->ctx.mode != ESP32_SHA_INIT) {
753
            ESP_LOGV(TAG, "Set ctx mode from prior value: "
754
                               "%d", sha256->ctx.mode);
755
        }
756
        sha256->ctx.mode = ESP32_SHA_INIT;
757
#endif
758
    #endif
759
760
        return InitSha256(sha256);
761
    }
762
763
#elif (defined(WOLFSSL_RENESAS_TSIP_TLS) || \
764
       defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
765
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)
766
767
    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */
768
769
#elif (defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_RSIP)) \
770
     && !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
771
772
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
773
774
#elif defined(WOLFSSL_PSOC6_CRYPTO)
775
776
    /* implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */
777
778
#elif defined(WOLFSSL_IMXRT_DCP)
779
    #include <wolfssl/wolfcrypt/port/nxp/dcp_port.h>
780
    /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */
781
782
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
783
    /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
784
785
#elif defined(WOLFSSL_KCAPI_HASH)
786
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
787
788
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
789
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
790
791
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
792
793
    /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
794
795
#else
796
    #define NEED_SOFT_SHA256
797
798
    int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
799
15.0k
    {
800
15.0k
        int ret = 0;
801
15.0k
        if (sha256 == NULL)
802
0
            return BAD_FUNC_ARG;
803
15.0k
        ret = InitSha256(sha256);
804
15.0k
        if (ret != 0)
805
0
            return ret;
806
807
15.0k
        sha256->heap = heap;
808
15.0k
    #ifdef WOLF_CRYPTO_CB
809
15.0k
        sha256->devId = devId;
810
15.0k
        sha256->devCtx = NULL;
811
15.0k
    #endif
812
    #ifdef WOLFSSL_SMALL_STACK_CACHE
813
        sha256->W = NULL;
814
    #endif
815
816
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
817
        ret = wolfAsync_DevCtxInit(&sha256->asyncDev,
818
                            WOLFSSL_ASYNC_MARKER_SHA256, sha256->heap, devId);
819
    #else
820
15.0k
        (void)devId;
821
15.0k
    #endif /* WOLFSSL_ASYNC_CRYPT */
822
    #ifdef WOLFSSL_IMXRT1170_CAAM
823
         ret = wc_CAAM_HashInit(&sha256->hndl, &sha256->ctx, WC_HASH_TYPE_SHA256);
824
    #endif
825
826
15.0k
        return ret;
827
15.0k
    }
828
#endif /* End Hardware Acceleration */
829
830
#ifdef NEED_SOFT_SHA256
831
832
    static const FLASH_QUALIFIER ALIGN32 word32 K[64] = {
833
        0x428A2F98L, 0x71374491L, 0xB5C0FBCFL, 0xE9B5DBA5L, 0x3956C25BL,
834
        0x59F111F1L, 0x923F82A4L, 0xAB1C5ED5L, 0xD807AA98L, 0x12835B01L,
835
        0x243185BEL, 0x550C7DC3L, 0x72BE5D74L, 0x80DEB1FEL, 0x9BDC06A7L,
836
        0xC19BF174L, 0xE49B69C1L, 0xEFBE4786L, 0x0FC19DC6L, 0x240CA1CCL,
837
        0x2DE92C6FL, 0x4A7484AAL, 0x5CB0A9DCL, 0x76F988DAL, 0x983E5152L,
838
        0xA831C66DL, 0xB00327C8L, 0xBF597FC7L, 0xC6E00BF3L, 0xD5A79147L,
839
        0x06CA6351L, 0x14292967L, 0x27B70A85L, 0x2E1B2138L, 0x4D2C6DFCL,
840
        0x53380D13L, 0x650A7354L, 0x766A0ABBL, 0x81C2C92EL, 0x92722C85L,
841
        0xA2BFE8A1L, 0xA81A664BL, 0xC24B8B70L, 0xC76C51A3L, 0xD192E819L,
842
        0xD6990624L, 0xF40E3585L, 0x106AA070L, 0x19A4C116L, 0x1E376C08L,
843
        0x2748774CL, 0x34B0BCB5L, 0x391C0CB3L, 0x4ED8AA4AL, 0x5B9CCA4FL,
844
        0x682E6FF3L, 0x748F82EEL, 0x78A5636FL, 0x84C87814L, 0x8CC70208L,
845
        0x90BEFFFAL, 0xA4506CEBL, 0xBEF9A3F7L, 0xC67178F2L
846
    };
847
848
/* Both versions of Ch and Maj are logically the same, but with the second set
849
    the compilers can recognize them better for optimization */
850
#ifdef WOLFSSL_SHA256_BY_SPEC
851
    /* SHA256 math based on specification */
852
3.59M
    #define Ch(x,y,z)       ((z) ^ ((x) & ((y) ^ (z))))
853
3.59M
    #define Maj(x,y,z)      ((((x) | (y)) & (z)) | ((x) & (y)))
854
#else
855
    /* SHA256 math reworked for easier compiler optimization */
856
    #define Ch(x,y,z)       ((((y) ^ (z)) & (x)) ^ (z))
857
    #define Maj(x,y,z)      ((((x) ^ (y)) & ((y) ^ (z))) ^ (y))
858
#endif
859
5.39M
    #define R(x, n)         (((x) & 0xFFFFFFFFU) >> (n))
860
861
32.3M
    #define S(x, n)         rotrFixed(x, n)
862
3.59M
    #define Sigma0(x)       (S(x, 2)  ^ S(x, 13) ^ S(x, 22))
863
3.59M
    #define Sigma1(x)       (S(x, 6)  ^ S(x, 11) ^ S(x, 25))
864
2.69M
    #define Gamma0(x)       (S(x, 7)  ^ S(x, 18) ^ R(x, 3))
865
2.69M
    #define Gamma1(x)       (S(x, 17) ^ S(x, 19) ^ R(x, 10))
866
867
    #define a(i) S[(0-(i)) & 7]
868
    #define b(i) S[(1-(i)) & 7]
869
    #define c(i) S[(2-(i)) & 7]
870
3.59M
    #define d(i) S[(3-(i)) & 7]
871
    #define e(i) S[(4-(i)) & 7]
872
    #define f(i) S[(5-(i)) & 7]
873
    #define g(i) S[(6-(i)) & 7]
874
7.18M
    #define h(i) S[(7-(i)) & 7]
875
876
    #ifndef XTRANSFORM
877
56.2k
         #define XTRANSFORM(S, D)         Transform_Sha256((S),(D))
878
    #endif
879
880
#ifndef SHA256_MANY_REGISTERS
881
    #define RND(j) \
882
3.59M
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+(j)] + W[i+(j)]; \
883
3.59M
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
884
3.59M
         d(j) += t0; \
885
3.59M
         h(j)  = t0 + t1
886
887
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
888
56.2k
    {
889
56.2k
        word32 S[8], t0, t1;
890
56.2k
        int i;
891
892
    #ifdef WOLFSSL_SMALL_STACK_CACHE
893
        word32* W = sha256->W;
894
        if (W == NULL) {
895
            W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL,
896
                                                           DYNAMIC_TYPE_DIGEST);
897
            if (W == NULL)
898
                return MEMORY_E;
899
            sha256->W = W;
900
        }
901
    #elif defined(WOLFSSL_SMALL_STACK)
902
56.2k
        word32* W;
903
56.2k
        W = (word32*)XMALLOC(sizeof(word32) * WC_SHA256_BLOCK_SIZE, NULL,
904
56.2k
                                                       DYNAMIC_TYPE_TMP_BUFFER);
905
56.2k
        if (W == NULL)
906
69
            return MEMORY_E;
907
    #else
908
        word32 W[WC_SHA256_BLOCK_SIZE];
909
    #endif
910
911
        /* Copy context->state[] to working vars */
912
505k
        for (i = 0; i < 8; i++)
913
449k
            S[i] = sha256->digest[i];
914
915
954k
        for (i = 0; i < 16; i++)
916
898k
            W[i] = *((const word32*)&data[i*(int)sizeof(word32)]);
917
918
2.75M
        for (i = 16; i < WC_SHA256_BLOCK_SIZE; i++)
919
2.69M
            W[i] = Gamma1(W[i-2]) + W[i-7] + Gamma0(W[i-15]) + W[i-16];
920
921
    #ifdef USE_SLOW_SHA256
922
        /* not unrolled - ~2k smaller and ~25% slower */
923
        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {
924
            int j;
925
            for (j = 0; j < 8; j++) { /* braces needed here for macros {} */
926
                RND(j);
927
            }
928
        }
929
    #else
930
        /* partially loop unrolled */
931
505k
        for (i = 0; i < WC_SHA256_BLOCK_SIZE; i += 8) {
932
449k
            RND(0); RND(1); RND(2); RND(3);
933
449k
            RND(4); RND(5); RND(6); RND(7);
934
449k
        }
935
56.1k
    #endif /* USE_SLOW_SHA256 */
936
937
        /* Add the working vars back into digest state[] */
938
505k
        for (i = 0; i < 8; i++) {
939
449k
            sha256->digest[i] += S[i];
940
449k
        }
941
942
56.1k
    #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
943
56.1k
        ForceZero(W, sizeof(word32) * WC_SHA256_BLOCK_SIZE);
944
56.1k
        XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
945
56.1k
    #endif
946
56.1k
        return 0;
947
56.2k
    }
948
#else
949
    /* SHA256 version that keeps all data in registers */
950
    #define SCHED1(j) (W[j] = *((word32*)&data[j*sizeof(word32)]))
951
    #define SCHED(j) (               \
952
                   W[ j     & 15] += \
953
            Gamma1(W[(j-2)  & 15])+  \
954
                   W[(j-7)  & 15] +  \
955
            Gamma0(W[(j-15) & 15])   \
956
        )
957
958
    #define RND1(j) \
959
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED1(j); \
960
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
961
         d(j) += t0; \
962
         h(j)  = t0 + t1
963
    #define RNDN(j) \
964
         t0 = h(j) + Sigma1(e(j)) + Ch(e(j), f(j), g(j)) + K[i+j] + SCHED(j); \
965
         t1 = Sigma0(a(j)) + Maj(a(j), b(j), c(j)); \
966
         d(j) += t0; \
967
         h(j)  = t0 + t1
968
969
    static int Transform_Sha256(wc_Sha256* sha256, const byte* data)
970
    {
971
        word32 S[8], t0, t1;
972
        int i;
973
        word32 W[WC_SHA256_BLOCK_SIZE/sizeof(word32)];
974
975
        /* Copy digest to working vars */
976
        S[0] = sha256->digest[0];
977
        S[1] = sha256->digest[1];
978
        S[2] = sha256->digest[2];
979
        S[3] = sha256->digest[3];
980
        S[4] = sha256->digest[4];
981
        S[5] = sha256->digest[5];
982
        S[6] = sha256->digest[6];
983
        S[7] = sha256->digest[7];
984
985
        i = 0;
986
        RND1( 0); RND1( 1); RND1( 2); RND1( 3);
987
        RND1( 4); RND1( 5); RND1( 6); RND1( 7);
988
        RND1( 8); RND1( 9); RND1(10); RND1(11);
989
        RND1(12); RND1(13); RND1(14); RND1(15);
990
        /* 64 operations, partially loop unrolled */
991
        for (i = 16; i < 64; i += 16) {
992
            RNDN( 0); RNDN( 1); RNDN( 2); RNDN( 3);
993
            RNDN( 4); RNDN( 5); RNDN( 6); RNDN( 7);
994
            RNDN( 8); RNDN( 9); RNDN(10); RNDN(11);
995
            RNDN(12); RNDN(13); RNDN(14); RNDN(15);
996
        }
997
998
        /* Add the working vars back into digest */
999
        sha256->digest[0] += S[0];
1000
        sha256->digest[1] += S[1];
1001
        sha256->digest[2] += S[2];
1002
        sha256->digest[3] += S[3];
1003
        sha256->digest[4] += S[4];
1004
        sha256->digest[5] += S[5];
1005
        sha256->digest[6] += S[6];
1006
        sha256->digest[7] += S[7];
1007
1008
        return 0;
1009
    }
1010
#endif /* SHA256_MANY_REGISTERS */
1011
#endif
1012
/* End wc_ software implementation */
1013
1014
1015
#ifdef XTRANSFORM
1016
1017
    static WC_INLINE void AddLength(wc_Sha256* sha256, word32 len)
1018
30.8k
    {
1019
30.8k
        word32 tmp = sha256->loLen;
1020
30.8k
        if ((sha256->loLen += len) < tmp) {
1021
0
            sha256->hiLen++;                       /* carry low to high */
1022
0
        }
1023
30.8k
    }
1024
1025
    /* do block size increments/updates */
1026
    static WC_INLINE int Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
1027
30.8k
    {
1028
30.8k
        int ret = 0;
1029
30.8k
        word32 blocksLen;
1030
30.8k
        byte* local;
1031
1032
30.8k
        if (sha256 == NULL || (data == NULL && len > 0)) {
1033
0
            return BAD_FUNC_ARG;
1034
0
        }
1035
1036
30.8k
        if (data == NULL && len == 0) {
1037
            /* valid, but do nothing */
1038
18
            return 0;
1039
18
        }
1040
1041
        /* check that internal buffLen is valid */
1042
30.8k
        if (sha256->buffLen >= WC_SHA256_BLOCK_SIZE) {
1043
0
            return BUFFER_E;
1044
0
        }
1045
1046
        /* add length for final */
1047
30.8k
        AddLength(sha256, len);
1048
1049
30.8k
        local = (byte*)sha256->buffer;
1050
1051
        /* process any remainder from previous operation */
1052
30.8k
        if (sha256->buffLen > 0) {
1053
15.2k
            blocksLen = min(len, WC_SHA256_BLOCK_SIZE - sha256->buffLen);
1054
15.2k
            XMEMCPY(&local[sha256->buffLen], data, blocksLen);
1055
1056
15.2k
            sha256->buffLen += blocksLen;
1057
15.2k
            data            += blocksLen;
1058
15.2k
            len             -= blocksLen;
1059
1060
15.2k
            if (sha256->buffLen == WC_SHA256_BLOCK_SIZE) {
1061
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1062
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1063
                if (sha256->ctx.mode == ESP32_SHA_INIT) {
1064
                    ESP_LOGV(TAG, "Sha256Update try hardware");
1065
                    esp_sha_try_hw_lock(&sha256->ctx);
1066
                }
1067
            #endif
1068
1069
1070
303
            #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
1071
                #if defined(WOLFSSL_X86_64_BUILD) && \
1072
                          defined(USE_INTEL_SPEEDUP) && \
1073
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1074
                if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1075
                #endif
1076
                #if (defined(CONFIG_IDF_TARGET_ESP32C3) || \
1077
                     defined(CONFIG_IDF_TARGET_ESP32C6)) && \
1078
                    defined(WOLFSSL_ESP32_CRYPT) && \
1079
                   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1080
                   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1081
                    if (esp_sha_need_byte_reversal(&sha256->ctx))
1082
                #endif
1083
303
                {
1084
303
                    ByteReverseWords(sha256->buffer, sha256->buffer,
1085
303
                        WC_SHA256_BLOCK_SIZE);
1086
303
                }
1087
303
            #endif
1088
1089
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1090
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1091
1092
                if (sha256->ctx.mode == ESP32_SHA_SW) {
1093
                    #if defined(WOLFSSL_DEBUG_MUTEX)
1094
                    {
1095
                        ESP_LOGI(TAG, "Sha256Update process software");
1096
                    }
1097
                    #endif
1098
                    #ifdef WOLFSSL_HW_METRICS
1099
                    {
1100
                        /* Track of # SW during transforms during active HW */
1101
                        esp_sw_sha256_count_add();
1102
                    }
1103
                    #endif /* WOLFSSL_HW_METRICS */
1104
                    ret = XTRANSFORM(sha256, (const byte*)local);
1105
                }
1106
                else {
1107
                    #if defined(WOLFSSL_DEBUG_MUTEX)
1108
                    {
1109
                        ESP_LOGI(TAG, "Sha256Update process hardware");
1110
                    }
1111
                    #endif
1112
                    esp_sha256_process(sha256, (const byte*)local);
1113
                }
1114
            #else
1115
                /* Always SW */
1116
303
                ret = XTRANSFORM(sha256, (const byte*)local);
1117
303
            #endif
1118
1119
303
                if (ret == 0)
1120
303
                    sha256->buffLen = 0;
1121
0
                else
1122
0
                    len = 0; /* error */
1123
303
            }
1124
15.2k
        }
1125
1126
        /* process blocks */
1127
    #ifdef XTRANSFORM_LEN
1128
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1129
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1130
        if (Transform_Sha256_Len_p != NULL)
1131
        #endif
1132
        {
1133
            /* get number of blocks */
1134
            /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */
1135
            /* len (masked by 0xFFFFFFC0) returns block aligned length */
1136
            blocksLen = len & ~((word32)WC_SHA256_BLOCK_SIZE-1);
1137
            if (blocksLen > 0) {
1138
                /* Byte reversal and alignment handled in function if required */
1139
                XTRANSFORM_LEN(sha256, data, blocksLen);
1140
                data += blocksLen;
1141
                len  -= blocksLen;
1142
            }
1143
        }
1144
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1145
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1146
        else
1147
        #endif
1148
    #endif /* XTRANSFORM_LEN */
1149
30.8k
    #if !defined(XTRANSFORM_LEN) || \
1150
30.8k
        (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1151
30.8k
         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
1152
30.8k
        {
1153
64.9k
            while (len >= WC_SHA256_BLOCK_SIZE) {
1154
34.1k
                word32* local32 = sha256->buffer;
1155
                /* optimization to avoid memcpy if data pointer is properly aligned */
1156
                /* Intel transform function requires use of sha256->buffer */
1157
                /* Little Endian requires byte swap, so can't use data directly */
1158
            #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(LITTLE_ENDIAN_ORDER) && \
1159
                !(defined(WOLFSSL_X86_64_BUILD) && \
1160
                         defined(USE_INTEL_SPEEDUP) && \
1161
                         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
1162
                if (((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {
1163
                    local32 = (word32*)data;
1164
                }
1165
                else
1166
            #endif
1167
34.1k
                {
1168
34.1k
                    XMEMCPY(local32, data, WC_SHA256_BLOCK_SIZE);
1169
34.1k
                }
1170
1171
34.1k
                data += WC_SHA256_BLOCK_SIZE;
1172
34.1k
                len  -= WC_SHA256_BLOCK_SIZE;
1173
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1174
               !defined( NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1175
                if (sha256->ctx.mode == ESP32_SHA_INIT){
1176
                    ESP_LOGV(TAG, "Sha256Update try hardware loop");
1177
                    esp_sha_try_hw_lock(&sha256->ctx);
1178
                }
1179
            #endif
1180
1181
34.1k
            #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
1182
                #if (defined(CONFIG_IDF_TARGET_ESP32C3) || \
1183
                     defined(CONFIG_IDF_TARGET_ESP32C6)) && \
1184
                    defined(WOLFSSL_ESP32_CRYPT) && \
1185
                   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1186
                   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1187
                    if (esp_sha_need_byte_reversal(&sha256->ctx))
1188
                #endif
1189
                #if defined(WOLFSSL_X86_64_BUILD) && \
1190
                          defined(USE_INTEL_SPEEDUP) && \
1191
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1192
                if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1193
                #endif
1194
34.1k
                {
1195
34.1k
                    ByteReverseWords(local32, local32, WC_SHA256_BLOCK_SIZE);
1196
34.1k
                }
1197
34.1k
            #endif
1198
1199
            #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1200
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1201
                if (sha256->ctx.mode == ESP32_SHA_SW) {
1202
                    ESP_LOGV(TAG, "Sha256Update process software loop");
1203
                    ret = XTRANSFORM(sha256, (const byte*)local32);
1204
                }
1205
                else {
1206
                    ESP_LOGV(TAG, "Sha256Update process hardware");
1207
                    esp_sha256_process(sha256, (const byte*)local32);
1208
                }
1209
            #else
1210
34.1k
                ret = XTRANSFORM(sha256, (const byte*)local32);
1211
34.1k
            #endif
1212
1213
34.1k
                if (ret != 0)
1214
44
                    break;
1215
34.1k
            }
1216
30.8k
        }
1217
30.8k
    #endif
1218
1219
        /* save remainder */
1220
30.8k
        if (ret == 0 && len > 0) {
1221
15.6k
            XMEMCPY(local, data, len);
1222
15.6k
            sha256->buffLen = len;
1223
15.6k
        }
1224
1225
30.8k
        return ret;
1226
30.8k
    }
1227
1228
#if defined(WOLFSSL_KCAPI_HASH)
1229
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
1230
1231
#else
1232
    int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
1233
24.3k
    {
1234
24.3k
        if (sha256 == NULL || (data == NULL && len > 0)) {
1235
0
            return BAD_FUNC_ARG;
1236
0
        }
1237
1238
24.3k
        if (data == NULL && len == 0) {
1239
            /* valid, but do nothing */
1240
66
            return 0;
1241
66
        }
1242
1243
24.2k
    #ifdef WOLF_CRYPTO_CB
1244
24.2k
        #ifndef WOLF_CRYPTO_CB_FIND
1245
24.2k
        if (sha256->devId != INVALID_DEVID)
1246
205
        #endif
1247
205
        {
1248
205
            int ret = wc_CryptoCb_Sha256Hash(sha256, data, len, NULL);
1249
205
            if (ret != CRYPTOCB_UNAVAILABLE)
1250
0
                return ret;
1251
            /* fall-through when unavailable */
1252
205
        }
1253
24.2k
    #endif
1254
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
1255
        if (sha256->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA256) {
1256
        #if defined(HAVE_INTEL_QA)
1257
            return IntelQaSymSha256(&sha256->asyncDev, NULL, data, len);
1258
        #endif
1259
        }
1260
    #endif /* WOLFSSL_ASYNC_CRYPT */
1261
1262
24.2k
        return Sha256Update(sha256, data, len);
1263
24.2k
    }
1264
#endif
1265
1266
    static WC_INLINE int Sha256Final(wc_Sha256* sha256)
1267
15.3k
    {
1268
1269
15.3k
        int ret;
1270
15.3k
        byte* local;
1271
1272
15.3k
        if (sha256 == NULL) {
1273
0
            return BAD_FUNC_ARG;
1274
0
        }
1275
1276
        /* we'll add a 0x80 byte at the end,
1277
        ** so make sure we have appropriate buffer length. */
1278
15.3k
        if (sha256->buffLen > WC_SHA256_BLOCK_SIZE - 1) {
1279
            /* exit with error code if there's a bad buffer size in buffLen */
1280
0
            return BAD_STATE_E;
1281
0
        } /* buffLen check */
1282
1283
15.3k
        local = (byte*)sha256->buffer;
1284
15.3k
        local[sha256->buffLen++] = 0x80; /* add 1 */
1285
1286
        /* pad with zeros */
1287
15.3k
        if (sha256->buffLen > WC_SHA256_PAD_SIZE) {
1288
6.39k
            XMEMSET(&local[sha256->buffLen], 0,
1289
6.39k
                WC_SHA256_BLOCK_SIZE - sha256->buffLen);
1290
6.39k
            sha256->buffLen += WC_SHA256_BLOCK_SIZE - sha256->buffLen;
1291
1292
        #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1293
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1294
            if (sha256->ctx.mode == ESP32_SHA_INIT) {
1295
                esp_sha_try_hw_lock(&sha256->ctx);
1296
            }
1297
        #endif
1298
1299
6.39k
        #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
1300
            #if (defined(CONFIG_IDF_TARGET_ESP32C3) || \
1301
                 defined(CONFIG_IDF_TARGET_ESP32C6))  && \
1302
                defined(WOLFSSL_ESP32_CRYPT) && \
1303
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1304
               !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1305
                if (esp_sha_need_byte_reversal(&sha256->ctx))
1306
            #endif
1307
            #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1308
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1309
            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1310
            #endif
1311
6.39k
            {
1312
6.39k
                ByteReverseWords(sha256->buffer, sha256->buffer,
1313
6.39k
                                                      WC_SHA256_BLOCK_SIZE);
1314
6.39k
            }
1315
6.39k
        #endif
1316
1317
        #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1318
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1319
            if (sha256->ctx.mode == ESP32_SHA_INIT) {
1320
                esp_sha_try_hw_lock(&sha256->ctx);
1321
            }
1322
            if (sha256->ctx.mode == ESP32_SHA_SW) {
1323
                ret = XTRANSFORM(sha256, (const byte*)local);
1324
            }
1325
            else {
1326
                ret = esp_sha256_process(sha256, (const byte*)local);
1327
            }
1328
        #else
1329
6.39k
            ret = XTRANSFORM(sha256, (const byte*)local);
1330
6.39k
        #endif
1331
6.39k
            if (ret != 0)
1332
3
                return ret;
1333
1334
6.38k
            sha256->buffLen = 0;
1335
6.38k
        }
1336
15.3k
        XMEMSET(&local[sha256->buffLen], 0,
1337
15.3k
            WC_SHA256_PAD_SIZE - sha256->buffLen);
1338
1339
        /* put 64 bit length in separate 32 bit parts */
1340
15.3k
        sha256->hiLen = (sha256->loLen >> (8 * sizeof(sha256->loLen) - 3)) +
1341
15.3k
                                                         (sha256->hiLen << 3);
1342
15.3k
        sha256->loLen = sha256->loLen << 3;
1343
1344
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1345
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1346
        if (sha256->ctx.mode == ESP32_SHA_INIT) {
1347
            esp_sha_try_hw_lock(&sha256->ctx);
1348
        }
1349
    #endif
1350
1351
        /* store lengths */
1352
15.3k
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
1353
        #if (defined(CONFIG_IDF_TARGET_ESP32C3) || \
1354
             defined(CONFIG_IDF_TARGET_ESP32C6)) && \
1355
            defined(WOLFSSL_ESP32_CRYPT) && \
1356
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1357
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1358
            if (esp_sha_need_byte_reversal(&sha256->ctx))
1359
        #endif
1360
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1361
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1362
        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1363
        #endif
1364
15.3k
        {
1365
15.3k
            ByteReverseWords(sha256->buffer, sha256->buffer,
1366
15.3k
                WC_SHA256_BLOCK_SIZE);
1367
15.3k
        }
1368
15.3k
    #endif
1369
        /* ! 64-bit length ordering dependent on digest endian type ! */
1370
15.3k
        XMEMCPY(&local[WC_SHA256_PAD_SIZE], &sha256->hiLen, sizeof(word32));
1371
15.3k
        XMEMCPY(&local[WC_SHA256_PAD_SIZE + sizeof(word32)], &sha256->loLen,
1372
15.3k
                sizeof(word32));
1373
1374
    /* Only the ESP32-C3 with HW enabled may need pad size byte order reversal
1375
     * depending on HW or SW mode */
1376
    #if (defined(CONFIG_IDF_TARGET_ESP32C3) || \
1377
         defined(CONFIG_IDF_TARGET_ESP32C6)) && \
1378
         defined(WOLFSSL_ESP32_CRYPT) && \
1379
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1380
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1381
        if (sha256->ctx.mode == ESP32_SHA_HW) {
1382
        #if defined(WOLFSSL_SUPER_VERBOSE_DEBUG)
1383
            ESP_LOGV(TAG, "Start: Reverse PAD SIZE Endianness.");
1384
        #endif
1385
            ByteReverseWords(
1386
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)], /* out */
1387
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)], /* in  */
1388
                2 * sizeof(word32) /* byte count to reverse */
1389
            );
1390
        #if defined(WOLFSSL_SUPER_VERBOSE_DEBUG)
1391
            ESP_LOGV(TAG, "End: Reverse PAD SIZE Endianness.");
1392
        #endif
1393
        } /* end if (sha256->ctx.mode == ESP32_SHA_HW) */
1394
    #endif
1395
1396
    #if defined(FREESCALE_MMCAU_SHA) || \
1397
        (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1398
                         (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
1399
        /* Kinetis requires only these bytes reversed */
1400
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1401
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1402
        if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags))
1403
        #endif
1404
        {
1405
            ByteReverseWords(
1406
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
1407
                &sha256->buffer[WC_SHA256_PAD_SIZE / sizeof(word32)],
1408
                2 * sizeof(word32));
1409
        }
1410
    #endif
1411
1412
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1413
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1414
        if (sha256->ctx.mode == ESP32_SHA_INIT) {
1415
            esp_sha_try_hw_lock(&sha256->ctx);
1416
        }
1417
        /* depending on architecture and ctx.mode value
1418
         * we may or may not need default digest */
1419
        if (sha256->ctx.mode == ESP32_SHA_SW) {
1420
            ret = XTRANSFORM(sha256, (const byte*)local);
1421
        }
1422
        else {
1423
            ret = esp_sha256_digest_process(sha256, 1);
1424
        }
1425
    #else
1426
15.3k
        ret = XTRANSFORM(sha256, (const byte*)local);
1427
15.3k
    #endif
1428
1429
15.3k
        return ret;
1430
15.3k
    }
1431
1432
#if !defined(WOLFSSL_KCAPI_HASH)
1433
1434
    int wc_Sha256FinalRaw(wc_Sha256* sha256, byte* hash)
1435
0
    {
1436
0
    #ifdef LITTLE_ENDIAN_ORDER
1437
0
        word32 digest[WC_SHA256_DIGEST_SIZE / sizeof(word32)];
1438
0
    #endif
1439
1440
0
        if (sha256 == NULL || hash == NULL) {
1441
0
            return BAD_FUNC_ARG;
1442
0
        }
1443
1444
0
    #ifdef LITTLE_ENDIAN_ORDER
1445
        #if (defined(CONFIG_IDF_TARGET_ESP32C3) || \
1446
             defined(CONFIG_IDF_TARGET_ESP32C6)) && \
1447
            defined(WOLFSSL_ESP32_CRYPT) && \
1448
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1449
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1450
            if (esp_sha_need_byte_reversal(&sha256->ctx))
1451
        #endif
1452
0
            {
1453
0
                ByteReverseWords((word32*)digest,
1454
0
                                 (word32*)sha256->digest,
1455
0
                                  WC_SHA256_DIGEST_SIZE);
1456
0
            }
1457
0
        XMEMCPY(hash, digest, WC_SHA256_DIGEST_SIZE);
1458
    #else
1459
        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
1460
    #endif
1461
1462
0
        return 0;
1463
0
    }
1464
1465
    int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
1466
15.1k
    {
1467
15.1k
        int ret;
1468
1469
15.1k
        if (sha256 == NULL || hash == NULL) {
1470
0
            return BAD_FUNC_ARG;
1471
0
        }
1472
1473
15.1k
    #ifdef WOLF_CRYPTO_CB
1474
15.1k
        #ifndef WOLF_CRYPTO_CB_FIND
1475
15.1k
        if (sha256->devId != INVALID_DEVID)
1476
168
        #endif
1477
168
        {
1478
168
            ret = wc_CryptoCb_Sha256Hash(sha256, NULL, 0, hash);
1479
168
            if (ret != CRYPTOCB_UNAVAILABLE)
1480
0
                return ret;
1481
            /* fall-through when unavailable */
1482
168
        }
1483
15.1k
    #endif
1484
1485
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
1486
        if (sha256->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA256) {
1487
        #if defined(HAVE_INTEL_QA)
1488
            return IntelQaSymSha256(&sha256->asyncDev, hash, NULL,
1489
                                            WC_SHA256_DIGEST_SIZE);
1490
        #endif
1491
        }
1492
    #endif /* WOLFSSL_ASYNC_CRYPT */
1493
1494
15.1k
        ret = Sha256Final(sha256);
1495
15.1k
        if (ret != 0) {
1496
15
            return ret;
1497
15
        }
1498
1499
15.1k
    #if defined(LITTLE_ENDIAN_ORDER)
1500
        #if (defined(CONFIG_IDF_TARGET_ESP32C3) || defined(CONFIG_IDF_TARGET_ESP32C6))  && \
1501
            defined(WOLFSSL_ESP32_CRYPT) && \
1502
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1503
           !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1504
            if (esp_sha_need_byte_reversal(&sha256->ctx))
1505
        #endif
1506
15.1k
            {
1507
15.1k
                ByteReverseWords(sha256->digest, sha256->digest,
1508
15.1k
                                 WC_SHA256_DIGEST_SIZE);
1509
15.1k
            }
1510
15.1k
    #endif
1511
15.1k
        XMEMCPY(hash, sha256->digest, WC_SHA256_DIGEST_SIZE);
1512
1513
15.1k
        return InitSha256(sha256);  /* reset state */
1514
15.1k
    }
1515
1516
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
1517
/* Apply SHA256 transformation to the data                */
1518
/* @param sha  a pointer to wc_Sha256 structure           */
1519
/* @param data data to be applied SHA256 transformation   */
1520
/* @return 0 on successful, otherwise non-zero on failure */
1521
    int wc_Sha256Transform(wc_Sha256* sha, const unsigned char* data)
1522
    {
1523
        if (sha == NULL || data == NULL) {
1524
            return BAD_FUNC_ARG;
1525
        }
1526
        return (Transform_Sha256(sha, data));
1527
    }
1528
    #endif
1529
#endif /* OPENSSL_EXTRA */
1530
1531
#endif /* !WOLFSSL_KCAPI_HASH */
1532
1533
1534
#ifdef WOLFSSL_SHA224
1535
1536
#ifdef STM32_HASH_SHA2
1537
1538
    /* Supports CubeMX HAL or Standard Peripheral Library */
1539
1540
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
1541
    {
1542
        if (sha224 == NULL)
1543
            return BAD_FUNC_ARG;
1544
        (void)devId;
1545
        (void)heap;
1546
1547
        XMEMSET(sha224, 0, sizeof(wc_Sha224));
1548
        wc_Stm32_Hash_Init(&sha224->stmCtx);
1549
        return 0;
1550
    }
1551
1552
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
1553
    {
1554
        int ret = 0;
1555
1556
        if (sha224 == NULL || (data == NULL && len > 0)) {
1557
            return BAD_FUNC_ARG;
1558
        }
1559
1560
        ret = wolfSSL_CryptHwMutexLock();
1561
        if (ret == 0) {
1562
            ret = wc_Stm32_Hash_Update(&sha224->stmCtx,
1563
                HASH_AlgoSelection_SHA224, data, len, WC_SHA224_BLOCK_SIZE);
1564
            wolfSSL_CryptHwMutexUnLock();
1565
        }
1566
        return ret;
1567
    }
1568
1569
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
1570
    {
1571
        int ret = 0;
1572
1573
        if (sha224 == NULL || hash == NULL) {
1574
            return BAD_FUNC_ARG;
1575
        }
1576
1577
        ret = wolfSSL_CryptHwMutexLock();
1578
        if (ret == 0) {
1579
            ret = wc_Stm32_Hash_Final(&sha224->stmCtx,
1580
                HASH_AlgoSelection_SHA224, hash, WC_SHA224_DIGEST_SIZE);
1581
            wolfSSL_CryptHwMutexUnLock();
1582
        }
1583
1584
        (void)wc_InitSha224(sha224); /* reset state */
1585
1586
        return ret;
1587
    }
1588
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
1589
1590
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
1591
    {
1592
        if (sha224 == NULL) {
1593
            return BAD_FUNC_ARG;
1594
        }
1595
        (void)devId;
1596
1597
        return se050_hash_init(&sha224->se050Ctx, heap);
1598
    }
1599
1600
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
1601
    {
1602
        return se050_hash_update(&sha224->se050Ctx, data, len);
1603
    }
1604
1605
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
1606
    {
1607
        int ret = 0;
1608
        ret = se050_hash_final(&sha224->se050Ctx, hash, WC_SHA224_DIGEST_SIZE,
1609
                               kAlgorithm_SSS_SHA224);
1610
        (void)wc_InitSha224(sha224);
1611
        return ret;
1612
    }
1613
1614
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
1615
    !defined(WOLFSSL_QNX_CAAM)
1616
    /* functions defined in wolfcrypt/src/port/caam/caam_sha256.c */
1617
1618
#elif defined(WOLFSSL_AFALG_HASH)
1619
    #error SHA224 currently not supported with AF_ALG enabled
1620
1621
#elif defined(WOLFSSL_DEVCRYPTO_HASH)
1622
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
1623
1624
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
1625
    /* implemented in wolfcrypt/src/port/silabs/silabs_hash.c */
1626
1627
#elif defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224)
1628
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
1629
1630
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
1631
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
1632
1633
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
1634
1635
/* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
1636
1637
#elif defined(WOLFSSL_RENESAS_RSIP) && \
1638
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
1639
1640
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
1641
1642
#else
1643
1644
    #define NEED_SOFT_SHA224
1645
1646
1647
    static int InitSha224(wc_Sha224* sha224)
1648
460
    {
1649
460
        int ret = 0;
1650
1651
460
        if (sha224 == NULL) {
1652
0
            return BAD_FUNC_ARG;
1653
0
        }
1654
1655
460
        sha224->digest[0] = 0xc1059ed8;
1656
460
        sha224->digest[1] = 0x367cd507;
1657
460
        sha224->digest[2] = 0x3070dd17;
1658
460
        sha224->digest[3] = 0xf70e5939;
1659
460
        sha224->digest[4] = 0xffc00b31;
1660
460
        sha224->digest[5] = 0x68581511;
1661
460
        sha224->digest[6] = 0x64f98fa7;
1662
460
        sha224->digest[7] = 0xbefa4fa4;
1663
1664
460
        sha224->buffLen = 0;
1665
460
        sha224->loLen   = 0;
1666
460
        sha224->hiLen   = 0;
1667
1668
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1669
                          (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1670
        /* choose best Transform function under this runtime environment */
1671
        Sha256_SetTransform();
1672
    #endif
1673
460
    #ifdef WOLFSSL_HASH_FLAGS
1674
460
        sha224->flags = 0;
1675
460
    #endif
1676
    #ifdef WOLFSSL_HASH_KEEP
1677
        sha224->msg  = NULL;
1678
        sha224->len  = 0;
1679
        sha224->used = 0;
1680
    #endif
1681
1682
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1683
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
1684
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
1685
        /* not to be confused with SHAS512_224 */
1686
        ret = esp_sha_init(&(sha224->ctx), WC_HASH_TYPE_SHA224);
1687
    #endif
1688
1689
460
        return ret;
1690
460
    }
1691
1692
#endif
1693
1694
#ifdef NEED_SOFT_SHA224
1695
    int wc_InitSha224_ex(wc_Sha224* sha224, void* heap, int devId)
1696
195
    {
1697
195
        int ret = 0;
1698
1699
195
        if (sha224 == NULL)
1700
0
            return BAD_FUNC_ARG;
1701
1702
195
        sha224->heap = heap;
1703
    #ifdef WOLFSSL_SMALL_STACK_CACHE
1704
        sha224->W = NULL;
1705
    #endif
1706
1707
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)
1708
        #if defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224)
1709
        /* We know this is a fresh, uninitialized item, so set to INIT */
1710
        if (sha224->ctx.mode != ESP32_SHA_SW) {
1711
            ESP_LOGV(TAG, "Set sha224 ctx mode init to ESP32_SHA_SW. "
1712
                          "Prior value: %d", sha224->ctx.mode);
1713
        }
1714
        /* no sha224 HW support is available, set to SW */
1715
            sha224->ctx.mode = ESP32_SHA_SW;
1716
        #else
1717
            /* We know this is a fresh, uninitialized item, so set to INIT */
1718
            sha224->ctx.mode = ESP32_SHA_INIT;
1719
        #endif
1720
    #endif
1721
1722
195
        ret = InitSha224(sha224);
1723
195
        if (ret != 0) {
1724
0
            return ret;
1725
0
        }
1726
1727
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
1728
        ret = wolfAsync_DevCtxInit(&sha224->asyncDev,
1729
                            WOLFSSL_ASYNC_MARKER_SHA224, sha224->heap, devId);
1730
    #else
1731
195
        (void)devId;
1732
195
    #endif /* WOLFSSL_ASYNC_CRYPT */
1733
#ifdef WOLFSSL_IMXRT1170_CAAM
1734
     ret = wc_CAAM_HashInit(&sha224->hndl, &sha224->ctx, WC_HASH_TYPE_SHA224);
1735
#endif
1736
1737
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1738
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
1739
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
1740
        if (sha224->ctx.mode != ESP32_SHA_INIT) {
1741
            ESP_LOGV("SHA224", "Set ctx mode from prior value: "
1742
                               "%d", sha224->ctx.mode);
1743
        }
1744
        /* We know this is a fresh, uninitialized item, so set to INIT */
1745
        sha224->ctx.mode = ESP32_SHA_INIT;
1746
    #endif
1747
1748
195
        return ret;
1749
195
    }
1750
1751
    int wc_Sha224Update(wc_Sha224* sha224, const byte* data, word32 len)
1752
6.61k
    {
1753
6.61k
        int ret;
1754
1755
6.61k
        if (sha224 == NULL || (data == NULL && len > 0)) {
1756
0
            return BAD_FUNC_ARG;
1757
0
        }
1758
1759
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
1760
        if (sha224->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA224) {
1761
        #if defined(HAVE_INTEL_QA)
1762
            return IntelQaSymSha224(&sha224->asyncDev, NULL, data, len);
1763
        #endif
1764
        }
1765
    #endif /* WOLFSSL_ASYNC_CRYPT */
1766
1767
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1768
       (defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
1769
        defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
1770
        sha224->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
1771
    #endif
1772
1773
6.61k
        ret = Sha256Update((wc_Sha256*)sha224, data, len);
1774
1775
6.61k
        return ret;
1776
6.61k
    }
1777
1778
    int wc_Sha224Final(wc_Sha224* sha224, byte* hash)
1779
275
    {
1780
275
        int ret;
1781
1782
275
        if (sha224 == NULL || hash == NULL) {
1783
0
            return BAD_FUNC_ARG;
1784
0
        }
1785
1786
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
1787
        if (sha224->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA224) {
1788
        #if defined(HAVE_INTEL_QA)
1789
            return IntelQaSymSha224(&sha224->asyncDev, hash, NULL,
1790
                                            WC_SHA224_DIGEST_SIZE);
1791
        #endif
1792
        }
1793
    #endif /* WOLFSSL_ASYNC_CRYPT */
1794
1795
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1796
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
1797
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
1798
1799
        /* nothing enabled here for C3 success */
1800
    #endif
1801
1802
275
        ret = Sha256Final((wc_Sha256*)sha224);
1803
275
        if (ret != 0)
1804
10
            return ret;
1805
1806
265
    #if defined(LITTLE_ENDIAN_ORDER)
1807
        #if (defined(CONFIG_IDF_TARGET_ESP32C3) || \
1808
             defined(CONFIG_IDF_TARGET_ESP32C6))  && \
1809
            defined(WOLFSSL_ESP32_CRYPT) && \
1810
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
1811
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
1812
            if (esp_sha_need_byte_reversal(&sha224->ctx))
1813
        #endif
1814
265
        {
1815
265
            ByteReverseWords(sha224->digest,
1816
265
                             sha224->digest,
1817
265
                             WC_SHA224_DIGEST_SIZE);
1818
265
        }
1819
265
    #endif
1820
265
        XMEMCPY(hash, sha224->digest, WC_SHA224_DIGEST_SIZE);
1821
1822
265
        return InitSha224(sha224);  /* reset state */
1823
275
    }
1824
#endif /* end of SHA224 software implementation */
1825
1826
    int wc_InitSha224(wc_Sha224* sha224)
1827
111
    {
1828
111
        int devId = INVALID_DEVID;
1829
1830
111
    #ifdef WOLF_CRYPTO_CB
1831
111
        devId = wc_CryptoCb_DefaultDevID();
1832
111
    #endif
1833
111
        return wc_InitSha224_ex(sha224, NULL, devId);
1834
111
    }
1835
1836
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
1837
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
1838
1839
    void wc_Sha224Free(wc_Sha224* sha224)
1840
195
    {
1841
195
        if (sha224 == NULL)
1842
0
            return;
1843
1844
#ifdef WOLFSSL_SMALL_STACK_CACHE
1845
        if (sha224->W != NULL) {
1846
            ForceZero(sha224->W, sizeof(word32) * WC_SHA224_BLOCK_SIZE);
1847
            XFREE(sha224->W, NULL, DYNAMIC_TYPE_DIGEST);
1848
            sha224->W = NULL;
1849
        }
1850
#endif
1851
1852
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
1853
        wolfAsync_DevCtxFree(&sha224->asyncDev, WOLFSSL_ASYNC_MARKER_SHA224);
1854
    #endif /* WOLFSSL_ASYNC_CRYPT */
1855
1856
    #ifdef WOLFSSL_PIC32MZ_HASH
1857
        wc_Sha256Pic32Free(sha224);
1858
    #endif
1859
    #if defined(WOLFSSL_KCAPI_HASH)
1860
        KcapiHashFree(&sha224->kcapi);
1861
    #endif
1862
    #if defined(WOLFSSL_RENESAS_RX64_HASH)
1863
        if (sha224->msg != NULL) {
1864
            ForceZero(sha224->msg, sha224->len);
1865
            XFREE(sha224->msg, sha224->heap, DYNAMIC_TYPE_TMP_BUFFER);
1866
            sha224->msg = NULL;
1867
        }
1868
    #endif
1869
195
        ForceZero(sha224, sizeof(*sha224));
1870
195
    }
1871
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)  */
1872
#endif /*  WOLFSSL_SHA224 */
1873
1874
1875
int wc_InitSha256(wc_Sha256* sha256)
1876
57
{
1877
57
    int devId = INVALID_DEVID;
1878
1879
57
#ifdef WOLF_CRYPTO_CB
1880
57
    devId = wc_CryptoCb_DefaultDevID();
1881
57
#endif
1882
57
    return wc_InitSha256_ex(sha256, NULL, devId);
1883
57
}
1884
1885
#if !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH)
1886
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
1887
1888
void wc_Sha256Free(wc_Sha256* sha256)
1889
15.0k
{
1890
15.0k
    if (sha256 == NULL)
1891
0
        return;
1892
1893
#if defined(WOLFSSL_ESP32) && \
1894
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1895
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1896
    esp_sha_release_unfinished_lock(&sha256->ctx);
1897
#endif
1898
1899
#ifdef WOLFSSL_SMALL_STACK_CACHE
1900
    if (sha256->W != NULL) {
1901
        ForceZero(sha256->W, sizeof(word32) * WC_SHA256_BLOCK_SIZE);
1902
        XFREE(sha256->W, NULL, DYNAMIC_TYPE_DIGEST);
1903
        sha256->W = NULL;
1904
    }
1905
#endif
1906
1907
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
1908
    wolfAsync_DevCtxFree(&sha256->asyncDev, WOLFSSL_ASYNC_MARKER_SHA256);
1909
#endif /* WOLFSSL_ASYNC_CRYPT */
1910
#ifdef WOLFSSL_PIC32MZ_HASH
1911
    wc_Sha256Pic32Free(sha256);
1912
#endif
1913
#if defined(WOLFSSL_AFALG_HASH)
1914
    if (sha256->alFd > 0) {
1915
        close(sha256->alFd);
1916
        sha256->alFd = -1; /* avoid possible double close on socket */
1917
    }
1918
    if (sha256->rdFd > 0) {
1919
        close(sha256->rdFd);
1920
        sha256->rdFd = -1; /* avoid possible double close on socket */
1921
    }
1922
#endif /* WOLFSSL_AFALG_HASH */
1923
#ifdef WOLFSSL_DEVCRYPTO_HASH
1924
    wc_DevCryptoFree(&sha256->ctx);
1925
#endif /* WOLFSSL_DEVCRYPTO */
1926
#if (defined(WOLFSSL_AFALG_HASH) && defined(WOLFSSL_AFALG_HASH_KEEP)) || \
1927
    (defined(WOLFSSL_DEVCRYPTO_HASH) && defined(WOLFSSL_DEVCRYPTO_HASH_KEEP)) || \
1928
    ((defined(WOLFSSL_RENESAS_TSIP_TLS) || \
1929
      defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
1930
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)) || \
1931
    (defined(WOLFSSL_RENESAS_SCEPROTECT) && \
1932
    !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)) || \
1933
    defined(WOLFSSL_RENESAS_RX64_HASH) || \
1934
    defined(WOLFSSL_HASH_KEEP)
1935
1936
    if (sha256->msg != NULL) {
1937
        ForceZero(sha256->msg, sha256->len);
1938
        XFREE(sha256->msg, sha256->heap, DYNAMIC_TYPE_TMP_BUFFER);
1939
        sha256->msg = NULL;
1940
    }
1941
#endif
1942
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
1943
    se050_hash_free(&sha256->se050Ctx);
1944
#endif
1945
#if defined(WOLFSSL_KCAPI_HASH)
1946
    KcapiHashFree(&sha256->kcapi);
1947
#endif
1948
#ifdef WOLFSSL_IMXRT_DCP
1949
    DCPSha256Free(sha256);
1950
#endif
1951
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
1952
    wc_MAXQ10XX_Sha256Free(sha256);
1953
#endif
1954
1955
#ifdef HAVE_ARIA
1956
    if (sha256->hSession != NULL) {
1957
        MC_CloseSession(sha256->hSession);
1958
        sha256->hSession = NULL;
1959
    }
1960
#endif
1961
1962
/* Espressif embedded hardware acceleration specific: */
1963
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1964
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH) && \
1965
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
1966
    if (sha256->ctx.lockDepth > 0) {
1967
        /* probably due to unclean shutdown, error, or other problem.
1968
         *
1969
         * if you find yourself here, code needs to be cleaned up to
1970
         * properly release hardware. this init is only for handling
1971
         * the unexpected. by the time free is called, the hardware
1972
         * should have already been released (lockDepth = 0)
1973
         */
1974
        (void)InitSha256(sha256); /* unlock mutex, set mode to ESP32_SHA_INIT */
1975
        ESP_LOGV(TAG, "Alert: hardware unlock needed in wc_Sha256Free.");
1976
    }
1977
    else {
1978
        ESP_LOGV(TAG, "Hardware unlock not needed in wc_Sha256Free.");
1979
    }
1980
#endif
1981
15.0k
    ForceZero(sha256, sizeof(*sha256));
1982
15.0k
} /* wc_Sha256Free */
1983
1984
#endif /* !defined(WOLFSSL_HAVE_PSA) || defined(WOLFSSL_PSA_NO_HASH) */
1985
#ifdef WOLFSSL_HASH_KEEP
1986
/* Some hardware have issues with update, this function stores the data to be
1987
 * hashed into an array. Once ready, the Final operation is called on all of the
1988
 * data to be hashed at once.
1989
 * returns 0 on success
1990
 */
1991
int wc_Sha256_Grow(wc_Sha256* sha256, const byte* in, int inSz)
1992
{
1993
    return _wc_Hash_Grow(&(sha256->msg), &(sha256->used), &(sha256->len), in,
1994
                        inSz, sha256->heap);
1995
}
1996
#ifdef WOLFSSL_SHA224
1997
int wc_Sha224_Grow(wc_Sha224* sha224, const byte* in, int inSz)
1998
{
1999
    return _wc_Hash_Grow(&(sha224->msg), &(sha224->used), &(sha224->len), in,
2000
                        inSz, sha224->heap);
2001
}
2002
#endif /* WOLFSSL_SHA224 */
2003
#endif /* WOLFSSL_HASH_KEEP */
2004
2005
#endif /* !WOLFSSL_TI_HASH */
2006
2007
2008
#ifndef WOLFSSL_TI_HASH
2009
#if !defined(WOLFSSL_RENESAS_RX64_HASH) && \
2010
    (!defined(WOLFSSL_RENESAS_RSIP) || \
2011
      defined(NO_WOLFSSL_RENESAS_FSPSM_HASH))
2012
#ifdef WOLFSSL_SHA224
2013
2014
#if defined(WOLFSSL_KCAPI_HASH) && !defined(WOLFSSL_NO_KCAPI_SHA224)
2015
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2016
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
2017
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
2018
2019
#else
2020
2021
    int wc_Sha224GetHash(wc_Sha224* sha224, byte* hash)
2022
0
    {
2023
0
        int ret;
2024
0
    #ifdef WOLFSSL_SMALL_STACK
2025
0
        wc_Sha224* tmpSha224;
2026
    #else
2027
        wc_Sha224  tmpSha224[1];
2028
    #endif
2029
2030
0
        if (sha224 == NULL || hash == NULL) {
2031
0
            return BAD_FUNC_ARG;
2032
0
        }
2033
2034
0
    #ifdef WOLFSSL_SMALL_STACK
2035
0
        tmpSha224 = (wc_Sha224*)XMALLOC(sizeof(wc_Sha224), NULL,
2036
0
            DYNAMIC_TYPE_TMP_BUFFER);
2037
0
        if (tmpSha224 == NULL) {
2038
0
            return MEMORY_E;
2039
0
        }
2040
0
    #endif
2041
2042
0
        ret = wc_Sha224Copy(sha224, tmpSha224);
2043
0
        if (ret == 0) {
2044
0
            ret = wc_Sha224Final(tmpSha224, hash);
2045
0
            wc_Sha224Free(tmpSha224);
2046
0
        }
2047
2048
0
    #ifdef WOLFSSL_SMALL_STACK
2049
0
        XFREE(tmpSha224, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2050
0
    #endif
2051
0
        return ret;
2052
0
    }
2053
2054
    int wc_Sha224Copy(wc_Sha224* src, wc_Sha224* dst)
2055
6
    {
2056
6
        int ret = 0; /* assume success unless proven otherwise */
2057
2058
6
        if (src == NULL || dst == NULL) {
2059
0
            return BAD_FUNC_ARG;
2060
0
        }
2061
2062
6
        XMEMCPY(dst, src, sizeof(wc_Sha224));
2063
2064
    #ifdef WOLFSSL_SMALL_STACK_CACHE
2065
        dst->W = NULL;
2066
    #endif
2067
2068
    #if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3)
2069
        dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
2070
        dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
2071
    #endif
2072
2073
    #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA224)
2074
        ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
2075
    #endif
2076
2077
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2078
       (!defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256) || \
2079
        !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA224))
2080
        /* regardless of any other settings, there's no SHA-224 HW on ESP32 */
2081
        #ifndef CONFIG_IDF_TARGET_ESP32
2082
            ret = esp_sha224_ctx_copy(src, dst);
2083
        #endif
2084
    #endif
2085
2086
6
    #ifdef WOLFSSL_HASH_FLAGS
2087
6
        dst->flags |= WC_HASH_FLAG_ISCOPY;
2088
6
    #endif
2089
2090
    #if defined(WOLFSSL_HASH_KEEP)
2091
        if (src->msg != NULL) {
2092
            dst->msg = (byte*)XMALLOC(src->len, dst->heap,
2093
                                      DYNAMIC_TYPE_TMP_BUFFER);
2094
            if (dst->msg == NULL)
2095
                return MEMORY_E;
2096
            XMEMCPY(dst->msg, src->msg, src->len);
2097
        }
2098
    #endif
2099
2100
6
        return ret;
2101
6
    }
2102
2103
#endif /* WOLFSSL_KCAPI_HASH && !WOLFSSL_NO_KCAPI_SHA224 */
2104
2105
#ifdef WOLFSSL_HASH_FLAGS
2106
    int wc_Sha224SetFlags(wc_Sha224* sha224, word32 flags)
2107
0
    {
2108
0
        if (sha224) {
2109
0
            sha224->flags = flags;
2110
0
        }
2111
0
        return 0;
2112
0
    }
2113
    int wc_Sha224GetFlags(wc_Sha224* sha224, word32* flags)
2114
0
    {
2115
0
        if (sha224 && flags) {
2116
0
            *flags = sha224->flags;
2117
0
        }
2118
0
        return 0;
2119
0
    }
2120
#endif
2121
2122
#endif /* WOLFSSL_SHA224 */
2123
#endif /* WOLFSSL_RENESAS_RX64_HASH */
2124
2125
#ifdef WOLFSSL_AFALG_HASH
2126
    /* implemented in wolfcrypt/src/port/af_alg/afalg_hash.c */
2127
2128
#elif defined(WOLFSSL_DEVCRYPTO_HASH)
2129
    /* implemented in wolfcrypt/src/port/devcrypto/devcrypt_hash.c */
2130
2131
#elif (defined(WOLFSSL_RENESAS_TSIP_TLS) || \
2132
       defined(WOLFSSL_RENESAS_TSIP_CRYPTONLY)) && \
2133
    !defined(NO_WOLFSSL_RENESAS_TSIP_CRYPT_HASH)
2134
2135
    /* implemented in wolfcrypt/src/port/Renesas/renesas_tsip_sha.c */
2136
2137
#elif (defined(WOLFSSL_RENESAS_SCEPROTECT) || defined(WOLFSSL_RENESAS_RSIP))\
2138
     && !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2139
2140
    /* implemented in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2141
2142
#elif defined(WOLFSSL_PSOC6_CRYPTO)
2143
    /* implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */
2144
#elif defined(WOLFSSL_IMXRT_DCP)
2145
    /* implemented in wolfcrypt/src/port/nxp/dcp_port.c */
2146
#elif defined(WOLFSSL_KCAPI_HASH)
2147
    /* implemented in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2148
2149
#elif defined(WOLFSSL_HAVE_PSA) && !defined(WOLFSSL_PSA_NO_HASH)
2150
    /* implemented in wolfcrypt/src/port/psa/psa_hash.c */
2151
#elif defined(WOLFSSL_RENESAS_RX64_HASH)
2152
    /* implemented in wolfcrypt/src/port/Renesas/renesas_rx64_hw_sha.c */
2153
2154
#else
2155
2156
int wc_Sha256GetHash(wc_Sha256* sha256, byte* hash)
2157
0
{
2158
0
    int ret;
2159
0
#ifdef WOLFSSL_SMALL_STACK
2160
0
    wc_Sha256* tmpSha256;
2161
#else
2162
    wc_Sha256  tmpSha256[1];
2163
#endif
2164
2165
0
    if (sha256 == NULL || hash == NULL) {
2166
0
        return BAD_FUNC_ARG;
2167
0
    }
2168
2169
0
#ifdef WOLFSSL_SMALL_STACK
2170
0
    tmpSha256 = (wc_Sha256*)XMALLOC(sizeof(wc_Sha256), NULL,
2171
0
        DYNAMIC_TYPE_TMP_BUFFER);
2172
0
    if (tmpSha256 == NULL) {
2173
0
        return MEMORY_E;
2174
0
    }
2175
0
#endif
2176
2177
0
    ret = wc_Sha256Copy(sha256, tmpSha256);
2178
0
    if (ret == 0) {
2179
0
        ret = wc_Sha256Final(tmpSha256, hash);
2180
0
        wc_Sha256Free(tmpSha256); /* TODO move outside brackets? */
2181
0
    }
2182
2183
2184
0
#ifdef WOLFSSL_SMALL_STACK
2185
0
    XFREE(tmpSha256, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2186
0
#endif
2187
2188
0
    return ret;
2189
0
}
2190
int wc_Sha256Copy(wc_Sha256* src, wc_Sha256* dst)
2191
8
{
2192
8
    int ret = 0;
2193
2194
8
    if (src == NULL || dst == NULL) {
2195
0
        return BAD_FUNC_ARG;
2196
0
    }
2197
2198
8
    XMEMCPY(dst, src, sizeof(wc_Sha256));
2199
2200
#ifdef WOLFSSL_MAXQ10XX_CRYPTO
2201
    wc_MAXQ10XX_Sha256Copy(src);
2202
#endif
2203
2204
#ifdef WOLFSSL_SMALL_STACK_CACHE
2205
    dst->W = NULL;
2206
#endif
2207
2208
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3)
2209
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
2210
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
2211
#endif
2212
2213
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA256)
2214
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
2215
#endif
2216
2217
#ifdef WOLFSSL_PIC32MZ_HASH
2218
    ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
2219
#endif
2220
2221
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2222
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA256)
2223
    esp_sha256_ctx_copy(src, dst);
2224
#endif
2225
2226
#ifdef HAVE_ARIA
2227
    dst->hSession = NULL;
2228
    if((src->hSession != NULL) && (MC_CopySession(src->hSession, &(dst->hSession)) != MC_OK)) {
2229
        return MEMORY_E;
2230
    }
2231
#endif
2232
2233
8
#ifdef WOLFSSL_HASH_FLAGS
2234
8
     dst->flags |= WC_HASH_FLAG_ISCOPY;
2235
8
#endif
2236
2237
#if defined(WOLFSSL_HASH_KEEP)
2238
    if (src->msg != NULL) {
2239
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
2240
        if (dst->msg == NULL)
2241
            return MEMORY_E;
2242
        XMEMCPY(dst->msg, src->msg, src->len);
2243
    }
2244
#endif
2245
2246
8
    return ret;
2247
8
}
2248
#endif
2249
2250
#ifdef WOLFSSL_HASH_FLAGS
2251
int wc_Sha256SetFlags(wc_Sha256* sha256, word32 flags)
2252
0
{
2253
0
    if (sha256) {
2254
0
        sha256->flags = flags;
2255
0
    }
2256
0
    return 0;
2257
0
}
2258
int wc_Sha256GetFlags(wc_Sha256* sha256, word32* flags)
2259
0
{
2260
0
    if (sha256 && flags) {
2261
0
        *flags = sha256->flags;
2262
0
    }
2263
0
    return 0;
2264
0
}
2265
#endif
2266
#endif /* !WOLFSSL_TI_HASH */
2267
2268
#endif /* NO_SHA256 */