ssh lib
Embed:
(wiki syntax)
Show/hide line numbers
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