wolfSSL SSL/TLS library, support up to TLS1.3
Dependents: CyaSSL-Twitter-OAuth4Tw Example-client-tls-cert TwitterReader TweetTest ... more
md5.c
00001 /* md5.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 00024 #ifdef HAVE_CONFIG_H 00025 #include <config.h> 00026 #endif 00027 00028 #include <wolfssl/wolfcrypt/settings.h> 00029 00030 #if !defined(NO_MD5) 00031 00032 #if defined(WOLFSSL_TI_HASH) 00033 /* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */ 00034 00035 #else 00036 00037 #include <wolfssl/wolfcrypt/md5.h > 00038 #include <wolfssl/wolfcrypt/error-crypt.h > 00039 #include <wolfssl/wolfcrypt/logging.h > 00040 #include <wolfssl/wolfcrypt/hash.h > 00041 00042 #ifdef NO_INLINE 00043 #include <wolfssl/wolfcrypt/misc.h> 00044 #else 00045 #define WOLFSSL_MISC_INCLUDED 00046 #include <wolfcrypt/src/misc.c> 00047 #endif 00048 00049 00050 /* Hardware Acceleration */ 00051 #if defined(STM32_HASH) 00052 00053 /* Supports CubeMX HAL or Standard Peripheral Library */ 00054 #define HAVE_MD5_CUST_API 00055 00056 int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId) 00057 { 00058 if (md5 == NULL) { 00059 return BAD_FUNC_ARG; 00060 } 00061 00062 (void)devId; 00063 (void)heap; 00064 00065 wc_Stm32_Hash_Init(&md5->stmCtx); 00066 00067 return 0; 00068 } 00069 00070 int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len) 00071 { 00072 int ret; 00073 00074 if (md5 == NULL || (data == NULL && len > 0)) { 00075 return BAD_FUNC_ARG; 00076 } 00077 00078 ret = wolfSSL_CryptHwMutexLock(); 00079 if (ret == 0) { 00080 ret = wc_Stm32_Hash_Update(&md5->stmCtx, HASH_AlgoSelection_MD5, 00081 data, len); 00082 wolfSSL_CryptHwMutexUnLock(); 00083 } 00084 return ret; 00085 } 00086 00087 int wc_Md5Final(wc_Md5* md5, byte* hash) 00088 { 00089 int ret; 00090 00091 if (md5 == NULL || hash == NULL) { 00092 return BAD_FUNC_ARG; 00093 } 00094 00095 ret = wolfSSL_CryptHwMutexLock(); 00096 if (ret == 0) { 00097 ret = wc_Stm32_Hash_Final(&md5->stmCtx, HASH_AlgoSelection_MD5, 00098 hash, WC_MD5_DIGEST_SIZE); 00099 wolfSSL_CryptHwMutexUnLock(); 00100 } 00101 00102 (void)wc_InitMd5(md5); /* reset state */ 00103 00104 return ret; 00105 } 00106 00107 #elif defined(FREESCALE_MMCAU_SHA) 00108 00109 #ifdef FREESCALE_MMCAU_CLASSIC_SHA 00110 #include "cau_api.h" 00111 #else 00112 #include "fsl_mmcau.h" 00113 #endif 00114 00115 #define XTRANSFORM(S,B) Transform((S), (B)) 00116 #define XTRANSFORM_LEN(S,B,L) Transform_Len((S), (B), (L)) 00117 00118 #ifndef WC_HASH_DATA_ALIGNMENT 00119 /* these hardware API's require 4 byte (word32) alignment */ 00120 #define WC_HASH_DATA_ALIGNMENT 4 00121 #endif 00122 00123 static int Transform(wc_Md5* md5, const byte* data) 00124 { 00125 int ret = wolfSSL_CryptHwMutexLock(); 00126 if (ret == 0) { 00127 #ifdef FREESCALE_MMCAU_CLASSIC_SHA 00128 cau_md5_hash_n((byte*)data, 1, (unsigned char*)md5->digest); 00129 #else 00130 MMCAU_MD5_HashN((byte*)data, 1, (uint32_t*)md5->digest); 00131 #endif 00132 wolfSSL_CryptHwMutexUnLock(); 00133 } 00134 return ret; 00135 } 00136 00137 static int Transform_Len(wc_Md5* md5, const byte* data, word32 len) 00138 { 00139 int ret = wolfSSL_CryptHwMutexLock(); 00140 if (ret == 0) { 00141 #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0 00142 if ((size_t)data % WC_HASH_DATA_ALIGNMENT) { 00143 /* data pointer is NOT aligned, 00144 * so copy and perform one block at a time */ 00145 byte* local = (byte*)md5->buffer; 00146 while (len >= WC_MD5_BLOCK_SIZE) { 00147 XMEMCPY(local, data, WC_MD5_BLOCK_SIZE); 00148 #ifdef FREESCALE_MMCAU_CLASSIC_SHA 00149 cau_md5_hash_n(local, 1, (unsigned char*)md5->digest); 00150 #else 00151 MMCAU_MD5_HashN(local, 1, (uint32_t*)md5->digest); 00152 #endif 00153 data += WC_MD5_BLOCK_SIZE; 00154 len -= WC_MD5_BLOCK_SIZE; 00155 } 00156 } 00157 else 00158 #endif 00159 { 00160 #ifdef FREESCALE_MMCAU_CLASSIC_SHA 00161 cau_md5_hash_n((byte*)data, len / WC_MD5_BLOCK_SIZE, 00162 (unsigned char*)md5->digest); 00163 #else 00164 MMCAU_MD5_HashN((byte*)data, len / WC_MD5_BLOCK_SIZE, 00165 (uint32_t*)md5->digest); 00166 #endif 00167 } 00168 wolfSSL_CryptHwMutexUnLock(); 00169 } 00170 return ret; 00171 } 00172 00173 #elif defined(WOLFSSL_PIC32MZ_HASH) 00174 #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h> 00175 #define HAVE_MD5_CUST_API 00176 00177 #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) 00178 /* functions implemented in wolfcrypt/src/port/caam/caam_sha.c */ 00179 #define HAVE_MD5_CUST_API 00180 #else 00181 #define NEED_SOFT_MD5 00182 #endif /* End Hardware Acceleration */ 00183 00184 #ifdef NEED_SOFT_MD5 00185 00186 #define XTRANSFORM(S,B) Transform((S),(B)) 00187 00188 #define F1(x, y, z) (z ^ (x & (y ^ z))) 00189 #define F2(x, y, z) F1(z, x, y) 00190 #define F3(x, y, z) (x ^ y ^ z) 00191 #define F4(x, y, z) (y ^ (x | ~z)) 00192 00193 #define MD5STEP(f, w, x, y, z, data, s) \ 00194 w = rotlFixed(w + f(x, y, z) + data, s) + x 00195 00196 static int Transform(wc_Md5* md5, const byte* data) 00197 { 00198 word32* buffer = (word32*)data; 00199 /* Copy context->state[] to working vars */ 00200 word32 a = md5->digest[0]; 00201 word32 b = md5->digest[1]; 00202 word32 c = md5->digest[2]; 00203 word32 d = md5->digest[3]; 00204 00205 MD5STEP(F1, a, b, c, d, buffer[0] + 0xd76aa478, 7); 00206 MD5STEP(F1, d, a, b, c, buffer[1] + 0xe8c7b756, 12); 00207 MD5STEP(F1, c, d, a, b, buffer[2] + 0x242070db, 17); 00208 MD5STEP(F1, b, c, d, a, buffer[3] + 0xc1bdceee, 22); 00209 MD5STEP(F1, a, b, c, d, buffer[4] + 0xf57c0faf, 7); 00210 MD5STEP(F1, d, a, b, c, buffer[5] + 0x4787c62a, 12); 00211 MD5STEP(F1, c, d, a, b, buffer[6] + 0xa8304613, 17); 00212 MD5STEP(F1, b, c, d, a, buffer[7] + 0xfd469501, 22); 00213 MD5STEP(F1, a, b, c, d, buffer[8] + 0x698098d8, 7); 00214 MD5STEP(F1, d, a, b, c, buffer[9] + 0x8b44f7af, 12); 00215 MD5STEP(F1, c, d, a, b, buffer[10] + 0xffff5bb1, 17); 00216 MD5STEP(F1, b, c, d, a, buffer[11] + 0x895cd7be, 22); 00217 MD5STEP(F1, a, b, c, d, buffer[12] + 0x6b901122, 7); 00218 MD5STEP(F1, d, a, b, c, buffer[13] + 0xfd987193, 12); 00219 MD5STEP(F1, c, d, a, b, buffer[14] + 0xa679438e, 17); 00220 MD5STEP(F1, b, c, d, a, buffer[15] + 0x49b40821, 22); 00221 00222 MD5STEP(F2, a, b, c, d, buffer[1] + 0xf61e2562, 5); 00223 MD5STEP(F2, d, a, b, c, buffer[6] + 0xc040b340, 9); 00224 MD5STEP(F2, c, d, a, b, buffer[11] + 0x265e5a51, 14); 00225 MD5STEP(F2, b, c, d, a, buffer[0] + 0xe9b6c7aa, 20); 00226 MD5STEP(F2, a, b, c, d, buffer[5] + 0xd62f105d, 5); 00227 MD5STEP(F2, d, a, b, c, buffer[10] + 0x02441453, 9); 00228 MD5STEP(F2, c, d, a, b, buffer[15] + 0xd8a1e681, 14); 00229 MD5STEP(F2, b, c, d, a, buffer[4] + 0xe7d3fbc8, 20); 00230 MD5STEP(F2, a, b, c, d, buffer[9] + 0x21e1cde6, 5); 00231 MD5STEP(F2, d, a, b, c, buffer[14] + 0xc33707d6, 9); 00232 MD5STEP(F2, c, d, a, b, buffer[3] + 0xf4d50d87, 14); 00233 MD5STEP(F2, b, c, d, a, buffer[8] + 0x455a14ed, 20); 00234 MD5STEP(F2, a, b, c, d, buffer[13] + 0xa9e3e905, 5); 00235 MD5STEP(F2, d, a, b, c, buffer[2] + 0xfcefa3f8, 9); 00236 MD5STEP(F2, c, d, a, b, buffer[7] + 0x676f02d9, 14); 00237 MD5STEP(F2, b, c, d, a, buffer[12] + 0x8d2a4c8a, 20); 00238 00239 MD5STEP(F3, a, b, c, d, buffer[5] + 0xfffa3942, 4); 00240 MD5STEP(F3, d, a, b, c, buffer[8] + 0x8771f681, 11); 00241 MD5STEP(F3, c, d, a, b, buffer[11] + 0x6d9d6122, 16); 00242 MD5STEP(F3, b, c, d, a, buffer[14] + 0xfde5380c, 23); 00243 MD5STEP(F3, a, b, c, d, buffer[1] + 0xa4beea44, 4); 00244 MD5STEP(F3, d, a, b, c, buffer[4] + 0x4bdecfa9, 11); 00245 MD5STEP(F3, c, d, a, b, buffer[7] + 0xf6bb4b60, 16); 00246 MD5STEP(F3, b, c, d, a, buffer[10] + 0xbebfbc70, 23); 00247 MD5STEP(F3, a, b, c, d, buffer[13] + 0x289b7ec6, 4); 00248 MD5STEP(F3, d, a, b, c, buffer[0] + 0xeaa127fa, 11); 00249 MD5STEP(F3, c, d, a, b, buffer[3] + 0xd4ef3085, 16); 00250 MD5STEP(F3, b, c, d, a, buffer[6] + 0x04881d05, 23); 00251 MD5STEP(F3, a, b, c, d, buffer[9] + 0xd9d4d039, 4); 00252 MD5STEP(F3, d, a, b, c, buffer[12] + 0xe6db99e5, 11); 00253 MD5STEP(F3, c, d, a, b, buffer[15] + 0x1fa27cf8, 16); 00254 MD5STEP(F3, b, c, d, a, buffer[2] + 0xc4ac5665, 23); 00255 00256 MD5STEP(F4, a, b, c, d, buffer[0] + 0xf4292244, 6); 00257 MD5STEP(F4, d, a, b, c, buffer[7] + 0x432aff97, 10); 00258 MD5STEP(F4, c, d, a, b, buffer[14] + 0xab9423a7, 15); 00259 MD5STEP(F4, b, c, d, a, buffer[5] + 0xfc93a039, 21); 00260 MD5STEP(F4, a, b, c, d, buffer[12] + 0x655b59c3, 6); 00261 MD5STEP(F4, d, a, b, c, buffer[3] + 0x8f0ccc92, 10); 00262 MD5STEP(F4, c, d, a, b, buffer[10] + 0xffeff47d, 15); 00263 MD5STEP(F4, b, c, d, a, buffer[1] + 0x85845dd1, 21); 00264 MD5STEP(F4, a, b, c, d, buffer[8] + 0x6fa87e4f, 6); 00265 MD5STEP(F4, d, a, b, c, buffer[15] + 0xfe2ce6e0, 10); 00266 MD5STEP(F4, c, d, a, b, buffer[6] + 0xa3014314, 15); 00267 MD5STEP(F4, b, c, d, a, buffer[13] + 0x4e0811a1, 21); 00268 MD5STEP(F4, a, b, c, d, buffer[4] + 0xf7537e82, 6); 00269 MD5STEP(F4, d, a, b, c, buffer[11] + 0xbd3af235, 10); 00270 MD5STEP(F4, c, d, a, b, buffer[2] + 0x2ad7d2bb, 15); 00271 MD5STEP(F4, b, c, d, a, buffer[9] + 0xeb86d391, 21); 00272 00273 /* Add the working vars back into digest state[] */ 00274 md5->digest[0] += a; 00275 md5->digest[1] += b; 00276 md5->digest[2] += c; 00277 md5->digest[3] += d; 00278 00279 return 0; 00280 } 00281 #endif /* NEED_SOFT_MD5 */ 00282 00283 #ifndef HAVE_MD5_CUST_API 00284 00285 static WC_INLINE void AddLength(wc_Md5* md5, word32 len) 00286 { 00287 word32 tmp = md5->loLen; 00288 if ((md5->loLen += len) < tmp) { 00289 md5->hiLen++; /* carry low to high */ 00290 } 00291 } 00292 00293 static int _InitMd5(wc_Md5* md5) 00294 { 00295 int ret = 0; 00296 00297 md5->digest[0] = 0x67452301L; 00298 md5->digest[1] = 0xefcdab89L; 00299 md5->digest[2] = 0x98badcfeL; 00300 md5->digest[3] = 0x10325476L; 00301 00302 md5->buffLen = 0; 00303 md5->loLen = 0; 00304 md5->hiLen = 0; 00305 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) 00306 md5->flags = 0; 00307 #endif 00308 00309 return ret; 00310 } 00311 00312 int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId) 00313 { 00314 int ret = 0; 00315 00316 if (md5 == NULL) 00317 return BAD_FUNC_ARG; 00318 00319 md5->heap = heap; 00320 00321 ret = _InitMd5(md5); 00322 if (ret != 0) 00323 return ret; 00324 00325 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) 00326 ret = wolfAsync_DevCtxInit(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5, 00327 md5->heap, devId); 00328 #else 00329 (void)devId; 00330 #endif 00331 return ret; 00332 } 00333 00334 /* do block size increments/updates */ 00335 int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len) 00336 { 00337 int ret = 0; 00338 word32 blocksLen; 00339 byte* local; 00340 00341 if (md5 == NULL || (data == NULL && len > 0)) { 00342 return BAD_FUNC_ARG; 00343 } 00344 00345 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) 00346 if (md5->asyncDev.marker == WOLFSSL_ASYNC_MARKER_MD5) { 00347 #if defined(HAVE_INTEL_QA) 00348 return IntelQaSymMd5(&md5->asyncDev, NULL, data, len); 00349 #endif 00350 } 00351 #endif /* WOLFSSL_ASYNC_CRYPT */ 00352 00353 /* check that internal buffLen is valid */ 00354 if (md5->buffLen >= WC_MD5_BLOCK_SIZE) 00355 return BUFFER_E; 00356 00357 if (data == NULL && len == 0) { 00358 /* valid, but do nothing */ 00359 return 0; 00360 } 00361 00362 /* add length for final */ 00363 AddLength(md5, len); 00364 00365 local = (byte*)md5->buffer; 00366 00367 /* process any remainder from previous operation */ 00368 if (md5->buffLen > 0) { 00369 blocksLen = min(len, WC_MD5_BLOCK_SIZE - md5->buffLen); 00370 XMEMCPY(&local[md5->buffLen], data, blocksLen); 00371 00372 md5->buffLen += blocksLen; 00373 data += blocksLen; 00374 len -= blocksLen; 00375 00376 if (md5->buffLen == WC_MD5_BLOCK_SIZE) { 00377 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00378 ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE); 00379 #endif 00380 00381 ret = XTRANSFORM(md5, (const byte*)local); 00382 if (ret != 0) 00383 return ret; 00384 00385 md5->buffLen = 0; 00386 } 00387 } 00388 00389 /* process blocks */ 00390 #ifdef XTRANSFORM_LEN 00391 /* get number of blocks */ 00392 /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */ 00393 /* len (masked by 0xFFFFFFC0) returns block aligned length */ 00394 blocksLen = len & ~(WC_MD5_BLOCK_SIZE-1); 00395 if (blocksLen > 0) { 00396 /* Byte reversal performed in function if required. */ 00397 XTRANSFORM_LEN(md5, data, blocksLen); 00398 data += blocksLen; 00399 len -= blocksLen; 00400 } 00401 #else 00402 while (len >= WC_MD5_BLOCK_SIZE) { 00403 word32* local32 = md5->buffer; 00404 /* optimization to avoid memcpy if data pointer is properly aligned */ 00405 /* Big Endian requires byte swap, so can't use data directly */ 00406 #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(BIG_ENDIAN_ORDER) 00407 if (((size_t)data % WC_HASH_DATA_ALIGNMENT) == 0) { 00408 local32 = (word32*)data; 00409 } 00410 else 00411 #endif 00412 { 00413 XMEMCPY(local32, data, WC_MD5_BLOCK_SIZE); 00414 } 00415 00416 data += WC_MD5_BLOCK_SIZE; 00417 len -= WC_MD5_BLOCK_SIZE; 00418 00419 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00420 ByteReverseWords(local32, local32, WC_MD5_BLOCK_SIZE); 00421 #endif 00422 00423 ret = XTRANSFORM(md5, (const byte*)local32); 00424 } 00425 #endif /* XTRANSFORM_LEN */ 00426 00427 /* save remainder */ 00428 if (len > 0) { 00429 XMEMCPY(local, data, len); 00430 md5->buffLen = len; 00431 } 00432 00433 return ret; 00434 } 00435 00436 int wc_Md5Final(wc_Md5* md5, byte* hash) 00437 { 00438 byte* local; 00439 00440 if (md5 == NULL || hash == NULL) { 00441 return BAD_FUNC_ARG; 00442 } 00443 00444 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) 00445 if (md5->asyncDev.marker == WOLFSSL_ASYNC_MARKER_MD5) { 00446 #if defined(HAVE_INTEL_QA) 00447 return IntelQaSymMd5(&md5->asyncDev, hash, NULL, WC_MD5_DIGEST_SIZE); 00448 #endif 00449 } 00450 #endif /* WOLFSSL_ASYNC_CRYPT */ 00451 00452 local = (byte*)md5->buffer; 00453 00454 local[md5->buffLen++] = 0x80; /* add 1 */ 00455 00456 /* pad with zeros */ 00457 if (md5->buffLen > WC_MD5_PAD_SIZE) { 00458 XMEMSET(&local[md5->buffLen], 0, WC_MD5_BLOCK_SIZE - md5->buffLen); 00459 md5->buffLen += WC_MD5_BLOCK_SIZE - md5->buffLen; 00460 00461 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00462 ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE); 00463 #endif 00464 XTRANSFORM(md5, local); 00465 md5->buffLen = 0; 00466 } 00467 XMEMSET(&local[md5->buffLen], 0, WC_MD5_PAD_SIZE - md5->buffLen); 00468 00469 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00470 ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE); 00471 #endif 00472 00473 /* put lengths in bits */ 00474 md5->hiLen = (md5->loLen >> (8 * sizeof(md5->loLen) - 3)) + 00475 (md5->hiLen << 3); 00476 md5->loLen = md5->loLen << 3; 00477 00478 /* store lengths */ 00479 /* ! length ordering dependent on digest endian type ! */ 00480 XMEMCPY(&local[WC_MD5_PAD_SIZE], &md5->loLen, sizeof(word32)); 00481 XMEMCPY(&local[WC_MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32)); 00482 00483 /* final transform and result to hash */ 00484 XTRANSFORM(md5, local); 00485 #ifdef BIG_ENDIAN_ORDER 00486 ByteReverseWords(md5->digest, md5->digest, WC_MD5_DIGEST_SIZE); 00487 #endif 00488 XMEMCPY(hash, md5->digest, WC_MD5_DIGEST_SIZE); 00489 00490 return _InitMd5(md5); /* reset state */ 00491 } 00492 #endif /* !HAVE_MD5_CUST_API */ 00493 00494 00495 int wc_InitMd5(wc_Md5* md5) 00496 { 00497 if (md5 == NULL) { 00498 return BAD_FUNC_ARG; 00499 } 00500 return wc_InitMd5_ex(md5, NULL, INVALID_DEVID); 00501 } 00502 00503 void wc_Md5Free(wc_Md5* md5) 00504 { 00505 if (md5 == NULL) 00506 return; 00507 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) 00508 wolfAsync_DevCtxFree(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5); 00509 #endif /* WOLFSSL_ASYNC_CRYPT */ 00510 00511 #ifdef WOLFSSL_PIC32MZ_HASH 00512 wc_Md5Pic32Free(md5); 00513 #endif 00514 } 00515 00516 int wc_Md5GetHash(wc_Md5* md5, byte* hash) 00517 { 00518 int ret; 00519 wc_Md5 tmpMd5; 00520 00521 if (md5 == NULL || hash == NULL) 00522 return BAD_FUNC_ARG; 00523 00524 ret = wc_Md5Copy(md5, &tmpMd5); 00525 if (ret == 0) { 00526 ret = wc_Md5Final(&tmpMd5, hash); 00527 } 00528 00529 return ret; 00530 } 00531 00532 int wc_Md5Copy(wc_Md5* src, wc_Md5* dst) 00533 { 00534 int ret = 0; 00535 00536 if (src == NULL || dst == NULL) 00537 return BAD_FUNC_ARG; 00538 00539 XMEMCPY(dst, src, sizeof(wc_Md5)); 00540 00541 #ifdef WOLFSSL_ASYNC_CRYPT 00542 ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); 00543 #endif 00544 #ifdef WOLFSSL_PIC32MZ_HASH 00545 ret = wc_Pic32HashCopy(&src->cache, &dst->cache); 00546 #endif 00547 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) 00548 dst->flags |= WC_HASH_FLAG_ISCOPY; 00549 #endif 00550 00551 return ret; 00552 } 00553 00554 #if defined(WOLFSSL_HASH_FLAGS) || defined(WOLF_CRYPTO_CB) 00555 int wc_Md5SetFlags(wc_Md5* md5, word32 flags) 00556 { 00557 if (md5) { 00558 md5->flags = flags; 00559 } 00560 return 0; 00561 } 00562 int wc_Md5GetFlags(wc_Md5* md5, word32* flags) 00563 { 00564 if (md5 && flags) { 00565 *flags = md5->flags; 00566 } 00567 return 0; 00568 } 00569 #endif 00570 00571 #endif /* WOLFSSL_TI_HASH */ 00572 #endif /* NO_MD5 */ 00573
Generated on Tue Jul 12 2022 20:58:40 by 1.7.2