Coverage Report

Created: 2023-06-07 06:14

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