wolfSSL SSL/TLS library, support up to TLS1.3

Dependents:   CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sha512.c Source File

sha512.c

00001 /* sha512.c
00002  *
00003  * Copyright (C) 2006-2020 wolfSSL Inc.
00004  *
00005  * This file is part of wolfSSL.
00006  *
00007  * wolfSSL is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * wolfSSL is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
00020  */
00021 
00022 
00023 #ifdef HAVE_CONFIG_H
00024     #include <config.h>
00025 #endif
00026 
00027 #include <wolfssl/wolfcrypt/settings.h>
00028 
00029 #if (defined(WOLFSSL_SHA512) || defined(WOLFSSL_SHA384)) && !defined(WOLFSSL_ARMASM)
00030 
00031 #if defined(HAVE_FIPS) && \
00032     defined(HAVE_FIPS_VERSION) && (HAVE_FIPS_VERSION >= 2)
00033 
00034     /* set NO_WRAPPERS before headers, use direct internal f()s not wrappers */
00035     #define FIPS_NO_WRAPPERS
00036 
00037     #ifdef USE_WINDOWS_API
00038         #pragma code_seg(".fipsA$k")
00039         #pragma const_seg(".fipsB$k")
00040     #endif
00041 #endif
00042 
00043 #include <wolfssl/wolfcrypt/sha512.h >
00044 #include <wolfssl/wolfcrypt/error-crypt.h >
00045 #include <wolfssl/wolfcrypt/cpuid.h>
00046 #include <wolfssl/wolfcrypt/hash.h >
00047 
00048 /* deprecated USE_SLOW_SHA2 (replaced with USE_SLOW_SHA512) */
00049 #if defined(USE_SLOW_SHA2) && !defined(USE_SLOW_SHA512)
00050     #define USE_SLOW_SHA512
00051 #endif
00052 
00053 /* fips wrapper calls, user can call direct */
00054 #if defined(HAVE_FIPS) && \
00055     (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2))
00056 
00057     #ifdef WOLFSSL_SHA512
00058 
00059         int wc_InitSha512(wc_Sha512* sha)
00060         {
00061             if (sha == NULL) {
00062                 return BAD_FUNC_ARG;
00063             }
00064 
00065             return InitSha512_fips(sha);
00066         }
00067         int wc_InitSha512_ex(wc_Sha512* sha, void* heap, int devId)
00068         {
00069             (void)heap;
00070             (void)devId;
00071             if (sha == NULL) {
00072                 return BAD_FUNC_ARG;
00073             }
00074             return InitSha512_fips(sha);
00075         }
00076         int wc_Sha512Update(wc_Sha512* sha, const byte* data, word32 len)
00077         {
00078             if (sha == NULL || (data == NULL && len > 0)) {
00079                 return BAD_FUNC_ARG;
00080             }
00081 
00082             return Sha512Update_fips(sha, data, len);
00083         }
00084         int wc_Sha512Final(wc_Sha512* sha, byte* out)
00085         {
00086             if (sha == NULL || out == NULL) {
00087                 return BAD_FUNC_ARG;
00088             }
00089 
00090             return Sha512Final_fips(sha, out);
00091         }
00092         void wc_Sha512Free(wc_Sha512* sha)
00093         {
00094             (void)sha;
00095             /* Not supported in FIPS */
00096         }
00097     #endif
00098 
00099     #if defined(WOLFSSL_SHA384) || defined(HAVE_AESGCM)
00100         int wc_InitSha384(wc_Sha384* sha)
00101         {
00102             if (sha == NULL) {
00103                 return BAD_FUNC_ARG;
00104             }
00105             return InitSha384_fips(sha);
00106         }
00107         int wc_InitSha384_ex(wc_Sha384* sha, void* heap, int devId)
00108         {
00109             (void)heap;
00110             (void)devId;
00111             if (sha == NULL) {
00112                 return BAD_FUNC_ARG;
00113             }
00114             return InitSha384_fips(sha);
00115         }
00116         int wc_Sha384Update(wc_Sha384* sha, const byte* data, word32 len)
00117         {
00118             if (sha == NULL || (data == NULL && len > 0)) {
00119                 return BAD_FUNC_ARG;
00120             }
00121             return Sha384Update_fips(sha, data, len);
00122         }
00123         int wc_Sha384Final(wc_Sha384* sha, byte* out)
00124         {
00125             if (sha == NULL || out == NULL) {
00126                 return BAD_FUNC_ARG;
00127             }
00128             return Sha384Final_fips(sha, out);
00129         }
00130         void wc_Sha384Free(wc_Sha384* sha)
00131         {
00132             (void)sha;
00133             /* Not supported in FIPS */
00134         }
00135     #endif /* WOLFSSL_SHA384 || HAVE_AESGCM */
00136 
00137 #else /* else build without fips, or for FIPS v2 */
00138 
00139 #include <wolfssl/wolfcrypt/logging.h >
00140 
00141 #ifdef NO_INLINE
00142     #include <wolfssl/wolfcrypt/misc.h>
00143 #else
00144     #define WOLFSSL_MISC_INCLUDED
00145     #include <wolfcrypt/src/misc.c>
00146 #endif
00147 
00148 
00149 #if defined(USE_INTEL_SPEEDUP)
00150     #if defined(__GNUC__) && ((__GNUC__ < 4) || \
00151                               (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
00152         #undef  NO_AVX2_SUPPORT
00153         #define NO_AVX2_SUPPORT
00154     #endif
00155     #if defined(__clang__) && ((__clang_major__ < 3) || \
00156                                (__clang_major__ == 3 && __clang_minor__ <= 5))
00157         #define NO_AVX2_SUPPORT
00158     #elif defined(__clang__) && defined(NO_AVX2_SUPPORT)
00159         #undef NO_AVX2_SUPPORT
00160     #endif
00161 
00162     #define HAVE_INTEL_AVX1
00163     #ifndef NO_AVX2_SUPPORT
00164         #define HAVE_INTEL_AVX2
00165     #endif
00166 #endif
00167 
00168 #if defined(HAVE_INTEL_AVX1)
00169     /* #define DEBUG_XMM  */
00170 #endif
00171 
00172 #if defined(HAVE_INTEL_AVX2)
00173     #define HAVE_INTEL_RORX
00174     /* #define DEBUG_YMM  */
00175 #endif
00176 
00177 #if defined(HAVE_BYTEREVERSE64) && \
00178         !defined(HAVE_INTEL_AVX1) && !defined(HAVE_INTEL_AVX2)
00179     #define ByteReverseWords64(out, in, size) ByteReverseWords64_1(out, size)
00180     #define ByteReverseWords64_1(buf, size) \
00181         { unsigned int i ;\
00182             for(i=0; i< size/sizeof(word64); i++){\
00183                 __asm__ volatile("bswapq %0":"+r"(buf[i])::) ;\
00184             }\
00185         }
00186 #endif
00187 
00188 #if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
00189     /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
00190 
00191 #else
00192 
00193 #ifdef WOLFSSL_SHA512
00194 
00195 static int InitSha512(wc_Sha512* sha512)
00196 {
00197     if (sha512 == NULL)
00198         return BAD_FUNC_ARG;
00199 
00200     sha512->digest[0] = W64LIT(0x6a09e667f3bcc908);
00201     sha512->digest[1] = W64LIT(0xbb67ae8584caa73b);
00202     sha512->digest[2] = W64LIT(0x3c6ef372fe94f82b);
00203     sha512->digest[3] = W64LIT(0xa54ff53a5f1d36f1);
00204     sha512->digest[4] = W64LIT(0x510e527fade682d1);
00205     sha512->digest[5] = W64LIT(0x9b05688c2b3e6c1f);
00206     sha512->digest[6] = W64LIT(0x1f83d9abfb41bd6b);
00207     sha512->digest[7] = W64LIT(0x5be0cd19137e2179);
00208 
00209     sha512->buffLen = 0;
00210     sha512->loLen   = 0;
00211     sha512->hiLen   = 0;
00212 
00213 #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
00214     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00215 
00216     sha512->ctx.sha_type = SHA2_512;
00217      /* always start firstblock = 1 when using hw engine */
00218     sha512->ctx.isfirstblock = 1;
00219     if(sha512->ctx.mode == ESP32_SHA_HW) {
00220         /* release hw */
00221         esp_sha_hw_unlock();
00222     }
00223     /* always set mode as INIT
00224     *  whether using HW or SW is determined at first call of update()
00225     */
00226     sha512->ctx.mode = ESP32_SHA_INIT;
00227 #endif
00228 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
00229     sha512->flags = 0;
00230 #endif
00231     return 0;
00232 }
00233 
00234 #endif /* WOLFSSL_SHA512 */
00235 
00236 /* Hardware Acceleration */
00237 #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00238 
00239 #ifdef WOLFSSL_SHA512
00240 
00241     /*****
00242     Intel AVX1/AVX2 Macro Control Structure
00243 
00244     #if defined(HAVE_INteL_SPEEDUP)
00245         #define HAVE_INTEL_AVX1
00246         #define HAVE_INTEL_AVX2
00247     #endif
00248 
00249     int InitSha512(wc_Sha512* sha512) {
00250          Save/Recover XMM, YMM
00251          ...
00252 
00253          Check Intel AVX cpuid flags
00254     }
00255 
00256     #if defined(HAVE_INTEL_AVX1)|| defined(HAVE_INTEL_AVX2)
00257       Transform_Sha512_AVX1(); # Function prototype
00258       Transform_Sha512_AVX2(); #
00259     #endif
00260 
00261       _Transform_Sha512() {     # Native Transform Function body
00262 
00263       }
00264 
00265       int Sha512Update() {
00266          Save/Recover XMM, YMM
00267          ...
00268       }
00269 
00270       int Sha512Final() {
00271          Save/Recover XMM, YMM
00272          ...
00273       }
00274 
00275 
00276     #if defined(HAVE_INTEL_AVX1)
00277 
00278        XMM Instructions/INLINE asm Definitions
00279 
00280     #endif
00281 
00282     #if defined(HAVE_INTEL_AVX2)
00283 
00284        YMM Instructions/INLINE asm Definitions
00285 
00286     #endif
00287 
00288     #if defnied(HAVE_INTEL_AVX1)
00289 
00290       int Transform_Sha512_AVX1() {
00291           Stitched Message Sched/Round
00292       }
00293 
00294     #endif
00295 
00296     #if defnied(HAVE_INTEL_AVX2)
00297 
00298       int Transform_Sha512_AVX2() {
00299           Stitched Message Sched/Round
00300       }
00301     #endif
00302 
00303     */
00304 
00305 
00306     /* Each platform needs to query info type 1 from cpuid to see if aesni is
00307      * supported. Also, let's setup a macro for proper linkage w/o ABI conflicts
00308      */
00309 
00310 #ifdef __cplusplus
00311     extern "C" {
00312 #endif
00313 
00314     #if defined(HAVE_INTEL_AVX1)
00315         extern int Transform_Sha512_AVX1(wc_Sha512 *sha512);
00316         extern int Transform_Sha512_AVX1_Len(wc_Sha512 *sha512, word32 len);
00317     #endif
00318     #if defined(HAVE_INTEL_AVX2)
00319         extern int Transform_Sha512_AVX2(wc_Sha512 *sha512);
00320         extern int Transform_Sha512_AVX2_Len(wc_Sha512 *sha512, word32 len);
00321         #if defined(HAVE_INTEL_RORX)
00322             extern int Transform_Sha512_AVX1_RORX(wc_Sha512 *sha512);
00323             extern int Transform_Sha512_AVX1_RORX_Len(wc_Sha512 *sha512,
00324                                                       word32 len);
00325             extern int Transform_Sha512_AVX2_RORX(wc_Sha512 *sha512);
00326             extern int Transform_Sha512_AVX2_RORX_Len(wc_Sha512 *sha512,
00327                                                       word32 len);
00328         #endif
00329     #endif
00330 
00331 #ifdef __cplusplus
00332     }  /* extern "C" */
00333 #endif
00334 
00335     static int _Transform_Sha512(wc_Sha512 *sha512);
00336     static int (*Transform_Sha512_p)(wc_Sha512* sha512) = _Transform_Sha512;
00337     static int (*Transform_Sha512_Len_p)(wc_Sha512* sha512, word32 len) = NULL;
00338     static int transform_check = 0;
00339     static int intel_flags;
00340     #define Transform_Sha512(sha512)     (*Transform_Sha512_p)(sha512)
00341     #define Transform_Sha512_Len(sha512, len) \
00342                                           (*Transform_Sha512_Len_p)(sha512, len)
00343 
00344     static void Sha512_SetTransform()
00345     {
00346         if (transform_check)
00347             return;
00348 
00349         intel_flags = cpuid_get_flags();
00350 
00351     #if defined(HAVE_INTEL_AVX2)
00352         if (IS_INTEL_AVX2(intel_flags)) {
00353         #ifdef HAVE_INTEL_RORX
00354             if (IS_INTEL_BMI2(intel_flags)) {
00355                 Transform_Sha512_p = Transform_Sha512_AVX2_RORX;
00356                 Transform_Sha512_Len_p = Transform_Sha512_AVX2_RORX_Len;
00357             }
00358             else
00359         #endif
00360             if (1) {
00361                 Transform_Sha512_p = Transform_Sha512_AVX2;
00362                 Transform_Sha512_Len_p = Transform_Sha512_AVX2_Len;
00363             }
00364         #ifdef HAVE_INTEL_RORX
00365             else {
00366                 Transform_Sha512_p = Transform_Sha512_AVX1_RORX;
00367                 Transform_Sha512_Len_p = Transform_Sha512_AVX1_RORX_Len;
00368             }
00369         #endif
00370         }
00371         else
00372     #endif
00373     #if defined(HAVE_INTEL_AVX1)
00374         if (IS_INTEL_AVX1(intel_flags)) {
00375             Transform_Sha512_p = Transform_Sha512_AVX1;
00376             Transform_Sha512_Len_p = Transform_Sha512_AVX1_Len;
00377         }
00378         else
00379     #endif
00380             Transform_Sha512_p = _Transform_Sha512;
00381 
00382         transform_check = 1;
00383     }
00384 #endif /* WOLFSSL_SHA512 */
00385 
00386 #else
00387     #define Transform_Sha512(sha512) _Transform_Sha512(sha512)
00388 
00389 #endif
00390 
00391 #ifdef WOLFSSL_SHA512
00392 
00393 int wc_InitSha512_ex(wc_Sha512* sha512, void* heap, int devId)
00394 {
00395     int ret = 0;
00396 
00397     if (sha512 == NULL)
00398         return BAD_FUNC_ARG;
00399 
00400     sha512->heap = heap;
00401 
00402     ret = InitSha512(sha512);
00403     if (ret != 0)
00404         return ret;
00405 
00406 #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00407     Sha512_SetTransform();
00408 #endif
00409 
00410 #ifdef WOLFSSL_SMALL_STACK_CACHE
00411     sha512->W = NULL;
00412 #endif
00413 
00414 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
00415     ret = wolfAsync_DevCtxInit(&sha512->asyncDev,
00416                         WOLFSSL_ASYNC_MARKER_SHA512, sha512->heap, devId);
00417 #else
00418     (void)devId;
00419 #endif /* WOLFSSL_ASYNC_CRYPT */
00420 
00421     return ret;
00422 }
00423 
00424 #endif /* WOLFSSL_SHA512 */
00425 
00426 
00427 static const word64 K512[80] = {
00428     W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd),
00429     W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc),
00430     W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019),
00431     W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118),
00432     W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe),
00433     W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2),
00434     W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1),
00435     W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694),
00436     W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3),
00437     W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65),
00438     W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483),
00439     W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5),
00440     W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210),
00441     W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4),
00442     W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725),
00443     W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70),
00444     W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926),
00445     W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df),
00446     W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8),
00447     W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b),
00448     W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001),
00449     W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30),
00450     W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910),
00451     W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8),
00452     W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53),
00453     W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8),
00454     W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb),
00455     W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3),
00456     W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60),
00457     W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec),
00458     W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9),
00459     W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b),
00460     W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207),
00461     W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178),
00462     W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6),
00463     W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b),
00464     W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493),
00465     W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c),
00466     W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a),
00467     W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817)
00468 };
00469 
00470 #define blk0(i) (W[i] = sha512->buffer[i])
00471 
00472 #define blk2(i) (\
00473                W[ i     & 15] += \
00474             s1(W[(i-2)  & 15])+ \
00475                W[(i-7)  & 15] + \
00476             s0(W[(i-15) & 15])  \
00477         )
00478 
00479 #define Ch(x,y,z)  (z ^ (x & (y ^ z)))
00480 #define Maj(x,y,z) ((x & y) | (z & (x | y)))
00481 
00482 #define a(i) T[(0-i) & 7]
00483 #define b(i) T[(1-i) & 7]
00484 #define c(i) T[(2-i) & 7]
00485 #define d(i) T[(3-i) & 7]
00486 #define e(i) T[(4-i) & 7]
00487 #define f(i) T[(5-i) & 7]
00488 #define g(i) T[(6-i) & 7]
00489 #define h(i) T[(7-i) & 7]
00490 
00491 #define S0(x) (rotrFixed64(x,28) ^ rotrFixed64(x,34) ^ rotrFixed64(x,39))
00492 #define S1(x) (rotrFixed64(x,14) ^ rotrFixed64(x,18) ^ rotrFixed64(x,41))
00493 #define s0(x) (rotrFixed64(x,1)  ^ rotrFixed64(x,8)  ^ (x>>7))
00494 #define s1(x) (rotrFixed64(x,19) ^ rotrFixed64(x,61) ^ (x>>6))
00495 
00496 #define R(i) \
00497     h(i) += S1(e(i)) + Ch(e(i),f(i),g(i)) + K[i+j] + (j ? blk2(i) : blk0(i)); \
00498     d(i) += h(i); \
00499     h(i) += S0(a(i)) + Maj(a(i),b(i),c(i))
00500 
00501 static int _Transform_Sha512(wc_Sha512* sha512)
00502 {
00503     const word64* K = K512;
00504     word32 j;
00505     word64 T[8];
00506 
00507 #ifdef WOLFSSL_SMALL_STACK_CACHE
00508     word64* W = sha512->W;
00509     if (W == NULL) {
00510         W = (word64*) XMALLOC(sizeof(word64) * 16, NULL,
00511                                                        DYNAMIC_TYPE_TMP_BUFFER);
00512         if (W == NULL)
00513             return MEMORY_E;
00514         sha512->W = W;
00515     }
00516 #elif defined(WOLFSSL_SMALL_STACK)
00517     word64* W;
00518     W = (word64*) XMALLOC(sizeof(word64) * 16, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00519     if (W == NULL)
00520         return MEMORY_E;
00521 #else
00522     word64 W[16];
00523 #endif
00524 
00525     /* Copy digest to working vars */
00526     XMEMCPY(T, sha512->digest, sizeof(T));
00527 
00528 #ifdef USE_SLOW_SHA512
00529     /* over twice as small, but 50% slower */
00530     /* 80 operations, not unrolled */
00531     for (j = 0; j < 80; j += 16) {
00532         int m;
00533         for (m = 0; m < 16; m++) { /* braces needed here for macros {} */
00534             R(m);
00535         }
00536     }
00537 #else
00538     /* 80 operations, partially loop unrolled */
00539     for (j = 0; j < 80; j += 16) {
00540         R( 0); R( 1); R( 2); R( 3);
00541         R( 4); R( 5); R( 6); R( 7);
00542         R( 8); R( 9); R(10); R(11);
00543         R(12); R(13); R(14); R(15);
00544     }
00545 #endif /* USE_SLOW_SHA512 */
00546 
00547     /* Add the working vars back into digest */
00548     sha512->digest[0] += a(0);
00549     sha512->digest[1] += b(0);
00550     sha512->digest[2] += c(0);
00551     sha512->digest[3] += d(0);
00552     sha512->digest[4] += e(0);
00553     sha512->digest[5] += f(0);
00554     sha512->digest[6] += g(0);
00555     sha512->digest[7] += h(0);
00556 
00557     /* Wipe variables */
00558     ForceZero(W, sizeof(word64) * 16);
00559     ForceZero(T, sizeof(T));
00560 
00561 #if defined(WOLFSSL_SMALL_STACK) && !defined(WOLFSSL_SMALL_STACK_CACHE)
00562     XFREE(W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00563 #endif
00564 
00565     return 0;
00566 }
00567 
00568 
00569 static WC_INLINE void AddLength(wc_Sha512* sha512, word32 len)
00570 {
00571     word64 tmp = sha512->loLen;
00572     if ( (sha512->loLen += len) < tmp)
00573         sha512->hiLen++;                       /* carry low to high */
00574 }
00575 
00576 static WC_INLINE int Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
00577 {
00578     int ret = 0;
00579     /* do block size increments */
00580     byte* local = (byte*)sha512->buffer;
00581 
00582     /* check that internal buffLen is valid */
00583     if (sha512->buffLen >= WC_SHA512_BLOCK_SIZE)
00584         return BUFFER_E;
00585 
00586     AddLength(sha512, len);
00587 
00588     if (sha512->buffLen > 0) {
00589         word32 add = min(len, WC_SHA512_BLOCK_SIZE - sha512->buffLen);
00590         if (add > 0) {
00591             XMEMCPY(&local[sha512->buffLen], data, add);
00592 
00593             sha512->buffLen += add;
00594             data            += add;
00595             len             -= add;
00596         }
00597 
00598         if (sha512->buffLen == WC_SHA512_BLOCK_SIZE) {
00599     #if defined(LITTLE_ENDIAN_ORDER)
00600         #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00601             if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
00602         #endif
00603             {
00604         #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00605              defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00606                 ByteReverseWords64(sha512->buffer, sha512->buffer,
00607                                                          WC_SHA512_BLOCK_SIZE);
00608         #endif
00609             }
00610     #endif
00611     #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00612          defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00613             ret = Transform_Sha512(sha512);
00614     #else
00615             if(sha512->ctx.mode == ESP32_SHA_INIT) {
00616                 esp_sha_try_hw_lock(&sha512->ctx);
00617             }
00618             ret = esp_sha512_process(sha512);
00619             if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){
00620                 ret = Transform_Sha512(sha512);
00621             }
00622     #endif
00623             if (ret == 0)
00624                 sha512->buffLen = 0;
00625             else
00626                 len = 0;
00627         }
00628     }
00629 
00630 #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00631     if (Transform_Sha512_Len_p != NULL) {
00632         word32 blocksLen = len & ~(WC_SHA512_BLOCK_SIZE-1);
00633 
00634         if (blocksLen > 0) {
00635             sha512->data = data;
00636             /* Byte reversal performed in function if required. */
00637             Transform_Sha512_Len(sha512, blocksLen);
00638             data += blocksLen;
00639             len  -= blocksLen;
00640         }
00641     }
00642     else
00643 #endif
00644 #if !defined(LITTLE_ENDIAN_ORDER) || defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00645     {
00646         while (len >= WC_SHA512_BLOCK_SIZE) {
00647             XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
00648 
00649             data += WC_SHA512_BLOCK_SIZE;
00650             len  -= WC_SHA512_BLOCK_SIZE;
00651 
00652         #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00653             if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
00654             {
00655                 ByteReverseWords64(sha512->buffer, sha512->buffer,
00656                                                           WC_SHA512_BLOCK_SIZE);
00657             }
00658         #endif
00659             /* Byte reversal performed in function if required. */
00660             ret = Transform_Sha512(sha512);
00661             if (ret != 0)
00662                 break;
00663         }
00664     }
00665 #else
00666     {
00667         while (len >= WC_SHA512_BLOCK_SIZE) {
00668             XMEMCPY(local, data, WC_SHA512_BLOCK_SIZE);
00669 
00670             data += WC_SHA512_BLOCK_SIZE;
00671             len  -= WC_SHA512_BLOCK_SIZE;
00672     #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00673          defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00674             ByteReverseWords64(sha512->buffer, sha512->buffer,
00675                                                        WC_SHA512_BLOCK_SIZE);
00676     #endif
00677     #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00678          defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00679             ret = Transform_Sha512(sha512);
00680     #else
00681             if(sha512->ctx.mode == ESP32_SHA_INIT) {
00682                 esp_sha_try_hw_lock(&sha512->ctx);
00683             }
00684             ret = esp_sha512_process(sha512);
00685             if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){
00686                 ret = Transform_Sha512(sha512);
00687             }
00688     #endif
00689             if (ret != 0)
00690                 break;
00691         }
00692     }
00693 #endif
00694 
00695     if (len > 0) {
00696         XMEMCPY(local, data, len);
00697         sha512->buffLen = len;
00698     }
00699 
00700     return ret;
00701 }
00702 
00703 #ifdef WOLFSSL_SHA512
00704 
00705 int wc_Sha512Update(wc_Sha512* sha512, const byte* data, word32 len)
00706 {
00707     if (sha512 == NULL || (data == NULL && len > 0)) {
00708         return BAD_FUNC_ARG;
00709     }
00710 
00711 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
00712     if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {
00713     #if defined(HAVE_INTEL_QA)
00714         return IntelQaSymSha512(&sha512->asyncDev, NULL, data, len);
00715     #endif
00716     }
00717 #endif /* WOLFSSL_ASYNC_CRYPT */
00718 
00719     return Sha512Update(sha512, data, len);
00720 }
00721 
00722 #endif /* WOLFSSL_SHA512 */
00723 
00724 #endif /* WOLFSSL_IMX6_CAAM */
00725 
00726 static WC_INLINE int Sha512Final(wc_Sha512* sha512)
00727 {
00728     byte* local = (byte*)sha512->buffer;
00729     int ret;
00730 
00731     if (sha512 == NULL) {
00732         return BAD_FUNC_ARG;
00733     }
00734 
00735     local[sha512->buffLen++] = 0x80;  /* add 1 */
00736 
00737     /* pad with zeros */
00738     if (sha512->buffLen > WC_SHA512_PAD_SIZE) {
00739         XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_BLOCK_SIZE - sha512->buffLen);
00740         sha512->buffLen += WC_SHA512_BLOCK_SIZE - sha512->buffLen;
00741 #if defined(LITTLE_ENDIAN_ORDER)
00742     #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00743         if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
00744     #endif
00745         {
00746 
00747        #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00748             defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00749             ByteReverseWords64(sha512->buffer,sha512->buffer,
00750                                                          WC_SHA512_BLOCK_SIZE);
00751        #endif
00752         }
00753 #endif /* LITTLE_ENDIAN_ORDER */
00754 #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00755      defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00756         ret = Transform_Sha512(sha512);
00757 #else
00758        if(sha512->ctx.mode == ESP32_SHA_INIT) {
00759             esp_sha_try_hw_lock(&sha512->ctx);
00760        }
00761         ret = esp_sha512_process(sha512);
00762         if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW){
00763             ret = Transform_Sha512(sha512);
00764         }
00765 #endif
00766         if (ret != 0)
00767             return ret;
00768 
00769         sha512->buffLen = 0;
00770     }
00771     XMEMSET(&local[sha512->buffLen], 0, WC_SHA512_PAD_SIZE - sha512->buffLen);
00772 
00773     /* put lengths in bits */
00774     sha512->hiLen = (sha512->loLen >> (8 * sizeof(sha512->loLen) - 3)) +
00775                                                          (sha512->hiLen << 3);
00776     sha512->loLen = sha512->loLen << 3;
00777 
00778     /* store lengths */
00779 #if defined(LITTLE_ENDIAN_ORDER)
00780     #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00781         if (!IS_INTEL_AVX1(intel_flags) && !IS_INTEL_AVX2(intel_flags))
00782     #endif
00783     #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00784          defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00785             ByteReverseWords64(sha512->buffer, sha512->buffer, WC_SHA512_PAD_SIZE);
00786     #endif
00787 #endif
00788     /* ! length ordering dependent on digest endian type ! */
00789 
00790 #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00791      defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00792     sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2] = sha512->hiLen;
00793     sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 1] = sha512->loLen;
00794 #endif
00795 
00796 #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
00797     if (IS_INTEL_AVX1(intel_flags) || IS_INTEL_AVX2(intel_flags))
00798         ByteReverseWords64(&(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
00799                            &(sha512->buffer[WC_SHA512_BLOCK_SIZE / sizeof(word64) - 2]),
00800                            WC_SHA512_BLOCK_SIZE - WC_SHA512_PAD_SIZE);
00801 #endif
00802 #if !defined(WOLFSSL_ESP32WROOM32_CRYPT) || \
00803     defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00804     ret = Transform_Sha512(sha512);
00805 #else
00806     if(sha512->ctx.mode == ESP32_SHA_INIT) {
00807         esp_sha_try_hw_lock(&sha512->ctx);
00808     }
00809     ret = esp_sha512_digest_process(sha512, 1);
00810     if(ret == 0 && sha512->ctx.mode == ESP32_SHA_SW) {
00811         ret = Transform_Sha512(sha512);
00812     }
00813 #endif
00814     if (ret != 0)
00815         return ret;
00816 
00817     #ifdef LITTLE_ENDIAN_ORDER
00818         ByteReverseWords64(sha512->digest, sha512->digest, WC_SHA512_DIGEST_SIZE);
00819     #endif
00820 
00821     return 0;
00822 }
00823 
00824 #ifdef WOLFSSL_SHA512
00825 
00826 int wc_Sha512FinalRaw(wc_Sha512* sha512, byte* hash)
00827 {
00828 #ifdef LITTLE_ENDIAN_ORDER
00829     word64 digest[WC_SHA512_DIGEST_SIZE / sizeof(word64)];
00830 #endif
00831 
00832     if (sha512 == NULL || hash == NULL) {
00833         return BAD_FUNC_ARG;
00834     }
00835 
00836 #ifdef LITTLE_ENDIAN_ORDER
00837     ByteReverseWords64((word64*)digest, (word64*)sha512->digest,
00838                                                          WC_SHA512_DIGEST_SIZE);
00839     XMEMCPY(hash, digest, WC_SHA512_DIGEST_SIZE);
00840 #else
00841     XMEMCPY(hash, sha512->digest, WC_SHA512_DIGEST_SIZE);
00842 #endif
00843 
00844     return 0;
00845 }
00846 
00847 int wc_Sha512Final(wc_Sha512* sha512, byte* hash)
00848 {
00849     int ret;
00850 
00851     if (sha512 == NULL || hash == NULL) {
00852         return BAD_FUNC_ARG;
00853     }
00854 
00855 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
00856     if (sha512->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA512) {
00857     #if defined(HAVE_INTEL_QA)
00858         return IntelQaSymSha512(&sha512->asyncDev, hash, NULL,
00859                                             WC_SHA512_DIGEST_SIZE);
00860     #endif
00861     }
00862 #endif /* WOLFSSL_ASYNC_CRYPT */
00863 
00864     ret = Sha512Final(sha512);
00865     if (ret != 0)
00866         return ret;
00867 
00868     XMEMCPY(hash, sha512->digest, WC_SHA512_DIGEST_SIZE);
00869 
00870     return InitSha512(sha512);  /* reset state */
00871 }
00872 
00873 int wc_InitSha512(wc_Sha512* sha512)
00874 {
00875     return wc_InitSha512_ex(sha512, NULL, INVALID_DEVID);
00876 }
00877 
00878 void wc_Sha512Free(wc_Sha512* sha512)
00879 {
00880     if (sha512 == NULL)
00881         return;
00882 
00883 #ifdef WOLFSSL_SMALL_STACK_CACHE
00884     if (sha512->W != NULL) {
00885         XFREE(sha512->W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
00886         sha512->W = NULL;
00887     }
00888 #endif
00889 
00890 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA512)
00891     wolfAsync_DevCtxFree(&sha512->asyncDev, WOLFSSL_ASYNC_MARKER_SHA512);
00892 #endif /* WOLFSSL_ASYNC_CRYPT */
00893 }
00894 
00895 #endif /* WOLFSSL_SHA512 */
00896 
00897 /* -------------------------------------------------------------------------- */
00898 /* SHA384 */
00899 /* -------------------------------------------------------------------------- */
00900 #ifdef WOLFSSL_SHA384
00901 
00902 #if defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH)
00903     /* functions defined in wolfcrypt/src/port/caam/caam_sha.c */
00904 
00905 #else
00906 
00907 static int InitSha384(wc_Sha384* sha384)
00908 {
00909     if (sha384 == NULL) {
00910         return BAD_FUNC_ARG;
00911     }
00912 
00913     sha384->digest[0] = W64LIT(0xcbbb9d5dc1059ed8);
00914     sha384->digest[1] = W64LIT(0x629a292a367cd507);
00915     sha384->digest[2] = W64LIT(0x9159015a3070dd17);
00916     sha384->digest[3] = W64LIT(0x152fecd8f70e5939);
00917     sha384->digest[4] = W64LIT(0x67332667ffc00b31);
00918     sha384->digest[5] = W64LIT(0x8eb44a8768581511);
00919     sha384->digest[6] = W64LIT(0xdb0c2e0d64f98fa7);
00920     sha384->digest[7] = W64LIT(0x47b5481dbefa4fa4);
00921 
00922     sha384->buffLen = 0;
00923     sha384->loLen   = 0;
00924     sha384->hiLen   = 0;
00925 
00926 #if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
00927     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
00928     sha384->ctx.sha_type = SHA2_384;
00929      /* always start firstblock = 1 when using hw engine */
00930     sha384->ctx.isfirstblock = 1;
00931     if(sha384->ctx.mode == ESP32_SHA_HW) {
00932         /* release hw */
00933         esp_sha_hw_unlock();
00934     }
00935     /* always set mode as INIT
00936     *  whether using HW or SW is determined at first call of update()
00937     */
00938     sha384->ctx.mode = ESP32_SHA_INIT;
00939 
00940 #endif
00941 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
00942     sha384->flags = 0;
00943 #endif
00944 
00945     return 0;
00946 }
00947 
00948 int wc_Sha384Update(wc_Sha384* sha384, const byte* data, word32 len)
00949 {
00950     if (sha384 == NULL || (data == NULL && len > 0)) {
00951         return BAD_FUNC_ARG;
00952     }
00953 
00954 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
00955     if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {
00956     #if defined(HAVE_INTEL_QA)
00957         return IntelQaSymSha384(&sha384->asyncDev, NULL, data, len);
00958     #endif
00959     }
00960 #endif /* WOLFSSL_ASYNC_CRYPT */
00961 
00962     return Sha512Update((wc_Sha512*)sha384, data, len);
00963 }
00964 
00965 
00966 int wc_Sha384FinalRaw(wc_Sha384* sha384, byte* hash)
00967 {
00968 #ifdef LITTLE_ENDIAN_ORDER
00969     word64 digest[WC_SHA384_DIGEST_SIZE / sizeof(word64)];
00970 #endif
00971 
00972     if (sha384 == NULL || hash == NULL) {
00973         return BAD_FUNC_ARG;
00974     }
00975 
00976 #ifdef LITTLE_ENDIAN_ORDER
00977     ByteReverseWords64((word64*)digest, (word64*)sha384->digest,
00978                                                          WC_SHA384_DIGEST_SIZE);
00979     XMEMCPY(hash, digest, WC_SHA384_DIGEST_SIZE);
00980 #else
00981     XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
00982 #endif
00983 
00984     return 0;
00985 }
00986 
00987 int wc_Sha384Final(wc_Sha384* sha384, byte* hash)
00988 {
00989     int ret;
00990 
00991     if (sha384 == NULL || hash == NULL) {
00992         return BAD_FUNC_ARG;
00993     }
00994 
00995 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
00996     if (sha384->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA384) {
00997     #if defined(HAVE_INTEL_QA)
00998         return IntelQaSymSha384(&sha384->asyncDev, hash, NULL,
00999                                             WC_SHA384_DIGEST_SIZE);
01000     #endif
01001     }
01002 #endif /* WOLFSSL_ASYNC_CRYPT */
01003 
01004     ret = Sha512Final((wc_Sha512*)sha384);
01005     if (ret != 0)
01006         return ret;
01007 
01008     XMEMCPY(hash, sha384->digest, WC_SHA384_DIGEST_SIZE);
01009 
01010     return InitSha384(sha384);  /* reset state */
01011 }
01012 
01013 int wc_InitSha384_ex(wc_Sha384* sha384, void* heap, int devId)
01014 {
01015     int ret;
01016 
01017     if (sha384 == NULL) {
01018         return BAD_FUNC_ARG;
01019     }
01020 
01021     sha384->heap = heap;
01022     ret = InitSha384(sha384);
01023     if (ret != 0)
01024         return ret;
01025 
01026 #if defined(HAVE_INTEL_AVX1) || defined(HAVE_INTEL_AVX2)
01027     Sha512_SetTransform();
01028 #endif
01029 #ifdef WOLFSSL_SMALL_STACK_CACHE
01030     sha384->W = NULL;
01031 #endif
01032 
01033 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
01034     ret = wolfAsync_DevCtxInit(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384,
01035                                                            sha384->heap, devId);
01036 #else
01037     (void)devId;
01038 #endif /* WOLFSSL_ASYNC_CRYPT */
01039 
01040     return ret;
01041 }
01042 
01043 #endif /* WOLFSSL_IMX6_CAAM */
01044 
01045 int wc_InitSha384(wc_Sha384* sha384)
01046 {
01047     return wc_InitSha384_ex(sha384, NULL, INVALID_DEVID);
01048 }
01049 
01050 void wc_Sha384Free(wc_Sha384* sha384)
01051 {
01052     if (sha384 == NULL)
01053         return;
01054 
01055 #ifdef WOLFSSL_SMALL_STACK_CACHE
01056     if (sha384->W != NULL) {
01057         XFREE(sha384->W, NULL, DYNAMIC_TYPE_TMP_BUFFER);
01058         sha384->W = NULL;
01059     }
01060 #endif
01061 
01062 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA384)
01063     wolfAsync_DevCtxFree(&sha384->asyncDev, WOLFSSL_ASYNC_MARKER_SHA384);
01064 #endif /* WOLFSSL_ASYNC_CRYPT */
01065 }
01066 
01067 #endif /* WOLFSSL_SHA384 */
01068 
01069 #endif /* HAVE_FIPS */
01070 
01071 #ifdef WOLFSSL_SHA512
01072 
01073 int wc_Sha512GetHash(wc_Sha512* sha512, byte* hash)
01074 {
01075     int ret;
01076     wc_Sha512 tmpSha512;
01077 
01078     if (sha512 == NULL || hash == NULL)
01079         return BAD_FUNC_ARG;
01080 
01081 #if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
01082     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
01083     if(sha512->ctx.mode == ESP32_SHA_INIT) {
01084         esp_sha_try_hw_lock(&sha512->ctx);
01085     }
01086     if(sha512->ctx.mode != ESP32_SHA_SW)
01087        esp_sha512_digest_process(sha512, 0);
01088 #endif
01089 
01090     ret = wc_Sha512Copy(sha512, &tmpSha512);
01091     if (ret == 0) {
01092         ret = wc_Sha512Final(&tmpSha512, hash);
01093 #if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
01094     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
01095         sha512->ctx.mode = ESP32_SHA_SW;;
01096 #endif
01097         wc_Sha512Free(&tmpSha512);
01098     }
01099     return ret;
01100 }
01101 
01102 int wc_Sha512Copy(wc_Sha512* src, wc_Sha512* dst)
01103 {
01104     int ret = 0;
01105 
01106     if (src == NULL || dst == NULL)
01107         return BAD_FUNC_ARG;
01108 
01109     XMEMCPY(dst, src, sizeof(wc_Sha512));
01110 #ifdef WOLFSSL_SMALL_STACK_CACHE
01111     dst->W = NULL;
01112 #endif
01113 
01114 #ifdef WOLFSSL_ASYNC_CRYPT
01115     ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
01116 #endif
01117 #if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
01118     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
01119     dst->ctx.mode = src->ctx.mode;
01120     dst->ctx.isfirstblock = src->ctx.isfirstblock;
01121     dst->ctx.sha_type = src->ctx.sha_type;
01122 #endif
01123 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
01124      dst->flags |= WC_HASH_FLAG_ISCOPY;
01125 #endif
01126 
01127     return ret;
01128 }
01129 
01130 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
01131 int wc_Sha512SetFlags(wc_Sha512* sha512, word32 flags)
01132 {
01133     if (sha512) {
01134         sha512->flags = flags;
01135     }
01136     return 0;
01137 }
01138 int wc_Sha512GetFlags(wc_Sha512* sha512, word32* flags)
01139 {
01140     if (sha512 && flags) {
01141         *flags = sha512->flags;
01142     }
01143     return 0;
01144 }
01145 #endif
01146 
01147 #endif /* WOLFSSL_SHA512 */
01148 
01149 #ifdef WOLFSSL_SHA384
01150 
01151 int wc_Sha384GetHash(wc_Sha384* sha384, byte* hash)
01152 {
01153     int ret;
01154     wc_Sha384 tmpSha384;
01155 
01156     if (sha384 == NULL || hash == NULL)
01157         return BAD_FUNC_ARG;
01158 #if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
01159     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
01160     if(sha384->ctx.mode == ESP32_SHA_INIT) {
01161         esp_sha_try_hw_lock(&sha384->ctx);
01162     }
01163     if(sha384->ctx.mode != ESP32_SHA_SW) {
01164         esp_sha512_digest_process(sha384, 0);
01165     }
01166 #endif
01167     ret = wc_Sha384Copy(sha384, &tmpSha384);
01168     if (ret == 0) {
01169         ret = wc_Sha384Final(&tmpSha384, hash);
01170 #if  defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
01171     !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
01172         sha384->ctx.mode = ESP32_SHA_SW;
01173 #endif
01174         wc_Sha384Free(&tmpSha384);
01175     }
01176     return ret;
01177 }
01178 int wc_Sha384Copy(wc_Sha384* src, wc_Sha384* dst)
01179 {
01180     int ret = 0;
01181 
01182     if (src == NULL || dst == NULL)
01183         return BAD_FUNC_ARG;
01184 
01185     XMEMCPY(dst, src, sizeof(wc_Sha384));
01186 #ifdef WOLFSSL_SMALL_STACK_CACHE
01187     dst->W = NULL;
01188 #endif
01189 
01190 #ifdef WOLFSSL_ASYNC_CRYPT
01191     ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
01192 #endif
01193 #if defined(WOLFSSL_ESP32WROOM32_CRYPT) && \
01194    !defined(NO_WOLFSSL_ESP32WROOM32_CRYPT_HASH)
01195     dst->ctx.mode = src->ctx.mode;
01196     dst->ctx.isfirstblock = src->ctx.isfirstblock;
01197     dst->ctx.sha_type = src->ctx.sha_type;
01198 #endif
01199 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
01200      dst->flags |= WC_HASH_FLAG_ISCOPY;
01201 #endif
01202 
01203     return ret;
01204 }
01205 
01206 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB)
01207 int wc_Sha384SetFlags(wc_Sha384* sha384, word32 flags)
01208 {
01209     if (sha384) {
01210         sha384->flags = flags;
01211     }
01212     return 0;
01213 }
01214 int wc_Sha384GetFlags(wc_Sha384* sha384, word32* flags)
01215 {
01216     if (sha384 && flags) {
01217         *flags = sha384->flags;
01218     }
01219     return 0;
01220 }
01221 #endif
01222 
01223 #endif /* WOLFSSL_SHA384 */
01224 
01225 #endif /* WOLFSSL_SHA512 || WOLFSSL_SHA384 */
01226