Coverage Report

Created: 2026-05-18 06:53

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