Coverage Report

Created: 2025-07-23 06:53

/src/wolfssl/wolfcrypt/src/sha512.c
Line
Count
Source (jump to first uncovered line)
1
/* sha512.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 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
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) && \
25
    (!defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_ARMASM_NO_NEON)) && \
26
    !defined(WOLFSSL_PSOC6_CRYPTO) && !defined(WOLFSSL_RISCV_ASM)
27
28
/* determine if we are using Espressif SHA hardware acceleration */
29
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
30
#if defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
31
    #include "sdkconfig.h"
32
    /* Define a single keyword for simplicity & readability.
33
     *
34
     * By default the HW acceleration is on for ESP32 Chipsets,
35
     * but individual components can be turned off. See user_settings.h
36
     */
37
    #define TAG "wc_sha_512"
38
    #define WOLFSSL_USE_ESP32_CRYPT_HASH_HW
39
#else
40
    #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
41
#endif
42
43
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
44
    /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
45
    #define FIPS_NO_WRAPPERS
46
47
    #ifdef USE_WINDOWS_API
48
        #pragma code_seg(".fipsA$m")
49
        #pragma const_seg(".fipsB$m")
50
    #endif
51
#endif
52
53
#include <wolfssl/wolfcrypt/sha512.h>
54
#include <wolfssl/wolfcrypt/cpuid.h>
55
#include <wolfssl/wolfcrypt/hash.h>
56
57
#ifdef WOLF_CRYPTO_CB
58
    #include <wolfssl/wolfcrypt/cryptocb.h>
59
#endif
60
61
#ifdef WOLFSSL_IMXRT1170_CAAM
62
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h>
63
#endif
64
65
/* deprecated USE_SLOW_SHA2 (replaced with USE_SLOW_SHA512) */
66
#if defined(USE_SLOW_SHA2) && !defined(USE_SLOW_SHA512)
67
    #define USE_SLOW_SHA512
68
#endif
69
70
#ifdef NO_INLINE
71
    #include <wolfssl/wolfcrypt/misc.h>
72
#else
73
    #define WOLFSSL_MISC_INCLUDED
74
    #include <wolfcrypt/src/misc.c>
75
#endif
76
77
#if FIPS_VERSION3_GE(6,0,0)
78
    const unsigned int wolfCrypt_FIPS_sha512_ro_sanity[2] =
79
                                                     { 0x1a2b3c4d, 0x00000015 };
80
    int wolfCrypt_FIPS_SHA512_sanity(void)
81
    {
82
        return 0;
83
    }
84
#endif
85
86
87
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
88
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
89
#endif
90
91
#if defined(MAX3266X_SHA)
92
    /* Already brought in by sha512.h */
93
    /* #include <wolfssl/wolfcrypt/port/maxim/max3266x.h> */
94
#endif
95
96
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP)
97
    #if defined(__GNUC__) && ((__GNUC__ < 4) || \
98
                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
99
        #undef  NO_AVX2_SUPPORT
100
        #define NO_AVX2_SUPPORT
101
    #endif
102
    #if defined(__clang__) && ((__clang_major__ < 3) || \
103
                               (__clang_major__ == 3 && __clang_minor__ <= 5))
104
        #define NO_AVX2_SUPPORT
105
    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)
106
        #undef NO_AVX2_SUPPORT
107
    #endif
108
109
    #define HAVE_INTEL_AVX1
110
    #ifndef NO_AVX2_SUPPORT
111
        #define HAVE_INTEL_AVX2
112
    #endif
113
#endif
114
115
#if defined(HAVE_INTEL_AVX1)
116
    /* #define DEBUG_XMM  */
117
#endif
118
119
#if defined(HAVE_INTEL_AVX2)
120
    #define HAVE_INTEL_RORX
121
    /* #define DEBUG_YMM  */
122
#endif
123
124
#if defined(HAVE_BYTEREVERSE64) && \
125
        !defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2)
126
    #define ByteReverseWords64(out, in, size) ByteReverseWords64_1(out, size)
127
    #define ByteReverseWords64_1(buf, size) \
128
        { unsigned int i ;\
129
            for(i=0; i< size/sizeof(word64); i++){\
130
                __asm__ volatile("bswapq %0":"+r"(buf[i])::) ;\
131
            }\
132
        }
133
#endif
134
135
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
136
    !defined(WOLFSSL_QNX_CAAM)
137
    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
138
139
#elif defined(WOLFSSL_SILABS_SHA384)
140
    /* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */
141
142
#elif defined(WOLFSSL_KCAPI_HASH)
143
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
144
145
#elif defined(WOLFSSL_RENESAS_RSIP) && \
146
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
147
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
148
149
#elif defined(MAX3266X_SHA)
150
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
151
152
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
153
    int wc_InitSha512(wc_Sha512* sha512)
154
    {
155
        if (sha512 == NULL)
156
            return BAD_FUNC_ARG;
157
        return se050_hash_init(&sha512->se050Ctx, NULL);
158
    }
159
    int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
160
    {
161
        if (sha512 == NULL) {
162
            return BAD_FUNC_ARG;
163
        }
164
        (void)devId;
165
        return se050_hash_init(&sha512->se050Ctx, heap);
166
    }
167
    int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
168
    {
169
        if (sha512 == NULL) {
170
            return BAD_FUNC_ARG;
171
        }
172
        if (data == NULL && len == 0) {
173
            /* valid, but do nothing */
174
            return 0;
175
        }
176
        if (data == NULL) {
177
            return BAD_FUNC_ARG;
178
        }
179
180
        return se050_hash_update(&sha512->se050Ctx, data, len);
181
    }
182
    int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
183
    {
184
        int ret = 0;
185
        int devId = INVALID_DEVID;
186
        if (sha512 == NULL) {
187
            return BAD_FUNC_ARG;
188
        }
189
    #ifdef WOLF_CRYPTO_CB
190
        devId = sha512->devId;
191
    #endif
192
        ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE,
193
                               kAlgorithm_SSS_SHA512);
194
        return ret;
195
    }
196
    int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
197
    {
198
        int ret = 0;
199
        int devId = INVALID_DEVID;
200
        if (sha512 == NULL) {
201
            return BAD_FUNC_ARG;
202
        }
203
    #ifdef WOLF_CRYPTO_CB
204
        devId = sha512->devId;
205
    #endif
206
        ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE,
207
                               kAlgorithm_SSS_SHA512);
208
        return ret;
209
    }
210
    void wc_Sha512Free(wc_Sha512* sha512)
211
    {
212
        se050_hash_free(&sha512->se050Ctx);
213
    }
214
#elif defined(STM32_HASH_SHA512)
215
216
    /* Supports CubeMX HAL or Standard Peripheral Library */
217
218
    int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
219
    {
220
        if (sha512 == NULL)
221
            return BAD_FUNC_ARG;
222
223
        (void)devId;
224
        (void)heap;
225
226
        XMEMSET(sha512, 0, sizeof(wc_Sha512));
227
        wc_Stm32_Hash_Init(&sha512->stmCtx);
228
        return 0;
229
    }
230
231
    int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
232
    {
233
        int ret = 0;
234
235
        if (sha512 == NULL) {
236
            return BAD_FUNC_ARG;
237
        }
238
        if (data == NULL && len == 0) {
239
            /* valid, but do nothing */
240
            return 0;
241
        }
242
        if (data == NULL) {
243
            return BAD_FUNC_ARG;
244
        }
245
246
        ret = wolfSSL_CryptHwMutexLock();
247
        if (ret == 0) {
248
            ret = wc_Stm32_Hash_Update(&sha512->stmCtx,
249
                HASH_ALGOSELECTION_SHA512, data, len, WC_SHA512_BLOCK_SIZE);
250
            wolfSSL_CryptHwMutexUnLock();
251
        }
252
        return ret;
253
    }
254
255
    int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
256
    {
257
        int ret = 0;
258
259
        if (sha512 == NULL || hash == NULL) {
260
            return BAD_FUNC_ARG;
261
        }
262
263
        ret = wolfSSL_CryptHwMutexLock();
264
        if (ret == 0) {
265
            ret = wc_Stm32_Hash_Final(&sha512->stmCtx,
266
                HASH_ALGOSELECTION_SHA512, hash, WC_SHA512_DIGEST_SIZE);
267
            wolfSSL_CryptHwMutexUnLock();
268
        }
269
270
        (void)wc_InitSha512(sha512); /* reset state */
271
272
        return ret;
273
    }
274
275
#else
276
277
#ifdef WOLFSSL_SHA512
278
279
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
280
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
281
#ifdef WC_C_DYNAMIC_FALLBACK
282
    #define SHA512_SETTRANSFORM_ARGS int *sha_method
283
#else
284
    #define SHA512_SETTRANSFORM_ARGS void
285
#endif
286
static void Sha512_SetTransform(SHA512_SETTRANSFORM_ARGS);
287
#endif
288
289
static int InitSha512(wc_Sha512* sha512)
290
0
{
291
0
    if (sha512 == NULL)
292
0
        return BAD_FUNC_ARG;
293
294
0
    sha512->digest[0] = W64LIT(0x6a09e667f3bcc908);
295
0
    sha512->digest[1] = W64LIT(0xbb67ae8584caa73b);
296
0
    sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b);
297
0
    sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1);
298
0
    sha512->digest[4] = W64LIT(0x510e527fade682d1);
299
0
    sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f);
300
0
    sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b);
301
0
    sha512->digest[7] = W64LIT(0x5be0cd19137e2179);
302
303
0
    sha512->buffLen = 0;
304
0
    sha512->loLen   = 0;
305
0
    sha512->hiLen   = 0;
306
307
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
308
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
309
#ifdef WC_C_DYNAMIC_FALLBACK
310
    sha512->sha_method = 0;
311
    Sha512_SetTransform(&sha512->sha_method);
312
#else
313
    Sha512_SetTransform();
314
#endif
315
#endif
316
317
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
318
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
319
320
    /* HW needs to be carefully initialized, taking into account soft copy.
321
    ** If already in use; copy may revert to SW as needed. */
322
    esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512);
323
#endif
324
325
#ifdef WOLFSSL_HASH_FLAGS
326
    sha512->flags = 0;
327
#endif
328
0
    return 0;
329
0
}
330
331
#if !defined(WOLFSSL_NOSHA512_224) && \
332
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
333
334
/**
335
 * Initialize given wc_Sha512 structure with value specific to sha512/224.
336
 * Note that sha512/224 has different initial hash value from sha512.
337
 * The initial hash value consists of eight 64bit words. They are given
338
 * in FIPS180-4.
339
 */
340
static int InitSha512_224(wc_Sha512* sha512)
341
0
{
342
0
    if (sha512 == NULL)
343
0
        return BAD_FUNC_ARG;
344
345
0
    sha512->digest[0] = W64LIT(0x8c3d37c819544da2);
346
0
    sha512->digest[1] = W64LIT(0x73e1996689dcd4d6);
347
0
    sha512->digest[2] = W64LIT(0x1dfab7ae32ff9c82);
348
0
    sha512->digest[3] = W64LIT(0x679dd514582f9fcf);
349
0
    sha512->digest[4] = W64LIT(0x0f6d2b697bd44da8);
350
0
    sha512->digest[5] = W64LIT(0x77e36f7304c48942);
351
0
    sha512->digest[6] = W64LIT(0x3f9d85a86a1d36c8);
352
0
    sha512->digest[7] = W64LIT(0x1112e6ad91d692a1);
353
354
0
    sha512->buffLen = 0;
355
0
    sha512->loLen   = 0;
356
0
    sha512->hiLen   = 0;
357
358
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
359
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
360
#ifdef WC_C_DYNAMIC_FALLBACK
361
    sha512->sha_method = 0;
362
    Sha512_SetTransform(&sha512->sha_method);
363
#else
364
    Sha512_SetTransform();
365
#endif
366
#endif
367
368
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
369
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
370
    /* HW needs to be carefully initialized, taking into account soft copy.
371
    ** If already in use; copy may revert to SW as needed.
372
    **
373
    ** Note for original ESP32, there's no HW for SHA512/224
374
    */
375
    esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_224);
376
#endif
377
378
#ifdef WOLFSSL_HASH_FLAGS
379
    sha512->flags = 0;
380
#endif
381
0
    return 0;
382
0
}
383
#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */
384
385
#if !defined(WOLFSSL_NOSHA512_256) && \
386
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
387
/**
388
 * Initialize given wc_Sha512 structure with value specific to sha512/256.
389
 * Note that sha512/256 has different initial hash value from sha512.
390
 * The initial hash value consists of eight 64bit words. They are given
391
 * in FIPS180-4.
392
 */
393
static int InitSha512_256(wc_Sha512* sha512)
394
0
{
395
0
    if (sha512 == NULL)
396
0
        return BAD_FUNC_ARG;
397
398
0
    sha512->digest[0] = W64LIT(0x22312194fc2bf72c);
399
0
    sha512->digest[1] = W64LIT(0x9f555fa3c84c64c2);
400
0
    sha512->digest[2] = W64LIT(0x2393b86b6f53b151);
401
0
    sha512->digest[3] = W64LIT(0x963877195940eabd);
402
0
    sha512->digest[4] = W64LIT(0x96283ee2a88effe3);
403
0
    sha512->digest[5] = W64LIT(0xbe5e1e2553863992);
404
0
    sha512->digest[6] = W64LIT(0x2b0199fc2c85b8aa);
405
0
    sha512->digest[7] = W64LIT(0x0eb72ddc81c52ca2);
406
407
0
    sha512->buffLen = 0;
408
0
    sha512->loLen   = 0;
409
0
    sha512->hiLen   = 0;
410
411
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
412
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
413
#ifdef WC_C_DYNAMIC_FALLBACK
414
    sha512->sha_method = 0;
415
    Sha512_SetTransform(&sha512->sha_method);
416
#else
417
    Sha512_SetTransform();
418
#endif
419
#endif
420
421
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
422
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
423
    /* HW needs to be carefully initialized, taking into account soft copy.
424
    ** If already in use; copy may revert to SW as needed.
425
    **
426
    ** Note for original ESP32, there's no HW for SHA512/2256.
427
    */
428
    esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_256);
429
#endif
430
431
#ifdef WOLFSSL_HASH_FLAGS
432
    sha512->flags = 0;
433
#endif
434
0
    return 0;
435
0
}
436
#endif /* !WOLFSSL_NOSHA512_256 && !FIPS... */
437
438
#endif /* WOLFSSL_SHA512 */
439
440
/* Hardware Acceleration */
441
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
442
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
443
444
    /*****
445
    Intel AVX1/AVX2 Macro Control Structure
446
447
    #if defined(HAVE_INTEL_SPEEDUP)
448
        #define HAVE_INTEL_AVX1
449
        #define HAVE_INTEL_AVX2
450
    #endif
451
452
    int InitSha512(wc_Sha512* sha512) {
453
         Save/Recover XMM, YMM
454
         ...
455
456
         Check Intel AVX cpuid flags
457
    }
458
459
    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
460
      Transform_Sha512_AVX1(); # Function prototype
461
      Transform_Sha512_AVX2(); #
462
    #endif
463
464
      _Transform_Sha512() {     # Native Transform Function body
465
466
      }
467
468
      int Sha512Update() {
469
         Save/Recover XMM, YMM
470
         ...
471
      }
472
473
      int Sha512Final() {
474
         Save/Recover XMM, YMM
475
         ...
476
      }
477
478
479
    #if defined(HAVE_INTEL_AVX1)
480
481
       XMM Instructions/INLINE asm Definitions
482
483
    #endif
484
485
    #if defined(HAVE_INTEL_AVX2)
486
487
       YMM Instructions/INLINE asm Definitions
488
489
    #endif
490
491
    #if defined(HAVE_INTEL_AVX1)
492
493
      int Transform_Sha512_AVX1() {
494
          Stitched Message Sched/Round
495
      }
496
497
    #endif
498
499
    #if defined(HAVE_INTEL_AVX2)
500
501
      int Transform_Sha512_AVX2() {
502
          Stitched Message Sched/Round
503
      }
504
    #endif
505
506
    */
507
508
509
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
510
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
511
     */
512
513
#ifdef __cplusplus
514
    extern "C" {
515
#endif
516
517
    #if defined(HAVE_INTEL_AVX1)
518
        extern int Transform_Sha512_AVX1(wc_Sha512 *sha512);
519
        extern int Transform_Sha512_AVX1_Len(wc_Sha512 *sha512, word32 len);
520
    #endif
521
    #if defined(HAVE_INTEL_AVX2)
522
        extern int Transform_Sha512_AVX2(wc_Sha512 *sha512);
523
        extern int Transform_Sha512_AVX2_Len(wc_Sha512 *sha512, word32 len);
524
        #if defined(HAVE_INTEL_RORX)
525
            extern int Transform_Sha512_AVX1_RORX(wc_Sha512 *sha512);
526
            extern int Transform_Sha512_AVX1_RORX_Len(wc_Sha512 *sha512,
527
                                                      word32 len);
528
            extern int Transform_Sha512_AVX2_RORX(wc_Sha512 *sha512);
529
            extern int Transform_Sha512_AVX2_RORX_Len(wc_Sha512 *sha512,
530
                                                      word32 len);
531
        #endif
532
    #endif
533
534
#ifdef __cplusplus
535
    }  /* extern "C" */
536
#endif
537
538
    static word32 intel_flags = 0;
539
540
#if defined(WC_C_DYNAMIC_FALLBACK) && !defined(WC_NO_INTERNAL_FUNCTION_POINTERS)
541
    #define WC_NO_INTERNAL_FUNCTION_POINTERS
542
#endif
543
544
    static int _Transform_Sha512(wc_Sha512 *sha512);
545
546
#ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
547
548
    enum sha_methods { SHA512_UNSET = 0, SHA512_AVX1, SHA512_AVX2,
549
                       SHA512_AVX1_RORX, SHA512_AVX2_RORX, SHA512_C };
550
551
#ifndef WC_C_DYNAMIC_FALLBACK
552
    /* note that all write access to this static variable must be idempotent,
553
     * as arranged by Sha512_SetTransform(), else it will be susceptible to
554
     * data races.
555
     */
556
    static enum sha_methods sha_method = SHA512_UNSET;
557
#endif
558
559
    static void Sha512_SetTransform(SHA512_SETTRANSFORM_ARGS)
560
    {
561
    #ifdef WC_C_DYNAMIC_FALLBACK
562
        #define SHA_METHOD (*sha_method)
563
    #else
564
        #define SHA_METHOD sha_method
565
    #endif
566
        if (SHA_METHOD != SHA512_UNSET)
567
            return;
568
569
    #ifdef WC_C_DYNAMIC_FALLBACK
570
        if (! CAN_SAVE_VECTOR_REGISTERS()) {
571
            SHA_METHOD = SHA512_C;
572
            return;
573
        }
574
    #endif
575
576
        if (intel_flags == 0)
577
            intel_flags = cpuid_get_flags();
578
579
    #if defined(HAVE_INTEL_AVX2)
580
        if (IS_INTEL_AVX2(intel_flags)) {
581
        #ifdef HAVE_INTEL_RORX
582
            if (IS_INTEL_BMI2(intel_flags)) {
583
                SHA_METHOD = SHA512_AVX2_RORX;
584
            }
585
            else
586
        #endif
587
            {
588
                SHA_METHOD = SHA512_AVX2;
589
            }
590
        }
591
        else
592
    #endif
593
    #if defined(HAVE_INTEL_AVX1)
594
        if (IS_INTEL_AVX1(intel_flags)) {
595
        #ifdef HAVE_INTEL_RORX
596
            if (IS_INTEL_BMI2(intel_flags)) {
597
                SHA_METHOD = SHA512_AVX1_RORX;
598
            }
599
            else
600
        #endif
601
            {
602
                SHA_METHOD = SHA512_AVX1;
603
            }
604
        }
605
        else
606
    #endif
607
        {
608
            SHA_METHOD = SHA512_C;
609
        }
610
    #undef SHA_METHOD
611
    }
612
613
    static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512) {
614
    #ifdef WC_C_DYNAMIC_FALLBACK
615
        #define SHA_METHOD (sha512->sha_method)
616
    #else
617
        #define SHA_METHOD sha_method
618
    #endif
619
        int ret;
620
        if (SHA_METHOD == SHA512_C)
621
            return _Transform_Sha512(sha512);
622
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
623
        switch (SHA_METHOD) {
624
        case SHA512_AVX2:
625
            ret = Transform_Sha512_AVX2(sha512);
626
            break;
627
        case SHA512_AVX2_RORX:
628
            ret = Transform_Sha512_AVX2_RORX(sha512);
629
            break;
630
        case SHA512_AVX1:
631
            ret = Transform_Sha512_AVX1(sha512);
632
            break;
633
        case SHA512_AVX1_RORX:
634
            ret = Transform_Sha512_AVX1_RORX(sha512);
635
            break;
636
        case SHA512_C:
637
        case SHA512_UNSET:
638
        default:
639
            ret = _Transform_Sha512(sha512);
640
            break;
641
        }
642
        RESTORE_VECTOR_REGISTERS();
643
        return ret;
644
    #undef SHA_METHOD
645
    }
646
647
    static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, word32 len) {
648
    #ifdef WC_C_DYNAMIC_FALLBACK
649
        #define SHA_METHOD (sha512->sha_method)
650
    #else
651
        #define SHA_METHOD sha_method
652
    #endif
653
        int ret;
654
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
655
        switch (SHA_METHOD) {
656
        case SHA512_AVX2:
657
            ret = Transform_Sha512_AVX2_Len(sha512, len);
658
            break;
659
        case SHA512_AVX2_RORX:
660
            ret = Transform_Sha512_AVX2_RORX_Len(sha512, len);
661
            break;
662
        case SHA512_AVX1:
663
            ret = Transform_Sha512_AVX1_Len(sha512, len);
664
            break;
665
        case SHA512_AVX1_RORX:
666
            ret = Transform_Sha512_AVX1_RORX_Len(sha512, len);
667
            break;
668
        case SHA512_C:
669
        case SHA512_UNSET:
670
        default:
671
            ret = 0;
672
            break;
673
        }
674
        RESTORE_VECTOR_REGISTERS();
675
        return ret;
676
    #undef SHA_METHOD
677
    }
678
679
#else /* !WC_NO_INTERNAL_FUNCTION_POINTERS */
680
681
    static int (*Transform_Sha512_p)(wc_Sha512* sha512) = _Transform_Sha512;
682
    static int (*Transform_Sha512_Len_p)(wc_Sha512* sha512, word32 len) = NULL;
683
    static int transform_check = 0;
684
    static int Transform_Sha512_is_vectorized = 0;
685
686
    static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512) {
687
        int ret;
688
    #ifdef WOLFSSL_LINUXKM
689
        if (Transform_Sha512_is_vectorized)
690
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
691
    #endif
692
        ret = (*Transform_Sha512_p)(sha512);
693
    #ifdef WOLFSSL_LINUXKM
694
        if (Transform_Sha512_is_vectorized)
695
            RESTORE_VECTOR_REGISTERS();
696
    #endif
697
        return ret;
698
    }
699
    static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, word32 len) {
700
        int ret;
701
    #ifdef WOLFSSL_LINUXKM
702
        if (Transform_Sha512_is_vectorized)
703
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
704
    #endif
705
        ret = (*Transform_Sha512_Len_p)(sha512, len);
706
    #ifdef WOLFSSL_LINUXKM
707
        if (Transform_Sha512_is_vectorized)
708
            RESTORE_VECTOR_REGISTERS();
709
    #endif
710
        return ret;
711
    }
712
713
    static void Sha512_SetTransform(void)
714
    {
715
        if (transform_check)
716
            return;
717
718
        intel_flags = cpuid_get_flags();
719
720
    #if defined(HAVE_INTEL_AVX2)
721
        if (IS_INTEL_AVX2(intel_flags)) {
722
        #ifdef HAVE_INTEL_RORX
723
            if (IS_INTEL_BMI2(intel_flags)) {
724
                Transform_Sha512_p = Transform_Sha512_AVX2_RORX;
725
                Transform_Sha512_Len_p = Transform_Sha512_AVX2_RORX_Len;
726
                Transform_Sha512_is_vectorized = 1;
727
            }
728
            else
729
        #endif
730
            {
731
                Transform_Sha512_p = Transform_Sha512_AVX2;
732
                Transform_Sha512_Len_p = Transform_Sha512_AVX2_Len;
733
                Transform_Sha512_is_vectorized = 1;
734
            }
735
        }
736
        else
737
    #endif
738
    #if defined(HAVE_INTEL_AVX1)
739
        if (IS_INTEL_AVX1(intel_flags)) {
740
        #ifdef HAVE_INTEL_RORX
741
            if (IS_INTEL_BMI2(intel_flags)) {
742
                Transform_Sha512_p = Transform_Sha512_AVX1_RORX;
743
                Transform_Sha512_Len_p = Transform_Sha512_AVX1_RORX_Len;
744
                Transform_Sha512_is_vectorized = 1;
745
            }
746
            else
747
        #endif
748
            {
749
                Transform_Sha512_p = Transform_Sha512_AVX1;
750
                Transform_Sha512_Len_p = Transform_Sha512_AVX1_Len;
751
                Transform_Sha512_is_vectorized = 1;
752
            }
753
        }
754
        else
755
    #endif
756
        {
757
            Transform_Sha512_p = _Transform_Sha512;
758
            Transform_Sha512_Len_p = NULL;
759
            Transform_Sha512_is_vectorized = 0;
760
        }
761
762
        transform_check = 1;
763
    }
764
765
#endif /* !WC_NO_INTERNAL_FUNCTION_POINTERS */
766
767
#else
768
0
    #define Transform_Sha512(sha512) _Transform_Sha512(sha512)
769
770
#endif
771
772
#ifdef WOLFSSL_SHA512
773
774
static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId,
775
                             int (*initfp)(wc_Sha512*))
776
0
{
777
0
    int ret = 0;
778
779
0
    if (sha512 == NULL) {
780
0
        return BAD_FUNC_ARG;
781
0
    }
782
783
784
0
    sha512->heap = heap;
785
#ifdef WOLFSSL_SMALL_STACK_CACHE
786
    sha512->W = NULL;
787
#endif
788
#ifdef WOLF_CRYPTO_CB
789
    sha512->devId = devId;
790
    sha512->devCtx = NULL;
791
#endif
792
793
    /* call the initialization function pointed to by initfp */
794
0
    ret = initfp(sha512);
795
0
    if (ret != 0)
796
0
        return ret;
797
798
#ifdef WOLFSSL_HASH_KEEP
799
    sha512->msg  = NULL;
800
    sha512->len  = 0;
801
    sha512->used = 0;
802
#endif
803
804
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
805
    ret = wolfAsync_DevCtxInit(&sha512->asyncDev,
806
                        WOLFSSL_ASYNC_MARKER_SHA512, sha512->heap, devId);
807
#else
808
0
    (void)devId;
809
0
#endif /* WOLFSSL_ASYNC_CRYPT */
810
#ifdef WOLFSSL_IMXRT1170_CAAM
811
     ret = wc_CAAM_HashInit(&sha512->hndl, &sha512->ctx, WC_HASH_TYPE_SHA512);
812
#endif
813
0
    return ret;
814
0
} /* InitSha512_Family */
815
816
int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
817
0
{
818
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
819
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
820
    if (sha512->ctx.mode != ESP32_SHA_INIT) {
821
        ESP_LOGV(TAG, "Set ctx mode from prior value: "
822
                      "%d", sha512->ctx.mode);
823
    }
824
    /* We know this is a fresh, uninitialized item, so set to INIT */
825
    sha512->ctx.mode = ESP32_SHA_INIT;
826
#endif
827
828
#ifdef MAX3266X_SHA_CB
829
    if (wc_MXC_TPU_SHA_Init(&(sha512->mxcCtx)) != 0){
830
        return BAD_FUNC_ARG;
831
    }
832
#endif
833
834
0
    return InitSha512_Family(sha512, heap, devId, InitSha512);
835
0
}
836
837
#if !defined(WOLFSSL_NOSHA512_224) && \
838
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
839
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
840
0
{
841
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
842
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
843
    /* No SHA512/224 HW support is available, set to SW. */
844
    sha512->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
845
#endif
846
0
    return InitSha512_Family(sha512, heap, devId, InitSha512_224);
847
0
}
848
#endif /* !WOLFSSL_NOSHA512_224 ... */
849
850
#if !defined(WOLFSSL_NOSHA512_256) && \
851
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
852
int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
853
0
{
854
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
855
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
856
    /* No SHA512/256 HW support is available on ESP32, set to SW. */
857
    sha512->ctx.mode = ESP32_SHA_SW;
858
#endif
859
0
    return InitSha512_Family(sha512, heap, devId, InitSha512_256);
860
0
}
861
#endif /* !WOLFSSL_NOSHA512_256 ... */
862
863
#endif /* WOLFSSL_SHA512 */
864
865
866
static const word64 K512[80] = {
867
    W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
868
    W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
869
    W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
870
    W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
871
    W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
872
    W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
873
    W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
874
    W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
875
    W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
876
    W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
877
    W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
878
    W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
879
    W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
880
    W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
881
    W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
882
    W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
883
    W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
884
    W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
885
    W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
886
    W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
887
    W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
888
    W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
889
    W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
890
    W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
891
    W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
892
    W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
893
    W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
894
    W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
895
    W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
896
    W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
897
    W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
898
    W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
899
    W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
900
    W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
901
    W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
902
    W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
903
    W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
904
    W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
905
    W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
906
    W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
907
};
908
909
0
#define blk0(i) (W[i] = sha512->buffer[i])
910
911
0
#define blk2(i) (\
912
0
               W[ (i)     & 15] += \
913
0
            s1(W[((i)-2)  & 15])+ \
914
0
               W[((i)-7)  & 15] + \
915
0
            s0(W[((i)-15) & 15])  \
916
0
        )
917
918
0
#define Ch(x,y,z)  ((z) ^ ((x) & ((y) ^ (z))))
919
0
#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
920
921
0
#define a(i) T[(0-(i)) & 7]
922
0
#define b(i) T[(1-(i)) & 7]
923
0
#define c(i) T[(2-(i)) & 7]
924
0
#define d(i) T[(3-(i)) & 7]
925
0
#define e(i) T[(4-(i)) & 7]
926
0
#define f(i) T[(5-(i)) & 7]
927
0
#define g(i) T[(6-(i)) & 7]
928
0
#define h(i) T[(7-(i)) & 7]
929
930
0
#define S0(x) (rotrFixed64(x,28) ^ rotrFixed64(x,34) ^ rotrFixed64(x,39))
931
0
#define S1(x) (rotrFixed64(x,14) ^ rotrFixed64(x,18) ^ rotrFixed64(x,41))
932
0
#define s0(x) (rotrFixed64(x,1)  ^ rotrFixed64(x,8)  ^ ((x)>>7))
933
0
#define s1(x) (rotrFixed64(x,19) ^ rotrFixed64(x,61) ^ ((x)>>6))
934
935
#define R(i) \
936
0
    h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+j] + (j ? blk2(i) : blk0(i)); \
937
0
    d(i) += h(i); \
938
0
    h(i) += S0(a(i)) + Maj(a(i),b(i),c(i))
939
940
static int _Transform_Sha512(wc_Sha512* sha512)
941
0
{
942
0
    const word64* K = K512;
943
0
    word32 j;
944
0
    word64 T[8];
945
946
#ifdef WOLFSSL_SMALL_STACK_CACHE
947
    word64* W = sha512->W;
948
    if (W == NULL) {
949
        W = (word64*)XMALLOC(sizeof(word64) * 16, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
950
        if (W == NULL)
951
            return MEMORY_E;
952
        sha512->W = W;
953
    }
954
#elif defined(WOLFSSL_SMALL_STACK)
955
    word64* W;
956
    W = (word64*) XMALLOC(sizeof(word64) * 16, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
957
    if (W == NULL)
958
        return MEMORY_E;
959
#else
960
0
    word64 W[16];
961
0
#endif
962
963
    /* Copy digest to working vars */
964
0
    XMEMCPY(T, sha512->digest, sizeof(T));
965
966
#ifdef USE_SLOW_SHA512
967
    /* over twice as small, but 50% slower */
968
    /* 80 operations, not unrolled */
969
    for (j = 0; j < 80; j += 16) {
970
        int m;
971
        for (m = 0; m < 16; m++) { /* braces needed here for macros {} */
972
            R(m);
973
        }
974
    }
975
#else
976
    /* 80 operations, partially loop unrolled */
977
0
    for (j = 0; j < 80; j += 16) {
978
0
        R( 0); R( 1); R( 2); R( 3);
979
0
        R( 4); R( 5); R( 6); R( 7);
980
0
        R( 8); R( 9); R(10); R(11);
981
0
        R(12); R(13); R(14); R(15);
982
0
    }
983
0
#endif /* USE_SLOW_SHA512 */
984
985
    /* Add the working vars back into digest */
986
0
    sha512->digest[0] += a(0);
987
0
    sha512->digest[1] += b(0);
988
0
    sha512->digest[2] += c(0);
989
0
    sha512->digest[3] += d(0);
990
0
    sha512->digest[4] += e(0);
991
0
    sha512->digest[5] += f(0);
992
0
    sha512->digest[6] += g(0);
993
0
    sha512->digest[7] += h(0);
994
995
    /* Wipe variables */
996
0
    ForceZero(W, sizeof(word64) * 16);
997
0
    ForceZero(T, sizeof(T));
998
999
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
1000
    XFREE(W, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
1001
#endif
1002
1003
0
    return 0;
1004
0
}
1005
1006
1007
static WC_INLINE void AddLength(wc_Sha512* sha512, word32 len)
1008
0
{
1009
0
    word64 tmp = sha512->loLen;
1010
0
    if ( (sha512->loLen += len) < tmp)
1011
0
        sha512->hiLen++;                       /* carry low to high */
1012
0
}
1013
1014
static WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
1015
0
{
1016
0
    int ret = 0;
1017
    /* do block size increments */
1018
0
    byte* local = (byte*)sha512->buffer;
1019
1020
    /* check that internal buffLen is valid */
1021
0
    if (sha512->buffLen >= WC_SHA512_BLOCK_SIZE)
1022
0
        return BUFFER_E;
1023
1024
0
    if (len == 0)
1025
0
        return 0;
1026
1027
0
    AddLength(sha512, len);
1028
1029
0
    if (sha512->buffLen > 0) {
1030
0
        word32 add = min(len, WC_SHA512_BLOCK_SIZE - sha512->buffLen);
1031
0
        if (add > 0) {
1032
0
            XMEMCPY(&local[sha512->buffLen], data, add);
1033
1034
0
            sha512->buffLen += add;
1035
0
            data            += add;
1036
0
            len             -= add;
1037
0
        }
1038
1039
0
        if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) {
1040
0
    #if defined(LITTLE_ENDIAN_ORDER)
1041
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1042
            (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1043
            #ifdef WC_C_DYNAMIC_FALLBACK
1044
            if (sha512->sha_method == SHA512_C)
1045
            #else
1046
            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1047
            #endif
1048
        #endif
1049
0
            {
1050
0
        #if !defined(WOLFSSL_ESP32_CRYPT) || \
1051
0
             defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
1052
0
             defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1053
0
                ByteReverseWords64(sha512->buffer, sha512->buffer,
1054
0
                                                         WC_SHA512_BLOCK_SIZE);
1055
0
        #endif
1056
0
            }
1057
0
    #endif
1058
0
    #if !defined(WOLFSSL_ESP32_CRYPT) || \
1059
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
1060
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1061
0
            ret = Transform_Sha512(sha512);
1062
    #else
1063
            if (sha512->ctx.mode == ESP32_SHA_INIT) {
1064
                esp_sha_try_hw_lock(&sha512->ctx);
1065
            }
1066
            if (sha512->ctx.mode == ESP32_SHA_SW) {
1067
                ByteReverseWords64(sha512->buffer, sha512->buffer,
1068
                                                         WC_SHA512_BLOCK_SIZE);
1069
                ret = Transform_Sha512(sha512);
1070
            }
1071
            else {
1072
                ret = esp_sha512_process(sha512);
1073
            }
1074
    #endif
1075
0
            if (ret == 0)
1076
0
                sha512->buffLen = 0;
1077
0
            else
1078
0
                len = 0;
1079
0
        }
1080
0
    }
1081
1082
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1083
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1084
1085
    #ifdef WC_C_DYNAMIC_FALLBACK
1086
    if (sha512->sha_method != SHA512_C)
1087
    #elif defined(WC_NO_INTERNAL_FUNCTION_POINTERS)
1088
    if (sha_method != SHA512_C)
1089
    #else
1090
    if (Transform_Sha512_Len_p != NULL)
1091
    #endif
1092
1093
    {
1094
        word32 blocksLen = len & ~((word32)WC_SHA512_BLOCK_SIZE-1);
1095
1096
        if (blocksLen > 0) {
1097
            sha512->data = data;
1098
            /* Byte reversal performed in function if required. */
1099
            Transform_Sha512_Len(sha512, blocksLen);
1100
            data += blocksLen;
1101
            len  -= blocksLen;
1102
        }
1103
    }
1104
    else
1105
#endif
1106
#if !defined(LITTLE_ENDIAN_ORDER) || (defined(WOLFSSL_X86_64_BUILD) && \
1107
        defined(USE_INTEL_SPEEDUP) && (defined(HAVE_INTEL_AVX1) || \
1108
        defined(HAVE_INTEL_AVX2)))
1109
    {
1110
        while (len >= WC_SHA512_BLOCK_SIZE) {
1111
            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
1112
1113
            data += WC_SHA512_BLOCK_SIZE;
1114
            len  -= WC_SHA512_BLOCK_SIZE;
1115
1116
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1117
            (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1118
            #ifdef WC_C_DYNAMIC_FALLBACK
1119
            if (sha512->sha_method == SHA512_C)
1120
            #else
1121
            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1122
            #endif
1123
            {
1124
                ByteReverseWords64(sha512->buffer, sha512->buffer,
1125
                                                          WC_SHA512_BLOCK_SIZE);
1126
            }
1127
        #endif
1128
            /* Byte reversal performed in function if required. */
1129
            ret = Transform_Sha512(sha512);
1130
            if (ret != 0)
1131
                break;
1132
        }
1133
    }
1134
#else
1135
0
    {
1136
0
        while (len >= WC_SHA512_BLOCK_SIZE) {
1137
0
            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
1138
1139
0
            data += WC_SHA512_BLOCK_SIZE;
1140
0
            len  -= WC_SHA512_BLOCK_SIZE;
1141
0
    #if !defined(WOLFSSL_ESP32_CRYPT) || \
1142
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
1143
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1144
0
            ByteReverseWords64(sha512->buffer, sha512->buffer,
1145
0
                                                       WC_SHA512_BLOCK_SIZE);
1146
0
    #endif
1147
0
    #if !defined(WOLFSSL_ESP32_CRYPT) || \
1148
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
1149
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1150
0
            ret = Transform_Sha512(sha512);
1151
    #else
1152
            if(sha512->ctx.mode == ESP32_SHA_INIT) {
1153
                esp_sha_try_hw_lock(&sha512->ctx);
1154
            }
1155
            if (sha512->ctx.mode == ESP32_SHA_SW) {
1156
                ByteReverseWords64(sha512->buffer, sha512->buffer,
1157
                                                          WC_SHA512_BLOCK_SIZE);
1158
                ret = Transform_Sha512(sha512);
1159
            }
1160
            else {
1161
                ret = esp_sha512_process(sha512);
1162
            }
1163
    #endif
1164
0
            if (ret != 0)
1165
0
                break;
1166
0
        } /* while (len >= WC_SHA512_BLOCK_SIZE) */
1167
0
    }
1168
0
#endif
1169
1170
0
    if (ret == 0 && len > 0) {
1171
0
        XMEMCPY(local, data, len);
1172
0
        sha512->buffLen = len;
1173
0
    }
1174
1175
0
    return ret;
1176
0
}
1177
1178
#ifdef WOLFSSL_SHA512
1179
1180
int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
1181
0
{
1182
0
    if (sha512 == NULL) {
1183
0
        return BAD_FUNC_ARG;
1184
0
    }
1185
0
    if (data == NULL && len == 0) {
1186
        /* valid, but do nothing */
1187
0
        return 0;
1188
0
    }
1189
0
    if (data == NULL) {
1190
0
        return BAD_FUNC_ARG;
1191
0
    }
1192
1193
#ifdef WOLF_CRYPTO_CB
1194
    #ifndef WOLF_CRYPTO_CB_FIND
1195
    if (sha512->devId != INVALID_DEVID)
1196
    #endif
1197
    {
1198
        int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL);
1199
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1200
            return ret;
1201
        /* fall-through when unavailable */
1202
    }
1203
#endif
1204
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
1205
    if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {
1206
    #if defined(HAVE_INTEL_QA)
1207
        return IntelQaSymSha512(&sha512->asyncDev, NULL, data, len);
1208
    #endif
1209
    }
1210
#endif /* WOLFSSL_ASYNC_CRYPT */
1211
1212
0
    return Sha512Update(sha512, data, len);
1213
0
}
1214
1215
#endif /* WOLFSSL_SHA512 */
1216
1217
#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA384 */
1218
1219
1220
#if defined(WOLFSSL_KCAPI_HASH)
1221
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
1222
#elif defined(WOLFSSL_RENESAS_RSIP) && \
1223
   !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
1224
    /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */
1225
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
1226
1227
#elif defined(MAX3266X_SHA)
1228
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
1229
#elif defined(STM32_HASH_SHA512)
1230
#else
1231
1232
static WC_INLINE int Sha512Final(wc_Sha512* sha512)
1233
0
{
1234
0
    int ret;
1235
0
    byte* local;
1236
1237
0
    if (sha512 == NULL) {
1238
0
        return BAD_FUNC_ARG;
1239
0
    }
1240
1241
0
    local = (byte*)sha512->buffer;
1242
1243
    /* we'll add a 0x80 byte at the end,
1244
    ** so make sure we have appropriate buffer length. */
1245
0
    if (sha512->buffLen > WC_SHA512_BLOCK_SIZE - 1) {
1246
0
        return BAD_STATE_E;
1247
0
    } /* buffLen check */
1248
1249
0
    local[sha512->buffLen++] = 0x80;  /* add 1 */
1250
1251
    /* pad with zeros */
1252
0
    if (sha512->buffLen > WC_SHA512_PAD_SIZE) {
1253
0
        if (sha512->buffLen < WC_SHA512_BLOCK_SIZE ) {
1254
0
            XMEMSET(&local[sha512->buffLen], 0,
1255
0
                WC_SHA512_BLOCK_SIZE - sha512->buffLen);
1256
0
        }
1257
1258
0
        sha512->buffLen += WC_SHA512_BLOCK_SIZE - sha512->buffLen;
1259
0
#if defined(LITTLE_ENDIAN_ORDER)
1260
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1261
        (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1262
        #ifdef WC_C_DYNAMIC_FALLBACK
1263
        if (sha512->sha_method == SHA512_C)
1264
        #else
1265
        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1266
        #endif
1267
    #endif
1268
0
        {
1269
1270
0
       #if !defined(WOLFSSL_ESP32_CRYPT) || \
1271
0
            defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
1272
0
            defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1273
0
            ByteReverseWords64(sha512->buffer,sha512->buffer,
1274
0
                                                         WC_SHA512_BLOCK_SIZE);
1275
0
       #endif
1276
0
        }
1277
1278
0
#endif /* LITTLE_ENDIAN_ORDER */
1279
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1280
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1281
        if (sha512->ctx.mode == ESP32_SHA_INIT) {
1282
            esp_sha_try_hw_lock(&sha512->ctx);
1283
        }
1284
        if (sha512->ctx.mode == ESP32_SHA_SW) {
1285
            ByteReverseWords64(sha512->buffer,sha512->buffer,
1286
                                                         WC_SHA512_BLOCK_SIZE);
1287
            ret = Transform_Sha512(sha512);
1288
        }
1289
        else {
1290
            ret = esp_sha512_process(sha512);
1291
        }
1292
    #else
1293
0
        ret = Transform_Sha512(sha512);
1294
0
    #endif
1295
0
        if (ret != 0)
1296
0
            return ret;
1297
1298
0
        sha512->buffLen = 0;
1299
0
    } /* (sha512->buffLen > WC_SHA512_PAD_SIZE) pad with zeros */
1300
1301
0
    XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen);
1302
1303
    /* put lengths in bits */
1304
0
    sha512->hiLen = (sha512->loLen >> (8 * sizeof(sha512->loLen) - 3)) +
1305
0
                                                         (sha512->hiLen << 3);
1306
0
    sha512->loLen = sha512->loLen << 3;
1307
1308
    /* store lengths */
1309
0
#if defined(LITTLE_ENDIAN_ORDER)
1310
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1311
        (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1312
        #ifdef WC_C_DYNAMIC_FALLBACK
1313
        if (sha512->sha_method == SHA512_C)
1314
        #else
1315
        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1316
        #endif
1317
    #endif
1318
0
    #if !defined(WOLFSSL_ESP32_CRYPT) || \
1319
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
1320
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1321
0
            ByteReverseWords64(sha512->buffer, sha512->buffer, WC_SHA512_PAD_SIZE);
1322
0
    #endif
1323
0
#endif
1324
    /* ! length ordering dependent on digest endian type ! */
1325
1326
0
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1327
0
     defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
1328
0
     defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1329
0
    sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
1330
0
    sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
1331
0
#endif
1332
1333
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1334
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1335
    #ifdef WC_C_DYNAMIC_FALLBACK
1336
    if (sha512->sha_method != SHA512_C)
1337
    #else
1338
    if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags))
1339
    #endif
1340
        ByteReverseWords64(&(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
1341
                           &(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
1342
                           WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
1343
#endif
1344
1345
0
#if !defined(WOLFSSL_ESP32_CRYPT) || \
1346
0
    defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
1347
0
    defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1348
0
    ret = Transform_Sha512(sha512);
1349
#else
1350
    if(sha512->ctx.mode == ESP32_SHA_INIT) {
1351
        /* typically for tiny block: first = last */
1352
        esp_sha_try_hw_lock(&sha512->ctx);
1353
    }
1354
    if (sha512->ctx.mode == ESP32_SHA_SW) {
1355
        ByteReverseWords64(sha512->buffer,
1356
                           sha512->buffer,
1357
                           WC_SHA512_BLOCK_SIZE);
1358
        sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
1359
        sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
1360
        ret = Transform_Sha512(sha512);
1361
    }
1362
    else {
1363
        ret = esp_sha512_digest_process(sha512, 1);
1364
    }
1365
#endif
1366
1367
0
    if (ret != 0)
1368
0
        return ret;
1369
1370
0
    #ifdef LITTLE_ENDIAN_ORDER
1371
0
        ByteReverseWords64(sha512->digest, sha512->digest, WC_SHA512_DIGEST_SIZE);
1372
0
    #endif
1373
1374
1375
0
    return 0;
1376
0
}
1377
1378
#endif /* WOLFSSL_KCAPI_HASH */
1379
1380
#ifdef WOLFSSL_SHA512
1381
1382
#if defined(WOLFSSL_KCAPI_HASH)
1383
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
1384
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
1385
1386
#elif defined(WOLFSSL_RENESAS_RSIP) && \
1387
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
1388
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
1389
1390
#elif defined(MAX3266X_SHA)
1391
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
1392
#elif defined(STM32_HASH_SHA512)
1393
#else
1394
1395
static int Sha512FinalRaw(wc_Sha512* sha512, byte* hash, size_t digestSz)
1396
0
{
1397
0
    if (sha512 == NULL || hash == NULL) {
1398
0
        return BAD_FUNC_ARG;
1399
0
    }
1400
1401
0
#ifdef LITTLE_ENDIAN_ORDER
1402
0
    ByteReverseWords64(sha512->digest, sha512->digest, WC_SHA512_DIGEST_SIZE);
1403
0
#endif
1404
1405
0
    XMEMCPY(hash, sha512->digest, digestSz);
1406
1407
0
    return 0;
1408
0
}
1409
1410
int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
1411
0
{
1412
0
    return Sha512FinalRaw(sha512, hash, WC_SHA512_DIGEST_SIZE);
1413
0
}
1414
1415
static int Sha512_Family_Final(wc_Sha512* sha512, byte* hash, size_t digestSz,
1416
                               int (*initfp)(wc_Sha512*))
1417
0
{
1418
0
    int ret;
1419
1420
0
    if (sha512 == NULL || hash == NULL) {
1421
0
        return BAD_FUNC_ARG;
1422
0
    }
1423
1424
#ifdef WOLF_CRYPTO_CB
1425
    #ifndef WOLF_CRYPTO_CB_FIND
1426
    if (sha512->devId != INVALID_DEVID)
1427
    #endif
1428
    {
1429
        byte localHash[WC_SHA512_DIGEST_SIZE];
1430
        ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, localHash);
1431
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
1432
            XMEMCPY(hash, localHash, digestSz);
1433
            return ret;
1434
        }
1435
        /* fall-through when unavailable */
1436
    }
1437
#endif
1438
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
1439
    if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {
1440
    #if defined(HAVE_INTEL_QA)
1441
        return IntelQaSymSha512(&sha512->asyncDev, hash, NULL, digestSz);
1442
    #endif
1443
    }
1444
#endif /* WOLFSSL_ASYNC_CRYPT */
1445
1446
0
    ret = Sha512Final(sha512);
1447
0
    if (ret != 0)
1448
0
        return ret;
1449
1450
0
    XMEMCPY(hash, sha512->digest, digestSz);
1451
1452
    /* initialize Sha512 structure for the next use */
1453
0
    return initfp(sha512);
1454
0
}
1455
1456
#ifndef STM32_HASH_SHA512
1457
int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
1458
0
{
1459
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_DIGEST_SIZE, InitSha512);
1460
0
}
1461
#endif
1462
1463
#endif /* WOLFSSL_KCAPI_HASH */
1464
1465
#if defined(MAX3266X_SHA)
1466
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
1467
1468
#else
1469
#if !defined(WOLFSSL_SE050) || !defined(WOLFSSL_SE050_HASH)
1470
int wc_InitSha512(wc_Sha512* sha512)
1471
0
{
1472
0
    int devId = INVALID_DEVID;
1473
1474
#ifdef WOLF_CRYPTO_CB
1475
    devId = wc_CryptoCb_DefaultDevID();
1476
#endif
1477
0
    return wc_InitSha512_ex(sha512, NULL, devId);
1478
0
}
1479
1480
void wc_Sha512Free(wc_Sha512* sha512)
1481
0
{
1482
0
    if (sha512 == NULL)
1483
0
        return;
1484
1485
#if defined(WOLFSSL_ESP32) && \
1486
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)  && \
1487
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1488
    esp_sha_release_unfinished_lock(&sha512->ctx);
1489
#endif
1490
1491
#ifdef WOLFSSL_SMALL_STACK_CACHE
1492
    if (sha512->W != NULL) {
1493
        ForceZero(sha512->W, sizeof(word64) * 16);
1494
        XFREE(sha512->W, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
1495
        sha512->W = NULL;
1496
    }
1497
#endif
1498
1499
#if defined(WOLFSSL_KCAPI_HASH)
1500
    KcapiHashFree(&sha512->kcapi);
1501
#endif
1502
1503
#if defined(WOLFSSL_HASH_KEEP)
1504
    if (sha512->msg != NULL) {
1505
        ForceZero(sha512->msg, sha512->len);
1506
        XFREE(sha512->msg, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
1507
        sha512->msg = NULL;
1508
    }
1509
#endif
1510
1511
#ifdef MAX3266X_SHA_CB
1512
    wc_MXC_TPU_SHA_Free(&(sha512->mxcCtx));
1513
#endif
1514
1515
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
1516
    wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512);
1517
#endif /* WOLFSSL_ASYNC_CRYPT */
1518
1519
0
    ForceZero(sha512, sizeof(*sha512));
1520
0
}
1521
#endif
1522
1523
#if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) \
1524
    && !defined(WOLFSSL_KCAPI_HASH)
1525
/* Apply SHA512 transformation to the data                */
1526
/* @param sha  a pointer to wc_Sha512 structure           */
1527
/* @param data data to be applied SHA512 transformation   */
1528
/* @return 0 on successful, otherwise non-zero on failure */
1529
int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data)
1530
{
1531
    int ret;
1532
    /* back up buffer */
1533
#ifdef WOLFSSL_SMALL_STACK
1534
    word64 *buffer;
1535
#else
1536
    word64  buffer[WC_SHA512_BLOCK_SIZE  / sizeof(word64)];
1537
#endif
1538
1539
    /* sanity check */
1540
    if (sha == NULL || data == NULL) {
1541
        return BAD_FUNC_ARG;
1542
    }
1543
1544
#ifdef WOLFSSL_SMALL_STACK
1545
    buffer = (word64*)XMALLOC(WC_SHA512_BLOCK_SIZE, sha->heap,
1546
        DYNAMIC_TYPE_TMP_BUFFER);
1547
    if (buffer == NULL)
1548
        return MEMORY_E;
1549
#endif
1550
1551
#if defined(LITTLE_ENDIAN_ORDER)
1552
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1553
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1554
    #ifdef WC_C_DYNAMIC_FALLBACK
1555
    if (sha->sha_method == SHA512_C)
1556
    #else
1557
    if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
1558
    #endif
1559
#endif
1560
    {
1561
        ByteReverseWords64((word64*)data, (word64*)data,
1562
                                                WC_SHA512_BLOCK_SIZE);
1563
    }
1564
#endif /* LITTLE_ENDIAN_ORDER */
1565
1566
    XMEMCPY(buffer, sha->buffer, WC_SHA512_BLOCK_SIZE);
1567
    XMEMCPY(sha->buffer, data, WC_SHA512_BLOCK_SIZE);
1568
1569
    ret = Transform_Sha512(sha);
1570
1571
    XMEMCPY(sha->buffer, buffer, WC_SHA512_BLOCK_SIZE);
1572
#ifdef WOLFSSL_SMALL_STACK
1573
    ForceZero(buffer, WC_SHA512_BLOCK_SIZE);
1574
    XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
1575
#endif
1576
    return ret;
1577
}
1578
#endif /* OPENSSL_EXTRA */
1579
#endif /* WOLFSSL_SHA512 */
1580
#endif /* !WOLFSSL_SE050 || !WOLFSSL_SE050_HASH */
1581
1582
1583
/* -------------------------------------------------------------------------- */
1584
/* SHA384 */
1585
/* -------------------------------------------------------------------------- */
1586
#ifdef WOLFSSL_SHA384
1587
1588
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
1589
    !defined(WOLFSSL_QNX_CAAM)
1590
    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
1591
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
1592
    int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
1593
    {
1594
        if (sha384 == NULL) {
1595
            return BAD_FUNC_ARG;
1596
        }
1597
        (void)devId;
1598
        return se050_hash_init(&sha384->se050Ctx, heap);
1599
    }
1600
    int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
1601
    {
1602
        if (sha384 == NULL) {
1603
            return BAD_FUNC_ARG;
1604
        }
1605
        if (data == NULL && len == 0) {
1606
            /* valid, but do nothing */
1607
            return 0;
1608
        }
1609
        if (data == NULL) {
1610
            return BAD_FUNC_ARG;
1611
        }
1612
1613
        return se050_hash_update(&sha384->se050Ctx, data, len);
1614
1615
    }
1616
    int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
1617
    {
1618
        int ret = 0;
1619
        ret = se050_hash_final(&sha384->se050Ctx, hash, WC_SHA384_DIGEST_SIZE,
1620
                               kAlgorithm_SSS_SHA384);
1621
        return ret;
1622
    }
1623
    int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
1624
    {
1625
        int ret = 0;
1626
        ret = se050_hash_final(&sha384->se050Ctx, hash, WC_SHA384_DIGEST_SIZE,
1627
                               kAlgorithm_SSS_SHA384);
1628
        return ret;
1629
    }
1630
1631
#elif defined(WOLFSSL_SILABS_SHA512)
1632
    /* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */
1633
1634
#elif defined(WOLFSSL_KCAPI_HASH)
1635
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
1636
1637
#elif defined(WOLFSSL_RENESAS_RSIP) && \
1638
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
1639
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
1640
1641
#elif defined(MAX3266X_SHA)
1642
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
1643
#elif defined(STM32_HASH_SHA384)
1644
1645
    int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
1646
    {
1647
        if (sha384 == NULL)
1648
            return BAD_FUNC_ARG;
1649
1650
        (void)devId;
1651
        (void)heap;
1652
1653
        XMEMSET(sha384, 0, sizeof(wc_Sha384));
1654
        wc_Stm32_Hash_Init(&sha384->stmCtx);
1655
        return 0;
1656
    }
1657
1658
    int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
1659
    {
1660
        int ret = 0;
1661
1662
        if (sha384 == NULL) {
1663
            return BAD_FUNC_ARG;
1664
        }
1665
        if (data == NULL && len == 0) {
1666
            /* valid, but do nothing */
1667
            return 0;
1668
        }
1669
        if (data == NULL) {
1670
            return BAD_FUNC_ARG;
1671
        }
1672
1673
        ret = wolfSSL_CryptHwMutexLock();
1674
        if (ret == 0) {
1675
            ret = wc_Stm32_Hash_Update(&sha384->stmCtx,
1676
                HASH_ALGOSELECTION_SHA384, data, len, WC_SHA384_BLOCK_SIZE);
1677
            wolfSSL_CryptHwMutexUnLock();
1678
        }
1679
        return ret;
1680
    }
1681
1682
    int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
1683
    {
1684
        int ret = 0;
1685
1686
        if (sha384 == NULL || hash == NULL) {
1687
            return BAD_FUNC_ARG;
1688
        }
1689
1690
        ret = wolfSSL_CryptHwMutexLock();
1691
        if (ret == 0) {
1692
            ret = wc_Stm32_Hash_Final(&sha384->stmCtx,
1693
                HASH_ALGOSELECTION_SHA384, hash, WC_SHA384_DIGEST_SIZE);
1694
            wolfSSL_CryptHwMutexUnLock();
1695
        }
1696
1697
        (void)wc_InitSha384(sha384); /* reset state */
1698
1699
        return ret;
1700
    }
1701
1702
#else
1703
1704
static int InitSha384(wc_Sha384* sha384)
1705
0
{
1706
0
    if (sha384 == NULL) {
1707
0
        return BAD_FUNC_ARG;
1708
0
    }
1709
1710
0
    sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8);
1711
0
    sha384->digest[1] = W64LIT(0x629a292a367cd507);
1712
0
    sha384->digest[2] = W64LIT(0x9159015a3070dd17);
1713
0
    sha384->digest[3] = W64LIT(0x152fecd8f70e5939);
1714
0
    sha384->digest[4] = W64LIT(0x67332667ffc00b31);
1715
0
    sha384->digest[5] = W64LIT(0x8eb44a8768581511);
1716
0
    sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7);
1717
0
    sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4);
1718
1719
0
    sha384->buffLen = 0;
1720
0
    sha384->loLen   = 0;
1721
0
    sha384->hiLen   = 0;
1722
1723
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1724
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1725
#ifdef WC_C_DYNAMIC_FALLBACK
1726
    sha384->sha_method = 0;
1727
    Sha512_SetTransform(&sha384->sha_method);
1728
#else
1729
    Sha512_SetTransform();
1730
#endif
1731
#endif
1732
1733
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)  && \
1734
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
1735
    /* HW needs to be carefully initialized, taking into account soft copy.
1736
    ** If already in use; copy may revert to SW as needed. */
1737
    esp_sha_init(&(sha384->ctx), WC_HASH_TYPE_SHA384);
1738
#endif
1739
1740
#ifdef WOLFSSL_HASH_FLAGS
1741
    sha384->flags = 0;
1742
#endif
1743
1744
#ifdef HAVE_ARIA
1745
    sha384->hSession = NULL;
1746
#endif
1747
1748
#ifdef WOLFSSL_HASH_KEEP
1749
    sha384->msg  = NULL;
1750
    sha384->len  = 0;
1751
    sha384->used = 0;
1752
#endif
1753
1754
0
    return 0;
1755
0
}
1756
1757
int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
1758
0
{
1759
1760
0
    if (sha384 == NULL) {
1761
0
        return BAD_FUNC_ARG;
1762
0
    }
1763
0
    if (data == NULL && len == 0) {
1764
        /* valid, but do nothing */
1765
0
        return 0;
1766
0
    }
1767
0
    if (data == NULL) {
1768
0
        return BAD_FUNC_ARG;
1769
0
    }
1770
1771
#ifdef WOLF_CRYPTO_CB
1772
    #ifndef WOLF_CRYPTO_CB_FIND
1773
    if (sha384->devId != INVALID_DEVID)
1774
    #endif
1775
    {
1776
        int ret = wc_CryptoCb_Sha384Hash(sha384, data, len, NULL);
1777
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1778
            return ret;
1779
        /* fall-through when unavailable */
1780
    }
1781
#endif
1782
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
1783
    if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {
1784
    #if defined(HAVE_INTEL_QA)
1785
        return IntelQaSymSha384(&sha384->asyncDev, NULL, data, len);
1786
    #endif
1787
    }
1788
#endif /* WOLFSSL_ASYNC_CRYPT */
1789
1790
0
    return Sha512Update((wc_Sha512*)sha384, data, len);
1791
0
}
1792
1793
1794
int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
1795
0
{
1796
0
    if (sha384 == NULL || hash == NULL) {
1797
0
        return BAD_FUNC_ARG;
1798
0
    }
1799
1800
0
#ifdef LITTLE_ENDIAN_ORDER
1801
0
    ByteReverseWords64(sha384->digest, sha384->digest, WC_SHA384_DIGEST_SIZE);
1802
0
#endif
1803
1804
0
    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
1805
1806
0
    return 0;
1807
0
}
1808
1809
int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
1810
0
{
1811
0
    int ret;
1812
1813
0
    if (sha384 == NULL || hash == NULL) {
1814
0
        return BAD_FUNC_ARG;
1815
0
    }
1816
1817
#ifdef WOLF_CRYPTO_CB
1818
    #ifndef WOLF_CRYPTO_CB_FIND
1819
    if (sha384->devId != INVALID_DEVID)
1820
    #endif
1821
    {
1822
        ret = wc_CryptoCb_Sha384Hash(sha384, NULL, 0, hash);
1823
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
1824
            return ret;
1825
        /* fall-through when unavailable */
1826
    }
1827
#endif
1828
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
1829
    if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {
1830
    #if defined(HAVE_INTEL_QA)
1831
        return IntelQaSymSha384(&sha384->asyncDev, hash, NULL,
1832
                                            WC_SHA384_DIGEST_SIZE);
1833
    #endif
1834
    }
1835
#endif /* WOLFSSL_ASYNC_CRYPT */
1836
1837
0
    ret = Sha512Final((wc_Sha512*)sha384);
1838
0
    if (ret != 0)
1839
0
        return ret;
1840
1841
0
    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
1842
1843
0
    return InitSha384(sha384);  /* reset state */
1844
0
}
1845
1846
int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
1847
0
{
1848
0
    int ret;
1849
1850
0
    if (sha384 == NULL) {
1851
0
        return BAD_FUNC_ARG;
1852
0
    }
1853
1854
0
    sha384->heap = heap;
1855
#ifdef WOLFSSL_SMALL_STACK_CACHE
1856
    sha384->W = NULL;
1857
#endif
1858
#ifdef WOLF_CRYPTO_CB
1859
    sha384->devId = devId;
1860
    sha384->devCtx = NULL;
1861
#endif
1862
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)  && \
1863
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
1864
    if (sha384->ctx.mode != ESP32_SHA_INIT) {
1865
        ESP_LOGV(TAG, "Set ctx mode from prior value: "
1866
                           "%d", sha384->ctx.mode);
1867
    }
1868
    /* We know this is a fresh, uninitialized item, so set to INIT */
1869
    sha384->ctx.mode = ESP32_SHA_INIT;
1870
#endif
1871
1872
#ifdef MAX3266X_SHA_CB
1873
    ret = wc_MXC_TPU_SHA_Init(&(sha384->mxcCtx));
1874
    if (ret != 0) {
1875
        return ret;
1876
    }
1877
#endif
1878
1879
0
    ret = InitSha384(sha384);
1880
0
    if (ret != 0) {
1881
0
        return ret;
1882
0
    }
1883
1884
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
1885
    ret = wolfAsync_DevCtxInit(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384,
1886
                                                           sha384->heap, devId);
1887
#else
1888
0
    (void)devId;
1889
0
#endif /* WOLFSSL_ASYNC_CRYPT */
1890
#ifdef WOLFSSL_IMXRT1170_CAAM
1891
     ret = wc_CAAM_HashInit(&sha384->hndl, &sha384->ctx, WC_HASH_TYPE_SHA384);
1892
#endif
1893
0
    return ret;
1894
0
}
1895
1896
#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA512 || WOLFSSL_KCAPI_HASH */
1897
1898
#if defined(MAX3266X_SHA)
1899
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
1900
1901
#else
1902
int wc_InitSha384(wc_Sha384* sha384)
1903
0
{
1904
0
    int devId = INVALID_DEVID;
1905
1906
#ifdef WOLF_CRYPTO_CB
1907
    devId = wc_CryptoCb_DefaultDevID();
1908
#endif
1909
0
    return wc_InitSha384_ex(sha384, NULL, devId);
1910
0
}
1911
1912
void wc_Sha384Free(wc_Sha384* sha384)
1913
0
{
1914
0
    if (sha384 == NULL)
1915
0
        return;
1916
1917
#if defined(WOLFSSL_ESP32) && !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)  && \
1918
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
1919
    esp_sha_release_unfinished_lock(&sha384->ctx);
1920
#endif
1921
1922
#ifdef WOLFSSL_SMALL_STACK_CACHE
1923
    if (sha384->W != NULL) {
1924
        ForceZero(sha384->W, sizeof(word64) * 16);
1925
        XFREE(sha384->W, sha384->heap, DYNAMIC_TYPE_TMP_BUFFER);
1926
        sha384->W = NULL;
1927
    }
1928
#endif
1929
1930
#if defined(WOLFSSL_KCAPI_HASH)
1931
    KcapiHashFree(&sha384->kcapi);
1932
#endif
1933
1934
#if defined(WOLFSSL_HASH_KEEP)
1935
    if (sha384->msg != NULL) {
1936
        ForceZero(sha384->msg, sha384->len);
1937
        XFREE(sha384->msg, sha384->heap, DYNAMIC_TYPE_TMP_BUFFER);
1938
        sha384->msg = NULL;
1939
    }
1940
#endif
1941
1942
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
1943
    se050_hash_free(&sha384->se050Ctx);
1944
#endif
1945
1946
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
1947
    wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384);
1948
#endif /* WOLFSSL_ASYNC_CRYPT */
1949
1950
#ifdef HAVE_ARIA
1951
    if (sha384->hSession != NULL) {
1952
        MC_CloseSession(sha384->hSession);
1953
        sha384->hSession = NULL;
1954
    }
1955
#endif
1956
1957
#ifdef MAX3266X_SHA_CB
1958
    wc_MXC_TPU_SHA_Free(&(sha384->mxcCtx));
1959
#endif
1960
1961
0
    ForceZero(sha384, sizeof(*sha384));
1962
0
}
1963
1964
#endif
1965
#endif /* WOLFSSL_SHA384 */
1966
1967
#ifdef WOLFSSL_SHA512
1968
1969
#if defined(WOLFSSL_KCAPI_HASH)
1970
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
1971
1972
#elif defined(WOLFSSL_RENESAS_RSIP) && \
1973
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
1974
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
1975
1976
#elif defined(MAX3266X_SHA)
1977
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
1978
1979
#else
1980
1981
static int Sha512_Family_GetHash(wc_Sha512* sha512, byte* hash,
1982
                                 int (*finalfp)(wc_Sha512*, byte*))
1983
0
{
1984
0
    int ret;
1985
#ifdef WOLFSSL_SMALL_STACK
1986
    wc_Sha512* tmpSha512;
1987
#else
1988
0
    wc_Sha512  tmpSha512[1];
1989
0
#endif
1990
1991
0
    if (sha512 == NULL || hash == NULL) {
1992
0
        return BAD_FUNC_ARG;
1993
0
    }
1994
1995
#ifdef WOLFSSL_SMALL_STACK
1996
    tmpSha512 = (wc_Sha512*)XMALLOC(sizeof(wc_Sha512), NULL,
1997
        DYNAMIC_TYPE_TMP_BUFFER);
1998
    if (tmpSha512 == NULL) {
1999
        return MEMORY_E;
2000
    }
2001
#endif
2002
2003
    /* copy this sha512 into tmpSha */
2004
0
    ret = wc_Sha512Copy(sha512, tmpSha512);
2005
0
    if (ret == 0) {
2006
0
        ret = finalfp(tmpSha512, hash);
2007
0
        wc_Sha512Free(tmpSha512);
2008
0
    }
2009
2010
#ifdef WOLFSSL_SMALL_STACK
2011
    XFREE(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2012
#endif
2013
2014
0
    return ret;
2015
0
}
2016
2017
int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)
2018
0
{
2019
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512Final);
2020
0
}
2021
2022
int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
2023
0
{
2024
0
    int ret = 0;
2025
2026
0
    if (src == NULL || dst == NULL) {
2027
0
        return BAD_FUNC_ARG;
2028
0
    }
2029
2030
0
    XMEMCPY(dst, src, sizeof(wc_Sha512));
2031
#ifdef WOLFSSL_SMALL_STACK_CACHE
2032
    dst->W = NULL;
2033
#endif
2034
2035
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3) && \
2036
    defined(WOLFSSL_SILABS_SHA512)
2037
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
2038
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
2039
#endif
2040
2041
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
2042
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
2043
#endif
2044
2045
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2046
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2047
    #if defined(CONFIG_IDF_TARGET_ESP32)
2048
    if (ret == 0) {
2049
        ret = esp_sha512_ctx_copy(src, dst);
2050
    }
2051
    #elif defined(CONFIG_IDF_TARGET_ESP32C2) || \
2052
          defined(CONFIG_IDF_TARGET_ESP8684) || \
2053
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
2054
          defined(CONFIG_IDF_TARGET_ESP32C6)
2055
        ESP_LOGV(TAG, "No SHA-512 HW on the ESP32-C3");
2056
2057
    #elif defined(CONFIG_IDF_TARGET_ESP32S2) || \
2058
          defined(CONFIG_IDF_TARGET_ESP32S3)
2059
        if (ret == 0) {
2060
            ret = esp_sha512_ctx_copy(src, dst);
2061
        }
2062
    #else
2063
        ESP_LOGW(TAG, "No SHA384 HW or not yet implemented for %s",
2064
                       CONFIG_IDF_TARGET);
2065
    #endif
2066
2067
#endif /* WOLFSSL_USE_ESP32_CRYPT_HASH_HW */
2068
2069
#ifdef WOLFSSL_HASH_FLAGS
2070
     dst->flags |= WC_HASH_FLAG_ISCOPY;
2071
#endif
2072
2073
#if defined(WOLFSSL_HASH_KEEP)
2074
    if (src->msg != NULL) {
2075
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
2076
        if (dst->msg == NULL)
2077
            return MEMORY_E;
2078
        XMEMCPY(dst->msg, src->msg, src->len);
2079
    }
2080
#endif
2081
2082
#ifdef MAX3266X_SHA_CB
2083
    ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx));
2084
    if (ret != 0) {
2085
        return ret;
2086
    }
2087
#endif
2088
2089
0
    return ret;
2090
0
}
2091
2092
#endif /* WOLFSSL_KCAPI_HASH */
2093
2094
#ifdef WOLFSSL_HASH_FLAGS
2095
int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags)
2096
{
2097
    if (sha512) {
2098
        sha512->flags = flags;
2099
    }
2100
    return 0;
2101
}
2102
int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags)
2103
{
2104
    if (sha512 && flags) {
2105
        *flags = sha512->flags;
2106
    }
2107
    return 0;
2108
}
2109
#endif /* WOLFSSL_HASH_FLAGS */
2110
2111
#if !defined(WOLFSSL_NOSHA512_224) && \
2112
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
2113
2114
#if defined(STM32_HASH_SHA512_224)
2115
2116
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
2117
{
2118
    if (sha512 == NULL)
2119
        return BAD_FUNC_ARG;
2120
2121
    (void)devId;
2122
    (void)heap;
2123
2124
    XMEMSET(sha512, 0, sizeof(wc_Sha512));
2125
    wc_Stm32_Hash_Init(&sha512->stmCtx);
2126
    return 0;
2127
}
2128
2129
int wc_Sha512_224Update(wc_Sha512* sha512, const byte* data, word32 len)
2130
{
2131
    int ret = 0;
2132
2133
    if (sha512 == NULL) {
2134
        return BAD_FUNC_ARG;
2135
    }
2136
    if (data == NULL && len == 0) {
2137
        /* valid, but do nothing */
2138
        return 0;
2139
    }
2140
    if (data == NULL) {
2141
        return BAD_FUNC_ARG;
2142
    }
2143
2144
    ret = wolfSSL_CryptHwMutexLock();
2145
    if (ret == 0) {
2146
        ret = wc_Stm32_Hash_Update(&sha512->stmCtx,
2147
            HASH_ALGOSELECTION_SHA512_224, data, len, WC_SHA512_224_BLOCK_SIZE);
2148
        wolfSSL_CryptHwMutexUnLock();
2149
    }
2150
    return ret;
2151
}
2152
2153
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
2154
{
2155
    int ret = 0;
2156
2157
    if (sha512 == NULL || hash == NULL) {
2158
        return BAD_FUNC_ARG;
2159
    }
2160
2161
    ret = wolfSSL_CryptHwMutexLock();
2162
    if (ret == 0) {
2163
        ret = wc_Stm32_Hash_Final(&sha512->stmCtx,
2164
            HASH_ALGOSELECTION_SHA512_224, hash, WC_SHA512_224_DIGEST_SIZE);
2165
        wolfSSL_CryptHwMutexUnLock();
2166
    }
2167
2168
    (void)wc_InitSha512_224(sha512); /* reset state */
2169
2170
    return ret;
2171
}
2172
#endif
2173
int wc_InitSha512_224(wc_Sha512* sha)
2174
0
{
2175
0
    return wc_InitSha512_224_ex(sha, NULL, INVALID_DEVID);
2176
0
}
2177
#if !defined(STM32_HASH_SHA512_224)
2178
int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len)
2179
0
{
2180
0
    return wc_Sha512Update(sha, data, len);
2181
0
}
2182
#endif
2183
#if defined(WOLFSSL_KCAPI_HASH)
2184
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2185
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2186
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2187
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2188
2189
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2190
#elif defined(STM32_HASH_SHA512_224)
2191
2192
#else
2193
int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash)
2194
0
{
2195
0
    return Sha512FinalRaw(sha, hash, WC_SHA512_224_DIGEST_SIZE);
2196
0
}
2197
2198
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
2199
0
{
2200
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_224_DIGEST_SIZE,
2201
0
                               InitSha512_224);
2202
0
}
2203
#endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
2204
2205
void wc_Sha512_224Free(wc_Sha512* sha)
2206
0
{
2207
0
    wc_Sha512Free(sha);
2208
0
}
2209
2210
#if defined(WOLFSSL_KCAPI_HASH)
2211
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2212
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2213
2214
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2215
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2216
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2217
2218
#else
2219
int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash)
2220
0
{
2221
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512_224Final);
2222
0
}
2223
2224
int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst)
2225
0
{
2226
0
    return wc_Sha512Copy(src, dst);
2227
0
}
2228
#endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
2229
2230
#ifdef WOLFSSL_HASH_FLAGS
2231
int wc_Sha512_224SetFlags(wc_Sha512* sha, word32 flags)
2232
{
2233
    return wc_Sha512SetFlags(sha, flags);
2234
}
2235
int wc_Sha512_224GetFlags(wc_Sha512* sha, word32* flags)
2236
{
2237
    return wc_Sha512GetFlags(sha, flags);
2238
}
2239
#endif /* WOLFSSL_HASH_FLAGS */
2240
2241
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
2242
int wc_Sha512_224Transform(wc_Sha512* sha, const unsigned char* data)
2243
{
2244
    return wc_Sha512Transform(sha, data);
2245
}
2246
#endif /* OPENSSL_EXTRA */
2247
2248
2249
#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */
2250
2251
#if !defined(WOLFSSL_NOSHA512_256) && \
2252
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
2253
#if defined(STM32_HASH_SHA512_256)
2254
2255
    int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
2256
    {
2257
        if (sha512 == NULL)
2258
            return BAD_FUNC_ARG;
2259
2260
        (void)devId;
2261
        (void)heap;
2262
2263
        XMEMSET(sha512, 0, sizeof(wc_Sha512));
2264
        wc_Stm32_Hash_Init(&sha512->stmCtx);
2265
        return 0;
2266
    }
2267
2268
    int wc_Sha512_256Update(wc_Sha512* sha512, const byte* data, word32 len)
2269
    {
2270
        int ret = 0;
2271
2272
        if (sha512 == NULL) {
2273
            return BAD_FUNC_ARG;
2274
        }
2275
        if (data == NULL && len == 0) {
2276
            /* valid, but do nothing */
2277
            return 0;
2278
        }
2279
        if (data == NULL) {
2280
            return BAD_FUNC_ARG;
2281
        }
2282
2283
        ret = wolfSSL_CryptHwMutexLock();
2284
        if (ret == 0) {
2285
            ret = wc_Stm32_Hash_Update(&sha512->stmCtx,
2286
                HASH_ALGOSELECTION_SHA512_256, data, len, WC_SHA512_256_BLOCK_SIZE);
2287
            wolfSSL_CryptHwMutexUnLock();
2288
        }
2289
        return ret;
2290
    }
2291
2292
    int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
2293
    {
2294
        int ret = 0;
2295
2296
        if (sha512 == NULL || hash == NULL) {
2297
            return BAD_FUNC_ARG;
2298
        }
2299
2300
        ret = wolfSSL_CryptHwMutexLock();
2301
        if (ret == 0) {
2302
            ret = wc_Stm32_Hash_Final(&sha512->stmCtx,
2303
                HASH_ALGOSELECTION_SHA512_256, hash, WC_SHA512_256_DIGEST_SIZE);
2304
            wolfSSL_CryptHwMutexUnLock();
2305
        }
2306
2307
        (void)wc_InitSha512_256(sha512); /* reset state */
2308
2309
        return ret;
2310
    }
2311
#endif
2312
int wc_InitSha512_256(wc_Sha512* sha)
2313
0
{
2314
0
    return wc_InitSha512_256_ex(sha, NULL, INVALID_DEVID);
2315
0
}
2316
#if !defined(STM32_HASH_SHA512_256)
2317
int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len)
2318
0
{
2319
0
    return wc_Sha512Update(sha, data, len);
2320
0
}
2321
#endif
2322
#if defined(WOLFSSL_KCAPI_HASH)
2323
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2324
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2325
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2326
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2327
2328
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2329
#elif defined(STM32_HASH_SHA512_256)
2330
#else
2331
int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash)
2332
0
{
2333
0
    return Sha512FinalRaw(sha, hash, WC_SHA512_256_DIGEST_SIZE);
2334
0
}
2335
2336
int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
2337
0
{
2338
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_256_DIGEST_SIZE,
2339
0
                               InitSha512_256);
2340
0
}
2341
#endif
2342
2343
void wc_Sha512_256Free(wc_Sha512* sha)
2344
0
{
2345
0
    wc_Sha512Free(sha);
2346
0
}
2347
2348
#if defined(WOLFSSL_KCAPI_HASH)
2349
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2350
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2351
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2352
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2353
2354
#else
2355
int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash)
2356
0
{
2357
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512_256Final);
2358
0
}
2359
int wc_Sha512_256Copy(wc_Sha512* src, wc_Sha512* dst)
2360
0
{
2361
0
    return wc_Sha512Copy(src, dst);
2362
0
}
2363
#endif
2364
2365
#ifdef WOLFSSL_HASH_FLAGS
2366
int wc_Sha512_256SetFlags(wc_Sha512* sha, word32 flags)
2367
{
2368
    return wc_Sha512SetFlags(sha, flags);
2369
}
2370
int wc_Sha512_256GetFlags(wc_Sha512* sha, word32* flags)
2371
{
2372
    return wc_Sha512GetFlags(sha, flags);
2373
}
2374
#endif /* WOLFSSL_HASH_FLAGS */
2375
2376
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
2377
int wc_Sha512_256Transform(wc_Sha512* sha, const unsigned char* data)
2378
{
2379
    return wc_Sha512Transform(sha, data);
2380
}
2381
#endif /* OPENSSL_EXTRA */
2382
2383
2384
#endif /* !WOLFSSL_NOSHA512_256 && !FIPS ... */
2385
2386
#endif /* WOLFSSL_SHA512 */
2387
2388
#ifdef WOLFSSL_SHA384
2389
2390
#if defined(WOLFSSL_KCAPI_HASH)
2391
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2392
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2393
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2394
    /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */
2395
#elif defined(MAX3266X_SHA)
2396
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2397
2398
#else
2399
2400
int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
2401
0
{
2402
0
    int ret;
2403
#ifdef WOLFSSL_SMALL_STACK
2404
    wc_Sha384* tmpSha384;
2405
#else
2406
0
    wc_Sha384  tmpSha384[1];
2407
0
#endif
2408
2409
0
    if (sha384 == NULL || hash == NULL) {
2410
0
        return BAD_FUNC_ARG;
2411
0
    }
2412
2413
#ifdef WOLFSSL_SMALL_STACK
2414
    tmpSha384 = (wc_Sha384*)XMALLOC(sizeof(wc_Sha384), NULL,
2415
        DYNAMIC_TYPE_TMP_BUFFER);
2416
    if (tmpSha384 == NULL) {
2417
        return MEMORY_E;
2418
    }
2419
#endif
2420
2421
    /* copy this sha384 into tmpSha */
2422
0
    ret = wc_Sha384Copy(sha384, tmpSha384);
2423
0
    if (ret == 0) {
2424
0
        ret = wc_Sha384Final(tmpSha384, hash);
2425
0
        wc_Sha384Free(tmpSha384);
2426
0
    }
2427
2428
#ifdef WOLFSSL_SMALL_STACK
2429
    XFREE(tmpSha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
2430
#endif
2431
2432
0
    return ret;
2433
0
}
2434
2435
int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
2436
0
{
2437
0
    int ret = 0;
2438
2439
0
    if (src == NULL || dst == NULL) {
2440
0
        return BAD_FUNC_ARG;
2441
0
    }
2442
2443
0
    XMEMCPY(dst, src, sizeof(wc_Sha384));
2444
2445
#ifdef WOLFSSL_SMALL_STACK_CACHE
2446
    dst->W = NULL;
2447
#endif
2448
2449
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3) && \
2450
    defined(WOLFSSL_SILABS_SHA384)
2451
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
2452
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
2453
#endif
2454
2455
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
2456
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
2457
#endif
2458
2459
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2460
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
2461
    #if defined(CONFIG_IDF_TARGET_ESP32)
2462
        esp_sha384_ctx_copy(src, dst);
2463
    #elif defined(CONFIG_IDF_TARGET_ESP32C2) || \
2464
          defined(CONFIG_IDF_TARGET_ESP8684) || \
2465
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
2466
          defined(CONFIG_IDF_TARGET_ESP32C6)
2467
        ESP_LOGV(TAG, "No SHA-384 HW on the ESP32-C3");
2468
    #elif defined(CONFIG_IDF_TARGET_ESP32S2) || \
2469
          defined(CONFIG_IDF_TARGET_ESP32S3)
2470
        esp_sha384_ctx_copy(src, dst);
2471
    #else
2472
        ESP_LOGW(TAG, "No SHA384 HW or not yet implemented for %s",
2473
                       CONFIG_IDF_TARGET);
2474
    #endif
2475
#endif
2476
2477
#ifdef HAVE_ARIA
2478
    dst->hSession = NULL;
2479
    if((src->hSession != NULL) && (MC_CopySession(src->hSession, &(dst->hSession)) != MC_OK)) {
2480
        return MEMORY_E;
2481
    }
2482
#endif
2483
2484
#ifdef WOLFSSL_HASH_FLAGS
2485
     dst->flags |= WC_HASH_FLAG_ISCOPY;
2486
#endif
2487
2488
#if defined(WOLFSSL_HASH_KEEP)
2489
    if (src->msg != NULL) {
2490
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
2491
        if (dst->msg == NULL)
2492
            return MEMORY_E;
2493
        XMEMCPY(dst->msg, src->msg, src->len);
2494
    }
2495
#endif
2496
2497
#ifdef MAX3266X_SHA_CB
2498
    ret = wc_MXC_TPU_SHA_Copy(&(src->mxcCtx), &(dst->mxcCtx));
2499
    if (ret != 0) {
2500
        return ret;
2501
    }
2502
#endif
2503
2504
0
    return ret;
2505
0
}
2506
2507
#endif /* WOLFSSL_KCAPI_HASH */
2508
2509
#ifdef WOLFSSL_HASH_FLAGS
2510
int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags)
2511
{
2512
    if (sha384) {
2513
        sha384->flags = flags;
2514
    }
2515
    return 0;
2516
}
2517
int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags)
2518
{
2519
    if (sha384 && flags) {
2520
        *flags = sha384->flags;
2521
    }
2522
    return 0;
2523
}
2524
#endif
2525
2526
#endif /* WOLFSSL_SHA384 */
2527
2528
#ifdef WOLFSSL_HASH_KEEP
2529
/* Some hardware have issues with update, this function stores the data to be
2530
 * hashed into an array. Once ready, the Final operation is called on all of the
2531
 * data to be hashed at once.
2532
 * returns 0 on success
2533
 */
2534
int wc_Sha512_Grow(wc_Sha512* sha512, const byte* in, int inSz)
2535
{
2536
    return _wc_Hash_Grow(&(sha512->msg), &(sha512->used), &(sha512->len), in,
2537
                        inSz, sha512->heap);
2538
}
2539
#ifdef WOLFSSL_SHA384
2540
int wc_Sha384_Grow(wc_Sha384* sha384, const byte* in, int inSz)
2541
{
2542
    return _wc_Hash_Grow(&(sha384->msg), &(sha384->used), &(sha384->len), in,
2543
                        inSz, sha384->heap);
2544
}
2545
#endif /* WOLFSSL_SHA384 */
2546
#endif /* WOLFSSL_HASH_KEEP */
2547
#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */