Coverage Report

Created: 2026-09-27 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl/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
#define WC_FIPS_LL_CRYPTO
58
#define _WC_BUILDING_SHA512_C
59
60
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
61
62
#if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) && \
63
    defined(WOLF_CRYPTO_CB_ONLY_SHA512) && defined(WOLFSSL_RISCV_ASM)
64
    #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with SHA-512 hardware" \
65
           " acceleration backends"
66
#endif
67
68
#if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384))
69
70
/* determine if we are using Espressif SHA hardware acceleration */
71
#undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
72
#if defined(WOLFSSL_ESP32_CRYPT) && !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)
73
    #include "sdkconfig.h"
74
    /* Define a single keyword for simplicity & readability.
75
     *
76
     * By default the HW acceleration is on for ESP32 Chipsets,
77
     * but individual components can be turned off. See user_settings.h
78
     */
79
    #define TAG "wc_sha_512"
80
    #define WOLFSSL_USE_ESP32_CRYPT_HASH_HW
81
#else
82
    #undef WOLFSSL_USE_ESP32_CRYPT_HASH_HW
83
#endif
84
85
#if defined(HAVE_FIPS) && defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
86
    #ifdef USE_WINDOWS_API
87
        #pragma code_seg(".fipsA$m")
88
        #pragma const_seg(".fipsB$m")
89
    #endif
90
#endif
91
92
#include <wolfssl/wolfcrypt/sha512.h>
93
#include <wolfssl/wolfcrypt/cpuid.h>
94
#include <wolfssl/wolfcrypt/hash.h>
95
96
#ifdef WOLF_CRYPTO_CB
97
    #include <wolfssl/wolfcrypt/cryptocb.h>
98
#endif
99
100
#ifdef WOLFSSL_IMXRT1170_CAAM
101
    #include <wolfssl/wolfcrypt/port/caam/wolfcaam_fsl_nxp.h>
102
#endif
103
104
/* deprecated USE_SLOW_SHA2 (replaced with USE_SLOW_SHA512) */
105
#if defined(USE_SLOW_SHA2) && !defined(USE_SLOW_SHA512)
106
    #define USE_SLOW_SHA512
107
#endif
108
109
#ifdef NO_INLINE
110
    #include <wolfssl/wolfcrypt/misc.h>
111
#else
112
    #define WOLFSSL_MISC_INCLUDED
113
    #include <wolfcrypt/src/misc.c>
114
#endif
115
116
#if FIPS_VERSION3_GE(6,0,0)
117
    const unsigned int wolfCrypt_FIPS_sha512_ro_sanity[2] =
118
                                                     { 0x1a2b3c4d, 0x00000015 };
119
    int wolfCrypt_FIPS_SHA512_sanity(void)
120
    {
121
        return 0;
122
    }
123
#endif
124
125
126
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
127
    #include <wolfssl/wolfcrypt/port/nxp/se050_port.h>
128
#endif
129
130
#if defined(MAX3266X_SHA)
131
    /* Already brought in by sha512.h */
132
    /* #include <wolfssl/wolfcrypt/port/maxim/max3266x.h> */
133
#endif
134
135
#if defined(WOLFSSL_PSOC6_CRYPTO)
136
    #include <wolfssl/wolfcrypt/port/cypress/psoc6_crypto.h>
137
#endif
138
139
#if defined(WC_C_DYNAMIC_FALLBACK) && \
140
        defined(WOLFSSL_AESNI) && !defined(USE_INTEL_SPEEDUP)
141
    /* AES-NI can be enabled with WC_C_DYNAMIC_FALLBACK, but without the rest of
142
     * USE_INTEL_SPEEDUP, in which case we need to disable the dynamic
143
     * fallback.
144
     */
145
    #undef WC_C_DYNAMIC_FALLBACK
146
#endif
147
148
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP)
149
    #if defined(__GNUC__) && ((__GNUC__ < 4) || \
150
                              (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
151
        #undef  NO_AVX2_SUPPORT
152
        #define NO_AVX2_SUPPORT
153
    #endif
154
    #if defined(__clang__) && ((__clang_major__ < 3) || \
155
                               (__clang_major__ == 3 && __clang_minor__ <= 5))
156
        #define NO_AVX2_SUPPORT
157
    #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)
158
        #undef NO_AVX2_SUPPORT
159
    #endif
160
161
    #define HAVE_INTEL_AVX1
162
    #ifndef NO_AVX2_SUPPORT
163
        #define HAVE_INTEL_AVX2
164
    #endif
165
#endif
166
167
#if defined(HAVE_INTEL_AVX1)
168
    /* #define DEBUG_XMM  */
169
#endif
170
171
#if defined(HAVE_INTEL_AVX2)
172
    #define HAVE_INTEL_RORX
173
    /* #define DEBUG_YMM  */
174
#endif
175
176
#ifdef WOLF_CRYPTO_CB_ONLY_SHA512
177
/* WOLF_CRYPTO_CB_ONLY_SHA512 strips the software SHA-512 implementation and
178
 * routes every operation (SHA-512, SHA-384, SHA-512/224, SHA-512/256) through
179
 * the crypto callback. It is mutually exclusive with any in-tree SHA-512
180
 * hardware/asm backend: keep this list in sync with the backend dispatch
181
 * chains in sha512.c. The RISC-V asm guard lives before the outer file guard;
182
 * these guards live before the dispatch chain so they are evaluated before a
183
 * hardware backend wins the #elif chain (in which case the
184
 * WOLF_CRYPTO_CB_ONLY_SHA512 branch itself is never compiled). */
185
#if (defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
186
        !defined(WOLFSSL_QNX_CAAM)) || \
187
    defined(WOLFSSL_SILABS_SHA512) || \
188
    defined(WOLFSSL_KCAPI_HASH) || \
189
    (defined(WOLFSSL_RENESAS_RSIP) && \
190
        !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)) || \
191
    defined(MAX3266X_SHA) || \
192
    (defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)) || \
193
    defined(STM32_HASH_SHA512) || \
194
    defined(PSOC6_HASH_SHA2) || \
195
    defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) || \
196
    defined(WOLFSSL_ARMASM) || \
197
    defined(WOLFSSL_RISCV_ASM) || \
198
    (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
199
        (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
200
    #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with SHA-512 hardware" \
201
           " acceleration backends"
202
#endif
203
#if defined(HAVE_FIPS)
204
    #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with FIPS builds"
205
#endif
206
/* WOLFSSL_HASH_KEEP accumulates all Update data into sha->msg and passes it
207
 * all to hardware in Final. That pattern is driven by port-specific backends
208
 * (e.g. CAAM) which are already excluded above; the crypto-callback Update
209
 * path dispatches each chunk directly to the callback instead, so the two
210
 * mechanisms are incompatible. */
211
#ifdef WOLFSSL_HASH_KEEP
212
    #error "WOLF_CRYPTO_CB_ONLY_SHA512 is incompatible with WOLFSSL_HASH_KEEP"
213
#endif
214
#endif /* WOLF_CRYPTO_CB_ONLY_SHA512 */
215
216
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
217
    !defined(WOLFSSL_QNX_CAAM)
218
    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
219
220
#elif defined(WOLFSSL_SILABS_SHA512)
221
    /* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */
222
223
#elif defined(WOLFSSL_KCAPI_HASH)
224
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
225
226
#elif defined(WOLFSSL_RENESAS_RSIP) && \
227
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
228
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
229
230
#elif defined(MAX3266X_SHA)
231
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
232
233
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
234
    int wc_InitSha512(wc_Sha512* sha512)
235
    {
236
        int ret;
237
        if (sha512 == NULL)
238
            return BAD_FUNC_ARG;
239
        ret = se050_hash_init(&sha512->se050Ctx, NULL);
240
#if defined(WOLFSSL_SHA512_HASHTYPE)
241
        if (ret == 0) {
242
            sha512->hashType = WC_HASH_TYPE_SHA512;
243
        }
244
#endif
245
        return ret;
246
    }
247
    int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
248
    {
249
        int ret;
250
        if (sha512 == NULL) {
251
            return BAD_FUNC_ARG;
252
        }
253
        (void)devId;
254
        ret = se050_hash_init(&sha512->se050Ctx, heap);
255
#if defined(WOLFSSL_SHA512_HASHTYPE)
256
        if (ret == 0) {
257
            sha512->hashType = WC_HASH_TYPE_SHA512;
258
        }
259
#endif
260
        return ret;
261
    }
262
    int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
263
    {
264
        if (sha512 == NULL) {
265
            return BAD_FUNC_ARG;
266
        }
267
        if (data == NULL && len == 0) {
268
            /* valid, but do nothing */
269
            return 0;
270
        }
271
        if (data == NULL) {
272
            return BAD_FUNC_ARG;
273
        }
274
275
        return se050_hash_update(&sha512->se050Ctx, data, len);
276
    }
277
    int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
278
    {
279
        int ret = 0;
280
        int devId = INVALID_DEVID;
281
        if (sha512 == NULL) {
282
            return BAD_FUNC_ARG;
283
        }
284
    #ifdef WOLF_CRYPTO_CB
285
        devId = sha512->devId;
286
    #endif
287
        ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE,
288
                               kAlgorithm_SSS_SHA512);
289
        return ret;
290
    }
291
    int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
292
    {
293
        int ret = 0;
294
        int devId = INVALID_DEVID;
295
        if (sha512 == NULL) {
296
            return BAD_FUNC_ARG;
297
        }
298
    #ifdef WOLF_CRYPTO_CB
299
        devId = sha512->devId;
300
    #endif
301
        ret = se050_hash_final(&sha512->se050Ctx, hash, WC_SHA512_DIGEST_SIZE,
302
                               kAlgorithm_SSS_SHA512);
303
        return ret;
304
    }
305
    void wc_Sha512Free(wc_Sha512* sha512)
306
    {
307
        se050_hash_free(&sha512->se050Ctx);
308
    }
309
#elif defined(STM32_HASH_SHA512)
310
311
    /* Supports CubeMX HAL or Standard Peripheral Library */
312
313
    int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
314
    {
315
        if (sha512 == NULL)
316
            return BAD_FUNC_ARG;
317
318
        (void)devId;
319
        (void)heap;
320
321
        XMEMSET(sha512, 0, sizeof(wc_Sha512));
322
        wc_Stm32_Hash_Init(&sha512->stmCtx);
323
#if defined(WOLFSSL_SHA512_HASHTYPE)
324
        sha512->hashType = WC_HASH_TYPE_SHA512;
325
#endif
326
        return 0;
327
    }
328
329
    int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
330
    {
331
        int ret = 0;
332
333
        if (sha512 == NULL) {
334
            return BAD_FUNC_ARG;
335
        }
336
        if (data == NULL && len == 0) {
337
            /* valid, but do nothing */
338
            return 0;
339
        }
340
        if (data == NULL) {
341
            return BAD_FUNC_ARG;
342
        }
343
344
        ret = wolfSSL_CryptHwMutexLock();
345
        if (ret == 0) {
346
            ret = wc_Stm32_Hash_Update(&sha512->stmCtx,
347
                HASH_ALGOSELECTION_SHA512, data, len, WC_SHA512_BLOCK_SIZE);
348
            wolfSSL_CryptHwMutexUnLock();
349
        }
350
        return ret;
351
    }
352
353
    int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
354
    {
355
        int ret = 0;
356
357
        if (sha512 == NULL || hash == NULL) {
358
            return BAD_FUNC_ARG;
359
        }
360
361
        ret = wolfSSL_CryptHwMutexLock();
362
        if (ret == 0) {
363
            ret = wc_Stm32_Hash_Final(&sha512->stmCtx,
364
                HASH_ALGOSELECTION_SHA512, hash, WC_SHA512_DIGEST_SIZE);
365
            wolfSSL_CryptHwMutexUnLock();
366
        }
367
368
        (void)wc_InitSha512(sha512); /* reset state */
369
370
        return ret;
371
    }
372
#elif defined(PSOC6_HASH_SHA2)
373
    /* Functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
374
375
#elif defined(WOLF_CRYPTO_CB_ONLY_SHA512)
376
377
static int Sha512_CbReset(wc_Sha512* sha512, const word64* initDigest,
378
    int hashType)
379
{
380
    int i;
381
382
    if (sha512 == NULL)
383
        return BAD_FUNC_ARG;
384
385
    for (i = 0; i < 8; i++)
386
        sha512->digest[i] = initDigest[i];
387
388
    sha512->buffLen = 0;
389
    XMEMSET(sha512->buffer, 0, sizeof(sha512->buffer));
390
    sha512->loLen = 0;
391
    sha512->hiLen = 0;
392
#ifdef WOLFSSL_HASH_FLAGS
393
    sha512->flags = 0;
394
#endif
395
#if defined(WOLFSSL_SHA512_HASHTYPE)
396
    sha512->hashType = hashType;
397
#else
398
    (void)hashType;
399
#endif
400
    return 0;
401
}
402
403
static int Sha512_CbInit(wc_Sha512* sha512, const word64* initDigest,
404
    void* heap, int devId, int hashType)
405
{
406
    int ret;
407
408
    /* Zero the whole struct first so fields not touched by the callback path
409
     * (e.g. asyncDev, W, devCtx) never expose uninitialized stack data to a
410
     * callback; the admin fields below are then set explicitly. */
411
    if (sha512 != NULL)
412
        XMEMSET(sha512, 0, sizeof(*sha512));
413
414
    ret = Sha512_CbReset(sha512, initDigest, hashType);
415
    if (ret != 0)
416
        return ret;
417
418
    sha512->heap = heap;
419
    sha512->devId = devId;
420
    sha512->devCtx = NULL;
421
422
    return 0;
423
}
424
425
#ifdef WOLFSSL_SHA512
426
427
static const word64 sha512Init[8] = {
428
    W64LIT(0x6a09e667f3bcc908), W64LIT(0xbb67ae8584caa73b),
429
    W64LIT(0x3c6ef372fe94f82b), W64LIT(0xa54ff53a5f1d36f1),
430
    W64LIT(0x510e527fade682d1), W64LIT(0x9b05688c2b3e6c1f),
431
    W64LIT(0x1f83d9abfb41bd6b), W64LIT(0x5be0cd19137e2179)
432
};
433
434
static int Sha512_CbFinal(wc_Sha512* sha512, byte* hash, size_t digestSz)
435
{
436
    if (sha512 == NULL || hash == NULL)
437
        return BAD_FUNC_ARG;
438
439
    #ifndef WOLF_CRYPTO_CB_FIND
440
    if (sha512->devId != INVALID_DEVID)
441
    #endif
442
    {
443
        int ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, hash, digestSz);
444
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
445
            return ret;
446
    }
447
    return NO_VALID_DEVID;
448
}
449
450
int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
451
{
452
    return Sha512_CbInit(sha512, sha512Init, heap, devId,
453
                         WC_HASH_TYPE_SHA512);
454
}
455
456
int wc_InitSha512(wc_Sha512* sha512)
457
{
458
    int devId = INVALID_DEVID;
459
460
#ifdef WOLF_CRYPTO_CB
461
    devId = wc_CryptoCb_DefaultDevID();
462
#endif
463
    return wc_InitSha512_ex(sha512, NULL, devId);
464
}
465
466
int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
467
{
468
    if (sha512 == NULL)
469
        return BAD_FUNC_ARG;
470
    if (data == NULL && len == 0)
471
        return 0;
472
    if (data == NULL)
473
        return BAD_FUNC_ARG;
474
475
    #ifndef WOLF_CRYPTO_CB_FIND
476
    if (sha512->devId != INVALID_DEVID)
477
    #endif
478
    {
479
        int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL, 0);
480
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
481
            return ret;
482
    }
483
    return NO_VALID_DEVID;
484
}
485
486
int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
487
{
488
    return Sha512_CbFinal(sha512, hash, WC_SHA512_DIGEST_SIZE);
489
}
490
491
void wc_Sha512Free(wc_Sha512* sha512)
492
{
493
#ifdef WOLF_CRYPTO_CB_FREE
494
    int ret = 0;
495
#endif
496
497
    if (sha512 == NULL)
498
        return;
499
500
#ifdef WOLF_CRYPTO_CB_FREE
501
    #ifndef WOLF_CRYPTO_CB_FIND
502
    if (sha512->devId != INVALID_DEVID)
503
    #endif
504
    {
505
        ret = wc_CryptoCb_Free(sha512->devId, WC_ALGO_TYPE_HASH,
506
                         WC_HASH_TYPE_SHA512, 0, (void*)sha512);
507
        /* If they want the standard free, they can call it themselves */
508
        /* via their callback setting devId to INVALID_DEVID */
509
        /* otherwise assume the callback handled it */
510
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
511
            return;
512
        /* fall-through when unavailable */
513
    }
514
515
    /* silence compiler warning */
516
    (void)ret;
517
#endif /* WOLF_CRYPTO_CB_FREE */
518
519
    ForceZero(sha512, sizeof(*sha512));
520
}
521
522
int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)
523
{
524
    int ret;
525
    WC_DECLARE_VAR(tmpSha512, wc_Sha512, 1, 0);
526
527
    if (sha512 == NULL || hash == NULL)
528
        return BAD_FUNC_ARG;
529
530
    WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
531
        return MEMORY_E);
532
533
    ret = wc_Sha512Copy(sha512, tmpSha512);
534
    if (ret == 0) {
535
        ret = wc_Sha512Final(tmpSha512, hash);
536
        wc_Sha512Free(tmpSha512);
537
    }
538
539
    WC_FREE_VAR_EX(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
540
541
    return ret;
542
}
543
544
int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
545
{
546
    int ret = 0;
547
548
    if (src == NULL || dst == NULL)
549
        return BAD_FUNC_ARG;
550
551
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
552
    #ifndef WOLF_CRYPTO_CB_FIND
553
    if (src->devId != INVALID_DEVID)
554
    #endif
555
    {
556
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
557
                               WC_HASH_TYPE_SHA512, (void*)src, (void*)dst);
558
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
559
            return ret;
560
        /* fall-through when the callback is unavailable */
561
    }
562
    ret = 0; /* discard CRYPTOCB_UNAVAILABLE before the plain struct copy */
563
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
564
565
    wc_Sha512Free(dst);
566
    XMEMCPY(dst, src, sizeof(wc_Sha512));
567
568
#ifdef WOLFSSL_HASH_FLAGS
569
    dst->flags |= WC_HASH_FLAG_ISCOPY;
570
#endif
571
572
    return ret;
573
}
574
575
#ifdef WOLFSSL_HASH_FLAGS
576
int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags)
577
{
578
    if (sha512)
579
        sha512->flags = flags;
580
    return 0;
581
}
582
int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags)
583
{
584
    if (sha512 && flags)
585
        *flags = sha512->flags;
586
    return 0;
587
}
588
#endif /* WOLFSSL_HASH_FLAGS */
589
590
#if !defined(WOLFSSL_NOSHA512_224) && !defined(HAVE_SELFTEST)
591
592
static const word64 sha512_224Init[8] = {
593
    W64LIT(0x8c3d37c819544da2), W64LIT(0x73e1996689dcd4d6),
594
    W64LIT(0x1dfab7ae32ff9c82), W64LIT(0x679dd514582f9fcf),
595
    W64LIT(0x0f6d2b697bd44da8), W64LIT(0x77e36f7304c48942),
596
    W64LIT(0x3f9d85a86a1d36c8), W64LIT(0x1112e6ad91d692a1)
597
};
598
599
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
600
{
601
    return Sha512_CbInit(sha512, sha512_224Init, heap, devId,
602
                         WC_HASH_TYPE_SHA512_224);
603
}
604
605
int wc_InitSha512_224(wc_Sha512* sha512)
606
{
607
    int devId = INVALID_DEVID;
608
609
#ifdef WOLF_CRYPTO_CB
610
    devId = wc_CryptoCb_DefaultDevID();
611
#endif
612
    return wc_InitSha512_224_ex(sha512, NULL, devId);
613
}
614
615
int wc_Sha512_224Update(wc_Sha512* sha512, const byte* data, word32 len)
616
{
617
    return wc_Sha512Update(sha512, data, len);
618
}
619
620
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
621
{
622
    return Sha512_CbFinal(sha512, hash, WC_SHA512_224_DIGEST_SIZE);
623
}
624
625
void wc_Sha512_224Free(wc_Sha512* sha512)
626
{
627
    wc_Sha512Free(sha512);
628
}
629
630
int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst)
631
{
632
    return wc_Sha512Copy(src, dst);
633
}
634
635
int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash)
636
{
637
    int ret;
638
    WC_DECLARE_VAR(tmpSha512, wc_Sha512, 1, 0);
639
640
    if (sha512 == NULL || hash == NULL)
641
        return BAD_FUNC_ARG;
642
643
    WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
644
        return MEMORY_E);
645
646
    ret = wc_Sha512_224Copy(sha512, tmpSha512);
647
    if (ret == 0) {
648
        ret = wc_Sha512_224Final(tmpSha512, hash);
649
        wc_Sha512_224Free(tmpSha512);
650
    }
651
652
    WC_FREE_VAR_EX(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
653
654
    return ret;
655
}
656
657
#ifdef WOLFSSL_HASH_FLAGS
658
int wc_Sha512_224SetFlags(wc_Sha512* sha512, word32 flags)
659
{
660
    return wc_Sha512SetFlags(sha512, flags);
661
}
662
int wc_Sha512_224GetFlags(wc_Sha512* sha512, word32* flags)
663
{
664
    return wc_Sha512GetFlags(sha512, flags);
665
}
666
#endif /* WOLFSSL_HASH_FLAGS */
667
668
#endif /* !WOLFSSL_NOSHA512_224 && !HAVE_SELFTEST */
669
670
#if !defined(WOLFSSL_NOSHA512_256) && !defined(HAVE_SELFTEST)
671
672
static const word64 sha512_256Init[8] = {
673
    W64LIT(0x22312194fc2bf72c), W64LIT(0x9f555fa3c84c64c2),
674
    W64LIT(0x2393b86b6f53b151), W64LIT(0x963877195940eabd),
675
    W64LIT(0x96283ee2a88effe3), W64LIT(0xbe5e1e2553863992),
676
    W64LIT(0x2b0199fc2c85b8aa), W64LIT(0x0eb72ddc81c52ca2)
677
};
678
679
int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
680
{
681
    return Sha512_CbInit(sha512, sha512_256Init, heap, devId,
682
                         WC_HASH_TYPE_SHA512_256);
683
}
684
685
int wc_InitSha512_256(wc_Sha512* sha512)
686
{
687
    int devId = INVALID_DEVID;
688
689
#ifdef WOLF_CRYPTO_CB
690
    devId = wc_CryptoCb_DefaultDevID();
691
#endif
692
    return wc_InitSha512_256_ex(sha512, NULL, devId);
693
}
694
695
int wc_Sha512_256Update(wc_Sha512* sha512, const byte* data, word32 len)
696
{
697
    return wc_Sha512Update(sha512, data, len);
698
}
699
700
int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
701
{
702
    return Sha512_CbFinal(sha512, hash, WC_SHA512_256_DIGEST_SIZE);
703
}
704
705
void wc_Sha512_256Free(wc_Sha512* sha512)
706
{
707
    wc_Sha512Free(sha512);
708
}
709
710
int wc_Sha512_256Copy(wc_Sha512* src, wc_Sha512* dst)
711
{
712
    return wc_Sha512Copy(src, dst);
713
}
714
715
int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash)
716
{
717
    int ret;
718
    WC_DECLARE_VAR(tmpSha512, wc_Sha512, 1, 0);
719
720
    if (sha512 == NULL || hash == NULL)
721
        return BAD_FUNC_ARG;
722
723
    WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
724
        return MEMORY_E);
725
726
    ret = wc_Sha512_256Copy(sha512, tmpSha512);
727
    if (ret == 0) {
728
        ret = wc_Sha512_256Final(tmpSha512, hash);
729
        wc_Sha512_256Free(tmpSha512);
730
    }
731
732
    WC_FREE_VAR_EX(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
733
734
    return ret;
735
}
736
737
#ifdef WOLFSSL_HASH_FLAGS
738
int wc_Sha512_256SetFlags(wc_Sha512* sha512, word32 flags)
739
{
740
    return wc_Sha512SetFlags(sha512, flags);
741
}
742
int wc_Sha512_256GetFlags(wc_Sha512* sha512, word32* flags)
743
{
744
    return wc_Sha512GetFlags(sha512, flags);
745
}
746
#endif /* WOLFSSL_HASH_FLAGS */
747
748
#endif /* !WOLFSSL_NOSHA512_256 && !HAVE_SELFTEST */
749
750
#endif /* WOLFSSL_SHA512 */
751
752
#ifdef WOLFSSL_SHA384
753
754
static const word64 sha384Init[8] = {
755
    W64LIT(0xcbbb9d5dc1059ed8), W64LIT(0x629a292a367cd507),
756
    W64LIT(0x9159015a3070dd17), W64LIT(0x152fecd8f70e5939),
757
    W64LIT(0x67332667ffc00b31), W64LIT(0x8eb44a8768581511),
758
    W64LIT(0xdb0c2e0d64f98fa7), W64LIT(0x47b5481dbefa4fa4)
759
};
760
761
int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
762
{
763
    return Sha512_CbInit(sha384, sha384Init, heap, devId,
764
                         WC_HASH_TYPE_SHA384);
765
}
766
767
int wc_InitSha384(wc_Sha384* sha384)
768
{
769
    int devId = INVALID_DEVID;
770
771
#ifdef WOLF_CRYPTO_CB
772
    devId = wc_CryptoCb_DefaultDevID();
773
#endif
774
    return wc_InitSha384_ex(sha384, NULL, devId);
775
}
776
777
int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
778
{
779
    if (sha384 == NULL)
780
        return BAD_FUNC_ARG;
781
    if (data == NULL && len == 0)
782
        return 0;
783
    if (data == NULL)
784
        return BAD_FUNC_ARG;
785
786
    #ifndef WOLF_CRYPTO_CB_FIND
787
    if (sha384->devId != INVALID_DEVID)
788
    #endif
789
    {
790
        int ret = wc_CryptoCb_Sha384Hash(sha384, data, len, NULL);
791
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
792
            return ret;
793
    }
794
    return NO_VALID_DEVID;
795
}
796
797
int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
798
{
799
    if (sha384 == NULL || hash == NULL)
800
        return BAD_FUNC_ARG;
801
802
    #ifndef WOLF_CRYPTO_CB_FIND
803
    if (sha384->devId != INVALID_DEVID)
804
    #endif
805
    {
806
        int ret = wc_CryptoCb_Sha384Hash(sha384, NULL, 0, hash);
807
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
808
            return ret;
809
    }
810
    return NO_VALID_DEVID;
811
}
812
813
void wc_Sha384Free(wc_Sha384* sha384)
814
{
815
#ifdef WOLF_CRYPTO_CB_FREE
816
    int ret = 0;
817
#endif
818
819
    if (sha384 == NULL)
820
        return;
821
822
#ifdef WOLF_CRYPTO_CB_FREE
823
    #ifndef WOLF_CRYPTO_CB_FIND
824
    if (sha384->devId != INVALID_DEVID)
825
    #endif
826
    {
827
        ret = wc_CryptoCb_Free(sha384->devId, WC_ALGO_TYPE_HASH,
828
                         WC_HASH_TYPE_SHA384, 0, (void*)sha384);
829
        /* If they want the standard free, they can call it themselves */
830
        /* via their callback setting devId to INVALID_DEVID */
831
        /* otherwise assume the callback handled it */
832
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
833
            return;
834
        /* fall-through when unavailable */
835
    }
836
837
    /* silence compiler warning */
838
    (void)ret;
839
#endif /* WOLF_CRYPTO_CB_FREE */
840
841
    ForceZero(sha384, sizeof(*sha384));
842
}
843
844
int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
845
{
846
    int ret;
847
    WC_DECLARE_VAR(tmpSha384, wc_Sha384, 1, 0);
848
849
    if (sha384 == NULL || hash == NULL)
850
        return BAD_FUNC_ARG;
851
852
    WC_CALLOC_VAR_EX(tmpSha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
853
        return MEMORY_E);
854
855
    ret = wc_Sha384Copy(sha384, tmpSha384);
856
    if (ret == 0) {
857
        ret = wc_Sha384Final(tmpSha384, hash);
858
        wc_Sha384Free(tmpSha384);
859
    }
860
861
    WC_FREE_VAR_EX(tmpSha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
862
863
    return ret;
864
}
865
866
int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
867
{
868
    int ret = 0;
869
870
    if (src == NULL || dst == NULL)
871
        return BAD_FUNC_ARG;
872
873
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
874
    #ifndef WOLF_CRYPTO_CB_FIND
875
    if (src->devId != INVALID_DEVID)
876
    #endif
877
    {
878
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
879
                               WC_HASH_TYPE_SHA384, (void*)src, (void*)dst);
880
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
881
            return ret;
882
        /* fall-through when the callback is unavailable */
883
    }
884
    ret = 0; /* discard CRYPTOCB_UNAVAILABLE before the plain struct copy */
885
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
886
887
    wc_Sha384Free(dst);
888
    XMEMCPY(dst, src, sizeof(wc_Sha384));
889
890
#ifdef WOLFSSL_HASH_FLAGS
891
    dst->flags |= WC_HASH_FLAG_ISCOPY;
892
#endif
893
894
    return ret;
895
}
896
897
#ifdef WOLFSSL_HASH_FLAGS
898
int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags)
899
{
900
    if (sha384)
901
        sha384->flags = flags;
902
    return 0;
903
}
904
int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags)
905
{
906
    if (sha384 && flags)
907
        *flags = sha384->flags;
908
    return 0;
909
}
910
#endif /* WOLFSSL_HASH_FLAGS */
911
912
#endif /* WOLFSSL_SHA384 */
913
#else
914
915
#ifdef WOLFSSL_SHA512
916
917
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
918
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
919
    defined(WOLFSSL_ARMASM)
920
static void Sha512_SetTransform(void);
921
#endif
922
923
static int InitSha512(wc_Sha512* sha512)
924
0
{
925
0
    if (sha512 == NULL)
926
0
        return BAD_FUNC_ARG;
927
928
0
    sha512->digest[0] = W64LIT(0x6a09e667f3bcc908);
929
0
    sha512->digest[1] = W64LIT(0xbb67ae8584caa73b);
930
0
    sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b);
931
0
    sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1);
932
0
    sha512->digest[4] = W64LIT(0x510e527fade682d1);
933
0
    sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f);
934
0
    sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b);
935
0
    sha512->digest[7] = W64LIT(0x5be0cd19137e2179);
936
937
0
    sha512->buffLen = 0;
938
0
    XMEMSET(sha512->buffer, 0, sizeof(sha512->buffer));
939
0
    sha512->loLen   = 0;
940
0
    sha512->hiLen   = 0;
941
942
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
943
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
944
    defined(WOLFSSL_ARMASM)
945
    Sha512_SetTransform();
946
#endif
947
948
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
949
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
950
951
    /* HW needs to be carefully initialized, taking into account soft copy.
952
    ** If already in use; copy may revert to SW as needed. */
953
    esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512);
954
#endif
955
956
#ifdef WOLFSSL_HASH_FLAGS
957
    sha512->flags = 0;
958
#endif
959
#if defined(WOLFSSL_SHA512_HASHTYPE)
960
    sha512->hashType = WC_HASH_TYPE_SHA512;
961
#endif /* WOLFSSL_SHA512_HASHTYPE */
962
0
    return 0;
963
0
}
964
965
#if !defined(WOLFSSL_HASH_KEEP)
966
967
/* Reset a hash context to its freshly initialized state, reusing its existing
968
 * allocations.  Like the Final functions, Reset does not destroy sensitive
969
 * internal state; use the matching Free function for teardown at end of life.
970
 */
971
0
int wc_Sha512Reset(wc_Sha512* sha512) {
972
0
    if (sha512 == NULL)
973
0
        return BAD_FUNC_ARG;
974
#ifdef WOLF_CRYPTO_CB
975
    /* A device may hang state off devCtx that InitSha512() cannot restart.
976
     * Free and re-init so the callback gets its teardown and setup. */
977
    #ifndef WOLF_CRYPTO_CB_FIND
978
    if (sha512->devId != INVALID_DEVID)
979
    #endif
980
    {
981
        void* heap = sha512->heap;
982
        int devId = sha512->devId;
983
        wc_Sha512Free(sha512);
984
        return wc_InitSha512_ex(sha512, heap, devId);
985
    }
986
#endif
987
0
    return InitSha512(sha512);
988
0
}
989
#define WC_SHA512RESET_DEFINED
990
#endif /* !WOLFSSL_HASH_KEEP */
991
992
#if !defined(WOLFSSL_NOSHA512_224) && \
993
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
994
995
/**
996
 * Initialize given wc_Sha512 structure with value specific to sha512/224.
997
 * Note that sha512/224 has different initial hash value from sha512.
998
 * The initial hash value consists of eight 64bit words. They are given
999
 * in FIPS180-4.
1000
 */
1001
static int InitSha512_224(wc_Sha512* sha512)
1002
0
{
1003
0
    if (sha512 == NULL)
1004
0
        return BAD_FUNC_ARG;
1005
1006
0
    sha512->digest[0] = W64LIT(0x8c3d37c819544da2);
1007
0
    sha512->digest[1] = W64LIT(0x73e1996689dcd4d6);
1008
0
    sha512->digest[2] = W64LIT(0x1dfab7ae32ff9c82);
1009
0
    sha512->digest[3] = W64LIT(0x679dd514582f9fcf);
1010
0
    sha512->digest[4] = W64LIT(0x0f6d2b697bd44da8);
1011
0
    sha512->digest[5] = W64LIT(0x77e36f7304c48942);
1012
0
    sha512->digest[6] = W64LIT(0x3f9d85a86a1d36c8);
1013
0
    sha512->digest[7] = W64LIT(0x1112e6ad91d692a1);
1014
1015
0
    sha512->buffLen = 0;
1016
0
    XMEMSET(sha512->buffer, 0, sizeof(sha512->buffer));
1017
0
    sha512->loLen   = 0;
1018
0
    sha512->hiLen   = 0;
1019
1020
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1021
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
1022
    defined(WOLFSSL_ARMASM)
1023
    Sha512_SetTransform();
1024
#endif
1025
1026
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1027
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1028
    /* HW needs to be carefully initialized, taking into account soft copy.
1029
    ** If already in use; copy may revert to SW as needed.
1030
    **
1031
    ** Note for original ESP32, there's no HW for SHA512/224
1032
    */
1033
    esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_224);
1034
#endif
1035
1036
#ifdef WOLFSSL_HASH_FLAGS
1037
    sha512->flags = 0;
1038
#endif
1039
#if defined(WOLFSSL_SHA512_HASHTYPE)
1040
    sha512->hashType = WC_HASH_TYPE_SHA512_224;
1041
#endif /* WOLFSSL_SHA512_HASHTYPE */
1042
0
    return 0;
1043
0
}
1044
1045
#if !defined(WOLFSSL_HASH_KEEP)
1046
0
int wc_Sha512_224Reset(wc_Sha512* sha512) {
1047
0
    if (sha512 == NULL)
1048
0
        return BAD_FUNC_ARG;
1049
#ifdef WOLF_CRYPTO_CB
1050
    /* A device may hang state off devCtx that InitSha512_224() cannot restart.
1051
     * Free and re-init so the callback gets its teardown and setup. */
1052
    #ifndef WOLF_CRYPTO_CB_FIND
1053
    if (sha512->devId != INVALID_DEVID)
1054
    #endif
1055
    {
1056
        void* heap = sha512->heap;
1057
        int devId = sha512->devId;
1058
        wc_Sha512_224Free(sha512);
1059
        return wc_InitSha512_224_ex(sha512, heap, devId);
1060
    }
1061
#endif
1062
0
    return InitSha512_224(sha512);
1063
0
}
1064
#define WC_SHA512_224RESET_DEFINED
1065
#endif /* !WOLFSSL_HASH_KEEP */
1066
#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */
1067
1068
#if !defined(WOLFSSL_NOSHA512_256) && \
1069
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
1070
/**
1071
 * Initialize given wc_Sha512 structure with value specific to sha512/256.
1072
 * Note that sha512/256 has different initial hash value from sha512.
1073
 * The initial hash value consists of eight 64bit words. They are given
1074
 * in FIPS180-4.
1075
 */
1076
static int InitSha512_256(wc_Sha512* sha512)
1077
0
{
1078
0
    if (sha512 == NULL)
1079
0
        return BAD_FUNC_ARG;
1080
1081
0
    sha512->digest[0] = W64LIT(0x22312194fc2bf72c);
1082
0
    sha512->digest[1] = W64LIT(0x9f555fa3c84c64c2);
1083
0
    sha512->digest[2] = W64LIT(0x2393b86b6f53b151);
1084
0
    sha512->digest[3] = W64LIT(0x963877195940eabd);
1085
0
    sha512->digest[4] = W64LIT(0x96283ee2a88effe3);
1086
0
    sha512->digest[5] = W64LIT(0xbe5e1e2553863992);
1087
0
    sha512->digest[6] = W64LIT(0x2b0199fc2c85b8aa);
1088
0
    sha512->digest[7] = W64LIT(0x0eb72ddc81c52ca2);
1089
1090
0
    sha512->buffLen = 0;
1091
0
    XMEMSET(sha512->buffer, 0, sizeof(sha512->buffer));
1092
0
    sha512->loLen   = 0;
1093
0
    sha512->hiLen   = 0;
1094
1095
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1096
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
1097
    defined(WOLFSSL_ARMASM)
1098
    Sha512_SetTransform();
1099
#endif
1100
1101
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1102
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1103
    /* HW needs to be carefully initialized, taking into account soft copy.
1104
    ** If already in use; copy may revert to SW as needed.
1105
    **
1106
    ** Note for original ESP32, there's no HW for SHA512/2256.
1107
    */
1108
    esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_256);
1109
#endif
1110
1111
#ifdef WOLFSSL_HASH_FLAGS
1112
    sha512->flags = 0;
1113
#endif
1114
#if defined(WOLFSSL_SHA512_HASHTYPE)
1115
    sha512->hashType = WC_HASH_TYPE_SHA512_256;
1116
#endif /* WOLFSSL_SHA512_HASHTYPE */
1117
0
    return 0;
1118
0
}
1119
1120
#if !defined(WOLFSSL_HASH_KEEP)
1121
0
int wc_Sha512_256Reset(wc_Sha512* sha512) {
1122
0
    if (sha512 == NULL)
1123
0
        return BAD_FUNC_ARG;
1124
#ifdef WOLF_CRYPTO_CB
1125
    /* A device may hang state off devCtx that InitSha512_256() cannot restart.
1126
     * Free and re-init so the callback gets its teardown and setup. */
1127
    #ifndef WOLF_CRYPTO_CB_FIND
1128
    if (sha512->devId != INVALID_DEVID)
1129
    #endif
1130
    {
1131
        void* heap = sha512->heap;
1132
        int devId = sha512->devId;
1133
        wc_Sha512_256Free(sha512);
1134
        return wc_InitSha512_256_ex(sha512, heap, devId);
1135
    }
1136
#endif
1137
0
    return InitSha512_256(sha512);
1138
0
}
1139
#define WC_SHA512_256RESET_DEFINED
1140
#endif /* !WOLFSSL_HASH_KEEP */
1141
#endif /* !WOLFSSL_NOSHA512_256 && !FIPS... */
1142
1143
#endif /* WOLFSSL_SHA512 */
1144
1145
/* Hardware Acceleration */
1146
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1147
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1148
1149
    /*****
1150
    Intel AVX1/AVX2 Macro Control Structure
1151
1152
    #if defined(HAVE_INTEL_SPEEDUP)
1153
        #define HAVE_INTEL_AVX1
1154
        #define HAVE_INTEL_AVX2
1155
    #endif
1156
1157
    int InitSha512(wc_Sha512* sha512) {
1158
         Save/Recover XMM, YMM
1159
         ...
1160
1161
         Check Intel AVX cpuid flags
1162
    }
1163
1164
    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
1165
      Transform_Sha512_AVX1(); # Function prototype
1166
      Transform_Sha512_AVX2(); #
1167
    #endif
1168
1169
      _Transform_Sha512() {     # Native Transform Function body
1170
1171
      }
1172
1173
      int Sha512Update() {
1174
         Save/Recover XMM, YMM
1175
         ...
1176
      }
1177
1178
      int Sha512Final() {
1179
         Save/Recover XMM, YMM
1180
         ...
1181
      }
1182
1183
1184
    #if defined(HAVE_INTEL_AVX1)
1185
1186
       XMM Instructions/INLINE asm Definitions
1187
1188
    #endif
1189
1190
    #if defined(HAVE_INTEL_AVX2)
1191
1192
       YMM Instructions/INLINE asm Definitions
1193
1194
    #endif
1195
1196
    #if defined(HAVE_INTEL_AVX1)
1197
1198
      int Transform_Sha512_AVX1() {
1199
          Stitched Message Sched/Round
1200
      }
1201
1202
    #endif
1203
1204
    #if defined(HAVE_INTEL_AVX2)
1205
1206
      int Transform_Sha512_AVX2() {
1207
          Stitched Message Sched/Round
1208
      }
1209
    #endif
1210
1211
    */
1212
1213
1214
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
1215
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
1216
     */
1217
1218
#ifdef __cplusplus
1219
    extern "C" {
1220
#endif
1221
1222
    #if defined(HAVE_INTEL_AVX1)
1223
        extern int Transform_Sha512_AVX1(wc_Sha512 *sha512);
1224
        extern int Transform_Sha512_AVX1_Len(wc_Sha512 *sha512, word32 len);
1225
    #endif
1226
    #if defined(HAVE_INTEL_AVX2)
1227
        extern int Transform_Sha512_AVX2(wc_Sha512 *sha512);
1228
        extern int Transform_Sha512_AVX2_Len(wc_Sha512 *sha512, word32 len);
1229
        #if defined(HAVE_INTEL_RORX)
1230
            extern int Transform_Sha512_AVX1_RORX(wc_Sha512 *sha512);
1231
            extern int Transform_Sha512_AVX1_RORX_Len(wc_Sha512 *sha512,
1232
                                                      word32 len);
1233
            extern int Transform_Sha512_AVX2_RORX(wc_Sha512 *sha512);
1234
            extern int Transform_Sha512_AVX2_RORX_Len(wc_Sha512 *sha512,
1235
                                                      word32 len);
1236
        #endif
1237
    #endif
1238
1239
#ifdef __cplusplus
1240
    }  /* extern "C" */
1241
#endif
1242
1243
    static cpuid_flags_atomic_t intel_flags = WC_CPUID_ATOMIC_INITIALIZER;
1244
1245
#if defined(WC_C_DYNAMIC_FALLBACK) && !defined(WC_NO_INTERNAL_FUNCTION_POINTERS)
1246
    #define WC_NO_INTERNAL_FUNCTION_POINTERS
1247
#endif
1248
1249
    static int _Transform_Sha512(wc_Sha512 *sha512);
1250
1251
#ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
1252
1253
    enum sha_methods { SHA512_UNSET = 0, SHA512_AVX1, SHA512_AVX2,
1254
                       SHA512_AVX1_RORX, SHA512_AVX2_RORX, SHA512_C };
1255
1256
    /* note that all write access to this static variable must be idempotent,
1257
     * as arranged by Sha512_SetTransform(), else it will be susceptible to
1258
     * data races.
1259
     */
1260
    static enum sha_methods sha_method = SHA512_UNSET;
1261
1262
    #ifdef WC_C_DYNAMIC_FALLBACK
1263
        /* With the AVX backend, wc_Sha512.buffer is in big endian even though
1264
         * the host is little endian.  For WC_C_DYNAMIC_FALLBACK, which requires
1265
         * alternating between AVX and C, we activate WC_SHA512_RAW_BE_BUFFER,
1266
         * which brings in the below shims for just-in-time byte swapping on
1267
         * each call to the C back end.  This keeps the buffers big endian at
1268
         * all times.
1269
         *
1270
         * Callers test WC_SHA512_RAW_BE_BUFFER rather than
1271
         * WC_C_DYNAMIC_FALLBACK directly: the latter is a global setting whose
1272
         * only prerequisite is WC_HAVE_VECTOR_SPEEDUPS, so it can be set in
1273
         * configurations that never compile these adapters (WOLFSSL_SP_ASM
1274
         * only, 32-bit x86 --enable-intelasm, ...), and suppressing the
1275
         * caller-side byte-reversal there would leave nothing to compensate.
1276
         */
1277
        #define WC_SHA512_RAW_BE_BUFFER
1278
    #endif
1279
1280
    #ifdef WC_SHA512_RAW_BE_BUFFER
1281
1282
    static WC_INLINE int Transform_Sha512_C_from_raw(wc_Sha512 *sha512)
1283
    {
1284
    #ifdef LITTLE_ENDIAN_ORDER
1285
        ByteReverseWords64(sha512->buffer, sha512->buffer,
1286
                           WC_SHA512_BLOCK_SIZE);
1287
    #endif
1288
        return _Transform_Sha512(sha512);
1289
    }
1290
1291
    static WC_INLINE int Transform_Sha512_Len_C_from_raw(wc_Sha512 *sha512,
1292
                                                         word32 len)
1293
    {
1294
        const byte* data = sha512->data;
1295
        int ret = 0;
1296
1297
        while (len >= WC_SHA512_BLOCK_SIZE) {
1298
            XMEMCPY(sha512->buffer, data, WC_SHA512_BLOCK_SIZE);
1299
            ret = Transform_Sha512_C_from_raw(sha512);
1300
            if (ret != 0)
1301
                break;
1302
            data += WC_SHA512_BLOCK_SIZE;
1303
            len  -= WC_SHA512_BLOCK_SIZE;
1304
        }
1305
1306
        return ret;
1307
    }
1308
    #endif /* WC_SHA512_RAW_BE_BUFFER */
1309
1310
    static void Sha512_SetTransform(void)
1311
    {
1312
        if (sha_method != SHA512_UNSET)
1313
            return;
1314
1315
        /* Note that, with WC_C_DYNAMIC_FALLBACK, sha_method records CPU
1316
         * capability only.  Whether vector registers are actually usable is
1317
         * determined independently at each transform via
1318
         * SAVE_VECTOR_REGISTERS2(), allowing a context to move freely between
1319
         * vectorized and C transforms call by call.
1320
         */
1321
1322
        cpuid_get_flags_atomic(&intel_flags);
1323
1324
    #if defined(HAVE_INTEL_AVX2)
1325
        if (IS_INTEL_AVX2(intel_flags)) {
1326
        #ifdef HAVE_INTEL_RORX
1327
            if (IS_INTEL_BMI2(intel_flags)) {
1328
                sha_method = SHA512_AVX2_RORX;
1329
            }
1330
            else
1331
        #endif
1332
            {
1333
                sha_method = SHA512_AVX2;
1334
            }
1335
        }
1336
        else
1337
    #endif
1338
    #if defined(HAVE_INTEL_AVX1)
1339
        if (IS_INTEL_AVX1(intel_flags)) {
1340
        #ifdef HAVE_INTEL_RORX
1341
            if (IS_INTEL_BMI2(intel_flags)) {
1342
                sha_method = SHA512_AVX1_RORX;
1343
            }
1344
            else
1345
        #endif
1346
            {
1347
                sha_method = SHA512_AVX1;
1348
            }
1349
        }
1350
        else
1351
    #endif
1352
        {
1353
            sha_method = SHA512_C;
1354
        }
1355
    }
1356
1357
    static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512) {
1358
        int ret;
1359
    #ifdef WC_C_DYNAMIC_FALLBACK
1360
        if ((sha_method == SHA512_C) ||
1361
            (SAVE_VECTOR_REGISTERS2() != 0))
1362
        {
1363
            return Transform_Sha512_C_from_raw(sha512);
1364
        }
1365
    #else
1366
        if (sha_method == SHA512_C) {
1367
            #ifdef WC_SHA512_RAW_BE_BUFFER
1368
            /* not currently reachable */
1369
            return Transform_Sha512_C_from_raw(sha512);
1370
            #else
1371
            return _Transform_Sha512(sha512);
1372
            #endif
1373
        }
1374
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
1375
    #endif
1376
        switch (sha_method) {
1377
        case SHA512_AVX2:
1378
            ret = Transform_Sha512_AVX2(sha512);
1379
            break;
1380
        case SHA512_AVX2_RORX:
1381
            ret = Transform_Sha512_AVX2_RORX(sha512);
1382
            break;
1383
        case SHA512_AVX1:
1384
            ret = Transform_Sha512_AVX1(sha512);
1385
            break;
1386
        case SHA512_AVX1_RORX:
1387
            ret = Transform_Sha512_AVX1_RORX(sha512);
1388
            break;
1389
        case SHA512_C:
1390
        case SHA512_UNSET:
1391
        default:
1392
            #ifdef WC_SHA512_RAW_BE_BUFFER
1393
            /* not reachable -- the C path exits above, before vector register
1394
             * save -- but must stay layout-correct. */
1395
            ret = Transform_Sha512_C_from_raw(sha512);
1396
            #else
1397
            ret = _Transform_Sha512(sha512);
1398
            #endif
1399
            break;
1400
        }
1401
        RESTORE_VECTOR_REGISTERS();
1402
        return ret;
1403
    }
1404
1405
    static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, word32 len) {
1406
        int ret;
1407
    #ifdef WC_C_DYNAMIC_FALLBACK
1408
        if ((sha_method == SHA512_C) ||
1409
            (SAVE_VECTOR_REGISTERS2() != 0))
1410
        {
1411
            return Transform_Sha512_Len_C_from_raw(sha512, len);
1412
        }
1413
    #else
1414
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
1415
    #endif
1416
        switch (sha_method) {
1417
        case SHA512_AVX2:
1418
            ret = Transform_Sha512_AVX2_Len(sha512, len);
1419
            break;
1420
        case SHA512_AVX2_RORX:
1421
            ret = Transform_Sha512_AVX2_RORX_Len(sha512, len);
1422
            break;
1423
        case SHA512_AVX1:
1424
            ret = Transform_Sha512_AVX1_Len(sha512, len);
1425
            break;
1426
        case SHA512_AVX1_RORX:
1427
            ret = Transform_Sha512_AVX1_RORX_Len(sha512, len);
1428
            break;
1429
        case SHA512_C:
1430
        case SHA512_UNSET:
1431
        default:
1432
            #ifdef WC_SHA512_RAW_BE_BUFFER
1433
            /* not reachable -- the C path exits above, before vector register
1434
             * save -- but must stay correct. */
1435
            ret = Transform_Sha512_Len_C_from_raw(sha512, len);
1436
            #else
1437
            ret = 0;
1438
            #endif
1439
            break;
1440
        }
1441
        RESTORE_VECTOR_REGISTERS();
1442
        return ret;
1443
    }
1444
1445
#else /* !WC_NO_INTERNAL_FUNCTION_POINTERS */
1446
1447
    static int (*Transform_Sha512_p)(wc_Sha512* sha512) = _Transform_Sha512;
1448
    static int (*Transform_Sha512_Len_p)(wc_Sha512* sha512, word32 len) = NULL;
1449
    static int transform_check = 0;
1450
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1451
    static int Transform_Sha512_is_vectorized = 0;
1452
    #endif
1453
1454
    static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512) {
1455
        int ret;
1456
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1457
        if (Transform_Sha512_is_vectorized)
1458
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
1459
    #endif
1460
        ret = (*Transform_Sha512_p)(sha512);
1461
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1462
        if (Transform_Sha512_is_vectorized)
1463
            RESTORE_VECTOR_REGISTERS();
1464
    #endif
1465
        return ret;
1466
    }
1467
    static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, word32 len) {
1468
        int ret;
1469
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1470
        if (Transform_Sha512_is_vectorized)
1471
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
1472
    #endif
1473
        ret = (*Transform_Sha512_Len_p)(sha512, len);
1474
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1475
        if (Transform_Sha512_is_vectorized)
1476
            RESTORE_VECTOR_REGISTERS();
1477
    #endif
1478
        return ret;
1479
    }
1480
1481
    static void Sha512_SetTransform(void)
1482
    {
1483
        if (transform_check)
1484
            return;
1485
1486
        cpuid_get_flags_atomic(&intel_flags);
1487
1488
    #if defined(HAVE_INTEL_AVX2)
1489
        if (IS_INTEL_AVX2(intel_flags)) {
1490
        #ifdef HAVE_INTEL_RORX
1491
            if (IS_INTEL_BMI2(intel_flags)) {
1492
                Transform_Sha512_p = Transform_Sha512_AVX2_RORX;
1493
                Transform_Sha512_Len_p = Transform_Sha512_AVX2_RORX_Len;
1494
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1495
                Transform_Sha512_is_vectorized = 1;
1496
            #endif
1497
            }
1498
            else
1499
        #endif
1500
            {
1501
                Transform_Sha512_p = Transform_Sha512_AVX2;
1502
                Transform_Sha512_Len_p = Transform_Sha512_AVX2_Len;
1503
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1504
                Transform_Sha512_is_vectorized = 1;
1505
            #endif
1506
            }
1507
        }
1508
        else
1509
    #endif
1510
    #if defined(HAVE_INTEL_AVX1)
1511
        if (IS_INTEL_AVX1(intel_flags)) {
1512
        #ifdef HAVE_INTEL_RORX
1513
            if (IS_INTEL_BMI2(intel_flags)) {
1514
                Transform_Sha512_p = Transform_Sha512_AVX1_RORX;
1515
                Transform_Sha512_Len_p = Transform_Sha512_AVX1_RORX_Len;
1516
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1517
                Transform_Sha512_is_vectorized = 1;
1518
            #endif
1519
            }
1520
            else
1521
        #endif
1522
            {
1523
                Transform_Sha512_p = Transform_Sha512_AVX1;
1524
                Transform_Sha512_Len_p = Transform_Sha512_AVX1_Len;
1525
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1526
                Transform_Sha512_is_vectorized = 1;
1527
            #endif
1528
            }
1529
        }
1530
        else
1531
    #endif
1532
        {
1533
            Transform_Sha512_p = _Transform_Sha512;
1534
            Transform_Sha512_Len_p = NULL;
1535
        #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1536
            Transform_Sha512_is_vectorized = 0;
1537
        #endif
1538
        }
1539
1540
        transform_check = 1;
1541
    }
1542
1543
#endif /* !WC_NO_INTERNAL_FUNCTION_POINTERS */
1544
1545
#elif defined(WOLFSSL_ARMASM)
1546
1547
#ifdef __aarch64__
1548
1549
/* AArch64: choose the SHA-512 crypto extension, NEON or the software
1550
 * implementation at runtime based on CPU features, so a core that lacks the
1551
 * crypto extension and/or NEON still has a working SHA-512. */
1552
#define NEED_SOFT_SHA512
1553
1554
static int transform_check = 0;
1555
static cpuid_flags_atomic_t cpuid_flags = WC_CPUID_ATOMIC_INITIALIZER;
1556
1557
static int _Transform_Sha512(wc_Sha512* sha512);
1558
static int Transform_Sha512_C(wc_Sha512* sha512, const byte* data);
1559
static int Transform_Sha512_Len_C(wc_Sha512* sha512, const byte* data,
1560
    word32 len);
1561
1562
/* Initialize to the software fallback so the pointers are never NULL if they
1563
 * are read before Sha512_SetTransform() has published the selected variant. */
1564
static int (*Transform_Sha512_p)(wc_Sha512* sha512, const byte* data)
1565
    = Transform_Sha512_C;
1566
static int (*Transform_Sha512_Len_p)(wc_Sha512* sha512, const byte* data,
1567
    word32 len) = Transform_Sha512_Len_C;
1568
1569
/* Software fallback adapters in the asm (sha512, data[, len]) form. The asm
1570
 * transforms consume raw big-endian input and byte-reverse internally, so the
1571
 * software path mirrors that by reversing the block before _Transform_Sha512()
1572
 * (which reads host-endian words from sha512->buffer). */
1573
static int Transform_Sha512_C(wc_Sha512* sha512, const byte* data)
1574
{
1575
    if (data != (const byte*)sha512->buffer)
1576
        XMEMCPY(sha512->buffer, data, WC_SHA512_BLOCK_SIZE);
1577
#ifdef LITTLE_ENDIAN_ORDER
1578
    ByteReverseWords64(sha512->buffer, sha512->buffer, WC_SHA512_BLOCK_SIZE);
1579
#endif
1580
    return _Transform_Sha512(sha512);
1581
}
1582
static int Transform_Sha512_Len_C(wc_Sha512* sha512, const byte* data,
1583
    word32 len)
1584
{
1585
    int ret = 0;
1586
1587
    while (len >= WC_SHA512_BLOCK_SIZE) {
1588
        ret = Transform_Sha512_C(sha512, data);
1589
        if (ret != 0)
1590
            break;
1591
        data += WC_SHA512_BLOCK_SIZE;
1592
        len  -= WC_SHA512_BLOCK_SIZE;
1593
    }
1594
1595
    return ret;
1596
}
1597
1598
/* The SHA-512 crypto instructions operate on SIMD registers, so the assembly
1599
 * only defines these when NEON is available - see armv8-sha512-asm.S and the
1600
 * prototype guard in sha512.h. */
1601
#if defined(WOLFSSL_ARMASM_CRYPTO_SHA512) && !defined(WOLFSSL_ARMASM_NO_NEON)
1602
static int Transform_Sha512_crypto_aarch64(wc_Sha512* sha512, const byte* data)
1603
{
1604
    Transform_Sha512_Len_crypto(sha512, data, WC_SHA512_BLOCK_SIZE);
1605
    return 0;
1606
}
1607
static int Transform_Sha512_Len_crypto_aarch64(wc_Sha512* sha512,
1608
    const byte* data, word32 len)
1609
{
1610
    Transform_Sha512_Len_crypto(sha512, data, len);
1611
    return 0;
1612
}
1613
#endif
1614
#ifndef WOLFSSL_ARMASM_NO_NEON
1615
static int Transform_Sha512_neon_aarch64(wc_Sha512* sha512, const byte* data)
1616
{
1617
    Transform_Sha512_Len_neon(sha512, data, WC_SHA512_BLOCK_SIZE);
1618
    return 0;
1619
}
1620
static int Transform_Sha512_Len_neon_aarch64(wc_Sha512* sha512,
1621
    const byte* data, word32 len)
1622
{
1623
    Transform_Sha512_Len_neon(sha512, data, len);
1624
    return 0;
1625
}
1626
#endif
1627
1628
static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512, const byte* data)
1629
{
1630
    return (*Transform_Sha512_p)(sha512, data);
1631
}
1632
static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, const byte* data,
1633
    word32 len)
1634
{
1635
    return (*Transform_Sha512_Len_p)(sha512, data, len);
1636
}
1637
1638
static void Sha512_SetTransform(void)
1639
{
1640
    if (transform_check)
1641
        return;
1642
1643
    cpuid_get_flags_atomic(&cpuid_flags);
1644
1645
#if defined(WOLFSSL_ARMASM_CRYPTO_SHA512) && !defined(WOLFSSL_ARMASM_NO_NEON)
1646
    if (IS_AARCH64_SHA512(cpuid_flags)) {
1647
        Transform_Sha512_p     = Transform_Sha512_crypto_aarch64;
1648
        Transform_Sha512_Len_p = Transform_Sha512_Len_crypto_aarch64;
1649
    }
1650
    else
1651
#endif
1652
#ifndef WOLFSSL_ARMASM_NO_NEON
1653
    if (IS_AARCH64_ASIMD(cpuid_flags)) {
1654
        Transform_Sha512_p     = Transform_Sha512_neon_aarch64;
1655
        Transform_Sha512_Len_p = Transform_Sha512_Len_neon_aarch64;
1656
    }
1657
    else
1658
#endif
1659
    {
1660
        Transform_Sha512_p     = Transform_Sha512_C;
1661
        Transform_Sha512_Len_p = Transform_Sha512_Len_C;
1662
    }
1663
1664
    transform_check = 1;
1665
}
1666
1667
#else /* !__aarch64__ : 32-bit Arm (Thumb2 / ARMv7) */
1668
1669
static int transform_check = 0;
1670
1671
#if !defined(WOLFSSL_ARMASM_THUMB2) && !defined(WOLFSSL_ARMASM_NO_NEON)
1672
static void Transform_Sha512_neon(wc_Sha512* sha512, const byte* data)
1673
{
1674
    Transform_Sha512_Len_neon(sha512, data, WC_SHA512_BLOCK_SIZE);
1675
}
1676
#endif
1677
#if defined(WOLFSSL_ARMASM_THUMB2) || defined(WOLFSSL_ARMASM_NO_NEON)
1678
static void Transform_Sha512_base(wc_Sha512* sha512, const byte* data)
1679
{
1680
    Transform_Sha512_Len_base(sha512, data, WC_SHA512_BLOCK_SIZE);
1681
}
1682
#endif
1683
1684
static void (*Transform_Sha512_p)(wc_Sha512* sha512, const byte* data) = NULL;
1685
static void (*Transform_Sha512_Len_p)(wc_Sha512* sha512, const byte* data,
1686
    word32 len) = NULL;
1687
1688
static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512, const byte* data)
1689
{
1690
    (*Transform_Sha512_p)(sha512, data);
1691
    return 0;
1692
}
1693
static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, const byte* data,
1694
    word32 len)
1695
{
1696
    (*Transform_Sha512_Len_p)(sha512, data, len);
1697
    return 0;
1698
}
1699
1700
static void Sha512_SetTransform(void)
1701
{
1702
    if (transform_check)
1703
        return;
1704
1705
#if !defined(WOLFSSL_ARMASM_THUMB2) && !defined(WOLFSSL_ARMASM_NO_NEON)
1706
    {
1707
        Transform_Sha512_p = Transform_Sha512_neon;
1708
        Transform_Sha512_Len_p = Transform_Sha512_Len_neon;
1709
    }
1710
#else
1711
    {
1712
        Transform_Sha512_p = Transform_Sha512_base;
1713
        Transform_Sha512_Len_p = Transform_Sha512_Len_base;
1714
    }
1715
#endif
1716
1717
    transform_check = 1;
1718
}
1719
1720
#endif /* __aarch64__ */
1721
1722
#elif defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
1723
1724
/* Scalar (base instruction) SHA-512 transform for big-endian PowerPC (32- and
1725
 * 64-bit).  The asm loads the message words directly, so no byte reversal is
1726
 * needed and the (sha512, data, len) form is used just like the ARM assembly. */
1727
extern void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data,
1728
    word32 len);
1729
1730
#if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
1731
/* POWER8+ has a vector SHA-512 sigma instruction (vshasigmad).  When built
1732
 * in, select that implementation at run time if the CPU supports it.
1733
 *
1734
 * A run-time flag with direct calls is used rather than a function pointer:
1735
 * an indirect call would require an ELFv1 function descriptor, whereas direct
1736
 * calls work under both the ELFv1 and ELFv2 ABIs. */
1737
extern void Transform_Sha512_Len_crypto(wc_Sha512* sha512, const byte* data,
1738
    word32 len);
1739
1740
/* Resolved dispatch decision, accessed with the wolfSSL atomic APIs so the
1741
 * lazy one-time detection is free of data races.  WC_CPUID_INITIALIZER means
1742
 * "not yet determined"; the write is idempotent (all callers compute the same
1743
 * value from the atomic master flags), so a benign concurrent double-write is
1744
 * harmless. */
1745
static wolfSSL_Atomic_Uint sha512_use_crypto =
1746
    WOLFSSL_ATOMIC_INITIALIZER(WC_CPUID_INITIALIZER);
1747
1748
/* Detect CPU support via the central cpuid module on first use. */
1749
static WC_INLINE void SHA512_TRANSFORM_LEN(wc_Sha512* sha512, const byte* data,
1750
    word32 len)
1751
{
1752
    unsigned int use_crypto = WOLFSSL_ATOMIC_LOAD(sha512_use_crypto);
1753
1754
    if (use_crypto == WC_CPUID_INITIALIZER) {
1755
        use_crypto = (unsigned int)(IS_PPC64_VEC_CRYPTO(cpuid_get_flags()) != 0);
1756
        WOLFSSL_ATOMIC_STORE(sha512_use_crypto, use_crypto);
1757
    }
1758
1759
    if (use_crypto)
1760
        Transform_Sha512_Len_crypto(sha512, data, len);
1761
    else
1762
        Transform_Sha512_Len(sha512, data, len);
1763
}
1764
/* SHA512_TRANSFORM_LEN is a function here, not a macro, so signal that a
1765
 * dispatcher is provided - otherwise the generic fallback below sees
1766
 * !defined(SHA512_TRANSFORM_LEN) and shadows it with a base-only macro. */
1767
#define SHA512_HAVE_TRANSFORM_LEN
1768
#else
1769
#define SHA512_TRANSFORM_LEN(s, d, l)   Transform_Sha512_Len((s), (d), (l))
1770
#define SHA512_HAVE_TRANSFORM_LEN
1771
#endif
1772
1773
static WC_INLINE int Transform_Sha512(wc_Sha512* sha512, const byte* data)
1774
{
1775
    SHA512_TRANSFORM_LEN(sha512, data, WC_SHA512_BLOCK_SIZE);
1776
    return 0;
1777
}
1778
1779
#define Sha512_SetTransform()   WC_DO_NOTHING
1780
1781
#elif defined(WOLFSSL_RISCV_ASM)
1782
1783
static WC_INLINE int Transform_Sha512(wc_Sha512* sha512, const byte* data)
1784
{
1785
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
1786
    Transform_Sha512_Len_riscv_vector(sha512, data, WC_SHA512_BLOCK_SIZE);
1787
#elif defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
1788
    Transform_Sha512_Len_riscv_crypto(sha512, data, WC_SHA512_BLOCK_SIZE);
1789
#else
1790
    Transform_Sha512_Len_riscv(sha512, data, WC_SHA512_BLOCK_SIZE);
1791
#endif
1792
    return 0;
1793
}
1794
static WC_INLINE int Transform_Sha512_Len(wc_Sha512* sha512, const byte* data,
1795
    word32 len)
1796
{
1797
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
1798
    Transform_Sha512_Len_riscv_vector(sha512, data, len);
1799
#elif defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
1800
    Transform_Sha512_Len_riscv_crypto(sha512, data, len);
1801
#else
1802
    Transform_Sha512_Len_riscv(sha512, data, len);
1803
#endif
1804
    return 0;
1805
}
1806
1807
#else
1808
0
    #define Transform_Sha512(sha512) _Transform_Sha512(sha512)
1809
1810
#endif
1811
1812
/* For platforms that share the (sha512, data, len) block-loop call below but
1813
 * don't provide their own dispatcher (e.g. ARM), call the length transform
1814
 * directly. */
1815
#if (defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
1816
     defined(WOLFSSL_PPC32_ASM)) && \
1817
    !defined(SHA512_TRANSFORM_LEN) && !defined(SHA512_HAVE_TRANSFORM_LEN)
1818
#define SHA512_TRANSFORM_LEN(s, d, l)   Transform_Sha512_Len((s), (d), (l))
1819
#endif
1820
1821
#ifdef WOLFSSL_SHA512
1822
1823
static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId,
1824
                             int (*initfp)(wc_Sha512*))
1825
0
{
1826
0
    int ret = 0;
1827
1828
0
    if (sha512 == NULL) {
1829
0
        return BAD_FUNC_ARG;
1830
0
    }
1831
1832
0
    XMEMSET(sha512, 0, sizeof(*sha512));
1833
1834
0
    sha512->heap = heap;
1835
#ifdef WOLFSSL_SMALL_STACK_CACHE
1836
    /* This allocation combines the customary W buffer used by
1837
     * _Transform_Sha512() with additional buffer space used by
1838
     * wc_Sha512Transform().
1839
     */
1840
    sha512->W = (word64 *)XMALLOC((sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE,
1841
                                  sha512->heap, DYNAMIC_TYPE_DIGEST);
1842
    if (sha512->W == NULL)
1843
        return MEMORY_E;
1844
#endif
1845
#ifdef WOLF_CRYPTO_CB
1846
    sha512->devId = devId;
1847
    sha512->devCtx = NULL;
1848
#endif
1849
1850
#ifdef WOLFSSL_HASH_KEEP
1851
    sha512->msg  = NULL;
1852
    sha512->len  = 0;
1853
    sha512->used = 0;
1854
#endif
1855
1856
    /* call the initialization function pointed to by initfp */
1857
0
    ret = initfp(sha512);
1858
1859
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
1860
    if (ret == 0) {
1861
        ret = wolfAsync_DevCtxInit(&sha512->asyncDev,
1862
                        WOLFSSL_ASYNC_MARKER_SHA512, sha512->heap, devId);
1863
    }
1864
#else
1865
0
    (void)devId;
1866
0
#endif /* WOLFSSL_ASYNC_CRYPT */
1867
#ifdef WOLFSSL_IMXRT1170_CAAM
1868
    if (ret == 0)
1869
        ret = wc_CAAM_HashInit(&sha512->hndl, &sha512->ctx, WC_HASH_TYPE_SHA512);
1870
#endif
1871
1872
#ifdef WOLFSSL_SMALL_STACK_CACHE
1873
    if (ret != 0) {
1874
        XFREE(sha512->W, sha512->heap, DYNAMIC_TYPE_DIGEST);
1875
        sha512->W = NULL;
1876
    }
1877
#endif
1878
1879
0
    return ret;
1880
0
} /* InitSha512_Family */
1881
1882
int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
1883
0
{
1884
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1885
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1886
    if (sha512->ctx.mode != ESP32_SHA_INIT) {
1887
        ESP_LOGV(TAG, "Set ctx mode from prior value: "
1888
                      "%d", sha512->ctx.mode);
1889
    }
1890
    /* We know this is a fresh, uninitialized item, so set to INIT */
1891
    sha512->ctx.mode = ESP32_SHA_INIT;
1892
#endif
1893
1894
1895
0
    return InitSha512_Family(sha512, heap, devId, InitSha512);
1896
0
}
1897
1898
#if !defined(WOLFSSL_NOSHA512_224) && \
1899
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
1900
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
1901
0
{
1902
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1903
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1904
    /* No SHA512/224 HW support is available, set to SW. */
1905
    sha512->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
1906
#endif
1907
0
    return InitSha512_Family(sha512, heap, devId, InitSha512_224);
1908
0
}
1909
#endif /* !WOLFSSL_NOSHA512_224 ... */
1910
1911
#if !defined(WOLFSSL_NOSHA512_256) && \
1912
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
1913
int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
1914
0
{
1915
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1916
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1917
    /* No SHA512/256 HW support is available on ESP32, set to SW. */
1918
    sha512->ctx.mode = ESP32_SHA_SW;
1919
#endif
1920
0
    return InitSha512_Family(sha512, heap, devId, InitSha512_256);
1921
0
}
1922
#endif /* !WOLFSSL_NOSHA512_256 ... */
1923
1924
#endif /* WOLFSSL_SHA512 */
1925
1926
#if (!defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PPC64_ASM) && \
1927
     !defined(WOLFSSL_PPC32_ASM) && !defined(WOLFSSL_RISCV_ASM)) || \
1928
    defined(NEED_SOFT_SHA512)
1929
1930
static const word64 K512[80] = {
1931
    W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
1932
    W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
1933
    W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
1934
    W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
1935
    W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
1936
    W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
1937
    W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
1938
    W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
1939
    W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
1940
    W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
1941
    W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
1942
    W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
1943
    W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
1944
    W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
1945
    W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
1946
    W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
1947
    W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
1948
    W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
1949
    W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
1950
    W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
1951
    W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
1952
    W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
1953
    W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
1954
    W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
1955
    W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
1956
    W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
1957
    W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
1958
    W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
1959
    W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
1960
    W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
1961
    W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
1962
    W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
1963
    W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
1964
    W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
1965
    W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
1966
    W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
1967
    W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
1968
    W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
1969
    W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
1970
    W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
1971
};
1972
1973
0
#define blk0(i) (W[i] = sha512->buffer[i])
1974
1975
0
#define blk2(i) (\
1976
0
               W[ (i)     & 15] += \
1977
0
            s1(W[((i)-2)  & 15])+ \
1978
0
               W[((i)-7)  & 15] + \
1979
0
            s0(W[((i)-15) & 15])  \
1980
0
        )
1981
1982
0
#define Ch(x,y,z)  ((z) ^ ((x) & ((y) ^ (z))))
1983
0
#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
1984
1985
0
#define a(i) T[(0-(i)) & 7]
1986
0
#define b(i) T[(1-(i)) & 7]
1987
0
#define c(i) T[(2-(i)) & 7]
1988
0
#define d(i) T[(3-(i)) & 7]
1989
0
#define e(i) T[(4-(i)) & 7]
1990
0
#define f(i) T[(5-(i)) & 7]
1991
0
#define g(i) T[(6-(i)) & 7]
1992
0
#define h(i) T[(7-(i)) & 7]
1993
1994
0
#define S0(x) (rotrFixed64(x,28) ^ rotrFixed64(x,34) ^ rotrFixed64(x,39))
1995
0
#define S1(x) (rotrFixed64(x,14) ^ rotrFixed64(x,18) ^ rotrFixed64(x,41))
1996
0
#define s0(x) (rotrFixed64(x,1)  ^ rotrFixed64(x,8)  ^ ((x)>>7))
1997
0
#define s1(x) (rotrFixed64(x,19) ^ rotrFixed64(x,61) ^ ((x)>>6))
1998
1999
#define R(i) \
2000
0
    h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+j] + (j ? blk2(i) : blk0(i)); \
2001
0
    d(i) += h(i); \
2002
0
    h(i) += S0(a(i)) + Maj(a(i),b(i),c(i))
2003
2004
static int _Transform_Sha512(wc_Sha512* sha512)
2005
0
{
2006
0
    const word64* K = K512;
2007
0
    word32 j;
2008
0
    word64 T[8];
2009
2010
#if defined(WOLFSSL_SMALL_STACK_CACHE)
2011
    word64* W = sha512->W;
2012
    if (W == NULL)
2013
        return BAD_FUNC_ARG;
2014
#elif defined(WOLFSSL_SMALL_STACK)
2015
    word64* W;
2016
    W = (word64*) XMALLOC(sizeof(word64) * 16, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
2017
    if (W == NULL)
2018
        return MEMORY_E;
2019
#else
2020
0
    word64 W[16];
2021
0
#endif
2022
2023
    /* Copy digest to working vars */
2024
0
    XMEMCPY(T, sha512->digest, sizeof(T));
2025
2026
#ifdef USE_SLOW_SHA512
2027
    /* over twice as small, but 50% slower */
2028
    /* 80 operations, not unrolled */
2029
    for (j = 0; j < 80; j += 16) {
2030
        int m;
2031
        for (m = 0; m < 16; m++) { /* braces needed here for macros {} */
2032
            R(m);
2033
        }
2034
    }
2035
#else
2036
    /* 80 operations, partially loop unrolled */
2037
0
    for (j = 0; j < 80; j += 16) {
2038
0
        R( 0); R( 1); R( 2); R( 3);
2039
0
        R( 4); R( 5); R( 6); R( 7);
2040
0
        R( 8); R( 9); R(10); R(11);
2041
0
        R(12); R(13); R(14); R(15);
2042
0
    }
2043
0
#endif /* USE_SLOW_SHA512 */
2044
2045
    /* Add the working vars back into digest */
2046
0
    sha512->digest[0] += a(0);
2047
0
    sha512->digest[1] += b(0);
2048
0
    sha512->digest[2] += c(0);
2049
0
    sha512->digest[3] += d(0);
2050
0
    sha512->digest[4] += e(0);
2051
0
    sha512->digest[5] += f(0);
2052
0
    sha512->digest[6] += g(0);
2053
0
    sha512->digest[7] += h(0);
2054
2055
    /* Wipe variables */
2056
0
    ForceZero(W, sizeof(word64) * 16);
2057
0
    ForceZero(T, sizeof(T));
2058
2059
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
2060
    XFREE(W, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
2061
#endif
2062
2063
0
    return 0;
2064
0
}
2065
#endif
2066
2067
2068
static WC_INLINE void AddLength(wc_Sha512* sha512, word32 len)
2069
0
{
2070
0
    word64 tmp = sha512->loLen;
2071
0
    if ( (sha512->loLen += len) < tmp)
2072
0
        sha512->hiLen++;                       /* carry low to high */
2073
0
}
2074
2075
static WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
2076
0
{
2077
0
    int ret = 0;
2078
    /* do block size increments */
2079
0
    byte* local = (byte*)sha512->buffer;
2080
2081
    /* check that internal buffLen is valid */
2082
0
    if (sha512->buffLen >= WC_SHA512_BLOCK_SIZE)
2083
0
        return BUFFER_E;
2084
2085
0
    if (len == 0)
2086
0
        return 0;
2087
2088
0
    AddLength(sha512, len);
2089
2090
0
    if (sha512->buffLen > 0) {
2091
0
        word32 add = min(len, WC_SHA512_BLOCK_SIZE - sha512->buffLen);
2092
0
        if (add > 0) {
2093
0
            XMEMCPY(&local[sha512->buffLen], data, add);
2094
2095
0
            sha512->buffLen += add;
2096
0
            data            += add;
2097
0
            len             -= add;
2098
0
        }
2099
2100
0
        if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) {
2101
0
    #if defined(LITTLE_ENDIAN_ORDER) && \
2102
0
            !defined(WC_SHA512_RAW_BE_BUFFER) && \
2103
0
            (!defined(WOLFSSL_ESP32_CRYPT) || \
2104
0
             defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2105
0
             defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)) && \
2106
0
            !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PPC64_ASM) && \
2107
0
            !defined(WOLFSSL_RISCV_ASM)
2108
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2109
                (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2110
            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2111
        #endif
2112
0
            {
2113
        #ifdef WOLFSSL_WIDE_BYTE
2114
                WordsFromBytesBE64(sha512->buffer,
2115
                    (const byte*)sha512->buffer, WC_SHA512_BLOCK_SIZE / 8);
2116
        #else
2117
0
                ByteReverseWords64(sha512->buffer, sha512->buffer,
2118
0
                                                         WC_SHA512_BLOCK_SIZE);
2119
0
        #endif
2120
0
            }
2121
0
    #endif
2122
    #if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
2123
        defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_RISCV_ASM)
2124
            ret = Transform_Sha512(sha512, (const byte*)sha512->buffer);
2125
    #elif !defined(WOLFSSL_ESP32_CRYPT) || \
2126
           defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2127
           defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2128
0
            ret = Transform_Sha512(sha512);
2129
    #else
2130
            if (sha512->ctx.mode == ESP32_SHA_INIT) {
2131
                esp_sha_try_hw_lock(&sha512->ctx);
2132
            }
2133
            if (sha512->ctx.mode == ESP32_SHA_SW) {
2134
                ByteReverseWords64(sha512->buffer, sha512->buffer,
2135
                                                         WC_SHA512_BLOCK_SIZE);
2136
                ret = Transform_Sha512(sha512);
2137
            }
2138
            else {
2139
                ret = esp_sha512_process(sha512);
2140
            }
2141
    #endif
2142
0
            if (ret == 0)
2143
0
                sha512->buffLen = 0;
2144
0
            else
2145
0
                len = 0;
2146
0
        }
2147
0
    }
2148
2149
#if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
2150
    defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_RISCV_ASM)
2151
    if (len >= WC_SHA512_BLOCK_SIZE) {
2152
        word32 blocksLen = len & ~((word32)WC_SHA512_BLOCK_SIZE-1);
2153
2154
#if defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
2155
        SHA512_TRANSFORM_LEN(sha512, data, blocksLen);
2156
#else
2157
        ret = Transform_Sha512_Len(sha512, data, blocksLen);
2158
        if (ret != 0)
2159
            return ret;
2160
#endif
2161
        data += blocksLen;
2162
        len  -= blocksLen;
2163
    }
2164
#else
2165
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2166
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
2167
2168
    #ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
2169
    if (sha_method != SHA512_C)
2170
    #else
2171
    if (Transform_Sha512_Len_p != NULL)
2172
    #endif
2173
2174
    {
2175
        word32 blocksLen = len & ~((word32)WC_SHA512_BLOCK_SIZE-1);
2176
2177
        if (blocksLen > 0) {
2178
            sha512->data = data;
2179
            /* Byte reversal performed in function if required. */
2180
            ret = Transform_Sha512_Len(sha512, blocksLen);
2181
            if (ret == 0) {
2182
                data += blocksLen;
2183
                len  -= blocksLen;
2184
            }
2185
        }
2186
    }
2187
    else
2188
#endif
2189
#if !defined(LITTLE_ENDIAN_ORDER) || (defined(WOLFSSL_X86_64_BUILD) && \
2190
        defined(USE_INTEL_SPEEDUP) && (defined(HAVE_INTEL_AVX1) || \
2191
        defined(HAVE_INTEL_AVX2)))
2192
    {
2193
        while (len >= WC_SHA512_BLOCK_SIZE) {
2194
            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
2195
2196
            data += WC_SHA512_BLOCK_SIZE;
2197
            len  -= WC_SHA512_BLOCK_SIZE;
2198
2199
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2200
            (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) && \
2201
            !defined(WC_SHA512_RAW_BE_BUFFER)
2202
            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2203
            {
2204
                ByteReverseWords64(sha512->buffer, sha512->buffer,
2205
                                                          WC_SHA512_BLOCK_SIZE);
2206
            }
2207
        #endif
2208
            /* Byte reversal performed in function if required. */
2209
            ret = Transform_Sha512(sha512);
2210
            if (ret != 0)
2211
                break;
2212
        }
2213
    }
2214
#else
2215
0
    {
2216
0
        while (len >= WC_SHA512_BLOCK_SIZE) {
2217
0
            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
2218
2219
0
            data += WC_SHA512_BLOCK_SIZE;
2220
0
            len  -= WC_SHA512_BLOCK_SIZE;
2221
0
    #if !defined(WOLFSSL_ESP32_CRYPT) || \
2222
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2223
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2224
        #ifdef WOLFSSL_WIDE_BYTE
2225
            WordsFromBytesBE64(sha512->buffer, (const byte*)sha512->buffer,
2226
                WC_SHA512_BLOCK_SIZE / 8);
2227
        #else
2228
0
            ByteReverseWords64(sha512->buffer, sha512->buffer,
2229
0
                                                       WC_SHA512_BLOCK_SIZE);
2230
0
        #endif
2231
0
    #endif
2232
0
    #if !defined(WOLFSSL_ESP32_CRYPT) || \
2233
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2234
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2235
0
            ret = Transform_Sha512(sha512);
2236
    #else
2237
            if(sha512->ctx.mode == ESP32_SHA_INIT) {
2238
                esp_sha_try_hw_lock(&sha512->ctx);
2239
            }
2240
            if (sha512->ctx.mode == ESP32_SHA_SW) {
2241
                ByteReverseWords64(sha512->buffer, sha512->buffer,
2242
                                                          WC_SHA512_BLOCK_SIZE);
2243
                ret = Transform_Sha512(sha512);
2244
            }
2245
            else {
2246
                ret = esp_sha512_process(sha512);
2247
            }
2248
    #endif
2249
0
            if (ret != 0)
2250
0
                break;
2251
0
        } /* while (len >= WC_SHA512_BLOCK_SIZE) */
2252
0
    }
2253
0
#endif
2254
0
#endif
2255
2256
0
    if (ret == 0 && len > 0) {
2257
0
        XMEMCPY(local, data, len);
2258
0
        sha512->buffLen = len;
2259
0
    }
2260
2261
0
    return ret;
2262
0
}
2263
2264
#ifdef WOLFSSL_SHA512
2265
2266
int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
2267
0
{
2268
0
    if (sha512 == NULL) {
2269
0
        return BAD_FUNC_ARG;
2270
0
    }
2271
0
    if (data == NULL && len == 0) {
2272
        /* valid, but do nothing */
2273
0
        return 0;
2274
0
    }
2275
0
    if (data == NULL) {
2276
0
        return BAD_FUNC_ARG;
2277
0
    }
2278
2279
#ifdef WOLF_CRYPTO_CB
2280
    #ifndef WOLF_CRYPTO_CB_FIND
2281
    if (sha512->devId != INVALID_DEVID)
2282
    #endif
2283
    {
2284
        int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL, 0);
2285
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2286
            return ret;
2287
        /* fall-through when unavailable */
2288
    }
2289
#endif
2290
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
2291
    if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {
2292
    #if defined(HAVE_INTEL_QA)
2293
        return IntelQaSymSha512(&sha512->asyncDev, NULL, data, len);
2294
    #endif
2295
    }
2296
#endif /* WOLFSSL_ASYNC_CRYPT */
2297
2298
0
    return Sha512Update(sha512, data, len);
2299
0
}
2300
2301
#endif /* WOLFSSL_SHA512 */
2302
2303
#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA512 */
2304
2305
#ifndef WOLF_CRYPTO_CB_ONLY_SHA512
2306
2307
#if defined(WOLFSSL_KCAPI_HASH)
2308
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2309
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2310
   !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2311
    /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */
2312
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2313
2314
#elif defined(MAX3266X_SHA)
2315
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2316
#elif defined(STM32_HASH_SHA512)
2317
#elif defined(PSOC6_HASH_SHA2)
2318
#else
2319
2320
static WC_INLINE int Sha512Final(wc_Sha512* sha512)
2321
0
{
2322
0
    int ret = 0;
2323
0
    byte* local;
2324
2325
0
    if (sha512 == NULL) {
2326
0
        return BAD_FUNC_ARG;
2327
0
    }
2328
2329
0
    local = (byte*)sha512->buffer;
2330
2331
    /* we'll add a 0x80 byte at the end,
2332
    ** so make sure we have appropriate buffer length. */
2333
0
    if (sha512->buffLen > WC_SHA512_BLOCK_SIZE - 1) {
2334
0
        return BAD_STATE_E;
2335
0
    } /* buffLen check */
2336
2337
0
    local[sha512->buffLen++] = 0x80;  /* add 1 */
2338
2339
    /* pad with zeros */
2340
0
    if (sha512->buffLen > WC_SHA512_PAD_SIZE) {
2341
0
        if (sha512->buffLen < WC_SHA512_BLOCK_SIZE ) {
2342
0
            XMEMSET(&local[sha512->buffLen], 0,
2343
0
                WC_SHA512_BLOCK_SIZE - sha512->buffLen);
2344
0
        }
2345
2346
0
        sha512->buffLen += WC_SHA512_BLOCK_SIZE - sha512->buffLen;
2347
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WC_SHA512_RAW_BE_BUFFER)
2348
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2349
        (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2350
        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2351
    #endif
2352
0
        {
2353
2354
0
        #if (!defined(WOLFSSL_ESP32_CRYPT) || \
2355
0
              defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2356
0
              defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)) && \
2357
0
             !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PPC64_ASM) && \
2358
0
             !defined(WOLFSSL_RISCV_ASM)
2359
            #ifdef WOLFSSL_WIDE_BYTE
2360
            WordsFromBytesBE64(sha512->buffer, (const byte*)sha512->buffer,
2361
                WC_SHA512_BLOCK_SIZE / 8);
2362
            #else
2363
0
            ByteReverseWords64(sha512->buffer,sha512->buffer,
2364
0
                                                         WC_SHA512_BLOCK_SIZE);
2365
0
            #endif
2366
0
        #endif
2367
0
        }
2368
2369
0
#endif /* LITTLE_ENDIAN_ORDER */
2370
#if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
2371
    defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_RISCV_ASM)
2372
        ret = Transform_Sha512(sha512, (const byte*)sha512->buffer);
2373
        if (ret != 0)
2374
            return ret;
2375
#else
2376
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2377
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2378
        if (sha512->ctx.mode == ESP32_SHA_INIT) {
2379
            esp_sha_try_hw_lock(&sha512->ctx);
2380
        }
2381
        if (sha512->ctx.mode == ESP32_SHA_SW) {
2382
            ByteReverseWords64(sha512->buffer,sha512->buffer,
2383
                                                         WC_SHA512_BLOCK_SIZE);
2384
            ret = Transform_Sha512(sha512);
2385
        }
2386
        else {
2387
            ret = esp_sha512_process(sha512);
2388
        }
2389
    #else
2390
0
        ret = Transform_Sha512(sha512);
2391
0
    #endif
2392
0
        if (ret != 0) {
2393
0
            return ret;
2394
0
        }
2395
0
#endif
2396
2397
0
        sha512->buffLen = 0;
2398
0
    } /* (sha512->buffLen > WC_SHA512_PAD_SIZE) pad with zeros */
2399
2400
0
    XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen);
2401
2402
    /* put lengths in bits */
2403
0
    sha512->hiLen = (sha512->loLen >>
2404
0
                        (CHAR_BIT * sizeof(sha512->loLen) - 3)) +
2405
0
                                                         (sha512->hiLen << 3);
2406
0
    sha512->loLen = sha512->loLen << 3;
2407
2408
    /* store lengths */
2409
#ifdef WOLFSSL_WIDE_BYTE
2410
    /* CHAR_BIT != 8: 'local' indexes octet cells, not the word64 layout (the
2411
     * buffer[BLOCK/sizeof(word64) - 2/-1] indices assume 16 words per block,
2412
     * which is wrong when sizeof(word64) != 8).  Place the 128-bit bit-length
2413
     * as 16 big-endian octets at the pad offset, then load all 16 big-endian
2414
     * schedule words octet-wise. */
2415
    local[WC_SHA512_PAD_SIZE +  0] = (byte)((sha512->hiLen >> 56) & 0xFF);
2416
    local[WC_SHA512_PAD_SIZE +  1] = (byte)((sha512->hiLen >> 48) & 0xFF);
2417
    local[WC_SHA512_PAD_SIZE +  2] = (byte)((sha512->hiLen >> 40) & 0xFF);
2418
    local[WC_SHA512_PAD_SIZE +  3] = (byte)((sha512->hiLen >> 32) & 0xFF);
2419
    local[WC_SHA512_PAD_SIZE +  4] = (byte)((sha512->hiLen >> 24) & 0xFF);
2420
    local[WC_SHA512_PAD_SIZE +  5] = (byte)((sha512->hiLen >> 16) & 0xFF);
2421
    local[WC_SHA512_PAD_SIZE +  6] = (byte)((sha512->hiLen >>  8) & 0xFF);
2422
    local[WC_SHA512_PAD_SIZE +  7] = (byte)((sha512->hiLen      ) & 0xFF);
2423
    local[WC_SHA512_PAD_SIZE +  8] = (byte)((sha512->loLen >> 56) & 0xFF);
2424
    local[WC_SHA512_PAD_SIZE +  9] = (byte)((sha512->loLen >> 48) & 0xFF);
2425
    local[WC_SHA512_PAD_SIZE + 10] = (byte)((sha512->loLen >> 40) & 0xFF);
2426
    local[WC_SHA512_PAD_SIZE + 11] = (byte)((sha512->loLen >> 32) & 0xFF);
2427
    local[WC_SHA512_PAD_SIZE + 12] = (byte)((sha512->loLen >> 24) & 0xFF);
2428
    local[WC_SHA512_PAD_SIZE + 13] = (byte)((sha512->loLen >> 16) & 0xFF);
2429
    local[WC_SHA512_PAD_SIZE + 14] = (byte)((sha512->loLen >>  8) & 0xFF);
2430
    local[WC_SHA512_PAD_SIZE + 15] = (byte)((sha512->loLen      ) & 0xFF);
2431
    WordsFromBytesBE64(sha512->buffer, (const byte*)sha512->buffer,
2432
        WC_SHA512_BLOCK_SIZE / 8);
2433
#else
2434
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WC_SHA512_RAW_BE_BUFFER)
2435
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2436
        (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2437
        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2438
    #endif
2439
0
    #if (!defined(WOLFSSL_ESP32_CRYPT) || \
2440
0
          defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2441
0
          defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)) && \
2442
0
         !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PPC64_ASM) && \
2443
0
         !defined(WOLFSSL_RISCV_ASM)
2444
0
            ByteReverseWords64(sha512->buffer, sha512->buffer, WC_SHA512_PAD_SIZE);
2445
0
    #endif
2446
0
#endif
2447
    /* ! length ordering dependent on digest endian type ! */
2448
2449
0
#if !defined(WOLFSSL_ESP32_CRYPT) || \
2450
0
     defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2451
0
     defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2452
0
    sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
2453
0
    sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
2454
0
#endif
2455
0
#endif /* WOLFSSL_WIDE_BYTE */
2456
2457
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2458
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2459
    #ifdef WC_SHA512_RAW_BE_BUFFER
2460
    /* raw-buffer convention -- the length words must be big-endian in the
2461
     * stream regardless of which transform consumes the final block. */
2462
    #else
2463
    if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags))
2464
    #endif
2465
    {
2466
        ByteReverseWords64(&(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
2467
                           &(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
2468
                           WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
2469
    }
2470
#elif defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM)
2471
    #define SHA512_PAD_LEN_64  (WC_SHA512_PAD_SIZE / sizeof(word64))
2472
    {
2473
        ByteReverseWords64(&(sha512->buffer[SHA512_PAD_LEN_64]),
2474
                           &(sha512->buffer[SHA512_PAD_LEN_64]),
2475
                           WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
2476
    }
2477
#elif defined(WOLFSSL_PPC64_ASM) && defined(LITTLE_ENDIAN_ORDER)
2478
    /* The PPC64 assembly loads the message with byte-reversed loads on
2479
     * little-endian, treating the whole block as a big-endian byte stream.  The
2480
     * 128-bit length just stored is in native (little-endian) word order, so
2481
     * reverse it here to keep the block a consistent big-endian stream. */
2482
    {
2483
        ByteReverseWords64(
2484
            &(sha512->buffer[WC_SHA512_PAD_SIZE / sizeof(word64)]),
2485
            &(sha512->buffer[WC_SHA512_PAD_SIZE / sizeof(word64)]),
2486
            WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
2487
    }
2488
#endif
2489
2490
#if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
2491
    defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_RISCV_ASM)
2492
    ret = Transform_Sha512(sha512, (const byte*)sha512->buffer);
2493
    if (ret != 0)
2494
        return ret;
2495
#else
2496
0
#if !defined(WOLFSSL_ESP32_CRYPT) || \
2497
0
      defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2498
0
      defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2499
0
    ret = Transform_Sha512(sha512);
2500
#else
2501
    if(sha512->ctx.mode == ESP32_SHA_INIT) {
2502
        /* typically for tiny block: first = last */
2503
        esp_sha_try_hw_lock(&sha512->ctx);
2504
    }
2505
    if (sha512->ctx.mode == ESP32_SHA_SW) {
2506
        ByteReverseWords64(sha512->buffer,
2507
                           sha512->buffer,
2508
                           WC_SHA512_BLOCK_SIZE);
2509
        sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
2510
        sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
2511
        ret = Transform_Sha512(sha512);
2512
    }
2513
    else {
2514
        ret = esp_sha512_digest_process(sha512, 1);
2515
    }
2516
#endif
2517
2518
0
    if (ret != 0)
2519
0
        return ret;
2520
0
#endif
2521
2522
    /* CHAR_BIT != 8: leave digest in host word order; the *Final functions
2523
     * emit big-endian octets via BytesFromWordsBE64 (no in-place reverse). */
2524
0
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_WIDE_BYTE)
2525
0
        ByteReverseWords64(sha512->digest, sha512->digest,
2526
0
            WC_SHA512_DIGEST_SIZE);
2527
0
    #endif
2528
2529
2530
0
    return 0;
2531
0
}
2532
2533
#endif /* WOLFSSL_KCAPI_HASH */
2534
2535
#ifdef WOLFSSL_SHA512
2536
2537
#if defined(WOLFSSL_KCAPI_HASH)
2538
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2539
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2540
2541
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2542
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2543
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2544
2545
#elif defined(MAX3266X_SHA)
2546
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2547
#elif defined(STM32_HASH_SHA512)
2548
#elif defined(PSOC6_HASH_SHA2)
2549
#elif defined(WOLFSSL_SILABS_SHA512)
2550
#else
2551
2552
static int Sha512FinalRaw(wc_Sha512* sha512, byte* hash, word32 digestSz)
2553
0
{
2554
0
    if (sha512 == NULL || hash == NULL) {
2555
0
        return BAD_FUNC_ARG;
2556
0
    }
2557
2558
#if defined(WOLFSSL_WIDE_BYTE)
2559
    BytesFromWordsBE64(hash, sha512->digest, digestSz);
2560
#elif defined(LITTLE_ENDIAN_ORDER)
2561
0
    if ((digestSz & 0x7) == 0)
2562
0
        ByteReverseWords64((word64 *)hash, sha512->digest, digestSz);
2563
0
    else {
2564
0
        ByteReverseWords64(sha512->digest, sha512->digest,
2565
0
                           WC_SHA512_DIGEST_SIZE);
2566
0
        XMEMCPY(hash, sha512->digest, digestSz);
2567
0
    }
2568
#else
2569
    XMEMCPY(hash, sha512->digest, digestSz);
2570
#endif
2571
2572
0
    return 0;
2573
0
}
2574
2575
int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
2576
0
{
2577
0
    return Sha512FinalRaw(sha512, hash, WC_SHA512_DIGEST_SIZE);
2578
0
}
2579
2580
static int Sha512_Family_Final(wc_Sha512* sha512, byte* hash, size_t digestSz,
2581
                               int (*initfp)(wc_Sha512*))
2582
0
{
2583
0
    int ret;
2584
2585
0
    if (sha512 == NULL || hash == NULL) {
2586
0
        return BAD_FUNC_ARG;
2587
0
    }
2588
2589
#ifdef WOLF_CRYPTO_CB
2590
    #ifndef WOLF_CRYPTO_CB_FIND
2591
    if (sha512->devId != INVALID_DEVID)
2592
    #endif
2593
    {
2594
        ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, hash, digestSz);
2595
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
2596
            return ret;
2597
        }
2598
        /* fall-through when unavailable */
2599
    }
2600
#endif
2601
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
2602
    if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {
2603
    #if defined(HAVE_INTEL_QA)
2604
        return IntelQaSymSha512(&sha512->asyncDev, hash, NULL, digestSz);
2605
    #endif
2606
    }
2607
#endif /* WOLFSSL_ASYNC_CRYPT */
2608
2609
0
    ret = Sha512Final(sha512);
2610
0
    if (ret != 0)
2611
0
        return ret;
2612
2613
#ifdef WOLFSSL_WIDE_BYTE
2614
    BytesFromWordsBE64(hash, sha512->digest, (word32)digestSz);
2615
#else
2616
0
    XMEMCPY(hash, sha512->digest, digestSz);
2617
0
#endif
2618
2619
    /* initialize Sha512 structure for the next use */
2620
0
    return initfp(sha512);
2621
0
}
2622
2623
#ifndef STM32_HASH_SHA512
2624
int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
2625
0
{
2626
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_DIGEST_SIZE, InitSha512);
2627
0
}
2628
#endif
2629
2630
#endif /* WOLFSSL_KCAPI_HASH */
2631
2632
#if defined(MAX3266X_SHA)
2633
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2634
2635
#else
2636
#if !defined(WOLFSSL_SE050) || !defined(WOLFSSL_SE050_HASH)
2637
int wc_InitSha512(wc_Sha512* sha512)
2638
0
{
2639
0
    int devId = INVALID_DEVID;
2640
2641
#ifdef WOLF_CRYPTO_CB
2642
    devId = wc_CryptoCb_DefaultDevID();
2643
#endif
2644
0
    return wc_InitSha512_ex(sha512, NULL, devId);
2645
0
}
2646
2647
void wc_Sha512Free(wc_Sha512* sha512)
2648
0
{
2649
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
2650
    int ret = 0;
2651
#endif
2652
2653
0
    if (sha512 == NULL)
2654
0
        return;
2655
2656
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
2657
    #ifndef WOLF_CRYPTO_CB_FIND
2658
    if (sha512->devId != INVALID_DEVID)
2659
    #endif
2660
    {
2661
        ret = wc_CryptoCb_Free(sha512->devId, WC_ALGO_TYPE_HASH,
2662
                         WC_HASH_TYPE_SHA512, 0, (void*)sha512);
2663
        /* If they want the standard free, they can call it themselves */
2664
        /* via their callback setting devId to INVALID_DEVID */
2665
        /* otherwise assume the callback handled it */
2666
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2667
            return;
2668
        /* fall-through when unavailable */
2669
    }
2670
2671
    /* silence compiler warning */
2672
    (void)ret;
2673
2674
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
2675
2676
#if defined(WOLFSSL_ESP32) && \
2677
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)  && \
2678
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2679
    esp_sha_release_unfinished_lock(&sha512->ctx);
2680
#endif
2681
2682
#ifdef WOLFSSL_SMALL_STACK_CACHE
2683
    if (sha512->W != NULL) {
2684
        ForceZero(sha512->W, (sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE);
2685
        XFREE(sha512->W, sha512->heap, DYNAMIC_TYPE_DIGEST);
2686
        sha512->W = NULL;
2687
    }
2688
#endif
2689
2690
#if defined(WOLFSSL_KCAPI_HASH)
2691
    KcapiHashFree(&sha512->kcapi);
2692
#endif
2693
2694
#if defined(WOLFSSL_HASH_KEEP) ||\
2695
   (defined(WOLFSSL_RENESAS_RSIP) && (WOLFSSL_RENESAS_RZFSP_VER >= 220))
2696
    if (sha512->msg != NULL) {
2697
        ForceZero(sha512->msg, sha512->len);
2698
        XFREE(sha512->msg, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
2699
        sha512->msg = NULL;
2700
    }
2701
#endif
2702
2703
2704
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
2705
    wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512);
2706
#endif /* WOLFSSL_ASYNC_CRYPT */
2707
2708
#if defined(PSOC6_HASH_SHA2)
2709
    wc_Psoc6_Sha_Free();
2710
#endif
2711
2712
0
    ForceZero(sha512, sizeof(*sha512));
2713
0
}
2714
#endif
2715
2716
#if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) \
2717
    && !defined(WOLFSSL_KCAPI_HASH)
2718
/* Apply SHA512 transformation to the data                */
2719
/* @param sha  a pointer to wc_Sha512 structure           */
2720
/* @param data data to be applied SHA512 transformation   */
2721
/* @return 0 on successful, otherwise non-zero on failure */
2722
int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data)
2723
{
2724
    int ret;
2725
    /* back up buffer */
2726
    WC_DECLARE_VAR(buffer, word64, WC_SHA512_BLOCK_SIZE  / sizeof(word64),
2727
        0);
2728
2729
    /* sanity check */
2730
    if (sha == NULL || data == NULL) {
2731
        return BAD_FUNC_ARG;
2732
    }
2733
2734
2735
#if defined(WOLFSSL_SMALL_STACK_CACHE)
2736
    if (sha->W == NULL)
2737
        return BAD_FUNC_ARG;
2738
    /* Skip over the initial `W' buffer at the start (used by
2739
     * _Transform_Sha512()).
2740
     */
2741
    buffer = sha->W + 16;
2742
#elif defined(WOLFSSL_SMALL_STACK)
2743
    buffer = (word64*)XMALLOC(WC_SHA512_BLOCK_SIZE, sha->heap,
2744
        DYNAMIC_TYPE_TMP_BUFFER);
2745
    if (buffer == NULL)
2746
        return MEMORY_E;
2747
#endif
2748
2749
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WC_SHA512_RAW_BE_BUFFER)
2750
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2751
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2752
    if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2753
#endif
2754
    {
2755
        ByteReverseWords64((word64*)data, (word64*)data,
2756
                                                WC_SHA512_BLOCK_SIZE);
2757
    }
2758
#endif /* LITTLE_ENDIAN_ORDER && !WC_SHA512_RAW_BE_BUFFER */
2759
2760
#if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM)
2761
    ByteReverseWords64(buffer, (word64*)data, WC_SHA512_BLOCK_SIZE);
2762
    Transform_Sha512(sha, (const byte*)buffer);
2763
    ret = 0;
2764
#elif defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
2765
    /* PPC assembly uses the (sha, data) form and reads the block directly
2766
     * (big-endian native - any little-endian reversal was done above). */
2767
    (void)buffer;
2768
    ret = Transform_Sha512(sha, data);
2769
#else
2770
    XMEMCPY(buffer, sha->buffer, WC_SHA512_BLOCK_SIZE);
2771
    XMEMCPY(sha->buffer, data, WC_SHA512_BLOCK_SIZE);
2772
2773
    ret = Transform_Sha512(sha);
2774
2775
    XMEMCPY(sha->buffer, buffer, WC_SHA512_BLOCK_SIZE);
2776
#endif
2777
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
2778
    ForceZero(buffer, WC_SHA512_BLOCK_SIZE);
2779
    XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
2780
#endif
2781
    return ret;
2782
}
2783
#endif /* OPENSSL_EXTRA */
2784
#endif /* WOLFSSL_SHA512 */
2785
#endif /* !WOLFSSL_SE050 || !WOLFSSL_SE050_HASH */
2786
2787
2788
/* -------------------------------------------------------------------------- */
2789
/* SHA384 */
2790
/* -------------------------------------------------------------------------- */
2791
#ifdef WOLFSSL_SHA384
2792
2793
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
2794
    !defined(WOLFSSL_QNX_CAAM)
2795
    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
2796
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2797
    int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
2798
    {
2799
        if (sha384 == NULL) {
2800
            return BAD_FUNC_ARG;
2801
        }
2802
        (void)devId;
2803
        return se050_hash_init(&sha384->se050Ctx, heap);
2804
    }
2805
    int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
2806
    {
2807
        if (sha384 == NULL) {
2808
            return BAD_FUNC_ARG;
2809
        }
2810
        if (data == NULL && len == 0) {
2811
            /* valid, but do nothing */
2812
            return 0;
2813
        }
2814
        if (data == NULL) {
2815
            return BAD_FUNC_ARG;
2816
        }
2817
2818
        return se050_hash_update(&sha384->se050Ctx, data, len);
2819
2820
    }
2821
    int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
2822
    {
2823
        int ret = 0;
2824
        ret = se050_hash_final(&sha384->se050Ctx, hash, WC_SHA384_DIGEST_SIZE,
2825
                               kAlgorithm_SSS_SHA384);
2826
        return ret;
2827
    }
2828
2829
#elif defined(WOLFSSL_SILABS_SHA384)
2830
    /* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */
2831
2832
#elif defined(WOLFSSL_KCAPI_HASH)
2833
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2834
2835
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2836
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2837
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2838
2839
#elif defined(MAX3266X_SHA)
2840
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2841
#elif defined(STM32_HASH_SHA384)
2842
2843
    int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
2844
    {
2845
        if (sha384 == NULL)
2846
            return BAD_FUNC_ARG;
2847
2848
        (void)devId;
2849
        (void)heap;
2850
2851
        XMEMSET(sha384, 0, sizeof(wc_Sha384));
2852
        wc_Stm32_Hash_Init(&sha384->stmCtx);
2853
        return 0;
2854
    }
2855
2856
    int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
2857
    {
2858
        int ret = 0;
2859
2860
        if (sha384 == NULL) {
2861
            return BAD_FUNC_ARG;
2862
        }
2863
        if (data == NULL && len == 0) {
2864
            /* valid, but do nothing */
2865
            return 0;
2866
        }
2867
        if (data == NULL) {
2868
            return BAD_FUNC_ARG;
2869
        }
2870
2871
        ret = wolfSSL_CryptHwMutexLock();
2872
        if (ret == 0) {
2873
            ret = wc_Stm32_Hash_Update(&sha384->stmCtx,
2874
                HASH_ALGOSELECTION_SHA384, data, len, WC_SHA384_BLOCK_SIZE);
2875
            wolfSSL_CryptHwMutexUnLock();
2876
        }
2877
        return ret;
2878
    }
2879
2880
    int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
2881
    {
2882
        int ret = 0;
2883
2884
        if (sha384 == NULL || hash == NULL) {
2885
            return BAD_FUNC_ARG;
2886
        }
2887
2888
        ret = wolfSSL_CryptHwMutexLock();
2889
        if (ret == 0) {
2890
            ret = wc_Stm32_Hash_Final(&sha384->stmCtx,
2891
                HASH_ALGOSELECTION_SHA384, hash, WC_SHA384_DIGEST_SIZE);
2892
            wolfSSL_CryptHwMutexUnLock();
2893
        }
2894
2895
        (void)wc_InitSha384(sha384); /* reset state */
2896
2897
        return ret;
2898
    }
2899
2900
#elif defined(PSOC6_HASH_SHA2)
2901
    /* implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */
2902
2903
#else
2904
2905
static int InitSha384(wc_Sha384* sha384)
2906
0
{
2907
0
    if (sha384 == NULL) {
2908
0
        return BAD_FUNC_ARG;
2909
0
    }
2910
2911
#ifdef WOLFSSL_SMALL_STACK_CACHE
2912
    if (sha384->W == NULL) {
2913
        /* This allocation combines the customary W buffer used by
2914
         * _Transform_Sha512() with additional buffer space used by
2915
         * wc_Sha512Transform().
2916
         */
2917
        sha384->W = (word64 *)XMALLOC((sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE,
2918
                                      sha384->heap, DYNAMIC_TYPE_DIGEST);
2919
        if (sha384->W == NULL)
2920
            return MEMORY_E;
2921
    }
2922
#endif
2923
2924
0
    sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8);
2925
0
    sha384->digest[1] = W64LIT(0x629a292a367cd507);
2926
0
    sha384->digest[2] = W64LIT(0x9159015a3070dd17);
2927
0
    sha384->digest[3] = W64LIT(0x152fecd8f70e5939);
2928
0
    sha384->digest[4] = W64LIT(0x67332667ffc00b31);
2929
0
    sha384->digest[5] = W64LIT(0x8eb44a8768581511);
2930
0
    sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7);
2931
0
    sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4);
2932
2933
0
    sha384->buffLen = 0;
2934
0
    XMEMSET(sha384->buffer, 0, sizeof(sha384->buffer));
2935
0
    sha384->loLen   = 0;
2936
0
    sha384->hiLen   = 0;
2937
2938
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2939
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
2940
    defined(WOLFSSL_ARMASM)
2941
    Sha512_SetTransform();
2942
#endif
2943
2944
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)  && \
2945
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
2946
    /* HW needs to be carefully initialized, taking into account soft copy.
2947
    ** If already in use; copy may revert to SW as needed. */
2948
    esp_sha_init(&(sha384->ctx), WC_HASH_TYPE_SHA384);
2949
#endif
2950
2951
#ifdef WOLFSSL_HASH_FLAGS
2952
    sha384->flags = 0;
2953
#endif
2954
2955
#ifdef HAVE_ARIA
2956
    sha384->hSession = NULL;
2957
#endif
2958
2959
#ifdef WOLFSSL_HASH_KEEP
2960
    sha384->msg  = NULL;
2961
    sha384->len  = 0;
2962
    sha384->used = 0;
2963
#endif
2964
2965
0
    return 0;
2966
0
}
2967
2968
#if !defined(WOLFSSL_HASH_KEEP)
2969
0
int wc_Sha384Reset(wc_Sha384* sha384) {
2970
0
    if (sha384 == NULL)
2971
0
        return BAD_FUNC_ARG;
2972
#ifdef WOLF_CRYPTO_CB
2973
    /* A device may hang state off devCtx that InitSha384() cannot restart.
2974
     * Free and re-init so the callback gets its teardown and setup. */
2975
    #ifndef WOLF_CRYPTO_CB_FIND
2976
    if (sha384->devId != INVALID_DEVID)
2977
    #endif
2978
    {
2979
        void* heap = sha384->heap;
2980
        int devId = sha384->devId;
2981
        wc_Sha384Free(sha384);
2982
        return wc_InitSha384_ex(sha384, heap, devId);
2983
    }
2984
#endif
2985
0
    return InitSha384(sha384);
2986
0
}
2987
#define WC_SHA384RESET_DEFINED
2988
#endif /* !WOLFSSL_HASH_KEEP */
2989
2990
int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
2991
0
{
2992
2993
0
    if (sha384 == NULL) {
2994
0
        return BAD_FUNC_ARG;
2995
0
    }
2996
0
    if (data == NULL && len == 0) {
2997
        /* valid, but do nothing */
2998
0
        return 0;
2999
0
    }
3000
0
    if (data == NULL) {
3001
0
        return BAD_FUNC_ARG;
3002
0
    }
3003
3004
#ifdef WOLF_CRYPTO_CB
3005
    #ifndef WOLF_CRYPTO_CB_FIND
3006
    if (sha384->devId != INVALID_DEVID)
3007
    #endif
3008
    {
3009
        int ret = wc_CryptoCb_Sha384Hash(sha384, data, len, NULL);
3010
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3011
            return ret;
3012
        /* fall-through when unavailable */
3013
    }
3014
#endif
3015
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
3016
    if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {
3017
    #if defined(HAVE_INTEL_QA)
3018
        return IntelQaSymSha384(&sha384->asyncDev, NULL, data, len);
3019
    #endif
3020
    }
3021
#endif /* WOLFSSL_ASYNC_CRYPT */
3022
3023
0
    return Sha512Update((wc_Sha512*)sha384, data, len);
3024
0
}
3025
3026
3027
int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
3028
0
{
3029
0
    if (sha384 == NULL || hash == NULL) {
3030
0
        return BAD_FUNC_ARG;
3031
0
    }
3032
3033
#if defined(WOLFSSL_WIDE_BYTE)
3034
    BytesFromWordsBE64(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
3035
#elif defined(LITTLE_ENDIAN_ORDER)
3036
0
    ByteReverseWords64((word64 *)hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
3037
#else
3038
    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
3039
#endif
3040
3041
0
    return 0;
3042
0
}
3043
3044
int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
3045
0
{
3046
0
    int ret;
3047
3048
0
    if (sha384 == NULL || hash == NULL) {
3049
0
        return BAD_FUNC_ARG;
3050
0
    }
3051
3052
#ifdef WOLF_CRYPTO_CB
3053
    #ifndef WOLF_CRYPTO_CB_FIND
3054
    if (sha384->devId != INVALID_DEVID)
3055
    #endif
3056
    {
3057
        ret = wc_CryptoCb_Sha384Hash(sha384, NULL, 0, hash);
3058
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3059
            return ret;
3060
        /* fall-through when unavailable */
3061
    }
3062
#endif
3063
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
3064
    if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {
3065
    #if defined(HAVE_INTEL_QA)
3066
        return IntelQaSymSha384(&sha384->asyncDev, hash, NULL,
3067
                                            WC_SHA384_DIGEST_SIZE);
3068
    #endif
3069
    }
3070
#endif /* WOLFSSL_ASYNC_CRYPT */
3071
3072
0
    ret = Sha512Final((wc_Sha512*)sha384);
3073
0
    if (ret != 0)
3074
0
        return ret;
3075
3076
#ifdef WOLFSSL_WIDE_BYTE
3077
    BytesFromWordsBE64(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
3078
#else
3079
0
    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
3080
0
#endif
3081
3082
0
    return InitSha384(sha384);  /* reset state */
3083
0
}
3084
3085
int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
3086
0
{
3087
0
    int ret;
3088
3089
0
    if (sha384 == NULL) {
3090
0
        return BAD_FUNC_ARG;
3091
0
    }
3092
3093
0
    sha384->heap = heap;
3094
#ifdef WOLFSSL_SMALL_STACK_CACHE
3095
    sha384->W = NULL;
3096
#endif
3097
#ifdef WOLF_CRYPTO_CB
3098
    sha384->devId = devId;
3099
    sha384->devCtx = NULL;
3100
#endif
3101
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)  && \
3102
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
3103
    if (sha384->ctx.mode != ESP32_SHA_INIT) {
3104
        ESP_LOGV(TAG, "Set ctx mode from prior value: "
3105
                           "%d", sha384->ctx.mode);
3106
    }
3107
    /* We know this is a fresh, uninitialized item, so set to INIT */
3108
    sha384->ctx.mode = ESP32_SHA_INIT;
3109
#endif
3110
3111
3112
0
    ret = InitSha384(sha384);
3113
0
    if (ret != 0) {
3114
0
        return ret;
3115
0
    }
3116
3117
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
3118
    ret = wolfAsync_DevCtxInit(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384,
3119
                                                           sha384->heap, devId);
3120
#else
3121
0
    (void)devId;
3122
0
#endif /* WOLFSSL_ASYNC_CRYPT */
3123
#ifdef WOLFSSL_IMXRT1170_CAAM
3124
     ret = wc_CAAM_HashInit(&sha384->hndl, &sha384->ctx, WC_HASH_TYPE_SHA384);
3125
#endif
3126
0
    return ret;
3127
0
}
3128
3129
#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA384 || WOLFSSL_KCAPI_HASH */
3130
3131
#if defined(MAX3266X_SHA)
3132
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
3133
3134
#else
3135
int wc_InitSha384(wc_Sha384* sha384)
3136
0
{
3137
0
    int devId = INVALID_DEVID;
3138
3139
#ifdef WOLF_CRYPTO_CB
3140
    devId = wc_CryptoCb_DefaultDevID();
3141
#endif
3142
0
    return wc_InitSha384_ex(sha384, NULL, devId);
3143
0
}
3144
3145
void wc_Sha384Free(wc_Sha384* sha384)
3146
0
{
3147
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
3148
    int ret = 0;
3149
#endif
3150
3151
0
    if (sha384 == NULL)
3152
0
        return;
3153
3154
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
3155
    #ifndef WOLF_CRYPTO_CB_FIND
3156
    if (sha384->devId != INVALID_DEVID)
3157
    #endif
3158
    {
3159
        ret = wc_CryptoCb_Free(sha384->devId, WC_ALGO_TYPE_HASH,
3160
                         WC_HASH_TYPE_SHA384, 0, (void*)sha384);
3161
        /* If they want the standard free, they can call it themselves */
3162
        /* via their callback setting devId to INVALID_DEVID */
3163
        /* otherwise assume the callback handled it */
3164
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3165
            return;
3166
        /* fall-through when unavailable */
3167
    }
3168
3169
    /* silence compiler warning */
3170
    (void)ret;
3171
3172
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
3173
3174
#if defined(WOLFSSL_ESP32) && !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)  && \
3175
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
3176
    esp_sha_release_unfinished_lock(&sha384->ctx);
3177
#endif
3178
3179
#ifdef WOLFSSL_SMALL_STACK_CACHE
3180
    if (sha384->W != NULL) {
3181
        ForceZero(sha384->W, (sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE);
3182
        XFREE(sha384->W, sha384->heap, DYNAMIC_TYPE_DIGEST);
3183
        sha384->W = NULL;
3184
    }
3185
#endif
3186
3187
#if defined(WOLFSSL_KCAPI_HASH)
3188
    KcapiHashFree(&sha384->kcapi);
3189
#endif
3190
3191
#if defined(WOLFSSL_HASH_KEEP) || \
3192
   (defined(WOLFSSL_RENESAS_RSIP) && (WOLFSSL_RENESAS_RZFSP_VER >= 220))
3193
    if (sha384->msg != NULL) {
3194
        ForceZero(sha384->msg, sha384->len);
3195
        XFREE(sha384->msg, sha384->heap, DYNAMIC_TYPE_TMP_BUFFER);
3196
        sha384->msg = NULL;
3197
    }
3198
#endif
3199
3200
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3201
    se050_hash_free(&sha384->se050Ctx);
3202
#endif
3203
3204
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
3205
    wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384);
3206
#endif /* WOLFSSL_ASYNC_CRYPT */
3207
3208
#ifdef HAVE_ARIA
3209
    if (sha384->hSession != NULL) {
3210
        MC_CloseSession(sha384->hSession);
3211
        sha384->hSession = NULL;
3212
    }
3213
#endif
3214
3215
3216
0
    ForceZero(sha384, sizeof(*sha384));
3217
0
}
3218
3219
#endif
3220
#endif /* WOLFSSL_SHA384 */
3221
3222
#ifdef WOLFSSL_SHA512
3223
3224
#if defined(WOLFSSL_KCAPI_HASH)
3225
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3226
3227
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3228
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3229
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3230
3231
#elif defined(MAX3266X_SHA)
3232
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
3233
3234
#else
3235
3236
static int Sha512_Family_GetHash(wc_Sha512* sha512, byte* hash,
3237
                                 int (*finalfp)(wc_Sha512*, byte*))
3238
0
{
3239
0
    int ret;
3240
0
    WC_DECLARE_VAR(tmpSha512, wc_Sha512, 1, 0);
3241
3242
0
    if (sha512 == NULL || hash == NULL) {
3243
0
        return BAD_FUNC_ARG;
3244
0
    }
3245
3246
0
    WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
3247
0
        return MEMORY_E);
3248
3249
    /* copy this sha512 into tmpSha */
3250
0
    ret = wc_Sha512Copy(sha512, tmpSha512);
3251
0
    if (ret == 0) {
3252
0
        ret = finalfp(tmpSha512, hash);
3253
0
        wc_Sha512Free(tmpSha512);
3254
0
    }
3255
3256
0
    WC_FREE_VAR_EX(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3257
3258
0
    return ret;
3259
0
}
3260
3261
int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)
3262
0
{
3263
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512Final);
3264
0
}
3265
3266
int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
3267
0
{
3268
0
    int ret = 0;
3269
3270
0
    if (src == NULL || dst == NULL) {
3271
0
        return BAD_FUNC_ARG;
3272
0
    }
3273
3274
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
3275
    #ifndef WOLF_CRYPTO_CB_FIND
3276
    if (src->devId != INVALID_DEVID)
3277
    #endif
3278
    {
3279
        /* Cast the source and destination to be void to keep the abstraction */
3280
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
3281
                               WC_HASH_TYPE_SHA512, (void*)src, (void*)dst);
3282
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3283
            return ret;
3284
        /* fall-through when unavailable */
3285
    }
3286
    ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
3287
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
3288
3289
    /* Free dst resources before copy to prevent memory leaks (e.g., msg
3290
     * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
3291
0
    wc_Sha512Free(dst);
3292
0
    XMEMCPY(dst, src, sizeof(wc_Sha512));
3293
#ifdef WOLFSSL_SMALL_STACK_CACHE
3294
    /* This allocation combines the customary W buffer used by
3295
     * _Transform_Sha512() with additional buffer space used by
3296
     * wc_Sha512Transform().
3297
     */
3298
    dst->W = (word64 *)XMALLOC((sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE,
3299
                               dst->heap, DYNAMIC_TYPE_DIGEST);
3300
    if (dst->W == NULL) {
3301
        XMEMSET(dst, 0, sizeof(wc_Sha512));
3302
        return MEMORY_E;
3303
    }
3304
#endif
3305
3306
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3) && \
3307
    defined(WOLFSSL_SILABS_SHA512)
3308
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
3309
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
3310
#endif
3311
3312
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
3313
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
3314
#endif
3315
3316
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3317
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
3318
    #if defined(CONFIG_IDF_TARGET_ESP32)
3319
    if (ret == 0) {
3320
        ret = esp_sha512_ctx_copy(src, dst);
3321
    }
3322
    #elif defined(CONFIG_IDF_TARGET_ESP32C2) || \
3323
          defined(CONFIG_IDF_TARGET_ESP8684) || \
3324
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
3325
          defined(CONFIG_IDF_TARGET_ESP32C6)
3326
        ESP_LOGV(TAG, "No SHA-512 HW on the ESP32-C3");
3327
3328
    #elif defined(CONFIG_IDF_TARGET_ESP32S2) || \
3329
          defined(CONFIG_IDF_TARGET_ESP32S3)
3330
        if (ret == 0) {
3331
            ret = esp_sha512_ctx_copy(src, dst);
3332
        }
3333
    #else
3334
        ESP_LOGW(TAG, "No SHA384 HW or not yet implemented for %s",
3335
                       CONFIG_IDF_TARGET);
3336
    #endif
3337
3338
#endif /* WOLFSSL_USE_ESP32_CRYPT_HASH_HW */
3339
3340
#ifdef WOLFSSL_HASH_FLAGS
3341
     dst->flags |= WC_HASH_FLAG_ISCOPY;
3342
#endif
3343
3344
#if defined(WOLFSSL_HASH_KEEP)
3345
    if (src->msg != NULL) {
3346
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
3347
        if (dst->msg == NULL)
3348
            return MEMORY_E;
3349
        XMEMCPY(dst->msg, src->msg, src->len);
3350
    }
3351
#endif
3352
3353
3354
#if defined(PSOC6_HASH_SHA2)
3355
    wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA512, 0);
3356
#endif
3357
3358
0
    return ret;
3359
0
}
3360
3361
#endif /* WOLFSSL_KCAPI_HASH */
3362
3363
#ifdef WOLFSSL_HASH_FLAGS
3364
int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags)
3365
{
3366
    if (sha512) {
3367
        sha512->flags = flags;
3368
    }
3369
    return 0;
3370
}
3371
int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags)
3372
{
3373
    if (sha512 && flags) {
3374
        *flags = sha512->flags;
3375
    }
3376
    return 0;
3377
}
3378
#endif /* WOLFSSL_HASH_FLAGS */
3379
3380
#if !defined(WOLFSSL_NOSHA512_224) && \
3381
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
3382
3383
#if defined(STM32_HASH_SHA512_224)
3384
3385
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
3386
{
3387
    if (sha512 == NULL)
3388
        return BAD_FUNC_ARG;
3389
3390
    (void)devId;
3391
    (void)heap;
3392
3393
    XMEMSET(sha512, 0, sizeof(wc_Sha512));
3394
    wc_Stm32_Hash_Init(&sha512->stmCtx);
3395
#if defined(WOLFSSL_SHA512_HASHTYPE)
3396
    sha512->hashType = WC_HASH_TYPE_SHA512_224;
3397
#endif
3398
    return 0;
3399
}
3400
3401
int wc_Sha512_224Update(wc_Sha512* sha512, const byte* data, word32 len)
3402
{
3403
    int ret = 0;
3404
3405
    if (sha512 == NULL) {
3406
        return BAD_FUNC_ARG;
3407
    }
3408
    if (data == NULL && len == 0) {
3409
        /* valid, but do nothing */
3410
        return 0;
3411
    }
3412
    if (data == NULL) {
3413
        return BAD_FUNC_ARG;
3414
    }
3415
3416
    ret = wolfSSL_CryptHwMutexLock();
3417
    if (ret == 0) {
3418
        ret = wc_Stm32_Hash_Update(&sha512->stmCtx,
3419
            HASH_ALGOSELECTION_SHA512_224, data, len, WC_SHA512_224_BLOCK_SIZE);
3420
        wolfSSL_CryptHwMutexUnLock();
3421
    }
3422
    return ret;
3423
}
3424
3425
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
3426
{
3427
    int ret = 0;
3428
3429
    if (sha512 == NULL || hash == NULL) {
3430
        return BAD_FUNC_ARG;
3431
    }
3432
3433
    ret = wolfSSL_CryptHwMutexLock();
3434
    if (ret == 0) {
3435
        ret = wc_Stm32_Hash_Final(&sha512->stmCtx,
3436
            HASH_ALGOSELECTION_SHA512_224, hash, WC_SHA512_224_DIGEST_SIZE);
3437
        wolfSSL_CryptHwMutexUnLock();
3438
    }
3439
3440
    (void)wc_InitSha512_224(sha512); /* reset state */
3441
3442
    return ret;
3443
}
3444
#elif defined(PSOC6_HASH_SHA2)
3445
    /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
3446
#endif
3447
int wc_InitSha512_224(wc_Sha512* sha)
3448
0
{
3449
0
    return wc_InitSha512_224_ex(sha, NULL, INVALID_DEVID);
3450
0
}
3451
#if !defined(STM32_HASH_SHA512_224) && !defined(PSOC6_HASH_SHA2)
3452
int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len)
3453
0
{
3454
0
    return wc_Sha512Update(sha, data, len);
3455
0
}
3456
#endif
3457
#if defined(WOLFSSL_KCAPI_HASH)
3458
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3459
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3460
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3461
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3462
3463
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3464
#elif defined(STM32_HASH_SHA512_224)
3465
#elif defined(PSOC6_HASH_SHA2)
3466
    /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
3467
3468
#else
3469
int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash)
3470
0
{
3471
0
    return Sha512FinalRaw(sha, hash, WC_SHA512_224_DIGEST_SIZE);
3472
0
}
3473
3474
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
3475
0
{
3476
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_224_DIGEST_SIZE,
3477
0
                               InitSha512_224);
3478
0
}
3479
#endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
3480
3481
void wc_Sha512_224Free(wc_Sha512* sha)
3482
0
{
3483
0
    wc_Sha512Free(sha);
3484
0
}
3485
3486
#if defined(WOLFSSL_KCAPI_HASH)
3487
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3488
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3489
3490
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3491
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3492
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3493
3494
#else
3495
int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash)
3496
0
{
3497
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512_224Final);
3498
0
}
3499
3500
int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst)
3501
0
{
3502
0
    return wc_Sha512Copy(src, dst);
3503
0
}
3504
#endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
3505
3506
#ifdef WOLFSSL_HASH_FLAGS
3507
int wc_Sha512_224SetFlags(wc_Sha512* sha, word32 flags)
3508
{
3509
    return wc_Sha512SetFlags(sha, flags);
3510
}
3511
int wc_Sha512_224GetFlags(wc_Sha512* sha, word32* flags)
3512
{
3513
    return wc_Sha512GetFlags(sha, flags);
3514
}
3515
#endif /* WOLFSSL_HASH_FLAGS */
3516
3517
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
3518
int wc_Sha512_224Transform(wc_Sha512* sha, const unsigned char* data)
3519
{
3520
    return wc_Sha512Transform(sha, data);
3521
}
3522
#endif /* OPENSSL_EXTRA */
3523
3524
3525
#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */
3526
3527
#if !defined(WOLFSSL_NOSHA512_256) && \
3528
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
3529
#if defined(STM32_HASH_SHA512_256)
3530
3531
    int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
3532
    {
3533
        if (sha512 == NULL)
3534
            return BAD_FUNC_ARG;
3535
3536
        (void)devId;
3537
        (void)heap;
3538
3539
        XMEMSET(sha512, 0, sizeof(wc_Sha512));
3540
        wc_Stm32_Hash_Init(&sha512->stmCtx);
3541
#if defined(WOLFSSL_SHA512_HASHTYPE)
3542
        sha512->hashType = WC_HASH_TYPE_SHA512_256;
3543
#endif
3544
        return 0;
3545
    }
3546
3547
    int wc_Sha512_256Update(wc_Sha512* sha512, const byte* data, word32 len)
3548
    {
3549
        int ret = 0;
3550
3551
        if (sha512 == NULL) {
3552
            return BAD_FUNC_ARG;
3553
        }
3554
        if (data == NULL && len == 0) {
3555
            /* valid, but do nothing */
3556
            return 0;
3557
        }
3558
        if (data == NULL) {
3559
            return BAD_FUNC_ARG;
3560
        }
3561
3562
        ret = wolfSSL_CryptHwMutexLock();
3563
        if (ret == 0) {
3564
            ret = wc_Stm32_Hash_Update(&sha512->stmCtx,
3565
                HASH_ALGOSELECTION_SHA512_256, data, len, WC_SHA512_256_BLOCK_SIZE);
3566
            wolfSSL_CryptHwMutexUnLock();
3567
        }
3568
        return ret;
3569
    }
3570
3571
    int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
3572
    {
3573
        int ret = 0;
3574
3575
        if (sha512 == NULL || hash == NULL) {
3576
            return BAD_FUNC_ARG;
3577
        }
3578
3579
        ret = wolfSSL_CryptHwMutexLock();
3580
        if (ret == 0) {
3581
            ret = wc_Stm32_Hash_Final(&sha512->stmCtx,
3582
                HASH_ALGOSELECTION_SHA512_256, hash, WC_SHA512_256_DIGEST_SIZE);
3583
            wolfSSL_CryptHwMutexUnLock();
3584
        }
3585
3586
        (void)wc_InitSha512_256(sha512); /* reset state */
3587
3588
        return ret;
3589
    }
3590
#elif defined(PSOC6_HASH_SHA2)
3591
    /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
3592
#endif
3593
int wc_InitSha512_256(wc_Sha512* sha)
3594
0
{
3595
0
    return wc_InitSha512_256_ex(sha, NULL, INVALID_DEVID);
3596
0
}
3597
#if !defined(STM32_HASH_SHA512_256) && !defined(PSOC6_HASH_SHA2)
3598
int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len)
3599
0
{
3600
0
    return wc_Sha512Update(sha, data, len);
3601
0
}
3602
#endif
3603
#if defined(WOLFSSL_KCAPI_HASH)
3604
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3605
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3606
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3607
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3608
3609
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3610
#elif defined(STM32_HASH_SHA512_256)
3611
#elif defined(PSOC6_HASH_SHA2)
3612
    /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
3613
#else
3614
int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash)
3615
0
{
3616
0
    return Sha512FinalRaw(sha, hash, WC_SHA512_256_DIGEST_SIZE);
3617
0
}
3618
3619
int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
3620
0
{
3621
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_256_DIGEST_SIZE,
3622
0
                               InitSha512_256);
3623
0
}
3624
#endif
3625
3626
void wc_Sha512_256Free(wc_Sha512* sha)
3627
0
{
3628
0
    wc_Sha512Free(sha);
3629
0
}
3630
3631
#if defined(WOLFSSL_KCAPI_HASH)
3632
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3633
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3634
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3635
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3636
3637
#else
3638
int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash)
3639
0
{
3640
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512_256Final);
3641
0
}
3642
int wc_Sha512_256Copy(wc_Sha512* src, wc_Sha512* dst)
3643
0
{
3644
0
    return wc_Sha512Copy(src, dst);
3645
0
}
3646
#endif
3647
3648
#ifdef WOLFSSL_HASH_FLAGS
3649
int wc_Sha512_256SetFlags(wc_Sha512* sha, word32 flags)
3650
{
3651
    return wc_Sha512SetFlags(sha, flags);
3652
}
3653
int wc_Sha512_256GetFlags(wc_Sha512* sha, word32* flags)
3654
{
3655
    return wc_Sha512GetFlags(sha, flags);
3656
}
3657
#endif /* WOLFSSL_HASH_FLAGS */
3658
3659
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
3660
int wc_Sha512_256Transform(wc_Sha512* sha, const unsigned char* data)
3661
{
3662
    return wc_Sha512Transform(sha, data);
3663
}
3664
#endif /* OPENSSL_EXTRA */
3665
3666
3667
#endif /* !WOLFSSL_NOSHA512_256 && !FIPS ... */
3668
3669
#endif /* WOLFSSL_SHA512 */
3670
3671
#ifdef WOLFSSL_SHA384
3672
3673
#if defined(WOLFSSL_KCAPI_HASH)
3674
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3675
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3676
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3677
    /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */
3678
#elif defined(MAX3266X_SHA)
3679
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
3680
3681
#else
3682
3683
int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
3684
0
{
3685
0
    int ret;
3686
0
    WC_DECLARE_VAR(tmpSha384, wc_Sha384, 1, 0);
3687
3688
0
    if (sha384 == NULL || hash == NULL) {
3689
0
        return BAD_FUNC_ARG;
3690
0
    }
3691
3692
0
    WC_CALLOC_VAR_EX(tmpSha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
3693
0
        return MEMORY_E);
3694
3695
    /* copy this sha384 into tmpSha */
3696
0
    ret = wc_Sha384Copy(sha384, tmpSha384);
3697
0
    if (ret == 0) {
3698
0
        ret = wc_Sha384Final(tmpSha384, hash);
3699
0
        wc_Sha384Free(tmpSha384);
3700
0
    }
3701
3702
0
    WC_FREE_VAR_EX(tmpSha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3703
3704
0
    return ret;
3705
0
}
3706
3707
int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
3708
0
{
3709
0
    int ret = 0;
3710
3711
0
    if (src == NULL || dst == NULL) {
3712
0
        return BAD_FUNC_ARG;
3713
0
    }
3714
3715
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
3716
    #ifndef WOLF_CRYPTO_CB_FIND
3717
    if (src->devId != INVALID_DEVID)
3718
    #endif
3719
    {
3720
        /* Cast the source and destination to be void to keep the abstraction */
3721
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
3722
                               WC_HASH_TYPE_SHA384, (void*)src, (void*)dst);
3723
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3724
            return ret;
3725
        /* fall-through when unavailable */
3726
    }
3727
    ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
3728
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
3729
3730
    /* Free dst resources before copy to prevent memory leaks (e.g., msg
3731
     * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
3732
0
    wc_Sha384Free(dst);
3733
0
    XMEMCPY(dst, src, sizeof(wc_Sha384));
3734
3735
#ifdef WOLFSSL_SMALL_STACK_CACHE
3736
    /* This allocation combines the customary W buffer used by
3737
     * _Transform_Sha512() with additional buffer space used by
3738
     * wc_Sha512Transform().
3739
     */
3740
    dst->W = (word64 *)XMALLOC((sizeof(word64) * 16) + WC_SHA384_BLOCK_SIZE,
3741
                               dst->heap, DYNAMIC_TYPE_DIGEST);
3742
    if (dst->W == NULL) {
3743
        XMEMSET(dst, 0, sizeof(wc_Sha384));
3744
        return MEMORY_E;
3745
    }
3746
#endif
3747
3748
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3) && \
3749
    defined(WOLFSSL_SILABS_SHA384)
3750
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
3751
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
3752
#endif
3753
3754
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
3755
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
3756
#endif
3757
3758
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3759
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
3760
    #if defined(CONFIG_IDF_TARGET_ESP32)
3761
        esp_sha384_ctx_copy(src, dst);
3762
    #elif defined(CONFIG_IDF_TARGET_ESP32C2) || \
3763
          defined(CONFIG_IDF_TARGET_ESP8684) || \
3764
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
3765
          defined(CONFIG_IDF_TARGET_ESP32C6)
3766
        ESP_LOGV(TAG, "No SHA-384 HW on the ESP32-C3");
3767
    #elif defined(CONFIG_IDF_TARGET_ESP32S2) || \
3768
          defined(CONFIG_IDF_TARGET_ESP32S3)
3769
        esp_sha384_ctx_copy(src, dst);
3770
    #else
3771
        ESP_LOGW(TAG, "No SHA384 HW or not yet implemented for %s",
3772
                       CONFIG_IDF_TARGET);
3773
    #endif
3774
#endif
3775
3776
#ifdef HAVE_ARIA
3777
    dst->hSession = NULL;
3778
    if((src->hSession != NULL) && (MC_CopySession(src->hSession, &(dst->hSession)) != MC_OK)) {
3779
        return MEMORY_E;
3780
    }
3781
#endif
3782
3783
#ifdef WOLFSSL_HASH_FLAGS
3784
     dst->flags |= WC_HASH_FLAG_ISCOPY;
3785
#endif
3786
3787
#if defined(WOLFSSL_HASH_KEEP)
3788
    if (src->msg != NULL) {
3789
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
3790
        if (dst->msg == NULL)
3791
            return MEMORY_E;
3792
        XMEMCPY(dst->msg, src->msg, src->len);
3793
    }
3794
#endif
3795
3796
3797
#if defined(PSOC6_HASH_SHA2)
3798
    wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA384, 0);
3799
#endif
3800
3801
0
    return ret;
3802
0
}
3803
3804
#endif /* WOLFSSL_KCAPI_HASH */
3805
3806
#ifdef WOLFSSL_HASH_FLAGS
3807
int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags)
3808
{
3809
    if (sha384) {
3810
        sha384->flags = flags;
3811
    }
3812
    return 0;
3813
}
3814
int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags)
3815
{
3816
    if (sha384 && flags) {
3817
        *flags = sha384->flags;
3818
    }
3819
    return 0;
3820
}
3821
#endif
3822
3823
#endif /* WOLFSSL_SHA384 */
3824
3825
#ifdef WOLFSSL_HASH_KEEP
3826
/* Some hardware have issues with update, this function stores the data to be
3827
 * hashed into an array. Once ready, the Final operation is called on all of the
3828
 * data to be hashed at once.
3829
 * returns 0 on success
3830
 */
3831
int wc_Sha512_Grow(wc_Sha512* sha512, const byte* in, int inSz)
3832
{
3833
    return _wc_Hash_Grow(&(sha512->msg), &(sha512->used), &(sha512->len), in,
3834
                        inSz, sha512->heap);
3835
}
3836
#ifdef WOLFSSL_SHA384
3837
int wc_Sha384_Grow(wc_Sha384* sha384, const byte* in, int inSz)
3838
{
3839
    return _wc_Hash_Grow(&(sha384->msg), &(sha384->used), &(sha384->len), in,
3840
                        inSz, sha384->heap);
3841
}
3842
#endif /* WOLFSSL_SHA384 */
3843
#endif /* WOLFSSL_HASH_KEEP */
3844
3845
#endif /* !WOLF_CRYPTO_CB_ONLY_SHA512 */
3846
3847
/* Fallback implementations of the Reset functions, for all configurations other
3848
 * than plain software.  Continues with the established heap and devId.
3849
 */
3850
3851
#ifdef WOLF_CRYPTO_CB
3852
    #define WC_SHA512_RESET_DEVID(sha) ((sha)->devId)
3853
#else
3854
    #define WC_SHA512_RESET_DEVID(sha) (INVALID_DEVID)
3855
#endif
3856
#define WC_SHA512_RESET_FALLBACK_IMPLEMENT(flavor)              \
3857
    int wc_##flavor##Reset(wc_##flavor *sha) {                  \
3858
        void *heap;                                             \
3859
        int devId;                                              \
3860
                                                                \
3861
        if (sha == NULL)                                        \
3862
            return BAD_FUNC_ARG;                                \
3863
                                                                \
3864
        heap = sha->heap;                                       \
3865
        devId = WC_SHA512_RESET_DEVID(sha);                     \
3866
                                                                \
3867
        wc_##flavor##Free(sha);                                 \
3868
        return wc_Init##flavor##_ex(sha, heap, devId);          \
3869
    }
3870
3871
#if defined(WOLFSSL_SHA512) && !defined(WC_SHA512RESET_DEFINED)
3872
    WC_SHA512_RESET_FALLBACK_IMPLEMENT(Sha512)
3873
#endif
3874
3875
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_224) && \
3876
    !defined(WC_SHA512_224RESET_DEFINED) && \
3877
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
3878
    WC_SHA512_RESET_FALLBACK_IMPLEMENT(Sha512_224)
3879
#endif
3880
3881
#if defined(WOLFSSL_SHA512) && !defined(WOLFSSL_NOSHA512_256) && \
3882
    !defined(WC_SHA512_256RESET_DEFINED) && \
3883
    (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
3884
    WC_SHA512_RESET_FALLBACK_IMPLEMENT(Sha512_256)
3885
#endif
3886
3887
#if defined(WOLFSSL_SHA384) && !defined(WC_SHA384RESET_DEFINED)
3888
    WC_SHA512_RESET_FALLBACK_IMPLEMENT(Sha384)
3889
#endif
3890
3891
#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */