Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
sha.c
00001 /* sha.c 00002 * 00003 * Copyright (C) 2006-2017 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 <wolfcrypt/settings.h> 00028 00029 #if !defined(NO_SHA) 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$j") 00039 #pragma const_seg(".fipsB$j") 00040 #endif 00041 #endif 00042 00043 #include <wolfcrypt/sha.h> 00044 #include <wolfcrypt/error-crypt.h> 00045 00046 /* fips wrapper calls, user can call direct */ 00047 #if defined(HAVE_FIPS) && \ 00048 (!defined(HAVE_FIPS_VERSION) || (HAVE_FIPS_VERSION < 2)) 00049 00050 int wc_InitSha(wc_Sha* sha) 00051 { 00052 if (sha == NULL) { 00053 return BAD_FUNC_ARG; 00054 } 00055 return InitSha_fips(sha); 00056 } 00057 int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) 00058 { 00059 (void)heap; 00060 (void)devId; 00061 if (sha == NULL) { 00062 return BAD_FUNC_ARG; 00063 } 00064 return InitSha_fips(sha); 00065 } 00066 00067 int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len) 00068 { 00069 if (sha == NULL || (data == NULL && len > 0)) { 00070 return BAD_FUNC_ARG; 00071 } 00072 return ShaUpdate_fips(sha, data, len); 00073 } 00074 00075 int wc_ShaFinal(wc_Sha* sha, byte* out) 00076 { 00077 if (sha == NULL || out == NULL) { 00078 return BAD_FUNC_ARG; 00079 } 00080 return ShaFinal_fips(sha,out); 00081 } 00082 void wc_ShaFree(wc_Sha* sha) 00083 { 00084 (void)sha; 00085 /* Not supported in FIPS */ 00086 } 00087 00088 #else /* else build without fips, or for FIPS v2 */ 00089 00090 00091 #if defined(WOLFSSL_TI_HASH) 00092 /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */ 00093 00094 #else 00095 00096 #include <wolfcrypt/logging.h> 00097 #ifdef NO_INLINE 00098 #include <wolfcrypt/misc.h> 00099 #else 00100 #define WOLFSSL_MISC_INCLUDED 00101 #include <wolfcrypt/src/misc.c> 00102 #endif 00103 00104 00105 /* Hardware Acceleration */ 00106 #if defined(WOLFSSL_PIC32MZ_HASH) 00107 #include <wolfcrypt/port/pic32/pic32mz-crypt.h> 00108 00109 #elif defined(STM32_HASH) 00110 00111 /* Supports CubeMX HAL or Standard Peripheral Library */ 00112 int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) 00113 { 00114 if (sha == NULL) { 00115 return BAD_FUNC_ARG; 00116 } 00117 00118 (void)devId; 00119 (void)heap; 00120 00121 wc_Stm32_Hash_Init(&sha->stmCtx); 00122 00123 return 0; 00124 } 00125 00126 int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len) 00127 { 00128 int ret; 00129 00130 if (sha == NULL || (data == NULL && len > 0)) { 00131 return BAD_FUNC_ARG; 00132 } 00133 00134 ret = wolfSSL_CryptHwMutexLock(); 00135 if (ret == 0) { 00136 ret = wc_Stm32_Hash_Update(&sha->stmCtx, HASH_AlgoSelection_SHA1, 00137 data, len); 00138 wolfSSL_CryptHwMutexUnLock(); 00139 } 00140 return ret; 00141 } 00142 00143 int wc_ShaFinal(wc_Sha* sha, byte* hash) 00144 { 00145 int ret; 00146 00147 if (sha == NULL || hash == NULL) { 00148 return BAD_FUNC_ARG; 00149 } 00150 00151 ret = wolfSSL_CryptHwMutexLock(); 00152 if (ret == 0) { 00153 ret = wc_Stm32_Hash_Final(&sha->stmCtx, HASH_AlgoSelection_SHA1, 00154 hash, WC_SHA_DIGEST_SIZE); 00155 wolfSSL_CryptHwMutexUnLock(); 00156 } 00157 00158 (void)wc_InitSha(sha); /* reset state */ 00159 00160 return ret; 00161 } 00162 00163 00164 #elif defined(FREESCALE_LTC_SHA) 00165 00166 #include "fsl_ltc.h" 00167 int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) 00168 { 00169 if (sha == NULL) { 00170 return BAD_FUNC_ARG; 00171 } 00172 00173 (void)devId; 00174 (void)heap; 00175 00176 LTC_HASH_Init(LTC_BASE, &sha->ctx, kLTC_Sha1, NULL, 0); 00177 return 0; 00178 } 00179 00180 int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len) 00181 { 00182 LTC_HASH_Update(&sha->ctx, data, len); 00183 return 0; 00184 } 00185 00186 int wc_ShaFinal(wc_Sha* sha, byte* hash) 00187 { 00188 uint32_t hashlen = WC_SHA_DIGEST_SIZE; 00189 LTC_HASH_Finish(&sha->ctx, hash, &hashlen); 00190 return wc_InitSha(sha); /* reset state */ 00191 } 00192 00193 00194 #elif defined(FREESCALE_MMCAU_SHA) 00195 00196 #ifdef FREESCALE_MMCAU_CLASSIC_SHA 00197 #include "cau_api.h" 00198 #else 00199 #include "fsl_mmcau.h" 00200 #endif 00201 00202 #define USE_SHA_SOFTWARE_IMPL /* Only for API's, actual transform is here */ 00203 #define XTRANSFORM(S,B) Transform((S),(B)) 00204 00205 static int InitSha(wc_Sha* sha) 00206 { 00207 int ret = 0; 00208 ret = wolfSSL_CryptHwMutexLock(); 00209 if (ret != 0) { 00210 return ret; 00211 } 00212 #ifdef FREESCALE_MMCAU_CLASSIC_SHA 00213 cau_sha1_initialize_output(sha->digest); 00214 #else 00215 MMCAU_SHA1_InitializeOutput((uint32_t*)sha->digest); 00216 #endif 00217 wolfSSL_CryptHwMutexUnLock(); 00218 00219 sha->buffLen = 0; 00220 sha->loLen = 0; 00221 sha->hiLen = 0; 00222 00223 return ret; 00224 } 00225 00226 static int Transform(wc_Sha* sha, byte* data) 00227 { 00228 int ret = wolfSSL_CryptHwMutexLock(); 00229 if(ret == 0) { 00230 #ifdef FREESCALE_MMCAU_CLASSIC_SHA 00231 cau_sha1_hash_n(data, 1, sha->digest); 00232 #else 00233 MMCAU_SHA1_HashN(data, 1, (uint32_t*)sha->digest); 00234 #endif 00235 wolfSSL_CryptHwMutexUnLock(); 00236 } 00237 return ret; 00238 } 00239 00240 #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) 00241 /* wolfcrypt/src/port/caam/caam_sha.c */ 00242 #else 00243 00244 /* Software implementation */ 00245 #define USE_SHA_SOFTWARE_IMPL 00246 00247 static int InitSha(wc_Sha* sha) 00248 { 00249 int ret = 0; 00250 00251 sha->digest[0] = 0x67452301L; 00252 sha->digest[1] = 0xEFCDAB89L; 00253 sha->digest[2] = 0x98BADCFEL; 00254 sha->digest[3] = 0x10325476L; 00255 sha->digest[4] = 0xC3D2E1F0L; 00256 00257 sha->buffLen = 0; 00258 sha->loLen = 0; 00259 sha->hiLen = 0; 00260 00261 return ret; 00262 } 00263 00264 #endif /* End Hardware Acceleration */ 00265 00266 00267 /* Software implementation */ 00268 #ifdef USE_SHA_SOFTWARE_IMPL 00269 00270 static WC_INLINE void AddLength(wc_Sha* sha, word32 len) 00271 { 00272 word32 tmp = sha->loLen; 00273 if ((sha->loLen += len) < tmp) 00274 sha->hiLen++; /* carry low to high */ 00275 } 00276 00277 /* Check if custom wc_Sha transform is used */ 00278 #ifndef XTRANSFORM 00279 #define XTRANSFORM(S,B) Transform((S),(B)) 00280 00281 #define blk0(i) (W[i] = sha->buffer[i]) 00282 #define blk1(i) (W[(i)&15] = \ 00283 rotlFixed(W[((i)+13)&15]^W[((i)+8)&15]^W[((i)+2)&15]^W[(i)&15],1)) 00284 00285 #define f1(x,y,z) ((z)^((x) &((y)^(z)))) 00286 #define f2(x,y,z) ((x)^(y)^(z)) 00287 #define f3(x,y,z) (((x)&(y))|((z)&((x)|(y)))) 00288 #define f4(x,y,z) ((x)^(y)^(z)) 00289 00290 #ifdef WOLFSSL_NUCLEUS_1_2 00291 /* nucleus.h also defines R1-R4 */ 00292 #undef R1 00293 #undef R2 00294 #undef R3 00295 #undef R4 00296 #endif 00297 00298 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 00299 #define R0(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk0((i)) + 0x5A827999+ \ 00300 rotlFixed((v),5); (w) = rotlFixed((w),30); 00301 #define R1(v,w,x,y,z,i) (z)+= f1((w),(x),(y)) + blk1((i)) + 0x5A827999+ \ 00302 rotlFixed((v),5); (w) = rotlFixed((w),30); 00303 #define R2(v,w,x,y,z,i) (z)+= f2((w),(x),(y)) + blk1((i)) + 0x6ED9EBA1+ \ 00304 rotlFixed((v),5); (w) = rotlFixed((w),30); 00305 #define R3(v,w,x,y,z,i) (z)+= f3((w),(x),(y)) + blk1((i)) + 0x8F1BBCDC+ \ 00306 rotlFixed((v),5); (w) = rotlFixed((w),30); 00307 #define R4(v,w,x,y,z,i) (z)+= f4((w),(x),(y)) + blk1((i)) + 0xCA62C1D6+ \ 00308 rotlFixed((v),5); (w) = rotlFixed((w),30); 00309 00310 static void Transform(wc_Sha* sha, byte* data) 00311 { 00312 word32 W[WC_SHA_BLOCK_SIZE / sizeof(word32)]; 00313 00314 /* Copy context->state[] to working vars */ 00315 word32 a = sha->digest[0]; 00316 word32 b = sha->digest[1]; 00317 word32 c = sha->digest[2]; 00318 word32 d = sha->digest[3]; 00319 word32 e = sha->digest[4]; 00320 00321 #ifdef USE_SLOW_SHA 00322 word32 t, i; 00323 00324 for (i = 0; i < 16; i++) { 00325 R0(a, b, c, d, e, i); 00326 t = e; e = d; d = c; c = b; b = a; a = t; 00327 } 00328 00329 for (; i < 20; i++) { 00330 R1(a, b, c, d, e, i); 00331 t = e; e = d; d = c; c = b; b = a; a = t; 00332 } 00333 00334 for (; i < 40; i++) { 00335 R2(a, b, c, d, e, i); 00336 t = e; e = d; d = c; c = b; b = a; a = t; 00337 } 00338 00339 for (; i < 60; i++) { 00340 R3(a, b, c, d, e, i); 00341 t = e; e = d; d = c; c = b; b = a; a = t; 00342 } 00343 00344 for (; i < 80; i++) { 00345 R4(a, b, c, d, e, i); 00346 t = e; e = d; d = c; c = b; b = a; a = t; 00347 } 00348 #else 00349 /* nearly 1 K bigger in code size but 25% faster */ 00350 /* 4 rounds of 20 operations each. Loop unrolled. */ 00351 R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 00352 R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 00353 R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 00354 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 00355 00356 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 00357 00358 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 00359 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 00360 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 00361 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 00362 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 00363 00364 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 00365 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 00366 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 00367 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 00368 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 00369 00370 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 00371 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 00372 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 00373 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 00374 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 00375 #endif 00376 00377 /* Add the working vars back into digest state[] */ 00378 sha->digest[0] += a; 00379 sha->digest[1] += b; 00380 sha->digest[2] += c; 00381 sha->digest[3] += d; 00382 sha->digest[4] += e; 00383 00384 (void)data; /* Not used */ 00385 } 00386 #endif /* !USE_CUSTOM_SHA_TRANSFORM */ 00387 00388 00389 int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId) 00390 { 00391 int ret = 0; 00392 00393 if (sha == NULL) 00394 return BAD_FUNC_ARG; 00395 00396 sha->heap = heap; 00397 00398 ret = InitSha(sha); 00399 if (ret != 0) 00400 return ret; 00401 00402 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA) 00403 ret = wolfAsync_DevCtxInit(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA, 00404 sha->heap, devId); 00405 #else 00406 (void)devId; 00407 #endif /* WOLFSSL_ASYNC_CRYPT */ 00408 00409 return ret; 00410 } 00411 00412 int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len) 00413 { 00414 byte* local; 00415 00416 if (sha == NULL ||(data == NULL && len > 0)) { 00417 return BAD_FUNC_ARG; 00418 } 00419 00420 /* do block size increments */ 00421 local = (byte*)sha->buffer; 00422 00423 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA) 00424 if (sha->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA) { 00425 #if defined(HAVE_INTEL_QA) 00426 return IntelQaSymSha(&sha->asyncDev, NULL, data, len); 00427 #endif 00428 } 00429 #endif /* WOLFSSL_ASYNC_CRYPT */ 00430 00431 /* check that internal buffLen is valid */ 00432 if (sha->buffLen >= WC_SHA_BLOCK_SIZE) 00433 return BUFFER_E; 00434 00435 while (len) { 00436 word32 add = min(len, WC_SHA_BLOCK_SIZE - sha->buffLen); 00437 XMEMCPY(&local[sha->buffLen], data, add); 00438 00439 sha->buffLen += add; 00440 data += add; 00441 len -= add; 00442 00443 if (sha->buffLen == WC_SHA_BLOCK_SIZE) { 00444 #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00445 ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE); 00446 #endif 00447 XTRANSFORM(sha, local); 00448 AddLength(sha, WC_SHA_BLOCK_SIZE); 00449 sha->buffLen = 0; 00450 } 00451 } 00452 00453 return 0; 00454 } 00455 00456 int wc_ShaFinalRaw(wc_Sha* sha, byte* hash) 00457 { 00458 #ifdef LITTLE_ENDIAN_ORDER 00459 word32 digest[WC_SHA_DIGEST_SIZE / sizeof(word32)]; 00460 #endif 00461 00462 if (sha == NULL || hash == NULL) { 00463 return BAD_FUNC_ARG; 00464 } 00465 00466 #ifdef LITTLE_ENDIAN_ORDER 00467 ByteReverseWords((word32*)digest, (word32*)sha->digest, WC_SHA_DIGEST_SIZE); 00468 XMEMCPY(hash, digest, WC_SHA_DIGEST_SIZE); 00469 #else 00470 XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE); 00471 #endif 00472 00473 return 0; 00474 } 00475 00476 int wc_ShaFinal(wc_Sha* sha, byte* hash) 00477 { 00478 byte* local; 00479 00480 if (sha == NULL || hash == NULL) { 00481 return BAD_FUNC_ARG; 00482 } 00483 00484 local = (byte*)sha->buffer; 00485 00486 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA) 00487 if (sha->asyncDev.marker == WOLFSSL_ASYNC_MARKER_SHA) { 00488 #if defined(HAVE_INTEL_QA) 00489 return IntelQaSymSha(&sha->asyncDev, hash, NULL, WC_SHA_DIGEST_SIZE); 00490 #endif 00491 } 00492 #endif /* WOLFSSL_ASYNC_CRYPT */ 00493 00494 AddLength(sha, sha->buffLen); /* before adding pads */ 00495 00496 local[sha->buffLen++] = 0x80; /* add 1 */ 00497 00498 /* pad with zeros */ 00499 if (sha->buffLen > WC_SHA_PAD_SIZE) { 00500 XMEMSET(&local[sha->buffLen], 0, WC_SHA_BLOCK_SIZE - sha->buffLen); 00501 sha->buffLen += WC_SHA_BLOCK_SIZE - sha->buffLen; 00502 00503 #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00504 ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE); 00505 #endif 00506 XTRANSFORM(sha, local); 00507 sha->buffLen = 0; 00508 } 00509 XMEMSET(&local[sha->buffLen], 0, WC_SHA_PAD_SIZE - sha->buffLen); 00510 00511 #if defined(LITTLE_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00512 ByteReverseWords(sha->buffer, sha->buffer, WC_SHA_BLOCK_SIZE); 00513 #endif 00514 00515 /* store lengths */ 00516 /* put lengths in bits */ 00517 sha->hiLen = (sha->loLen >> (8*sizeof(sha->loLen) - 3)) + (sha->hiLen << 3); 00518 sha->loLen = sha->loLen << 3; 00519 00520 /* ! length ordering dependent on digest endian type ! */ 00521 XMEMCPY(&local[WC_SHA_PAD_SIZE], &sha->hiLen, sizeof(word32)); 00522 XMEMCPY(&local[WC_SHA_PAD_SIZE + sizeof(word32)], &sha->loLen, sizeof(word32)); 00523 00524 #if defined(FREESCALE_MMCAU_SHA) 00525 /* Kinetis requires only these bytes reversed */ 00526 ByteReverseWords(&sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)], 00527 &sha->buffer[WC_SHA_PAD_SIZE/sizeof(word32)], 00528 2 * sizeof(word32)); 00529 #endif 00530 00531 XTRANSFORM(sha, local); 00532 #ifdef LITTLE_ENDIAN_ORDER 00533 ByteReverseWords(sha->digest, sha->digest, WC_SHA_DIGEST_SIZE); 00534 #endif 00535 XMEMCPY(hash, sha->digest, WC_SHA_DIGEST_SIZE); 00536 00537 return InitSha(sha); /* reset state */ 00538 } 00539 00540 #endif /* USE_SHA_SOFTWARE_IMPL */ 00541 00542 00543 int wc_InitSha(wc_Sha* sha) 00544 { 00545 return wc_InitSha_ex(sha, NULL, INVALID_DEVID); 00546 } 00547 00548 void wc_ShaFree(wc_Sha* sha) 00549 { 00550 if (sha == NULL) 00551 return; 00552 00553 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_SHA) 00554 wolfAsync_DevCtxFree(&sha->asyncDev, WOLFSSL_ASYNC_MARKER_SHA); 00555 #endif /* WOLFSSL_ASYNC_CRYPT */ 00556 } 00557 00558 #endif /* !WOLFSSL_TI_HASH */ 00559 #endif /* HAVE_FIPS */ 00560 00561 #ifndef WOLFSSL_TI_HASH 00562 int wc_ShaGetHash(wc_Sha* sha, byte* hash) 00563 { 00564 int ret; 00565 wc_Sha tmpSha; 00566 00567 if (sha == NULL || hash == NULL) 00568 return BAD_FUNC_ARG; 00569 00570 ret = wc_ShaCopy(sha, &tmpSha); 00571 if (ret == 0) { 00572 ret = wc_ShaFinal(&tmpSha, hash); 00573 } 00574 return ret; 00575 } 00576 00577 int wc_ShaCopy(wc_Sha* src, wc_Sha* dst) 00578 { 00579 int ret = 0; 00580 00581 if (src == NULL || dst == NULL) 00582 return BAD_FUNC_ARG; 00583 00584 XMEMCPY(dst, src, sizeof(wc_Sha)); 00585 00586 #ifdef WOLFSSL_ASYNC_CRYPT 00587 ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); 00588 #endif 00589 #ifdef WOLFSSL_PIC32MZ_HASH 00590 ret = wc_Pic32HashCopy(&src->cache, &dst->cache); 00591 #endif 00592 00593 return ret; 00594 } 00595 #endif /* !WOLFSSL_TI_HASH */ 00596 00597 #endif /* !NO_SHA */ 00598
Generated on Tue Jul 12 2022 16:58:07 by
1.7.2