Coverage Report

Created: 2026-08-12 07:05

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_NOSHA512_224) && \
966
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
967
968
/**
969
 * Initialize given wc_Sha512 structure with value specific to sha512/224.
970
 * Note that sha512/224 has different initial hash value from sha512.
971
 * The initial hash value consists of eight 64bit words. They are given
972
 * in FIPS180-4.
973
 */
974
static int InitSha512_224(wc_Sha512* sha512)
975
0
{
976
0
    if (sha512 == NULL)
977
0
        return BAD_FUNC_ARG;
978
979
0
    sha512->digest[0] = W64LIT(0x8c3d37c819544da2);
980
0
    sha512->digest[1] = W64LIT(0x73e1996689dcd4d6);
981
0
    sha512->digest[2] = W64LIT(0x1dfab7ae32ff9c82);
982
0
    sha512->digest[3] = W64LIT(0x679dd514582f9fcf);
983
0
    sha512->digest[4] = W64LIT(0x0f6d2b697bd44da8);
984
0
    sha512->digest[5] = W64LIT(0x77e36f7304c48942);
985
0
    sha512->digest[6] = W64LIT(0x3f9d85a86a1d36c8);
986
0
    sha512->digest[7] = W64LIT(0x1112e6ad91d692a1);
987
988
0
    sha512->buffLen = 0;
989
0
    XMEMSET(sha512->buffer, 0, sizeof(sha512->buffer));
990
0
    sha512->loLen   = 0;
991
0
    sha512->hiLen   = 0;
992
993
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
994
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
995
    defined(WOLFSSL_ARMASM)
996
    Sha512_SetTransform();
997
#endif
998
999
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1000
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1001
    /* HW needs to be carefully initialized, taking into account soft copy.
1002
    ** If already in use; copy may revert to SW as needed.
1003
    **
1004
    ** Note for original ESP32, there's no HW for SHA512/224
1005
    */
1006
    esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_224);
1007
#endif
1008
1009
#ifdef WOLFSSL_HASH_FLAGS
1010
    sha512->flags = 0;
1011
#endif
1012
#if defined(WOLFSSL_SHA512_HASHTYPE)
1013
    sha512->hashType = WC_HASH_TYPE_SHA512_224;
1014
#endif /* WOLFSSL_SHA512_HASHTYPE */
1015
0
    return 0;
1016
0
}
1017
#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */
1018
1019
#if !defined(WOLFSSL_NOSHA512_256) && \
1020
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
1021
/**
1022
 * Initialize given wc_Sha512 structure with value specific to sha512/256.
1023
 * Note that sha512/256 has different initial hash value from sha512.
1024
 * The initial hash value consists of eight 64bit words. They are given
1025
 * in FIPS180-4.
1026
 */
1027
static int InitSha512_256(wc_Sha512* sha512)
1028
0
{
1029
0
    if (sha512 == NULL)
1030
0
        return BAD_FUNC_ARG;
1031
1032
0
    sha512->digest[0] = W64LIT(0x22312194fc2bf72c);
1033
0
    sha512->digest[1] = W64LIT(0x9f555fa3c84c64c2);
1034
0
    sha512->digest[2] = W64LIT(0x2393b86b6f53b151);
1035
0
    sha512->digest[3] = W64LIT(0x963877195940eabd);
1036
0
    sha512->digest[4] = W64LIT(0x96283ee2a88effe3);
1037
0
    sha512->digest[5] = W64LIT(0xbe5e1e2553863992);
1038
0
    sha512->digest[6] = W64LIT(0x2b0199fc2c85b8aa);
1039
0
    sha512->digest[7] = W64LIT(0x0eb72ddc81c52ca2);
1040
1041
0
    sha512->buffLen = 0;
1042
0
    XMEMSET(sha512->buffer, 0, sizeof(sha512->buffer));
1043
0
    sha512->loLen   = 0;
1044
0
    sha512->hiLen   = 0;
1045
1046
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1047
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
1048
    defined(WOLFSSL_ARMASM)
1049
    Sha512_SetTransform();
1050
#endif
1051
1052
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1053
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1054
    /* HW needs to be carefully initialized, taking into account soft copy.
1055
    ** If already in use; copy may revert to SW as needed.
1056
    **
1057
    ** Note for original ESP32, there's no HW for SHA512/2256.
1058
    */
1059
    esp_sha_init(&(sha512->ctx), WC_HASH_TYPE_SHA512_256);
1060
#endif
1061
1062
#ifdef WOLFSSL_HASH_FLAGS
1063
    sha512->flags = 0;
1064
#endif
1065
#if defined(WOLFSSL_SHA512_HASHTYPE)
1066
    sha512->hashType = WC_HASH_TYPE_SHA512_256;
1067
#endif /* WOLFSSL_SHA512_HASHTYPE */
1068
0
    return 0;
1069
0
}
1070
#endif /* !WOLFSSL_NOSHA512_256 && !FIPS... */
1071
1072
#endif /* WOLFSSL_SHA512 */
1073
1074
/* Hardware Acceleration */
1075
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
1076
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
1077
1078
    /*****
1079
    Intel AVX1/AVX2 Macro Control Structure
1080
1081
    #if defined(HAVE_INTEL_SPEEDUP)
1082
        #define HAVE_INTEL_AVX1
1083
        #define HAVE_INTEL_AVX2
1084
    #endif
1085
1086
    int InitSha512(wc_Sha512* sha512) {
1087
         Save/Recover XMM, YMM
1088
         ...
1089
1090
         Check Intel AVX cpuid flags
1091
    }
1092
1093
    #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
1094
      Transform_Sha512_AVX1(); # Function prototype
1095
      Transform_Sha512_AVX2(); #
1096
    #endif
1097
1098
      _Transform_Sha512() {     # Native Transform Function body
1099
1100
      }
1101
1102
      int Sha512Update() {
1103
         Save/Recover XMM, YMM
1104
         ...
1105
      }
1106
1107
      int Sha512Final() {
1108
         Save/Recover XMM, YMM
1109
         ...
1110
      }
1111
1112
1113
    #if defined(HAVE_INTEL_AVX1)
1114
1115
       XMM Instructions/INLINE asm Definitions
1116
1117
    #endif
1118
1119
    #if defined(HAVE_INTEL_AVX2)
1120
1121
       YMM Instructions/INLINE asm Definitions
1122
1123
    #endif
1124
1125
    #if defined(HAVE_INTEL_AVX1)
1126
1127
      int Transform_Sha512_AVX1() {
1128
          Stitched Message Sched/Round
1129
      }
1130
1131
    #endif
1132
1133
    #if defined(HAVE_INTEL_AVX2)
1134
1135
      int Transform_Sha512_AVX2() {
1136
          Stitched Message Sched/Round
1137
      }
1138
    #endif
1139
1140
    */
1141
1142
1143
    /* Each platform needs to query info type 1 from cpuid to see if aesni is
1144
     * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
1145
     */
1146
1147
#ifdef __cplusplus
1148
    extern "C" {
1149
#endif
1150
1151
    #if defined(HAVE_INTEL_AVX1)
1152
        extern int Transform_Sha512_AVX1(wc_Sha512 *sha512);
1153
        extern int Transform_Sha512_AVX1_Len(wc_Sha512 *sha512, word32 len);
1154
    #endif
1155
    #if defined(HAVE_INTEL_AVX2)
1156
        extern int Transform_Sha512_AVX2(wc_Sha512 *sha512);
1157
        extern int Transform_Sha512_AVX2_Len(wc_Sha512 *sha512, word32 len);
1158
        #if defined(HAVE_INTEL_RORX)
1159
            extern int Transform_Sha512_AVX1_RORX(wc_Sha512 *sha512);
1160
            extern int Transform_Sha512_AVX1_RORX_Len(wc_Sha512 *sha512,
1161
                                                      word32 len);
1162
            extern int Transform_Sha512_AVX2_RORX(wc_Sha512 *sha512);
1163
            extern int Transform_Sha512_AVX2_RORX_Len(wc_Sha512 *sha512,
1164
                                                      word32 len);
1165
        #endif
1166
    #endif
1167
1168
#ifdef __cplusplus
1169
    }  /* extern "C" */
1170
#endif
1171
1172
    static cpuid_flags_atomic_t intel_flags = WC_CPUID_ATOMIC_INITIALIZER;
1173
1174
#if defined(WC_C_DYNAMIC_FALLBACK) && !defined(WC_NO_INTERNAL_FUNCTION_POINTERS)
1175
    #define WC_NO_INTERNAL_FUNCTION_POINTERS
1176
#endif
1177
1178
    static int _Transform_Sha512(wc_Sha512 *sha512);
1179
1180
#ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
1181
1182
    enum sha_methods { SHA512_UNSET = 0, SHA512_AVX1, SHA512_AVX2,
1183
                       SHA512_AVX1_RORX, SHA512_AVX2_RORX, SHA512_C };
1184
1185
    /* note that all write access to this static variable must be idempotent,
1186
     * as arranged by Sha512_SetTransform(), else it will be susceptible to
1187
     * data races.
1188
     */
1189
    static enum sha_methods sha_method = SHA512_UNSET;
1190
1191
    #ifdef WC_C_DYNAMIC_FALLBACK
1192
        /* With the AVX backend, wc_Sha512.buffer is in big endian even though
1193
         * the host is little endian.  For WC_C_DYNAMIC_FALLBACK, which requires
1194
         * alternating between AVX and C, we activate WC_SHA512_RAW_BE_BUFFER,
1195
         * which brings in the below shims for just-in-time byte swapping on
1196
         * each call to the C back end.  This keeps the buffers big endian at
1197
         * all times.
1198
         *
1199
         * Callers test WC_SHA512_RAW_BE_BUFFER rather than
1200
         * WC_C_DYNAMIC_FALLBACK directly: the latter is a global setting whose
1201
         * only prerequisite is WC_HAVE_VECTOR_SPEEDUPS, so it can be set in
1202
         * configurations that never compile these adapters (WOLFSSL_SP_ASM
1203
         * only, 32-bit x86 --enable-intelasm, ...), and suppressing the
1204
         * caller-side byte-reversal there would leave nothing to compensate.
1205
         */
1206
        #define WC_SHA512_RAW_BE_BUFFER
1207
    #endif
1208
1209
    #ifdef WC_SHA512_RAW_BE_BUFFER
1210
1211
    static WC_INLINE int Transform_Sha512_C_from_raw(wc_Sha512 *sha512)
1212
    {
1213
    #ifdef LITTLE_ENDIAN_ORDER
1214
        ByteReverseWords64(sha512->buffer, sha512->buffer,
1215
                           WC_SHA512_BLOCK_SIZE);
1216
    #endif
1217
        return _Transform_Sha512(sha512);
1218
    }
1219
1220
    static WC_INLINE int Transform_Sha512_Len_C_from_raw(wc_Sha512 *sha512,
1221
                                                         word32 len)
1222
    {
1223
        const byte* data = sha512->data;
1224
        int ret = 0;
1225
1226
        while (len >= WC_SHA512_BLOCK_SIZE) {
1227
            XMEMCPY(sha512->buffer, data, WC_SHA512_BLOCK_SIZE);
1228
            ret = Transform_Sha512_C_from_raw(sha512);
1229
            if (ret != 0)
1230
                break;
1231
            data += WC_SHA512_BLOCK_SIZE;
1232
            len  -= WC_SHA512_BLOCK_SIZE;
1233
        }
1234
1235
        return ret;
1236
    }
1237
    #endif /* WC_SHA512_RAW_BE_BUFFER */
1238
1239
    static void Sha512_SetTransform(void)
1240
    {
1241
        if (sha_method != SHA512_UNSET)
1242
            return;
1243
1244
        /* Note that, with WC_C_DYNAMIC_FALLBACK, sha_method records CPU
1245
         * capability only.  Whether vector registers are actually usable is
1246
         * determined independently at each transform via
1247
         * SAVE_VECTOR_REGISTERS2(), allowing a context to move freely between
1248
         * vectorized and C transforms call by call.
1249
         */
1250
1251
        cpuid_get_flags_atomic(&intel_flags);
1252
1253
    #if defined(HAVE_INTEL_AVX2)
1254
        if (IS_INTEL_AVX2(intel_flags)) {
1255
        #ifdef HAVE_INTEL_RORX
1256
            if (IS_INTEL_BMI2(intel_flags)) {
1257
                sha_method = SHA512_AVX2_RORX;
1258
            }
1259
            else
1260
        #endif
1261
            {
1262
                sha_method = SHA512_AVX2;
1263
            }
1264
        }
1265
        else
1266
    #endif
1267
    #if defined(HAVE_INTEL_AVX1)
1268
        if (IS_INTEL_AVX1(intel_flags)) {
1269
        #ifdef HAVE_INTEL_RORX
1270
            if (IS_INTEL_BMI2(intel_flags)) {
1271
                sha_method = SHA512_AVX1_RORX;
1272
            }
1273
            else
1274
        #endif
1275
            {
1276
                sha_method = SHA512_AVX1;
1277
            }
1278
        }
1279
        else
1280
    #endif
1281
        {
1282
            sha_method = SHA512_C;
1283
        }
1284
    }
1285
1286
    static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512) {
1287
        int ret;
1288
    #ifdef WC_C_DYNAMIC_FALLBACK
1289
        if ((sha_method == SHA512_C) ||
1290
            (SAVE_VECTOR_REGISTERS2() != 0))
1291
        {
1292
            return Transform_Sha512_C_from_raw(sha512);
1293
        }
1294
    #else
1295
        if (sha_method == SHA512_C) {
1296
            #ifdef WC_SHA512_RAW_BE_BUFFER
1297
            /* not currently reachable */
1298
            return Transform_Sha512_C_from_raw(sha512);
1299
            #else
1300
            return _Transform_Sha512(sha512);
1301
            #endif
1302
        }
1303
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
1304
    #endif
1305
        switch (sha_method) {
1306
        case SHA512_AVX2:
1307
            ret = Transform_Sha512_AVX2(sha512);
1308
            break;
1309
        case SHA512_AVX2_RORX:
1310
            ret = Transform_Sha512_AVX2_RORX(sha512);
1311
            break;
1312
        case SHA512_AVX1:
1313
            ret = Transform_Sha512_AVX1(sha512);
1314
            break;
1315
        case SHA512_AVX1_RORX:
1316
            ret = Transform_Sha512_AVX1_RORX(sha512);
1317
            break;
1318
        case SHA512_C:
1319
        case SHA512_UNSET:
1320
        default:
1321
            #ifdef WC_SHA512_RAW_BE_BUFFER
1322
            /* not reachable -- the C path exits above, before vector register
1323
             * save -- but must stay layout-correct. */
1324
            ret = Transform_Sha512_C_from_raw(sha512);
1325
            #else
1326
            ret = _Transform_Sha512(sha512);
1327
            #endif
1328
            break;
1329
        }
1330
        RESTORE_VECTOR_REGISTERS();
1331
        return ret;
1332
    }
1333
1334
    static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, word32 len) {
1335
        int ret;
1336
    #ifdef WC_C_DYNAMIC_FALLBACK
1337
        if ((sha_method == SHA512_C) ||
1338
            (SAVE_VECTOR_REGISTERS2() != 0))
1339
        {
1340
            return Transform_Sha512_Len_C_from_raw(sha512, len);
1341
        }
1342
    #else
1343
        SAVE_VECTOR_REGISTERS(return _svr_ret;);
1344
    #endif
1345
        switch (sha_method) {
1346
        case SHA512_AVX2:
1347
            ret = Transform_Sha512_AVX2_Len(sha512, len);
1348
            break;
1349
        case SHA512_AVX2_RORX:
1350
            ret = Transform_Sha512_AVX2_RORX_Len(sha512, len);
1351
            break;
1352
        case SHA512_AVX1:
1353
            ret = Transform_Sha512_AVX1_Len(sha512, len);
1354
            break;
1355
        case SHA512_AVX1_RORX:
1356
            ret = Transform_Sha512_AVX1_RORX_Len(sha512, len);
1357
            break;
1358
        case SHA512_C:
1359
        case SHA512_UNSET:
1360
        default:
1361
            #ifdef WC_SHA512_RAW_BE_BUFFER
1362
            /* not reachable -- the C path exits above, before vector register
1363
             * save -- but must stay correct. */
1364
            ret = Transform_Sha512_Len_C_from_raw(sha512, len);
1365
            #else
1366
            ret = 0;
1367
            #endif
1368
            break;
1369
        }
1370
        RESTORE_VECTOR_REGISTERS();
1371
        return ret;
1372
    }
1373
1374
#else /* !WC_NO_INTERNAL_FUNCTION_POINTERS */
1375
1376
    static int (*Transform_Sha512_p)(wc_Sha512* sha512) = _Transform_Sha512;
1377
    static int (*Transform_Sha512_Len_p)(wc_Sha512* sha512, word32 len) = NULL;
1378
    static int transform_check = 0;
1379
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1380
    static int Transform_Sha512_is_vectorized = 0;
1381
    #endif
1382
1383
    static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512) {
1384
        int ret;
1385
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1386
        if (Transform_Sha512_is_vectorized)
1387
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
1388
    #endif
1389
        ret = (*Transform_Sha512_p)(sha512);
1390
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1391
        if (Transform_Sha512_is_vectorized)
1392
            RESTORE_VECTOR_REGISTERS();
1393
    #endif
1394
        return ret;
1395
    }
1396
    static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, word32 len) {
1397
        int ret;
1398
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1399
        if (Transform_Sha512_is_vectorized)
1400
            SAVE_VECTOR_REGISTERS(return _svr_ret;);
1401
    #endif
1402
        ret = (*Transform_Sha512_Len_p)(sha512, len);
1403
    #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1404
        if (Transform_Sha512_is_vectorized)
1405
            RESTORE_VECTOR_REGISTERS();
1406
    #endif
1407
        return ret;
1408
    }
1409
1410
    static void Sha512_SetTransform(void)
1411
    {
1412
        if (transform_check)
1413
            return;
1414
1415
        cpuid_get_flags_atomic(&intel_flags);
1416
1417
    #if defined(HAVE_INTEL_AVX2)
1418
        if (IS_INTEL_AVX2(intel_flags)) {
1419
        #ifdef HAVE_INTEL_RORX
1420
            if (IS_INTEL_BMI2(intel_flags)) {
1421
                Transform_Sha512_p = Transform_Sha512_AVX2_RORX;
1422
                Transform_Sha512_Len_p = Transform_Sha512_AVX2_RORX_Len;
1423
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1424
                Transform_Sha512_is_vectorized = 1;
1425
            #endif
1426
            }
1427
            else
1428
        #endif
1429
            {
1430
                Transform_Sha512_p = Transform_Sha512_AVX2;
1431
                Transform_Sha512_Len_p = Transform_Sha512_AVX2_Len;
1432
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1433
                Transform_Sha512_is_vectorized = 1;
1434
            #endif
1435
            }
1436
        }
1437
        else
1438
    #endif
1439
    #if defined(HAVE_INTEL_AVX1)
1440
        if (IS_INTEL_AVX1(intel_flags)) {
1441
        #ifdef HAVE_INTEL_RORX
1442
            if (IS_INTEL_BMI2(intel_flags)) {
1443
                Transform_Sha512_p = Transform_Sha512_AVX1_RORX;
1444
                Transform_Sha512_Len_p = Transform_Sha512_AVX1_RORX_Len;
1445
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1446
                Transform_Sha512_is_vectorized = 1;
1447
            #endif
1448
            }
1449
            else
1450
        #endif
1451
            {
1452
                Transform_Sha512_p = Transform_Sha512_AVX1;
1453
                Transform_Sha512_Len_p = Transform_Sha512_AVX1_Len;
1454
            #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1455
                Transform_Sha512_is_vectorized = 1;
1456
            #endif
1457
            }
1458
        }
1459
        else
1460
    #endif
1461
        {
1462
            Transform_Sha512_p = _Transform_Sha512;
1463
            Transform_Sha512_Len_p = NULL;
1464
        #ifdef WOLFSSL_USE_SAVE_VECTOR_REGISTERS
1465
            Transform_Sha512_is_vectorized = 0;
1466
        #endif
1467
        }
1468
1469
        transform_check = 1;
1470
    }
1471
1472
#endif /* !WC_NO_INTERNAL_FUNCTION_POINTERS */
1473
1474
#elif defined(WOLFSSL_ARMASM)
1475
1476
#ifdef __aarch64__
1477
1478
/* AArch64: choose the SHA-512 crypto extension, NEON or the software
1479
 * implementation at runtime based on CPU features, so a core that lacks the
1480
 * crypto extension and/or NEON still has a working SHA-512. */
1481
#define NEED_SOFT_SHA512
1482
1483
static int transform_check = 0;
1484
static cpuid_flags_atomic_t cpuid_flags = WC_CPUID_ATOMIC_INITIALIZER;
1485
1486
static int _Transform_Sha512(wc_Sha512* sha512);
1487
static int Transform_Sha512_C(wc_Sha512* sha512, const byte* data);
1488
static int Transform_Sha512_Len_C(wc_Sha512* sha512, const byte* data,
1489
    word32 len);
1490
1491
/* Initialize to the software fallback so the pointers are never NULL if they
1492
 * are read before Sha512_SetTransform() has published the selected variant. */
1493
static int (*Transform_Sha512_p)(wc_Sha512* sha512, const byte* data)
1494
    = Transform_Sha512_C;
1495
static int (*Transform_Sha512_Len_p)(wc_Sha512* sha512, const byte* data,
1496
    word32 len) = Transform_Sha512_Len_C;
1497
1498
/* Software fallback adapters in the asm (sha512, data[, len]) form. The asm
1499
 * transforms consume raw big-endian input and byte-reverse internally, so the
1500
 * software path mirrors that by reversing the block before _Transform_Sha512()
1501
 * (which reads host-endian words from sha512->buffer). */
1502
static int Transform_Sha512_C(wc_Sha512* sha512, const byte* data)
1503
{
1504
    if (data != (const byte*)sha512->buffer)
1505
        XMEMCPY(sha512->buffer, data, WC_SHA512_BLOCK_SIZE);
1506
#ifdef LITTLE_ENDIAN_ORDER
1507
    ByteReverseWords64(sha512->buffer, sha512->buffer, WC_SHA512_BLOCK_SIZE);
1508
#endif
1509
    return _Transform_Sha512(sha512);
1510
}
1511
static int Transform_Sha512_Len_C(wc_Sha512* sha512, const byte* data,
1512
    word32 len)
1513
{
1514
    int ret = 0;
1515
1516
    while (len >= WC_SHA512_BLOCK_SIZE) {
1517
        ret = Transform_Sha512_C(sha512, data);
1518
        if (ret != 0)
1519
            break;
1520
        data += WC_SHA512_BLOCK_SIZE;
1521
        len  -= WC_SHA512_BLOCK_SIZE;
1522
    }
1523
1524
    return ret;
1525
}
1526
1527
/* The SHA-512 crypto instructions operate on SIMD registers, so the assembly
1528
 * only defines these when NEON is available - see armv8-sha512-asm.S and the
1529
 * prototype guard in sha512.h. */
1530
#if defined(WOLFSSL_ARMASM_CRYPTO_SHA512) && !defined(WOLFSSL_ARMASM_NO_NEON)
1531
static int Transform_Sha512_crypto_aarch64(wc_Sha512* sha512, const byte* data)
1532
{
1533
    Transform_Sha512_Len_crypto(sha512, data, WC_SHA512_BLOCK_SIZE);
1534
    return 0;
1535
}
1536
static int Transform_Sha512_Len_crypto_aarch64(wc_Sha512* sha512,
1537
    const byte* data, word32 len)
1538
{
1539
    Transform_Sha512_Len_crypto(sha512, data, len);
1540
    return 0;
1541
}
1542
#endif
1543
#ifndef WOLFSSL_ARMASM_NO_NEON
1544
static int Transform_Sha512_neon_aarch64(wc_Sha512* sha512, const byte* data)
1545
{
1546
    Transform_Sha512_Len_neon(sha512, data, WC_SHA512_BLOCK_SIZE);
1547
    return 0;
1548
}
1549
static int Transform_Sha512_Len_neon_aarch64(wc_Sha512* sha512,
1550
    const byte* data, word32 len)
1551
{
1552
    Transform_Sha512_Len_neon(sha512, data, len);
1553
    return 0;
1554
}
1555
#endif
1556
1557
static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512, const byte* data)
1558
{
1559
    return (*Transform_Sha512_p)(sha512, data);
1560
}
1561
static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, const byte* data,
1562
    word32 len)
1563
{
1564
    return (*Transform_Sha512_Len_p)(sha512, data, len);
1565
}
1566
1567
static void Sha512_SetTransform(void)
1568
{
1569
    if (transform_check)
1570
        return;
1571
1572
    cpuid_get_flags_atomic(&cpuid_flags);
1573
1574
#if defined(WOLFSSL_ARMASM_CRYPTO_SHA512) && !defined(WOLFSSL_ARMASM_NO_NEON)
1575
    if (IS_AARCH64_SHA512(cpuid_flags)) {
1576
        Transform_Sha512_p     = Transform_Sha512_crypto_aarch64;
1577
        Transform_Sha512_Len_p = Transform_Sha512_Len_crypto_aarch64;
1578
    }
1579
    else
1580
#endif
1581
#ifndef WOLFSSL_ARMASM_NO_NEON
1582
    if (IS_AARCH64_ASIMD(cpuid_flags)) {
1583
        Transform_Sha512_p     = Transform_Sha512_neon_aarch64;
1584
        Transform_Sha512_Len_p = Transform_Sha512_Len_neon_aarch64;
1585
    }
1586
    else
1587
#endif
1588
    {
1589
        Transform_Sha512_p     = Transform_Sha512_C;
1590
        Transform_Sha512_Len_p = Transform_Sha512_Len_C;
1591
    }
1592
1593
    transform_check = 1;
1594
}
1595
1596
#else /* !__aarch64__ : 32-bit Arm (Thumb2 / ARMv7) */
1597
1598
static int transform_check = 0;
1599
1600
#if !defined(WOLFSSL_ARMASM_THUMB2) && !defined(WOLFSSL_ARMASM_NO_NEON)
1601
static void Transform_Sha512_neon(wc_Sha512* sha512, const byte* data)
1602
{
1603
    Transform_Sha512_Len_neon(sha512, data, WC_SHA512_BLOCK_SIZE);
1604
}
1605
#endif
1606
#if defined(WOLFSSL_ARMASM_THUMB2) || defined(WOLFSSL_ARMASM_NO_NEON)
1607
static void Transform_Sha512_base(wc_Sha512* sha512, const byte* data)
1608
{
1609
    Transform_Sha512_Len_base(sha512, data, WC_SHA512_BLOCK_SIZE);
1610
}
1611
#endif
1612
1613
static void (*Transform_Sha512_p)(wc_Sha512* sha512, const byte* data) = NULL;
1614
static void (*Transform_Sha512_Len_p)(wc_Sha512* sha512, const byte* data,
1615
    word32 len) = NULL;
1616
1617
static WC_INLINE int Transform_Sha512(wc_Sha512 *sha512, const byte* data)
1618
{
1619
    (*Transform_Sha512_p)(sha512, data);
1620
    return 0;
1621
}
1622
static WC_INLINE int Transform_Sha512_Len(wc_Sha512 *sha512, const byte* data,
1623
    word32 len)
1624
{
1625
    (*Transform_Sha512_Len_p)(sha512, data, len);
1626
    return 0;
1627
}
1628
1629
static void Sha512_SetTransform(void)
1630
{
1631
    if (transform_check)
1632
        return;
1633
1634
#if !defined(WOLFSSL_ARMASM_THUMB2) && !defined(WOLFSSL_ARMASM_NO_NEON)
1635
    {
1636
        Transform_Sha512_p = Transform_Sha512_neon;
1637
        Transform_Sha512_Len_p = Transform_Sha512_Len_neon;
1638
    }
1639
#else
1640
    {
1641
        Transform_Sha512_p = Transform_Sha512_base;
1642
        Transform_Sha512_Len_p = Transform_Sha512_Len_base;
1643
    }
1644
#endif
1645
1646
    transform_check = 1;
1647
}
1648
1649
#endif /* __aarch64__ */
1650
1651
#elif defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
1652
1653
/* Scalar (base instruction) SHA-512 transform for big-endian PowerPC (32- and
1654
 * 64-bit).  The asm loads the message words directly, so no byte reversal is
1655
 * needed and the (sha512, data, len) form is used just like the ARM assembly. */
1656
extern void Transform_Sha512_Len(wc_Sha512* sha512, const byte* data,
1657
    word32 len);
1658
1659
#if defined(WOLFSSL_PPC64_ASM) && defined(WOLFSSL_PPC64_ASM_CRYPTO)
1660
/* POWER8+ has a vector SHA-512 sigma instruction (vshasigmad).  When built
1661
 * in, select that implementation at run time if the CPU supports it.
1662
 *
1663
 * A run-time flag with direct calls is used rather than a function pointer:
1664
 * an indirect call would require an ELFv1 function descriptor, whereas direct
1665
 * calls work under both the ELFv1 and ELFv2 ABIs. */
1666
extern void Transform_Sha512_Len_crypto(wc_Sha512* sha512, const byte* data,
1667
    word32 len);
1668
1669
/* Resolved dispatch decision, accessed with the wolfSSL atomic APIs so the
1670
 * lazy one-time detection is free of data races.  WC_CPUID_INITIALIZER means
1671
 * "not yet determined"; the write is idempotent (all callers compute the same
1672
 * value from the atomic master flags), so a benign concurrent double-write is
1673
 * harmless. */
1674
static wolfSSL_Atomic_Uint sha512_use_crypto =
1675
    WOLFSSL_ATOMIC_INITIALIZER(WC_CPUID_INITIALIZER);
1676
1677
/* Detect CPU support via the central cpuid module on first use. */
1678
static WC_INLINE void SHA512_TRANSFORM_LEN(wc_Sha512* sha512, const byte* data,
1679
    word32 len)
1680
{
1681
    unsigned int use_crypto = WOLFSSL_ATOMIC_LOAD(sha512_use_crypto);
1682
1683
    if (use_crypto == WC_CPUID_INITIALIZER) {
1684
        use_crypto = (unsigned int)(IS_PPC64_VEC_CRYPTO(cpuid_get_flags()) != 0);
1685
        WOLFSSL_ATOMIC_STORE(sha512_use_crypto, use_crypto);
1686
    }
1687
1688
    if (use_crypto)
1689
        Transform_Sha512_Len_crypto(sha512, data, len);
1690
    else
1691
        Transform_Sha512_Len(sha512, data, len);
1692
}
1693
/* SHA512_TRANSFORM_LEN is a function here, not a macro, so signal that a
1694
 * dispatcher is provided - otherwise the generic fallback below sees
1695
 * !defined(SHA512_TRANSFORM_LEN) and shadows it with a base-only macro. */
1696
#define SHA512_HAVE_TRANSFORM_LEN
1697
#else
1698
#define SHA512_TRANSFORM_LEN(s, d, l)   Transform_Sha512_Len((s), (d), (l))
1699
#define SHA512_HAVE_TRANSFORM_LEN
1700
#endif
1701
1702
static WC_INLINE int Transform_Sha512(wc_Sha512* sha512, const byte* data)
1703
{
1704
    SHA512_TRANSFORM_LEN(sha512, data, WC_SHA512_BLOCK_SIZE);
1705
    return 0;
1706
}
1707
1708
#define Sha512_SetTransform()   WC_DO_NOTHING
1709
1710
#elif defined(WOLFSSL_RISCV_ASM)
1711
1712
static WC_INLINE int Transform_Sha512(wc_Sha512* sha512, const byte* data)
1713
{
1714
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
1715
    Transform_Sha512_Len_riscv_vector(sha512, data, WC_SHA512_BLOCK_SIZE);
1716
#elif defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
1717
    Transform_Sha512_Len_riscv_crypto(sha512, data, WC_SHA512_BLOCK_SIZE);
1718
#else
1719
    Transform_Sha512_Len_riscv(sha512, data, WC_SHA512_BLOCK_SIZE);
1720
#endif
1721
    return 0;
1722
}
1723
static WC_INLINE int Transform_Sha512_Len(wc_Sha512* sha512, const byte* data,
1724
    word32 len)
1725
{
1726
#if defined(WOLFSSL_RISCV_VECTOR_CRYPTO_ASM)
1727
    Transform_Sha512_Len_riscv_vector(sha512, data, len);
1728
#elif defined(WOLFSSL_RISCV_SCALAR_CRYPTO_ASM)
1729
    Transform_Sha512_Len_riscv_crypto(sha512, data, len);
1730
#else
1731
    Transform_Sha512_Len_riscv(sha512, data, len);
1732
#endif
1733
    return 0;
1734
}
1735
1736
#else
1737
0
    #define Transform_Sha512(sha512) _Transform_Sha512(sha512)
1738
1739
#endif
1740
1741
/* For platforms that share the (sha512, data, len) block-loop call below but
1742
 * don't provide their own dispatcher (e.g. ARM), call the length transform
1743
 * directly. */
1744
#if (defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
1745
     defined(WOLFSSL_PPC32_ASM)) && \
1746
    !defined(SHA512_TRANSFORM_LEN) && !defined(SHA512_HAVE_TRANSFORM_LEN)
1747
#define SHA512_TRANSFORM_LEN(s, d, l)   Transform_Sha512_Len((s), (d), (l))
1748
#endif
1749
1750
#ifdef WOLFSSL_SHA512
1751
1752
static int InitSha512_Family(wc_Sha512* sha512, void* heap, int devId,
1753
                             int (*initfp)(wc_Sha512*))
1754
0
{
1755
0
    int ret = 0;
1756
1757
0
    if (sha512 == NULL) {
1758
0
        return BAD_FUNC_ARG;
1759
0
    }
1760
1761
0
    XMEMSET(sha512, 0, sizeof(*sha512));
1762
1763
0
    sha512->heap = heap;
1764
#ifdef WOLFSSL_SMALL_STACK_CACHE
1765
    /* This allocation combines the customary W buffer used by
1766
     * _Transform_Sha512() with additional buffer space used by
1767
     * wc_Sha512Transform().
1768
     */
1769
    sha512->W = (word64 *)XMALLOC((sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE,
1770
                                  sha512->heap, DYNAMIC_TYPE_DIGEST);
1771
    if (sha512->W == NULL)
1772
        return MEMORY_E;
1773
#endif
1774
#ifdef WOLF_CRYPTO_CB
1775
    sha512->devId = devId;
1776
    sha512->devCtx = NULL;
1777
#endif
1778
1779
#ifdef WOLFSSL_HASH_KEEP
1780
    sha512->msg  = NULL;
1781
    sha512->len  = 0;
1782
    sha512->used = 0;
1783
#endif
1784
1785
    /* call the initialization function pointed to by initfp */
1786
0
    ret = initfp(sha512);
1787
1788
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
1789
    if (ret == 0) {
1790
        ret = wolfAsync_DevCtxInit(&sha512->asyncDev,
1791
                        WOLFSSL_ASYNC_MARKER_SHA512, sha512->heap, devId);
1792
    }
1793
#else
1794
0
    (void)devId;
1795
0
#endif /* WOLFSSL_ASYNC_CRYPT */
1796
#ifdef WOLFSSL_IMXRT1170_CAAM
1797
    if (ret == 0)
1798
        ret = wc_CAAM_HashInit(&sha512->hndl, &sha512->ctx, WC_HASH_TYPE_SHA512);
1799
#endif
1800
1801
#ifdef WOLFSSL_SMALL_STACK_CACHE
1802
    if (ret != 0) {
1803
        XFREE(sha512->W, sha512->heap, DYNAMIC_TYPE_DIGEST);
1804
        sha512->W = NULL;
1805
    }
1806
#endif
1807
1808
0
    return ret;
1809
0
} /* InitSha512_Family */
1810
1811
int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
1812
0
{
1813
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1814
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1815
    if (sha512->ctx.mode != ESP32_SHA_INIT) {
1816
        ESP_LOGV(TAG, "Set ctx mode from prior value: "
1817
                      "%d", sha512->ctx.mode);
1818
    }
1819
    /* We know this is a fresh, uninitialized item, so set to INIT */
1820
    sha512->ctx.mode = ESP32_SHA_INIT;
1821
#endif
1822
1823
1824
0
    return InitSha512_Family(sha512, heap, devId, InitSha512);
1825
0
}
1826
1827
#if !defined(WOLFSSL_NOSHA512_224) && \
1828
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
1829
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
1830
0
{
1831
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1832
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1833
    /* No SHA512/224 HW support is available, set to SW. */
1834
    sha512->ctx.mode = ESP32_SHA_SW; /* no SHA224 HW, so always SW */
1835
#endif
1836
0
    return InitSha512_Family(sha512, heap, devId, InitSha512_224);
1837
0
}
1838
#endif /* !WOLFSSL_NOSHA512_224 ... */
1839
1840
#if !defined(WOLFSSL_NOSHA512_256) && \
1841
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
1842
int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
1843
0
{
1844
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
1845
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
1846
    /* No SHA512/256 HW support is available on ESP32, set to SW. */
1847
    sha512->ctx.mode = ESP32_SHA_SW;
1848
#endif
1849
0
    return InitSha512_Family(sha512, heap, devId, InitSha512_256);
1850
0
}
1851
#endif /* !WOLFSSL_NOSHA512_256 ... */
1852
1853
#endif /* WOLFSSL_SHA512 */
1854
1855
#if (!defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PPC64_ASM) && \
1856
     !defined(WOLFSSL_PPC32_ASM) && !defined(WOLFSSL_RISCV_ASM)) || \
1857
    defined(NEED_SOFT_SHA512)
1858
1859
static const word64 K512[80] = {
1860
    W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
1861
    W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
1862
    W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
1863
    W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
1864
    W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
1865
    W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
1866
    W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
1867
    W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
1868
    W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
1869
    W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
1870
    W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
1871
    W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
1872
    W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
1873
    W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
1874
    W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
1875
    W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
1876
    W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
1877
    W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
1878
    W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
1879
    W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
1880
    W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
1881
    W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
1882
    W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
1883
    W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
1884
    W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
1885
    W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
1886
    W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
1887
    W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
1888
    W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
1889
    W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
1890
    W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
1891
    W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
1892
    W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
1893
    W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
1894
    W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
1895
    W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
1896
    W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
1897
    W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
1898
    W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
1899
    W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
1900
};
1901
1902
0
#define blk0(i) (W[i] = sha512->buffer[i])
1903
1904
0
#define blk2(i) (\
1905
0
               W[ (i)     & 15] += \
1906
0
            s1(W[((i)-2)  & 15])+ \
1907
0
               W[((i)-7)  & 15] + \
1908
0
            s0(W[((i)-15) & 15])  \
1909
0
        )
1910
1911
0
#define Ch(x,y,z)  ((z) ^ ((x) & ((y) ^ (z))))
1912
0
#define Maj(x,y,z) (((x) & (y)) | ((z) & ((x) | (y))))
1913
1914
0
#define a(i) T[(0-(i)) & 7]
1915
0
#define b(i) T[(1-(i)) & 7]
1916
0
#define c(i) T[(2-(i)) & 7]
1917
0
#define d(i) T[(3-(i)) & 7]
1918
0
#define e(i) T[(4-(i)) & 7]
1919
0
#define f(i) T[(5-(i)) & 7]
1920
0
#define g(i) T[(6-(i)) & 7]
1921
0
#define h(i) T[(7-(i)) & 7]
1922
1923
0
#define S0(x) (rotrFixed64(x,28) ^ rotrFixed64(x,34) ^ rotrFixed64(x,39))
1924
0
#define S1(x) (rotrFixed64(x,14) ^ rotrFixed64(x,18) ^ rotrFixed64(x,41))
1925
0
#define s0(x) (rotrFixed64(x,1)  ^ rotrFixed64(x,8)  ^ ((x)>>7))
1926
0
#define s1(x) (rotrFixed64(x,19) ^ rotrFixed64(x,61) ^ ((x)>>6))
1927
1928
#define R(i) \
1929
0
    h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[(i)+j] + (j ? blk2(i) : blk0(i)); \
1930
0
    d(i) += h(i); \
1931
0
    h(i) += S0(a(i)) + Maj(a(i),b(i),c(i))
1932
1933
static int _Transform_Sha512(wc_Sha512* sha512)
1934
0
{
1935
0
    const word64* K = K512;
1936
0
    word32 j;
1937
0
    word64 T[8];
1938
1939
#if defined(WOLFSSL_SMALL_STACK_CACHE)
1940
    word64* W = sha512->W;
1941
    if (W == NULL)
1942
        return BAD_FUNC_ARG;
1943
#elif defined(WOLFSSL_SMALL_STACK)
1944
    word64* W;
1945
    W = (word64*) XMALLOC(sizeof(word64) * 16, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
1946
    if (W == NULL)
1947
        return MEMORY_E;
1948
#else
1949
0
    word64 W[16];
1950
0
#endif
1951
1952
    /* Copy digest to working vars */
1953
0
    XMEMCPY(T, sha512->digest, sizeof(T));
1954
1955
#ifdef USE_SLOW_SHA512
1956
    /* over twice as small, but 50% slower */
1957
    /* 80 operations, not unrolled */
1958
    for (j = 0; j < 80; j += 16) {
1959
        int m;
1960
        for (m = 0; m < 16; m++) { /* braces needed here for macros {} */
1961
            R(m);
1962
        }
1963
    }
1964
#else
1965
    /* 80 operations, partially loop unrolled */
1966
0
    for (j = 0; j < 80; j += 16) {
1967
0
        R( 0); R( 1); R( 2); R( 3);
1968
0
        R( 4); R( 5); R( 6); R( 7);
1969
0
        R( 8); R( 9); R(10); R(11);
1970
0
        R(12); R(13); R(14); R(15);
1971
0
    }
1972
0
#endif /* USE_SLOW_SHA512 */
1973
1974
    /* Add the working vars back into digest */
1975
0
    sha512->digest[0] += a(0);
1976
0
    sha512->digest[1] += b(0);
1977
0
    sha512->digest[2] += c(0);
1978
0
    sha512->digest[3] += d(0);
1979
0
    sha512->digest[4] += e(0);
1980
0
    sha512->digest[5] += f(0);
1981
0
    sha512->digest[6] += g(0);
1982
0
    sha512->digest[7] += h(0);
1983
1984
    /* Wipe variables */
1985
0
    ForceZero(W, sizeof(word64) * 16);
1986
0
    ForceZero(T, sizeof(T));
1987
1988
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
1989
    XFREE(W, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
1990
#endif
1991
1992
0
    return 0;
1993
0
}
1994
#endif
1995
1996
1997
static WC_INLINE void AddLength(wc_Sha512* sha512, word32 len)
1998
0
{
1999
0
    word64 tmp = sha512->loLen;
2000
0
    if ( (sha512->loLen += len) < tmp)
2001
0
        sha512->hiLen++;                       /* carry low to high */
2002
0
}
2003
2004
static WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
2005
0
{
2006
0
    int ret = 0;
2007
    /* do block size increments */
2008
0
    byte* local = (byte*)sha512->buffer;
2009
2010
    /* check that internal buffLen is valid */
2011
0
    if (sha512->buffLen >= WC_SHA512_BLOCK_SIZE)
2012
0
        return BUFFER_E;
2013
2014
0
    if (len == 0)
2015
0
        return 0;
2016
2017
0
    AddLength(sha512, len);
2018
2019
0
    if (sha512->buffLen > 0) {
2020
0
        word32 add = min(len, WC_SHA512_BLOCK_SIZE - sha512->buffLen);
2021
0
        if (add > 0) {
2022
0
            XMEMCPY(&local[sha512->buffLen], data, add);
2023
2024
0
            sha512->buffLen += add;
2025
0
            data            += add;
2026
0
            len             -= add;
2027
0
        }
2028
2029
0
        if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) {
2030
0
    #if defined(LITTLE_ENDIAN_ORDER) && \
2031
0
            !defined(WC_SHA512_RAW_BE_BUFFER) && \
2032
0
            (!defined(WOLFSSL_ESP32_CRYPT) || \
2033
0
             defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2034
0
             defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)) && \
2035
0
            !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PPC64_ASM) && \
2036
0
            !defined(WOLFSSL_RISCV_ASM)
2037
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2038
                (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2039
            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2040
        #endif
2041
0
            {
2042
        #ifdef WOLFSSL_WIDE_BYTE
2043
                WordsFromBytesBE64(sha512->buffer,
2044
                    (const byte*)sha512->buffer, WC_SHA512_BLOCK_SIZE / 8);
2045
        #else
2046
0
                ByteReverseWords64(sha512->buffer, sha512->buffer,
2047
0
                                                         WC_SHA512_BLOCK_SIZE);
2048
0
        #endif
2049
0
            }
2050
0
    #endif
2051
    #if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
2052
        defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_RISCV_ASM)
2053
            ret = Transform_Sha512(sha512, (const byte*)sha512->buffer);
2054
    #elif !defined(WOLFSSL_ESP32_CRYPT) || \
2055
           defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2056
           defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2057
0
            ret = Transform_Sha512(sha512);
2058
    #else
2059
            if (sha512->ctx.mode == ESP32_SHA_INIT) {
2060
                esp_sha_try_hw_lock(&sha512->ctx);
2061
            }
2062
            if (sha512->ctx.mode == ESP32_SHA_SW) {
2063
                ByteReverseWords64(sha512->buffer, sha512->buffer,
2064
                                                         WC_SHA512_BLOCK_SIZE);
2065
                ret = Transform_Sha512(sha512);
2066
            }
2067
            else {
2068
                ret = esp_sha512_process(sha512);
2069
            }
2070
    #endif
2071
0
            if (ret == 0)
2072
0
                sha512->buffLen = 0;
2073
0
            else
2074
0
                len = 0;
2075
0
        }
2076
0
    }
2077
2078
#if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
2079
    defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_RISCV_ASM)
2080
    if (len >= WC_SHA512_BLOCK_SIZE) {
2081
        word32 blocksLen = len & ~((word32)WC_SHA512_BLOCK_SIZE-1);
2082
2083
#if defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
2084
        SHA512_TRANSFORM_LEN(sha512, data, blocksLen);
2085
#else
2086
        ret = Transform_Sha512_Len(sha512, data, blocksLen);
2087
        if (ret != 0)
2088
            return ret;
2089
#endif
2090
        data += blocksLen;
2091
        len  -= blocksLen;
2092
    }
2093
#else
2094
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2095
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)))
2096
2097
    #ifdef WC_NO_INTERNAL_FUNCTION_POINTERS
2098
    if (sha_method != SHA512_C)
2099
    #else
2100
    if (Transform_Sha512_Len_p != NULL)
2101
    #endif
2102
2103
    {
2104
        word32 blocksLen = len & ~((word32)WC_SHA512_BLOCK_SIZE-1);
2105
2106
        if (blocksLen > 0) {
2107
            sha512->data = data;
2108
            /* Byte reversal performed in function if required. */
2109
            ret = Transform_Sha512_Len(sha512, blocksLen);
2110
            if (ret == 0) {
2111
                data += blocksLen;
2112
                len  -= blocksLen;
2113
            }
2114
        }
2115
    }
2116
    else
2117
#endif
2118
#if !defined(LITTLE_ENDIAN_ORDER) || (defined(WOLFSSL_X86_64_BUILD) && \
2119
        defined(USE_INTEL_SPEEDUP) && (defined(HAVE_INTEL_AVX1) || \
2120
        defined(HAVE_INTEL_AVX2)))
2121
    {
2122
        while (len >= WC_SHA512_BLOCK_SIZE) {
2123
            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
2124
2125
            data += WC_SHA512_BLOCK_SIZE;
2126
            len  -= WC_SHA512_BLOCK_SIZE;
2127
2128
        #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2129
            (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)) && \
2130
            !defined(WC_SHA512_RAW_BE_BUFFER)
2131
            if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2132
            {
2133
                ByteReverseWords64(sha512->buffer, sha512->buffer,
2134
                                                          WC_SHA512_BLOCK_SIZE);
2135
            }
2136
        #endif
2137
            /* Byte reversal performed in function if required. */
2138
            ret = Transform_Sha512(sha512);
2139
            if (ret != 0)
2140
                break;
2141
        }
2142
    }
2143
#else
2144
0
    {
2145
0
        while (len >= WC_SHA512_BLOCK_SIZE) {
2146
0
            XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
2147
2148
0
            data += WC_SHA512_BLOCK_SIZE;
2149
0
            len  -= WC_SHA512_BLOCK_SIZE;
2150
0
    #if !defined(WOLFSSL_ESP32_CRYPT) || \
2151
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2152
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2153
        #ifdef WOLFSSL_WIDE_BYTE
2154
            WordsFromBytesBE64(sha512->buffer, (const byte*)sha512->buffer,
2155
                WC_SHA512_BLOCK_SIZE / 8);
2156
        #else
2157
0
            ByteReverseWords64(sha512->buffer, sha512->buffer,
2158
0
                                                       WC_SHA512_BLOCK_SIZE);
2159
0
        #endif
2160
0
    #endif
2161
0
    #if !defined(WOLFSSL_ESP32_CRYPT) || \
2162
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2163
0
         defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2164
0
            ret = Transform_Sha512(sha512);
2165
    #else
2166
            if(sha512->ctx.mode == ESP32_SHA_INIT) {
2167
                esp_sha_try_hw_lock(&sha512->ctx);
2168
            }
2169
            if (sha512->ctx.mode == ESP32_SHA_SW) {
2170
                ByteReverseWords64(sha512->buffer, sha512->buffer,
2171
                                                          WC_SHA512_BLOCK_SIZE);
2172
                ret = Transform_Sha512(sha512);
2173
            }
2174
            else {
2175
                ret = esp_sha512_process(sha512);
2176
            }
2177
    #endif
2178
0
            if (ret != 0)
2179
0
                break;
2180
0
        } /* while (len >= WC_SHA512_BLOCK_SIZE) */
2181
0
    }
2182
0
#endif
2183
0
#endif
2184
2185
0
    if (ret == 0 && len > 0) {
2186
0
        XMEMCPY(local, data, len);
2187
0
        sha512->buffLen = len;
2188
0
    }
2189
2190
0
    return ret;
2191
0
}
2192
2193
#ifdef WOLFSSL_SHA512
2194
2195
int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
2196
0
{
2197
0
    if (sha512 == NULL) {
2198
0
        return BAD_FUNC_ARG;
2199
0
    }
2200
0
    if (data == NULL && len == 0) {
2201
        /* valid, but do nothing */
2202
0
        return 0;
2203
0
    }
2204
0
    if (data == NULL) {
2205
0
        return BAD_FUNC_ARG;
2206
0
    }
2207
2208
#ifdef WOLF_CRYPTO_CB
2209
    #ifndef WOLF_CRYPTO_CB_FIND
2210
    if (sha512->devId != INVALID_DEVID)
2211
    #endif
2212
    {
2213
        int ret = wc_CryptoCb_Sha512Hash(sha512, data, len, NULL, 0);
2214
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2215
            return ret;
2216
        /* fall-through when unavailable */
2217
    }
2218
#endif
2219
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
2220
    if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {
2221
    #if defined(HAVE_INTEL_QA)
2222
        return IntelQaSymSha512(&sha512->asyncDev, NULL, data, len);
2223
    #endif
2224
    }
2225
#endif /* WOLFSSL_ASYNC_CRYPT */
2226
2227
0
    return Sha512Update(sha512, data, len);
2228
0
}
2229
2230
#endif /* WOLFSSL_SHA512 */
2231
2232
#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA512 */
2233
2234
#ifndef WOLF_CRYPTO_CB_ONLY_SHA512
2235
2236
#if defined(WOLFSSL_KCAPI_HASH)
2237
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2238
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2239
   !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2240
    /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */
2241
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2242
2243
#elif defined(MAX3266X_SHA)
2244
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2245
#elif defined(STM32_HASH_SHA512)
2246
#elif defined(PSOC6_HASH_SHA2)
2247
#else
2248
2249
static WC_INLINE int Sha512Final(wc_Sha512* sha512)
2250
0
{
2251
0
    int ret = 0;
2252
0
    byte* local;
2253
2254
0
    if (sha512 == NULL) {
2255
0
        return BAD_FUNC_ARG;
2256
0
    }
2257
2258
0
    local = (byte*)sha512->buffer;
2259
2260
    /* we'll add a 0x80 byte at the end,
2261
    ** so make sure we have appropriate buffer length. */
2262
0
    if (sha512->buffLen > WC_SHA512_BLOCK_SIZE - 1) {
2263
0
        return BAD_STATE_E;
2264
0
    } /* buffLen check */
2265
2266
0
    local[sha512->buffLen++] = 0x80;  /* add 1 */
2267
2268
    /* pad with zeros */
2269
0
    if (sha512->buffLen > WC_SHA512_PAD_SIZE) {
2270
0
        if (sha512->buffLen < WC_SHA512_BLOCK_SIZE ) {
2271
0
            XMEMSET(&local[sha512->buffLen], 0,
2272
0
                WC_SHA512_BLOCK_SIZE - sha512->buffLen);
2273
0
        }
2274
2275
0
        sha512->buffLen += WC_SHA512_BLOCK_SIZE - sha512->buffLen;
2276
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WC_SHA512_RAW_BE_BUFFER)
2277
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2278
        (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2279
        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2280
    #endif
2281
0
        {
2282
2283
0
        #if (!defined(WOLFSSL_ESP32_CRYPT) || \
2284
0
              defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2285
0
              defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)) && \
2286
0
             !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PPC64_ASM) && \
2287
0
             !defined(WOLFSSL_RISCV_ASM)
2288
            #ifdef WOLFSSL_WIDE_BYTE
2289
            WordsFromBytesBE64(sha512->buffer, (const byte*)sha512->buffer,
2290
                WC_SHA512_BLOCK_SIZE / 8);
2291
            #else
2292
0
            ByteReverseWords64(sha512->buffer,sha512->buffer,
2293
0
                                                         WC_SHA512_BLOCK_SIZE);
2294
0
            #endif
2295
0
        #endif
2296
0
        }
2297
2298
0
#endif /* LITTLE_ENDIAN_ORDER */
2299
#if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
2300
    defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_RISCV_ASM)
2301
        ret = Transform_Sha512(sha512, (const byte*)sha512->buffer);
2302
        if (ret != 0)
2303
            return ret;
2304
#else
2305
    #if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
2306
       !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2307
        if (sha512->ctx.mode == ESP32_SHA_INIT) {
2308
            esp_sha_try_hw_lock(&sha512->ctx);
2309
        }
2310
        if (sha512->ctx.mode == ESP32_SHA_SW) {
2311
            ByteReverseWords64(sha512->buffer,sha512->buffer,
2312
                                                         WC_SHA512_BLOCK_SIZE);
2313
            ret = Transform_Sha512(sha512);
2314
        }
2315
        else {
2316
            ret = esp_sha512_process(sha512);
2317
        }
2318
    #else
2319
0
        ret = Transform_Sha512(sha512);
2320
0
    #endif
2321
0
        if (ret != 0) {
2322
0
            return ret;
2323
0
        }
2324
0
#endif
2325
2326
0
        sha512->buffLen = 0;
2327
0
    } /* (sha512->buffLen > WC_SHA512_PAD_SIZE) pad with zeros */
2328
2329
0
    XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen);
2330
2331
    /* put lengths in bits */
2332
0
    sha512->hiLen = (sha512->loLen >>
2333
0
                        (CHAR_BIT * sizeof(sha512->loLen) - 3)) +
2334
0
                                                         (sha512->hiLen << 3);
2335
0
    sha512->loLen = sha512->loLen << 3;
2336
2337
    /* store lengths */
2338
#ifdef WOLFSSL_WIDE_BYTE
2339
    /* CHAR_BIT != 8: 'local' indexes octet cells, not the word64 layout (the
2340
     * buffer[BLOCK/sizeof(word64) - 2/-1] indices assume 16 words per block,
2341
     * which is wrong when sizeof(word64) != 8).  Place the 128-bit bit-length
2342
     * as 16 big-endian octets at the pad offset, then load all 16 big-endian
2343
     * schedule words octet-wise. */
2344
    local[WC_SHA512_PAD_SIZE +  0] = (byte)((sha512->hiLen >> 56) & 0xFF);
2345
    local[WC_SHA512_PAD_SIZE +  1] = (byte)((sha512->hiLen >> 48) & 0xFF);
2346
    local[WC_SHA512_PAD_SIZE +  2] = (byte)((sha512->hiLen >> 40) & 0xFF);
2347
    local[WC_SHA512_PAD_SIZE +  3] = (byte)((sha512->hiLen >> 32) & 0xFF);
2348
    local[WC_SHA512_PAD_SIZE +  4] = (byte)((sha512->hiLen >> 24) & 0xFF);
2349
    local[WC_SHA512_PAD_SIZE +  5] = (byte)((sha512->hiLen >> 16) & 0xFF);
2350
    local[WC_SHA512_PAD_SIZE +  6] = (byte)((sha512->hiLen >>  8) & 0xFF);
2351
    local[WC_SHA512_PAD_SIZE +  7] = (byte)((sha512->hiLen      ) & 0xFF);
2352
    local[WC_SHA512_PAD_SIZE +  8] = (byte)((sha512->loLen >> 56) & 0xFF);
2353
    local[WC_SHA512_PAD_SIZE +  9] = (byte)((sha512->loLen >> 48) & 0xFF);
2354
    local[WC_SHA512_PAD_SIZE + 10] = (byte)((sha512->loLen >> 40) & 0xFF);
2355
    local[WC_SHA512_PAD_SIZE + 11] = (byte)((sha512->loLen >> 32) & 0xFF);
2356
    local[WC_SHA512_PAD_SIZE + 12] = (byte)((sha512->loLen >> 24) & 0xFF);
2357
    local[WC_SHA512_PAD_SIZE + 13] = (byte)((sha512->loLen >> 16) & 0xFF);
2358
    local[WC_SHA512_PAD_SIZE + 14] = (byte)((sha512->loLen >>  8) & 0xFF);
2359
    local[WC_SHA512_PAD_SIZE + 15] = (byte)((sha512->loLen      ) & 0xFF);
2360
    WordsFromBytesBE64(sha512->buffer, (const byte*)sha512->buffer,
2361
        WC_SHA512_BLOCK_SIZE / 8);
2362
#else
2363
0
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WC_SHA512_RAW_BE_BUFFER)
2364
    #if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2365
        (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2366
        if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2367
    #endif
2368
0
    #if (!defined(WOLFSSL_ESP32_CRYPT) || \
2369
0
          defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2370
0
          defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)) && \
2371
0
         !defined(WOLFSSL_ARMASM) && !defined(WOLFSSL_PPC64_ASM) && \
2372
0
         !defined(WOLFSSL_RISCV_ASM)
2373
0
            ByteReverseWords64(sha512->buffer, sha512->buffer, WC_SHA512_PAD_SIZE);
2374
0
    #endif
2375
0
#endif
2376
    /* ! length ordering dependent on digest endian type ! */
2377
2378
0
#if !defined(WOLFSSL_ESP32_CRYPT) || \
2379
0
     defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2380
0
     defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2381
0
    sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
2382
0
    sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
2383
0
#endif
2384
0
#endif /* WOLFSSL_WIDE_BYTE */
2385
2386
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2387
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2388
    #ifdef WC_SHA512_RAW_BE_BUFFER
2389
    /* raw-buffer convention -- the length words must be big-endian in the
2390
     * stream regardless of which transform consumes the final block. */
2391
    #else
2392
    if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags))
2393
    #endif
2394
    {
2395
        ByteReverseWords64(&(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
2396
                           &(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
2397
                           WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
2398
    }
2399
#elif defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM)
2400
    #define SHA512_PAD_LEN_64  (WC_SHA512_PAD_SIZE / sizeof(word64))
2401
    {
2402
        ByteReverseWords64(&(sha512->buffer[SHA512_PAD_LEN_64]),
2403
                           &(sha512->buffer[SHA512_PAD_LEN_64]),
2404
                           WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
2405
    }
2406
#elif defined(WOLFSSL_PPC64_ASM) && defined(LITTLE_ENDIAN_ORDER)
2407
    /* The PPC64 assembly loads the message with byte-reversed loads on
2408
     * little-endian, treating the whole block as a big-endian byte stream.  The
2409
     * 128-bit length just stored is in native (little-endian) word order, so
2410
     * reverse it here to keep the block a consistent big-endian stream. */
2411
    {
2412
        ByteReverseWords64(
2413
            &(sha512->buffer[WC_SHA512_PAD_SIZE / sizeof(word64)]),
2414
            &(sha512->buffer[WC_SHA512_PAD_SIZE / sizeof(word64)]),
2415
            WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
2416
    }
2417
#endif
2418
2419
#if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_PPC64_ASM) || \
2420
    defined(WOLFSSL_PPC32_ASM) || defined(WOLFSSL_RISCV_ASM)
2421
    ret = Transform_Sha512(sha512, (const byte*)sha512->buffer);
2422
    if (ret != 0)
2423
        return ret;
2424
#else
2425
0
#if !defined(WOLFSSL_ESP32_CRYPT) || \
2426
0
      defined(NO_WOLFSSL_ESP32_CRYPT_HASH) || \
2427
0
      defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2428
0
    ret = Transform_Sha512(sha512);
2429
#else
2430
    if(sha512->ctx.mode == ESP32_SHA_INIT) {
2431
        /* typically for tiny block: first = last */
2432
        esp_sha_try_hw_lock(&sha512->ctx);
2433
    }
2434
    if (sha512->ctx.mode == ESP32_SHA_SW) {
2435
        ByteReverseWords64(sha512->buffer,
2436
                           sha512->buffer,
2437
                           WC_SHA512_BLOCK_SIZE);
2438
        sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
2439
        sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
2440
        ret = Transform_Sha512(sha512);
2441
    }
2442
    else {
2443
        ret = esp_sha512_digest_process(sha512, 1);
2444
    }
2445
#endif
2446
2447
0
    if (ret != 0)
2448
0
        return ret;
2449
0
#endif
2450
2451
    /* CHAR_BIT != 8: leave digest in host word order; the *Final functions
2452
     * emit big-endian octets via BytesFromWordsBE64 (no in-place reverse). */
2453
0
    #if defined(LITTLE_ENDIAN_ORDER) && !defined(WOLFSSL_WIDE_BYTE)
2454
0
        ByteReverseWords64(sha512->digest, sha512->digest,
2455
0
            WC_SHA512_DIGEST_SIZE);
2456
0
    #endif
2457
2458
2459
0
    return 0;
2460
0
}
2461
2462
#endif /* WOLFSSL_KCAPI_HASH */
2463
2464
#ifdef WOLFSSL_SHA512
2465
2466
#if defined(WOLFSSL_KCAPI_HASH)
2467
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2468
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2469
2470
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2471
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2472
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2473
2474
#elif defined(MAX3266X_SHA)
2475
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2476
#elif defined(STM32_HASH_SHA512)
2477
#elif defined(PSOC6_HASH_SHA2)
2478
#elif defined(WOLFSSL_SILABS_SHA512)
2479
#else
2480
2481
static int Sha512FinalRaw(wc_Sha512* sha512, byte* hash, word32 digestSz)
2482
0
{
2483
0
    if (sha512 == NULL || hash == NULL) {
2484
0
        return BAD_FUNC_ARG;
2485
0
    }
2486
2487
#if defined(WOLFSSL_WIDE_BYTE)
2488
    BytesFromWordsBE64(hash, sha512->digest, digestSz);
2489
#elif defined(LITTLE_ENDIAN_ORDER)
2490
0
    if ((digestSz & 0x7) == 0)
2491
0
        ByteReverseWords64((word64 *)hash, sha512->digest, digestSz);
2492
0
    else {
2493
0
        ByteReverseWords64(sha512->digest, sha512->digest,
2494
0
                           WC_SHA512_DIGEST_SIZE);
2495
0
        XMEMCPY(hash, sha512->digest, digestSz);
2496
0
    }
2497
#else
2498
    XMEMCPY(hash, sha512->digest, digestSz);
2499
#endif
2500
2501
0
    return 0;
2502
0
}
2503
2504
int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
2505
0
{
2506
0
    return Sha512FinalRaw(sha512, hash, WC_SHA512_DIGEST_SIZE);
2507
0
}
2508
2509
static int Sha512_Family_Final(wc_Sha512* sha512, byte* hash, size_t digestSz,
2510
                               int (*initfp)(wc_Sha512*))
2511
0
{
2512
0
    int ret;
2513
2514
0
    if (sha512 == NULL || hash == NULL) {
2515
0
        return BAD_FUNC_ARG;
2516
0
    }
2517
2518
#ifdef WOLF_CRYPTO_CB
2519
    #ifndef WOLF_CRYPTO_CB_FIND
2520
    if (sha512->devId != INVALID_DEVID)
2521
    #endif
2522
    {
2523
        ret = wc_CryptoCb_Sha512Hash(sha512, NULL, 0, hash, digestSz);
2524
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE)) {
2525
            return ret;
2526
        }
2527
        /* fall-through when unavailable */
2528
    }
2529
#endif
2530
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
2531
    if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {
2532
    #if defined(HAVE_INTEL_QA)
2533
        return IntelQaSymSha512(&sha512->asyncDev, hash, NULL, digestSz);
2534
    #endif
2535
    }
2536
#endif /* WOLFSSL_ASYNC_CRYPT */
2537
2538
0
    ret = Sha512Final(sha512);
2539
0
    if (ret != 0)
2540
0
        return ret;
2541
2542
#ifdef WOLFSSL_WIDE_BYTE
2543
    BytesFromWordsBE64(hash, sha512->digest, (word32)digestSz);
2544
#else
2545
0
    XMEMCPY(hash, sha512->digest, digestSz);
2546
0
#endif
2547
2548
    /* initialize Sha512 structure for the next use */
2549
0
    return initfp(sha512);
2550
0
}
2551
2552
#ifndef STM32_HASH_SHA512
2553
int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
2554
0
{
2555
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_DIGEST_SIZE, InitSha512);
2556
0
}
2557
#endif
2558
2559
#endif /* WOLFSSL_KCAPI_HASH */
2560
2561
#if defined(MAX3266X_SHA)
2562
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2563
2564
#else
2565
#if !defined(WOLFSSL_SE050) || !defined(WOLFSSL_SE050_HASH)
2566
int wc_InitSha512(wc_Sha512* sha512)
2567
0
{
2568
0
    int devId = INVALID_DEVID;
2569
2570
#ifdef WOLF_CRYPTO_CB
2571
    devId = wc_CryptoCb_DefaultDevID();
2572
#endif
2573
0
    return wc_InitSha512_ex(sha512, NULL, devId);
2574
0
}
2575
2576
void wc_Sha512Free(wc_Sha512* sha512)
2577
0
{
2578
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
2579
    int ret = 0;
2580
#endif
2581
2582
0
    if (sha512 == NULL)
2583
0
        return;
2584
2585
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
2586
    #ifndef WOLF_CRYPTO_CB_FIND
2587
    if (sha512->devId != INVALID_DEVID)
2588
    #endif
2589
    {
2590
        ret = wc_CryptoCb_Free(sha512->devId, WC_ALGO_TYPE_HASH,
2591
                         WC_HASH_TYPE_SHA512, 0, (void*)sha512);
2592
        /* If they want the standard free, they can call it themselves */
2593
        /* via their callback setting devId to INVALID_DEVID */
2594
        /* otherwise assume the callback handled it */
2595
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2596
            return;
2597
        /* fall-through when unavailable */
2598
    }
2599
2600
    /* silence compiler warning */
2601
    (void)ret;
2602
2603
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
2604
2605
#if defined(WOLFSSL_ESP32) && \
2606
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)  && \
2607
    !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
2608
    esp_sha_release_unfinished_lock(&sha512->ctx);
2609
#endif
2610
2611
#ifdef WOLFSSL_SMALL_STACK_CACHE
2612
    if (sha512->W != NULL) {
2613
        ForceZero(sha512->W, (sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE);
2614
        XFREE(sha512->W, sha512->heap, DYNAMIC_TYPE_DIGEST);
2615
        sha512->W = NULL;
2616
    }
2617
#endif
2618
2619
#if defined(WOLFSSL_KCAPI_HASH)
2620
    KcapiHashFree(&sha512->kcapi);
2621
#endif
2622
2623
#if defined(WOLFSSL_HASH_KEEP) ||\
2624
   (defined(WOLFSSL_RENESAS_RSIP) && (WOLFSSL_RENESAS_RZFSP_VER >= 220))
2625
    if (sha512->msg != NULL) {
2626
        ForceZero(sha512->msg, sha512->len);
2627
        XFREE(sha512->msg, sha512->heap, DYNAMIC_TYPE_TMP_BUFFER);
2628
        sha512->msg = NULL;
2629
    }
2630
#endif
2631
2632
2633
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
2634
    wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512);
2635
#endif /* WOLFSSL_ASYNC_CRYPT */
2636
2637
#if defined(PSOC6_HASH_SHA2)
2638
    wc_Psoc6_Sha_Free();
2639
#endif
2640
2641
0
    ForceZero(sha512, sizeof(*sha512));
2642
0
}
2643
#endif
2644
2645
#if (defined(OPENSSL_EXTRA) || defined(HAVE_CURL)) \
2646
    && !defined(WOLFSSL_KCAPI_HASH)
2647
/* Apply SHA512 transformation to the data                */
2648
/* @param sha  a pointer to wc_Sha512 structure           */
2649
/* @param data data to be applied SHA512 transformation   */
2650
/* @return 0 on successful, otherwise non-zero on failure */
2651
int wc_Sha512Transform(wc_Sha512* sha, const unsigned char* data)
2652
{
2653
    int ret;
2654
    /* back up buffer */
2655
    WC_DECLARE_VAR(buffer, word64, WC_SHA512_BLOCK_SIZE  / sizeof(word64),
2656
        0);
2657
2658
    /* sanity check */
2659
    if (sha == NULL || data == NULL) {
2660
        return BAD_FUNC_ARG;
2661
    }
2662
2663
2664
#if defined(WOLFSSL_SMALL_STACK_CACHE)
2665
    if (sha->W == NULL)
2666
        return BAD_FUNC_ARG;
2667
    /* Skip over the initial `W' buffer at the start (used by
2668
     * _Transform_Sha512()).
2669
     */
2670
    buffer = sha->W + 16;
2671
#elif defined(WOLFSSL_SMALL_STACK)
2672
    buffer = (word64*)XMALLOC(WC_SHA512_BLOCK_SIZE, sha->heap,
2673
        DYNAMIC_TYPE_TMP_BUFFER);
2674
    if (buffer == NULL)
2675
        return MEMORY_E;
2676
#endif
2677
2678
#if defined(LITTLE_ENDIAN_ORDER) && !defined(WC_SHA512_RAW_BE_BUFFER)
2679
#if defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2680
    (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))
2681
    if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
2682
#endif
2683
    {
2684
        ByteReverseWords64((word64*)data, (word64*)data,
2685
                                                WC_SHA512_BLOCK_SIZE);
2686
    }
2687
#endif /* LITTLE_ENDIAN_ORDER && !WC_SHA512_RAW_BE_BUFFER */
2688
2689
#if defined(WOLFSSL_ARMASM) || defined(WOLFSSL_RISCV_ASM)
2690
    ByteReverseWords64(buffer, (word64*)data, WC_SHA512_BLOCK_SIZE);
2691
    Transform_Sha512(sha, (const byte*)buffer);
2692
    ret = 0;
2693
#elif defined(WOLFSSL_PPC64_ASM) || defined(WOLFSSL_PPC32_ASM)
2694
    /* PPC assembly uses the (sha, data) form and reads the block directly
2695
     * (big-endian native - any little-endian reversal was done above). */
2696
    (void)buffer;
2697
    ret = Transform_Sha512(sha, data);
2698
#else
2699
    XMEMCPY(buffer, sha->buffer, WC_SHA512_BLOCK_SIZE);
2700
    XMEMCPY(sha->buffer, data, WC_SHA512_BLOCK_SIZE);
2701
2702
    ret = Transform_Sha512(sha);
2703
2704
    XMEMCPY(sha->buffer, buffer, WC_SHA512_BLOCK_SIZE);
2705
#endif
2706
#if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
2707
    ForceZero(buffer, WC_SHA512_BLOCK_SIZE);
2708
    XFREE(buffer, sha->heap, DYNAMIC_TYPE_TMP_BUFFER);
2709
#endif
2710
    return ret;
2711
}
2712
#endif /* OPENSSL_EXTRA */
2713
#endif /* WOLFSSL_SHA512 */
2714
#endif /* !WOLFSSL_SE050 || !WOLFSSL_SE050_HASH */
2715
2716
2717
/* -------------------------------------------------------------------------- */
2718
/* SHA384 */
2719
/* -------------------------------------------------------------------------- */
2720
#ifdef WOLFSSL_SHA384
2721
2722
#if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
2723
    !defined(WOLFSSL_QNX_CAAM)
2724
    /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
2725
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
2726
    int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
2727
    {
2728
        if (sha384 == NULL) {
2729
            return BAD_FUNC_ARG;
2730
        }
2731
        (void)devId;
2732
        return se050_hash_init(&sha384->se050Ctx, heap);
2733
    }
2734
    int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
2735
    {
2736
        if (sha384 == NULL) {
2737
            return BAD_FUNC_ARG;
2738
        }
2739
        if (data == NULL && len == 0) {
2740
            /* valid, but do nothing */
2741
            return 0;
2742
        }
2743
        if (data == NULL) {
2744
            return BAD_FUNC_ARG;
2745
        }
2746
2747
        return se050_hash_update(&sha384->se050Ctx, data, len);
2748
2749
    }
2750
    int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
2751
    {
2752
        int ret = 0;
2753
        ret = se050_hash_final(&sha384->se050Ctx, hash, WC_SHA384_DIGEST_SIZE,
2754
                               kAlgorithm_SSS_SHA384);
2755
        return ret;
2756
    }
2757
2758
#elif defined(WOLFSSL_SILABS_SHA384)
2759
    /* functions defined in wolfcrypt/src/port/silabs/silabs_hash.c */
2760
2761
#elif defined(WOLFSSL_KCAPI_HASH)
2762
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
2763
2764
#elif defined(WOLFSSL_RENESAS_RSIP) && \
2765
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
2766
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
2767
2768
#elif defined(MAX3266X_SHA)
2769
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
2770
#elif defined(STM32_HASH_SHA384)
2771
2772
    int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
2773
    {
2774
        if (sha384 == NULL)
2775
            return BAD_FUNC_ARG;
2776
2777
        (void)devId;
2778
        (void)heap;
2779
2780
        XMEMSET(sha384, 0, sizeof(wc_Sha384));
2781
        wc_Stm32_Hash_Init(&sha384->stmCtx);
2782
        return 0;
2783
    }
2784
2785
    int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
2786
    {
2787
        int ret = 0;
2788
2789
        if (sha384 == NULL) {
2790
            return BAD_FUNC_ARG;
2791
        }
2792
        if (data == NULL && len == 0) {
2793
            /* valid, but do nothing */
2794
            return 0;
2795
        }
2796
        if (data == NULL) {
2797
            return BAD_FUNC_ARG;
2798
        }
2799
2800
        ret = wolfSSL_CryptHwMutexLock();
2801
        if (ret == 0) {
2802
            ret = wc_Stm32_Hash_Update(&sha384->stmCtx,
2803
                HASH_ALGOSELECTION_SHA384, data, len, WC_SHA384_BLOCK_SIZE);
2804
            wolfSSL_CryptHwMutexUnLock();
2805
        }
2806
        return ret;
2807
    }
2808
2809
    int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
2810
    {
2811
        int ret = 0;
2812
2813
        if (sha384 == NULL || hash == NULL) {
2814
            return BAD_FUNC_ARG;
2815
        }
2816
2817
        ret = wolfSSL_CryptHwMutexLock();
2818
        if (ret == 0) {
2819
            ret = wc_Stm32_Hash_Final(&sha384->stmCtx,
2820
                HASH_ALGOSELECTION_SHA384, hash, WC_SHA384_DIGEST_SIZE);
2821
            wolfSSL_CryptHwMutexUnLock();
2822
        }
2823
2824
        (void)wc_InitSha384(sha384); /* reset state */
2825
2826
        return ret;
2827
    }
2828
2829
#elif defined(PSOC6_HASH_SHA2)
2830
    /* implemented in wolfcrypt/src/port/cypress/psoc6_crypto.c */
2831
2832
#else
2833
2834
static int InitSha384(wc_Sha384* sha384)
2835
0
{
2836
0
    if (sha384 == NULL) {
2837
0
        return BAD_FUNC_ARG;
2838
0
    }
2839
2840
#ifdef WOLFSSL_SMALL_STACK_CACHE
2841
    if (sha384->W == NULL) {
2842
        /* This allocation combines the customary W buffer used by
2843
         * _Transform_Sha512() with additional buffer space used by
2844
         * wc_Sha512Transform().
2845
         */
2846
        sha384->W = (word64 *)XMALLOC((sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE,
2847
                                      sha384->heap, DYNAMIC_TYPE_DIGEST);
2848
        if (sha384->W == NULL)
2849
            return MEMORY_E;
2850
    }
2851
#endif
2852
2853
0
    sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8);
2854
0
    sha384->digest[1] = W64LIT(0x629a292a367cd507);
2855
0
    sha384->digest[2] = W64LIT(0x9159015a3070dd17);
2856
0
    sha384->digest[3] = W64LIT(0x152fecd8f70e5939);
2857
0
    sha384->digest[4] = W64LIT(0x67332667ffc00b31);
2858
0
    sha384->digest[5] = W64LIT(0x8eb44a8768581511);
2859
0
    sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7);
2860
0
    sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4);
2861
2862
0
    sha384->buffLen = 0;
2863
0
    XMEMSET(sha384->buffer, 0, sizeof(sha384->buffer));
2864
0
    sha384->loLen   = 0;
2865
0
    sha384->hiLen   = 0;
2866
2867
#if (defined(WOLFSSL_X86_64_BUILD) && defined(USE_INTEL_SPEEDUP) && \
2868
     (defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2))) || \
2869
    defined(WOLFSSL_ARMASM)
2870
    Sha512_SetTransform();
2871
#endif
2872
2873
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)  && \
2874
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
2875
    /* HW needs to be carefully initialized, taking into account soft copy.
2876
    ** If already in use; copy may revert to SW as needed. */
2877
    esp_sha_init(&(sha384->ctx), WC_HASH_TYPE_SHA384);
2878
#endif
2879
2880
#ifdef WOLFSSL_HASH_FLAGS
2881
    sha384->flags = 0;
2882
#endif
2883
2884
#ifdef HAVE_ARIA
2885
    sha384->hSession = NULL;
2886
#endif
2887
2888
#ifdef WOLFSSL_HASH_KEEP
2889
    sha384->msg  = NULL;
2890
    sha384->len  = 0;
2891
    sha384->used = 0;
2892
#endif
2893
2894
0
    return 0;
2895
0
}
2896
2897
int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
2898
0
{
2899
2900
0
    if (sha384 == NULL) {
2901
0
        return BAD_FUNC_ARG;
2902
0
    }
2903
0
    if (data == NULL && len == 0) {
2904
        /* valid, but do nothing */
2905
0
        return 0;
2906
0
    }
2907
0
    if (data == NULL) {
2908
0
        return BAD_FUNC_ARG;
2909
0
    }
2910
2911
#ifdef WOLF_CRYPTO_CB
2912
    #ifndef WOLF_CRYPTO_CB_FIND
2913
    if (sha384->devId != INVALID_DEVID)
2914
    #endif
2915
    {
2916
        int ret = wc_CryptoCb_Sha384Hash(sha384, data, len, NULL);
2917
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2918
            return ret;
2919
        /* fall-through when unavailable */
2920
    }
2921
#endif
2922
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
2923
    if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {
2924
    #if defined(HAVE_INTEL_QA)
2925
        return IntelQaSymSha384(&sha384->asyncDev, NULL, data, len);
2926
    #endif
2927
    }
2928
#endif /* WOLFSSL_ASYNC_CRYPT */
2929
2930
0
    return Sha512Update((wc_Sha512*)sha384, data, len);
2931
0
}
2932
2933
2934
int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
2935
0
{
2936
0
    if (sha384 == NULL || hash == NULL) {
2937
0
        return BAD_FUNC_ARG;
2938
0
    }
2939
2940
#if defined(WOLFSSL_WIDE_BYTE)
2941
    BytesFromWordsBE64(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
2942
#elif defined(LITTLE_ENDIAN_ORDER)
2943
0
    ByteReverseWords64((word64 *)hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
2944
#else
2945
    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
2946
#endif
2947
2948
0
    return 0;
2949
0
}
2950
2951
int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
2952
0
{
2953
0
    int ret;
2954
2955
0
    if (sha384 == NULL || hash == NULL) {
2956
0
        return BAD_FUNC_ARG;
2957
0
    }
2958
2959
#ifdef WOLF_CRYPTO_CB
2960
    #ifndef WOLF_CRYPTO_CB_FIND
2961
    if (sha384->devId != INVALID_DEVID)
2962
    #endif
2963
    {
2964
        ret = wc_CryptoCb_Sha384Hash(sha384, NULL, 0, hash);
2965
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
2966
            return ret;
2967
        /* fall-through when unavailable */
2968
    }
2969
#endif
2970
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
2971
    if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {
2972
    #if defined(HAVE_INTEL_QA)
2973
        return IntelQaSymSha384(&sha384->asyncDev, hash, NULL,
2974
                                            WC_SHA384_DIGEST_SIZE);
2975
    #endif
2976
    }
2977
#endif /* WOLFSSL_ASYNC_CRYPT */
2978
2979
0
    ret = Sha512Final((wc_Sha512*)sha384);
2980
0
    if (ret != 0)
2981
0
        return ret;
2982
2983
#ifdef WOLFSSL_WIDE_BYTE
2984
    BytesFromWordsBE64(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
2985
#else
2986
0
    XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
2987
0
#endif
2988
2989
0
    return InitSha384(sha384);  /* reset state */
2990
0
}
2991
2992
int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
2993
0
{
2994
0
    int ret;
2995
2996
0
    if (sha384 == NULL) {
2997
0
        return BAD_FUNC_ARG;
2998
0
    }
2999
3000
0
    sha384->heap = heap;
3001
#ifdef WOLFSSL_SMALL_STACK_CACHE
3002
    sha384->W = NULL;
3003
#endif
3004
#ifdef WOLF_CRYPTO_CB
3005
    sha384->devId = devId;
3006
    sha384->devCtx = NULL;
3007
#endif
3008
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW)  && \
3009
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
3010
    if (sha384->ctx.mode != ESP32_SHA_INIT) {
3011
        ESP_LOGV(TAG, "Set ctx mode from prior value: "
3012
                           "%d", sha384->ctx.mode);
3013
    }
3014
    /* We know this is a fresh, uninitialized item, so set to INIT */
3015
    sha384->ctx.mode = ESP32_SHA_INIT;
3016
#endif
3017
3018
3019
0
    ret = InitSha384(sha384);
3020
0
    if (ret != 0) {
3021
0
        return ret;
3022
0
    }
3023
3024
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
3025
    ret = wolfAsync_DevCtxInit(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384,
3026
                                                           sha384->heap, devId);
3027
#else
3028
0
    (void)devId;
3029
0
#endif /* WOLFSSL_ASYNC_CRYPT */
3030
#ifdef WOLFSSL_IMXRT1170_CAAM
3031
     ret = wc_CAAM_HashInit(&sha384->hndl, &sha384->ctx, WC_HASH_TYPE_SHA384);
3032
#endif
3033
0
    return ret;
3034
0
}
3035
3036
#endif /* WOLFSSL_IMX6_CAAM || WOLFSSL_SILABS_SHA384 || WOLFSSL_KCAPI_HASH */
3037
3038
#if defined(MAX3266X_SHA)
3039
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
3040
3041
#else
3042
int wc_InitSha384(wc_Sha384* sha384)
3043
0
{
3044
0
    int devId = INVALID_DEVID;
3045
3046
#ifdef WOLF_CRYPTO_CB
3047
    devId = wc_CryptoCb_DefaultDevID();
3048
#endif
3049
0
    return wc_InitSha384_ex(sha384, NULL, devId);
3050
0
}
3051
3052
void wc_Sha384Free(wc_Sha384* sha384)
3053
0
{
3054
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
3055
    int ret = 0;
3056
#endif
3057
3058
0
    if (sha384 == NULL)
3059
0
        return;
3060
3061
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_FREE)
3062
    #ifndef WOLF_CRYPTO_CB_FIND
3063
    if (sha384->devId != INVALID_DEVID)
3064
    #endif
3065
    {
3066
        ret = wc_CryptoCb_Free(sha384->devId, WC_ALGO_TYPE_HASH,
3067
                         WC_HASH_TYPE_SHA384, 0, (void*)sha384);
3068
        /* If they want the standard free, they can call it themselves */
3069
        /* via their callback setting devId to INVALID_DEVID */
3070
        /* otherwise assume the callback handled it */
3071
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3072
            return;
3073
        /* fall-through when unavailable */
3074
    }
3075
3076
    /* silence compiler warning */
3077
    (void)ret;
3078
3079
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_FREE */
3080
3081
#if defined(WOLFSSL_ESP32) && !defined(NO_WOLFSSL_ESP32_CRYPT_HASH)  && \
3082
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
3083
    esp_sha_release_unfinished_lock(&sha384->ctx);
3084
#endif
3085
3086
#ifdef WOLFSSL_SMALL_STACK_CACHE
3087
    if (sha384->W != NULL) {
3088
        ForceZero(sha384->W, (sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE);
3089
        XFREE(sha384->W, sha384->heap, DYNAMIC_TYPE_DIGEST);
3090
        sha384->W = NULL;
3091
    }
3092
#endif
3093
3094
#if defined(WOLFSSL_KCAPI_HASH)
3095
    KcapiHashFree(&sha384->kcapi);
3096
#endif
3097
3098
#if defined(WOLFSSL_HASH_KEEP) || \
3099
   (defined(WOLFSSL_RENESAS_RSIP) && (WOLFSSL_RENESAS_RZFSP_VER >= 220))
3100
    if (sha384->msg != NULL) {
3101
        ForceZero(sha384->msg, sha384->len);
3102
        XFREE(sha384->msg, sha384->heap, DYNAMIC_TYPE_TMP_BUFFER);
3103
        sha384->msg = NULL;
3104
    }
3105
#endif
3106
3107
#if defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3108
    se050_hash_free(&sha384->se050Ctx);
3109
#endif
3110
3111
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
3112
    wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384);
3113
#endif /* WOLFSSL_ASYNC_CRYPT */
3114
3115
#ifdef HAVE_ARIA
3116
    if (sha384->hSession != NULL) {
3117
        MC_CloseSession(sha384->hSession);
3118
        sha384->hSession = NULL;
3119
    }
3120
#endif
3121
3122
3123
0
    ForceZero(sha384, sizeof(*sha384));
3124
0
}
3125
3126
#endif
3127
#endif /* WOLFSSL_SHA384 */
3128
3129
#ifdef WOLFSSL_SHA512
3130
3131
#if defined(WOLFSSL_KCAPI_HASH)
3132
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3133
3134
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3135
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3136
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3137
3138
#elif defined(MAX3266X_SHA)
3139
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
3140
3141
#else
3142
3143
static int Sha512_Family_GetHash(wc_Sha512* sha512, byte* hash,
3144
                                 int (*finalfp)(wc_Sha512*, byte*))
3145
0
{
3146
0
    int ret;
3147
0
    WC_DECLARE_VAR(tmpSha512, wc_Sha512, 1, 0);
3148
3149
0
    if (sha512 == NULL || hash == NULL) {
3150
0
        return BAD_FUNC_ARG;
3151
0
    }
3152
3153
0
    WC_CALLOC_VAR_EX(tmpSha512, wc_Sha512, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
3154
0
        return MEMORY_E);
3155
3156
    /* copy this sha512 into tmpSha */
3157
0
    ret = wc_Sha512Copy(sha512, tmpSha512);
3158
0
    if (ret == 0) {
3159
0
        ret = finalfp(tmpSha512, hash);
3160
0
        wc_Sha512Free(tmpSha512);
3161
0
    }
3162
3163
0
    WC_FREE_VAR_EX(tmpSha512, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3164
3165
0
    return ret;
3166
0
}
3167
3168
int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)
3169
0
{
3170
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512Final);
3171
0
}
3172
3173
int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
3174
0
{
3175
0
    int ret = 0;
3176
3177
0
    if (src == NULL || dst == NULL) {
3178
0
        return BAD_FUNC_ARG;
3179
0
    }
3180
3181
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
3182
    #ifndef WOLF_CRYPTO_CB_FIND
3183
    if (src->devId != INVALID_DEVID)
3184
    #endif
3185
    {
3186
        /* Cast the source and destination to be void to keep the abstraction */
3187
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
3188
                               WC_HASH_TYPE_SHA512, (void*)src, (void*)dst);
3189
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3190
            return ret;
3191
        /* fall-through when unavailable */
3192
    }
3193
    ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
3194
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
3195
3196
    /* Free dst resources before copy to prevent memory leaks (e.g., msg
3197
     * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
3198
0
    wc_Sha512Free(dst);
3199
0
    XMEMCPY(dst, src, sizeof(wc_Sha512));
3200
#ifdef WOLFSSL_SMALL_STACK_CACHE
3201
    /* This allocation combines the customary W buffer used by
3202
     * _Transform_Sha512() with additional buffer space used by
3203
     * wc_Sha512Transform().
3204
     */
3205
    dst->W = (word64 *)XMALLOC((sizeof(word64) * 16) + WC_SHA512_BLOCK_SIZE,
3206
                               dst->heap, DYNAMIC_TYPE_DIGEST);
3207
    if (dst->W == NULL) {
3208
        XMEMSET(dst, 0, sizeof(wc_Sha512));
3209
        return MEMORY_E;
3210
    }
3211
#endif
3212
3213
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3) && \
3214
    defined(WOLFSSL_SILABS_SHA512)
3215
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
3216
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
3217
#endif
3218
3219
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
3220
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
3221
#endif
3222
3223
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3224
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA512)
3225
    #if defined(CONFIG_IDF_TARGET_ESP32)
3226
    if (ret == 0) {
3227
        ret = esp_sha512_ctx_copy(src, dst);
3228
    }
3229
    #elif defined(CONFIG_IDF_TARGET_ESP32C2) || \
3230
          defined(CONFIG_IDF_TARGET_ESP8684) || \
3231
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
3232
          defined(CONFIG_IDF_TARGET_ESP32C6)
3233
        ESP_LOGV(TAG, "No SHA-512 HW on the ESP32-C3");
3234
3235
    #elif defined(CONFIG_IDF_TARGET_ESP32S2) || \
3236
          defined(CONFIG_IDF_TARGET_ESP32S3)
3237
        if (ret == 0) {
3238
            ret = esp_sha512_ctx_copy(src, dst);
3239
        }
3240
    #else
3241
        ESP_LOGW(TAG, "No SHA384 HW or not yet implemented for %s",
3242
                       CONFIG_IDF_TARGET);
3243
    #endif
3244
3245
#endif /* WOLFSSL_USE_ESP32_CRYPT_HASH_HW */
3246
3247
#ifdef WOLFSSL_HASH_FLAGS
3248
     dst->flags |= WC_HASH_FLAG_ISCOPY;
3249
#endif
3250
3251
#if defined(WOLFSSL_HASH_KEEP)
3252
    if (src->msg != NULL) {
3253
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
3254
        if (dst->msg == NULL)
3255
            return MEMORY_E;
3256
        XMEMCPY(dst->msg, src->msg, src->len);
3257
    }
3258
#endif
3259
3260
3261
#if defined(PSOC6_HASH_SHA2)
3262
    wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA512, 0);
3263
#endif
3264
3265
0
    return ret;
3266
0
}
3267
3268
#endif /* WOLFSSL_KCAPI_HASH */
3269
3270
#ifdef WOLFSSL_HASH_FLAGS
3271
int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags)
3272
{
3273
    if (sha512) {
3274
        sha512->flags = flags;
3275
    }
3276
    return 0;
3277
}
3278
int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags)
3279
{
3280
    if (sha512 && flags) {
3281
        *flags = sha512->flags;
3282
    }
3283
    return 0;
3284
}
3285
#endif /* WOLFSSL_HASH_FLAGS */
3286
3287
#if !defined(WOLFSSL_NOSHA512_224) && \
3288
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
3289
3290
#if defined(STM32_HASH_SHA512_224)
3291
3292
int wc_InitSha512_224_ex(wc_Sha512* sha512, void* heap, int devId)
3293
{
3294
    if (sha512 == NULL)
3295
        return BAD_FUNC_ARG;
3296
3297
    (void)devId;
3298
    (void)heap;
3299
3300
    XMEMSET(sha512, 0, sizeof(wc_Sha512));
3301
    wc_Stm32_Hash_Init(&sha512->stmCtx);
3302
#if defined(WOLFSSL_SHA512_HASHTYPE)
3303
    sha512->hashType = WC_HASH_TYPE_SHA512_224;
3304
#endif
3305
    return 0;
3306
}
3307
3308
int wc_Sha512_224Update(wc_Sha512* sha512, const byte* data, word32 len)
3309
{
3310
    int ret = 0;
3311
3312
    if (sha512 == NULL) {
3313
        return BAD_FUNC_ARG;
3314
    }
3315
    if (data == NULL && len == 0) {
3316
        /* valid, but do nothing */
3317
        return 0;
3318
    }
3319
    if (data == NULL) {
3320
        return BAD_FUNC_ARG;
3321
    }
3322
3323
    ret = wolfSSL_CryptHwMutexLock();
3324
    if (ret == 0) {
3325
        ret = wc_Stm32_Hash_Update(&sha512->stmCtx,
3326
            HASH_ALGOSELECTION_SHA512_224, data, len, WC_SHA512_224_BLOCK_SIZE);
3327
        wolfSSL_CryptHwMutexUnLock();
3328
    }
3329
    return ret;
3330
}
3331
3332
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
3333
{
3334
    int ret = 0;
3335
3336
    if (sha512 == NULL || hash == NULL) {
3337
        return BAD_FUNC_ARG;
3338
    }
3339
3340
    ret = wolfSSL_CryptHwMutexLock();
3341
    if (ret == 0) {
3342
        ret = wc_Stm32_Hash_Final(&sha512->stmCtx,
3343
            HASH_ALGOSELECTION_SHA512_224, hash, WC_SHA512_224_DIGEST_SIZE);
3344
        wolfSSL_CryptHwMutexUnLock();
3345
    }
3346
3347
    (void)wc_InitSha512_224(sha512); /* reset state */
3348
3349
    return ret;
3350
}
3351
#elif defined(PSOC6_HASH_SHA2)
3352
    /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
3353
#endif
3354
int wc_InitSha512_224(wc_Sha512* sha)
3355
0
{
3356
0
    return wc_InitSha512_224_ex(sha, NULL, INVALID_DEVID);
3357
0
}
3358
#if !defined(STM32_HASH_SHA512_224) && !defined(PSOC6_HASH_SHA2)
3359
int wc_Sha512_224Update(wc_Sha512* sha, const byte* data, word32 len)
3360
0
{
3361
0
    return wc_Sha512Update(sha, data, len);
3362
0
}
3363
#endif
3364
#if defined(WOLFSSL_KCAPI_HASH)
3365
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3366
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3367
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3368
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3369
3370
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3371
#elif defined(STM32_HASH_SHA512_224)
3372
#elif defined(PSOC6_HASH_SHA2)
3373
    /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
3374
3375
#else
3376
int wc_Sha512_224FinalRaw(wc_Sha512* sha, byte* hash)
3377
0
{
3378
0
    return Sha512FinalRaw(sha, hash, WC_SHA512_224_DIGEST_SIZE);
3379
0
}
3380
3381
int wc_Sha512_224Final(wc_Sha512* sha512, byte* hash)
3382
0
{
3383
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_224_DIGEST_SIZE,
3384
0
                               InitSha512_224);
3385
0
}
3386
#endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
3387
3388
void wc_Sha512_224Free(wc_Sha512* sha)
3389
0
{
3390
0
    wc_Sha512Free(sha);
3391
0
}
3392
3393
#if defined(WOLFSSL_KCAPI_HASH)
3394
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3395
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3396
3397
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3398
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3399
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3400
3401
#else
3402
int wc_Sha512_224GetHash(wc_Sha512* sha512, byte* hash)
3403
0
{
3404
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512_224Final);
3405
0
}
3406
3407
int wc_Sha512_224Copy(wc_Sha512* src, wc_Sha512* dst)
3408
0
{
3409
0
    return wc_Sha512Copy(src, dst);
3410
0
}
3411
#endif /* else none of the above: WOLFSSL_KCAPI_HASH, WOLFSSL_SE050 */
3412
3413
#ifdef WOLFSSL_HASH_FLAGS
3414
int wc_Sha512_224SetFlags(wc_Sha512* sha, word32 flags)
3415
{
3416
    return wc_Sha512SetFlags(sha, flags);
3417
}
3418
int wc_Sha512_224GetFlags(wc_Sha512* sha, word32* flags)
3419
{
3420
    return wc_Sha512GetFlags(sha, flags);
3421
}
3422
#endif /* WOLFSSL_HASH_FLAGS */
3423
3424
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
3425
int wc_Sha512_224Transform(wc_Sha512* sha, const unsigned char* data)
3426
{
3427
    return wc_Sha512Transform(sha, data);
3428
}
3429
#endif /* OPENSSL_EXTRA */
3430
3431
3432
#endif /* !WOLFSSL_NOSHA512_224 && !FIPS ... */
3433
3434
#if !defined(WOLFSSL_NOSHA512_256) && \
3435
   (!defined(HAVE_FIPS) || FIPS_VERSION_GE(5, 3)) && !defined(HAVE_SELFTEST)
3436
#if defined(STM32_HASH_SHA512_256)
3437
3438
    int wc_InitSha512_256_ex(wc_Sha512* sha512, void* heap, int devId)
3439
    {
3440
        if (sha512 == NULL)
3441
            return BAD_FUNC_ARG;
3442
3443
        (void)devId;
3444
        (void)heap;
3445
3446
        XMEMSET(sha512, 0, sizeof(wc_Sha512));
3447
        wc_Stm32_Hash_Init(&sha512->stmCtx);
3448
#if defined(WOLFSSL_SHA512_HASHTYPE)
3449
        sha512->hashType = WC_HASH_TYPE_SHA512_256;
3450
#endif
3451
        return 0;
3452
    }
3453
3454
    int wc_Sha512_256Update(wc_Sha512* sha512, const byte* data, word32 len)
3455
    {
3456
        int ret = 0;
3457
3458
        if (sha512 == NULL) {
3459
            return BAD_FUNC_ARG;
3460
        }
3461
        if (data == NULL && len == 0) {
3462
            /* valid, but do nothing */
3463
            return 0;
3464
        }
3465
        if (data == NULL) {
3466
            return BAD_FUNC_ARG;
3467
        }
3468
3469
        ret = wolfSSL_CryptHwMutexLock();
3470
        if (ret == 0) {
3471
            ret = wc_Stm32_Hash_Update(&sha512->stmCtx,
3472
                HASH_ALGOSELECTION_SHA512_256, data, len, WC_SHA512_256_BLOCK_SIZE);
3473
            wolfSSL_CryptHwMutexUnLock();
3474
        }
3475
        return ret;
3476
    }
3477
3478
    int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
3479
    {
3480
        int ret = 0;
3481
3482
        if (sha512 == NULL || hash == NULL) {
3483
            return BAD_FUNC_ARG;
3484
        }
3485
3486
        ret = wolfSSL_CryptHwMutexLock();
3487
        if (ret == 0) {
3488
            ret = wc_Stm32_Hash_Final(&sha512->stmCtx,
3489
                HASH_ALGOSELECTION_SHA512_256, hash, WC_SHA512_256_DIGEST_SIZE);
3490
            wolfSSL_CryptHwMutexUnLock();
3491
        }
3492
3493
        (void)wc_InitSha512_256(sha512); /* reset state */
3494
3495
        return ret;
3496
    }
3497
#elif defined(PSOC6_HASH_SHA2)
3498
    /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
3499
#endif
3500
int wc_InitSha512_256(wc_Sha512* sha)
3501
0
{
3502
0
    return wc_InitSha512_256_ex(sha, NULL, INVALID_DEVID);
3503
0
}
3504
#if !defined(STM32_HASH_SHA512_256) && !defined(PSOC6_HASH_SHA2)
3505
int wc_Sha512_256Update(wc_Sha512* sha, const byte* data, word32 len)
3506
0
{
3507
0
    return wc_Sha512Update(sha, data, len);
3508
0
}
3509
#endif
3510
#if defined(WOLFSSL_KCAPI_HASH)
3511
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3512
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3513
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3514
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3515
3516
#elif defined(WOLFSSL_SE050) && defined(WOLFSSL_SE050_HASH)
3517
#elif defined(STM32_HASH_SHA512_256)
3518
#elif defined(PSOC6_HASH_SHA2)
3519
    /* functions defined in wolfcrypt/src/port/cypress/psoc6_crypto.c */
3520
#else
3521
int wc_Sha512_256FinalRaw(wc_Sha512* sha, byte* hash)
3522
0
{
3523
0
    return Sha512FinalRaw(sha, hash, WC_SHA512_256_DIGEST_SIZE);
3524
0
}
3525
3526
int wc_Sha512_256Final(wc_Sha512* sha512, byte* hash)
3527
0
{
3528
0
    return Sha512_Family_Final(sha512, hash, WC_SHA512_256_DIGEST_SIZE,
3529
0
                               InitSha512_256);
3530
0
}
3531
#endif
3532
3533
void wc_Sha512_256Free(wc_Sha512* sha)
3534
0
{
3535
0
    wc_Sha512Free(sha);
3536
0
}
3537
3538
#if defined(WOLFSSL_KCAPI_HASH)
3539
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3540
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3541
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3542
    /* functions defined in wolfcrypt/src/port/Renesas/renesas_fspsm_sha.c */
3543
3544
#else
3545
int wc_Sha512_256GetHash(wc_Sha512* sha512, byte* hash)
3546
0
{
3547
0
    return Sha512_Family_GetHash(sha512, hash, wc_Sha512_256Final);
3548
0
}
3549
int wc_Sha512_256Copy(wc_Sha512* src, wc_Sha512* dst)
3550
0
{
3551
0
    return wc_Sha512Copy(src, dst);
3552
0
}
3553
#endif
3554
3555
#ifdef WOLFSSL_HASH_FLAGS
3556
int wc_Sha512_256SetFlags(wc_Sha512* sha, word32 flags)
3557
{
3558
    return wc_Sha512SetFlags(sha, flags);
3559
}
3560
int wc_Sha512_256GetFlags(wc_Sha512* sha, word32* flags)
3561
{
3562
    return wc_Sha512GetFlags(sha, flags);
3563
}
3564
#endif /* WOLFSSL_HASH_FLAGS */
3565
3566
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
3567
int wc_Sha512_256Transform(wc_Sha512* sha, const unsigned char* data)
3568
{
3569
    return wc_Sha512Transform(sha, data);
3570
}
3571
#endif /* OPENSSL_EXTRA */
3572
3573
3574
#endif /* !WOLFSSL_NOSHA512_256 && !FIPS ... */
3575
3576
#endif /* WOLFSSL_SHA512 */
3577
3578
#ifdef WOLFSSL_SHA384
3579
3580
#if defined(WOLFSSL_KCAPI_HASH)
3581
    /* functions defined in wolfcrypt/src/port/kcapi/kcapi_hash.c */
3582
#elif defined(WOLFSSL_RENESAS_RSIP) && \
3583
     !defined(NO_WOLFSSL_RENESAS_FSPSM_HASH)
3584
    /* functions defined in wolfcrypt/src/port/renesas/renesas_fspsm_sha.c */
3585
#elif defined(MAX3266X_SHA)
3586
    /* Functions defined in wolfcrypt/src/port/maxim/max3266x.c */
3587
3588
#else
3589
3590
int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
3591
0
{
3592
0
    int ret;
3593
0
    WC_DECLARE_VAR(tmpSha384, wc_Sha384, 1, 0);
3594
3595
0
    if (sha384 == NULL || hash == NULL) {
3596
0
        return BAD_FUNC_ARG;
3597
0
    }
3598
3599
0
    WC_CALLOC_VAR_EX(tmpSha384, wc_Sha384, 1, NULL, DYNAMIC_TYPE_TMP_BUFFER,
3600
0
        return MEMORY_E);
3601
3602
    /* copy this sha384 into tmpSha */
3603
0
    ret = wc_Sha384Copy(sha384, tmpSha384);
3604
0
    if (ret == 0) {
3605
0
        ret = wc_Sha384Final(tmpSha384, hash);
3606
0
        wc_Sha384Free(tmpSha384);
3607
0
    }
3608
3609
0
    WC_FREE_VAR_EX(tmpSha384, NULL, DYNAMIC_TYPE_TMP_BUFFER);
3610
3611
0
    return ret;
3612
0
}
3613
3614
int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
3615
0
{
3616
0
    int ret = 0;
3617
3618
0
    if (src == NULL || dst == NULL) {
3619
0
        return BAD_FUNC_ARG;
3620
0
    }
3621
3622
#if defined(WOLF_CRYPTO_CB) && defined(WOLF_CRYPTO_CB_COPY)
3623
    #ifndef WOLF_CRYPTO_CB_FIND
3624
    if (src->devId != INVALID_DEVID)
3625
    #endif
3626
    {
3627
        /* Cast the source and destination to be void to keep the abstraction */
3628
        ret = wc_CryptoCb_Copy(src->devId, WC_ALGO_TYPE_HASH,
3629
                               WC_HASH_TYPE_SHA384, (void*)src, (void*)dst);
3630
        if (ret != WC_NO_ERR_TRACE(CRYPTOCB_UNAVAILABLE))
3631
            return ret;
3632
        /* fall-through when unavailable */
3633
    }
3634
    ret = 0; /* Reset ret to 0 to avoid returning the callback error code */
3635
#endif /* WOLF_CRYPTO_CB && WOLF_CRYPTO_CB_COPY */
3636
3637
    /* Free dst resources before copy to prevent memory leaks (e.g., msg
3638
     * buffer, W cache, hardware contexts). XMEMCPY overwrites dst. */
3639
0
    wc_Sha384Free(dst);
3640
0
    XMEMCPY(dst, src, sizeof(wc_Sha384));
3641
3642
#ifdef WOLFSSL_SMALL_STACK_CACHE
3643
    /* This allocation combines the customary W buffer used by
3644
     * _Transform_Sha512() with additional buffer space used by
3645
     * wc_Sha512Transform().
3646
     */
3647
    dst->W = (word64 *)XMALLOC((sizeof(word64) * 16) + WC_SHA384_BLOCK_SIZE,
3648
                               dst->heap, DYNAMIC_TYPE_DIGEST);
3649
    if (dst->W == NULL) {
3650
        XMEMSET(dst, 0, sizeof(wc_Sha384));
3651
        return MEMORY_E;
3652
    }
3653
#endif
3654
3655
#if defined(WOLFSSL_SILABS_SE_ACCEL) && defined(WOLFSSL_SILABS_SE_ACCEL_3) && \
3656
    defined(WOLFSSL_SILABS_SHA384)
3657
    dst->silabsCtx.hash_ctx.cmd_ctx = &dst->silabsCtx.cmd_ctx;
3658
    dst->silabsCtx.hash_ctx.hash_type_ctx = &dst->silabsCtx.hash_type_ctx;
3659
#endif
3660
3661
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
3662
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
3663
#endif
3664
3665
#if defined(WOLFSSL_USE_ESP32_CRYPT_HASH_HW) && \
3666
   !defined(NO_WOLFSSL_ESP32_CRYPT_HASH_SHA384)
3667
    #if defined(CONFIG_IDF_TARGET_ESP32)
3668
        esp_sha384_ctx_copy(src, dst);
3669
    #elif defined(CONFIG_IDF_TARGET_ESP32C2) || \
3670
          defined(CONFIG_IDF_TARGET_ESP8684) || \
3671
          defined(CONFIG_IDF_TARGET_ESP32C3) || \
3672
          defined(CONFIG_IDF_TARGET_ESP32C6)
3673
        ESP_LOGV(TAG, "No SHA-384 HW on the ESP32-C3");
3674
    #elif defined(CONFIG_IDF_TARGET_ESP32S2) || \
3675
          defined(CONFIG_IDF_TARGET_ESP32S3)
3676
        esp_sha384_ctx_copy(src, dst);
3677
    #else
3678
        ESP_LOGW(TAG, "No SHA384 HW or not yet implemented for %s",
3679
                       CONFIG_IDF_TARGET);
3680
    #endif
3681
#endif
3682
3683
#ifdef HAVE_ARIA
3684
    dst->hSession = NULL;
3685
    if((src->hSession != NULL) && (MC_CopySession(src->hSession, &(dst->hSession)) != MC_OK)) {
3686
        return MEMORY_E;
3687
    }
3688
#endif
3689
3690
#ifdef WOLFSSL_HASH_FLAGS
3691
     dst->flags |= WC_HASH_FLAG_ISCOPY;
3692
#endif
3693
3694
#if defined(WOLFSSL_HASH_KEEP)
3695
    if (src->msg != NULL) {
3696
        dst->msg = (byte*)XMALLOC(src->len, dst->heap, DYNAMIC_TYPE_TMP_BUFFER);
3697
        if (dst->msg == NULL)
3698
            return MEMORY_E;
3699
        XMEMCPY(dst->msg, src->msg, src->len);
3700
    }
3701
#endif
3702
3703
3704
#if defined(PSOC6_HASH_SHA2)
3705
    wc_Psoc6_Sha1_Sha2_Init(dst, WC_PSOC6_SHA384, 0);
3706
#endif
3707
3708
0
    return ret;
3709
0
}
3710
3711
#endif /* WOLFSSL_KCAPI_HASH */
3712
3713
#ifdef WOLFSSL_HASH_FLAGS
3714
int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags)
3715
{
3716
    if (sha384) {
3717
        sha384->flags = flags;
3718
    }
3719
    return 0;
3720
}
3721
int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags)
3722
{
3723
    if (sha384 && flags) {
3724
        *flags = sha384->flags;
3725
    }
3726
    return 0;
3727
}
3728
#endif
3729
3730
#endif /* WOLFSSL_SHA384 */
3731
3732
#ifdef WOLFSSL_HASH_KEEP
3733
/* Some hardware have issues with update, this function stores the data to be
3734
 * hashed into an array. Once ready, the Final operation is called on all of the
3735
 * data to be hashed at once.
3736
 * returns 0 on success
3737
 */
3738
int wc_Sha512_Grow(wc_Sha512* sha512, const byte* in, int inSz)
3739
{
3740
    return _wc_Hash_Grow(&(sha512->msg), &(sha512->used), &(sha512->len), in,
3741
                        inSz, sha512->heap);
3742
}
3743
#ifdef WOLFSSL_SHA384
3744
int wc_Sha384_Grow(wc_Sha384* sha384, const byte* in, int inSz)
3745
{
3746
    return _wc_Hash_Grow(&(sha384->msg), &(sha384->used), &(sha384->len), in,
3747
                        inSz, sha384->heap);
3748
}
3749
#endif /* WOLFSSL_SHA384 */
3750
#endif /* WOLFSSL_HASH_KEEP */
3751
3752
#endif /* !WOLF_CRYPTO_CB_ONLY_SHA512 */
3753
#endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */