Coverage Report

Created: 2025-07-04 06:22

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