Coverage Report

Created: 2026-04-05 07:22

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