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.
md5.c
00001 /* md5.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 00024 #ifdef HAVE_CONFIG_H 00025 #include <config.h> 00026 #endif 00027 00028 #include <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 <wolfcrypt/md5.h> 00038 #include <wolfcrypt/error-crypt.h> 00039 #include <wolfcrypt/logging.h> 00040 00041 #ifdef NO_INLINE 00042 #include <wolfcrypt/misc.h> 00043 #else 00044 #define WOLFSSL_MISC_INCLUDED 00045 #include <wolfcrypt/src/misc.c> 00046 #endif 00047 00048 00049 /* Hardware Acceleration */ 00050 #if defined(STM32_HASH) 00051 00052 /* Supports CubeMX HAL or Standard Peripheral Library */ 00053 #define HAVE_MD5_CUST_API 00054 00055 int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId) 00056 { 00057 if (md5 == NULL) { 00058 return BAD_FUNC_ARG; 00059 } 00060 00061 (void)devId; 00062 (void)heap; 00063 00064 wc_Stm32_Hash_Init(&md5->stmCtx); 00065 00066 return 0; 00067 } 00068 00069 int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len) 00070 { 00071 int ret; 00072 00073 if (md5 == NULL || (data == NULL && len > 0)) { 00074 return BAD_FUNC_ARG; 00075 } 00076 00077 ret = wolfSSL_CryptHwMutexLock(); 00078 if (ret == 0) { 00079 ret = wc_Stm32_Hash_Update(&md5->stmCtx, HASH_AlgoSelection_MD5, 00080 data, len); 00081 wolfSSL_CryptHwMutexUnLock(); 00082 } 00083 return ret; 00084 } 00085 00086 int wc_Md5Final(wc_Md5* md5, byte* hash) 00087 { 00088 int ret; 00089 00090 if (md5 == NULL || hash == NULL) { 00091 return BAD_FUNC_ARG; 00092 } 00093 00094 ret = wolfSSL_CryptHwMutexLock(); 00095 if (ret == 0) { 00096 ret = wc_Stm32_Hash_Final(&md5->stmCtx, HASH_AlgoSelection_MD5, 00097 hash, WC_MD5_DIGEST_SIZE); 00098 wolfSSL_CryptHwMutexUnLock(); 00099 } 00100 00101 (void)wc_InitMd5(md5); /* reset state */ 00102 00103 return ret; 00104 } 00105 00106 #elif defined(FREESCALE_MMCAU_SHA) 00107 #include "cau_api.h" 00108 #define XTRANSFORM(S,B) Transform((S), (B)) 00109 00110 static int Transform(wc_Md5* md5, byte* data) 00111 { 00112 int ret = wolfSSL_CryptHwMutexLock(); 00113 if(ret == 0) { 00114 #ifdef FREESCALE_MMCAU_CLASSIC_SHA 00115 cau_md5_hash_n(data, 1, (unsigned char*)md5->digest); 00116 #else 00117 MMCAU_MD5_HashN(data, 1, (uint32_t*)md5->digest); 00118 #endif 00119 wolfSSL_CryptHwMutexUnLock(); 00120 } 00121 return ret; 00122 } 00123 00124 #elif defined(WOLFSSL_PIC32MZ_HASH) 00125 #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h> 00126 #define HAVE_MD5_CUST_API 00127 00128 #elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) 00129 /* functions implemented in wolfcrypt/src/port/caam/caam_sha.c */ 00130 #define HAVE_MD5_CUST_API 00131 #else 00132 #define NEED_SOFT_MD5 00133 00134 #endif /* End Hardware Acceleration */ 00135 00136 00137 #ifdef NEED_SOFT_MD5 00138 00139 #define XTRANSFORM(S,B) Transform((S)) 00140 00141 #define F1(x, y, z) (z ^ (x & (y ^ z))) 00142 #define F2(x, y, z) F1(z, x, y) 00143 #define F3(x, y, z) (x ^ y ^ z) 00144 #define F4(x, y, z) (y ^ (x | ~z)) 00145 00146 #define MD5STEP(f, w, x, y, z, data, s) \ 00147 w = rotlFixed(w + f(x, y, z) + data, s) + x 00148 00149 static int Transform(wc_Md5* md5) 00150 { 00151 /* Copy context->state[] to working vars */ 00152 word32 a = md5->digest[0]; 00153 word32 b = md5->digest[1]; 00154 word32 c = md5->digest[2]; 00155 word32 d = md5->digest[3]; 00156 00157 MD5STEP(F1, a, b, c, d, md5->buffer[0] + 0xd76aa478, 7); 00158 MD5STEP(F1, d, a, b, c, md5->buffer[1] + 0xe8c7b756, 12); 00159 MD5STEP(F1, c, d, a, b, md5->buffer[2] + 0x242070db, 17); 00160 MD5STEP(F1, b, c, d, a, md5->buffer[3] + 0xc1bdceee, 22); 00161 MD5STEP(F1, a, b, c, d, md5->buffer[4] + 0xf57c0faf, 7); 00162 MD5STEP(F1, d, a, b, c, md5->buffer[5] + 0x4787c62a, 12); 00163 MD5STEP(F1, c, d, a, b, md5->buffer[6] + 0xa8304613, 17); 00164 MD5STEP(F1, b, c, d, a, md5->buffer[7] + 0xfd469501, 22); 00165 MD5STEP(F1, a, b, c, d, md5->buffer[8] + 0x698098d8, 7); 00166 MD5STEP(F1, d, a, b, c, md5->buffer[9] + 0x8b44f7af, 12); 00167 MD5STEP(F1, c, d, a, b, md5->buffer[10] + 0xffff5bb1, 17); 00168 MD5STEP(F1, b, c, d, a, md5->buffer[11] + 0x895cd7be, 22); 00169 MD5STEP(F1, a, b, c, d, md5->buffer[12] + 0x6b901122, 7); 00170 MD5STEP(F1, d, a, b, c, md5->buffer[13] + 0xfd987193, 12); 00171 MD5STEP(F1, c, d, a, b, md5->buffer[14] + 0xa679438e, 17); 00172 MD5STEP(F1, b, c, d, a, md5->buffer[15] + 0x49b40821, 22); 00173 00174 MD5STEP(F2, a, b, c, d, md5->buffer[1] + 0xf61e2562, 5); 00175 MD5STEP(F2, d, a, b, c, md5->buffer[6] + 0xc040b340, 9); 00176 MD5STEP(F2, c, d, a, b, md5->buffer[11] + 0x265e5a51, 14); 00177 MD5STEP(F2, b, c, d, a, md5->buffer[0] + 0xe9b6c7aa, 20); 00178 MD5STEP(F2, a, b, c, d, md5->buffer[5] + 0xd62f105d, 5); 00179 MD5STEP(F2, d, a, b, c, md5->buffer[10] + 0x02441453, 9); 00180 MD5STEP(F2, c, d, a, b, md5->buffer[15] + 0xd8a1e681, 14); 00181 MD5STEP(F2, b, c, d, a, md5->buffer[4] + 0xe7d3fbc8, 20); 00182 MD5STEP(F2, a, b, c, d, md5->buffer[9] + 0x21e1cde6, 5); 00183 MD5STEP(F2, d, a, b, c, md5->buffer[14] + 0xc33707d6, 9); 00184 MD5STEP(F2, c, d, a, b, md5->buffer[3] + 0xf4d50d87, 14); 00185 MD5STEP(F2, b, c, d, a, md5->buffer[8] + 0x455a14ed, 20); 00186 MD5STEP(F2, a, b, c, d, md5->buffer[13] + 0xa9e3e905, 5); 00187 MD5STEP(F2, d, a, b, c, md5->buffer[2] + 0xfcefa3f8, 9); 00188 MD5STEP(F2, c, d, a, b, md5->buffer[7] + 0x676f02d9, 14); 00189 MD5STEP(F2, b, c, d, a, md5->buffer[12] + 0x8d2a4c8a, 20); 00190 00191 MD5STEP(F3, a, b, c, d, md5->buffer[5] + 0xfffa3942, 4); 00192 MD5STEP(F3, d, a, b, c, md5->buffer[8] + 0x8771f681, 11); 00193 MD5STEP(F3, c, d, a, b, md5->buffer[11] + 0x6d9d6122, 16); 00194 MD5STEP(F3, b, c, d, a, md5->buffer[14] + 0xfde5380c, 23); 00195 MD5STEP(F3, a, b, c, d, md5->buffer[1] + 0xa4beea44, 4); 00196 MD5STEP(F3, d, a, b, c, md5->buffer[4] + 0x4bdecfa9, 11); 00197 MD5STEP(F3, c, d, a, b, md5->buffer[7] + 0xf6bb4b60, 16); 00198 MD5STEP(F3, b, c, d, a, md5->buffer[10] + 0xbebfbc70, 23); 00199 MD5STEP(F3, a, b, c, d, md5->buffer[13] + 0x289b7ec6, 4); 00200 MD5STEP(F3, d, a, b, c, md5->buffer[0] + 0xeaa127fa, 11); 00201 MD5STEP(F3, c, d, a, b, md5->buffer[3] + 0xd4ef3085, 16); 00202 MD5STEP(F3, b, c, d, a, md5->buffer[6] + 0x04881d05, 23); 00203 MD5STEP(F3, a, b, c, d, md5->buffer[9] + 0xd9d4d039, 4); 00204 MD5STEP(F3, d, a, b, c, md5->buffer[12] + 0xe6db99e5, 11); 00205 MD5STEP(F3, c, d, a, b, md5->buffer[15] + 0x1fa27cf8, 16); 00206 MD5STEP(F3, b, c, d, a, md5->buffer[2] + 0xc4ac5665, 23); 00207 00208 MD5STEP(F4, a, b, c, d, md5->buffer[0] + 0xf4292244, 6); 00209 MD5STEP(F4, d, a, b, c, md5->buffer[7] + 0x432aff97, 10); 00210 MD5STEP(F4, c, d, a, b, md5->buffer[14] + 0xab9423a7, 15); 00211 MD5STEP(F4, b, c, d, a, md5->buffer[5] + 0xfc93a039, 21); 00212 MD5STEP(F4, a, b, c, d, md5->buffer[12] + 0x655b59c3, 6); 00213 MD5STEP(F4, d, a, b, c, md5->buffer[3] + 0x8f0ccc92, 10); 00214 MD5STEP(F4, c, d, a, b, md5->buffer[10] + 0xffeff47d, 15); 00215 MD5STEP(F4, b, c, d, a, md5->buffer[1] + 0x85845dd1, 21); 00216 MD5STEP(F4, a, b, c, d, md5->buffer[8] + 0x6fa87e4f, 6); 00217 MD5STEP(F4, d, a, b, c, md5->buffer[15] + 0xfe2ce6e0, 10); 00218 MD5STEP(F4, c, d, a, b, md5->buffer[6] + 0xa3014314, 15); 00219 MD5STEP(F4, b, c, d, a, md5->buffer[13] + 0x4e0811a1, 21); 00220 MD5STEP(F4, a, b, c, d, md5->buffer[4] + 0xf7537e82, 6); 00221 MD5STEP(F4, d, a, b, c, md5->buffer[11] + 0xbd3af235, 10); 00222 MD5STEP(F4, c, d, a, b, md5->buffer[2] + 0x2ad7d2bb, 15); 00223 MD5STEP(F4, b, c, d, a, md5->buffer[9] + 0xeb86d391, 21); 00224 00225 /* Add the working vars back into digest state[] */ 00226 md5->digest[0] += a; 00227 md5->digest[1] += b; 00228 md5->digest[2] += c; 00229 md5->digest[3] += d; 00230 00231 return 0; 00232 } 00233 #endif /* NEED_SOFT_MD5 */ 00234 00235 #ifndef HAVE_MD5_CUST_API 00236 00237 static WC_INLINE void AddLength(wc_Md5* md5, word32 len) 00238 { 00239 word32 tmp = md5->loLen; 00240 if ((md5->loLen += len) < tmp) { 00241 md5->hiLen++; /* carry low to high */ 00242 } 00243 } 00244 00245 static int _InitMd5(wc_Md5* md5) 00246 { 00247 int ret = 0; 00248 00249 md5->digest[0] = 0x67452301L; 00250 md5->digest[1] = 0xefcdab89L; 00251 md5->digest[2] = 0x98badcfeL; 00252 md5->digest[3] = 0x10325476L; 00253 00254 md5->buffLen = 0; 00255 md5->loLen = 0; 00256 md5->hiLen = 0; 00257 00258 return ret; 00259 } 00260 00261 int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId) 00262 { 00263 int ret = 0; 00264 00265 if (md5 == NULL) 00266 return BAD_FUNC_ARG; 00267 00268 md5->heap = heap; 00269 00270 ret = _InitMd5(md5); 00271 if (ret != 0) 00272 return ret; 00273 00274 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) 00275 ret = wolfAsync_DevCtxInit(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5, 00276 md5->heap, devId); 00277 #else 00278 (void)devId; 00279 #endif 00280 return ret; 00281 } 00282 00283 int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len) 00284 { 00285 int ret = 0; 00286 byte* local; 00287 00288 if (md5 == NULL || (data == NULL && len > 0)) { 00289 return BAD_FUNC_ARG; 00290 } 00291 00292 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) 00293 if (md5->asyncDev.marker == WOLFSSL_ASYNC_MARKER_MD5) { 00294 #if defined(HAVE_INTEL_QA) 00295 return IntelQaSymMd5(&md5->asyncDev, NULL, data, len); 00296 #endif 00297 } 00298 #endif /* WOLFSSL_ASYNC_CRYPT */ 00299 00300 /* do block size increments */ 00301 local = (byte*)md5->buffer; 00302 00303 /* check that internal buffLen is valid */ 00304 if (md5->buffLen >= WC_MD5_BLOCK_SIZE) 00305 return BUFFER_E; 00306 00307 while (len) { 00308 word32 add = min(len, WC_MD5_BLOCK_SIZE - md5->buffLen); 00309 XMEMCPY(&local[md5->buffLen], data, add); 00310 00311 md5->buffLen += add; 00312 data += add; 00313 len -= add; 00314 00315 if (md5->buffLen == WC_MD5_BLOCK_SIZE) { 00316 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00317 ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE); 00318 #endif 00319 XTRANSFORM(md5, local); 00320 AddLength(md5, WC_MD5_BLOCK_SIZE); 00321 md5->buffLen = 0; 00322 } 00323 } 00324 return ret; 00325 } 00326 00327 int wc_Md5Final(wc_Md5* md5, byte* hash) 00328 { 00329 byte* local; 00330 00331 if (md5 == NULL || hash == NULL) { 00332 return BAD_FUNC_ARG; 00333 } 00334 00335 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) 00336 if (md5->asyncDev.marker == WOLFSSL_ASYNC_MARKER_MD5) { 00337 #if defined(HAVE_INTEL_QA) 00338 return IntelQaSymMd5(&md5->asyncDev, hash, NULL, WC_MD5_DIGEST_SIZE); 00339 #endif 00340 } 00341 #endif /* WOLFSSL_ASYNC_CRYPT */ 00342 00343 local = (byte*)md5->buffer; 00344 00345 AddLength(md5, md5->buffLen); /* before adding pads */ 00346 local[md5->buffLen++] = 0x80; /* add 1 */ 00347 00348 /* pad with zeros */ 00349 if (md5->buffLen > WC_MD5_PAD_SIZE) { 00350 XMEMSET(&local[md5->buffLen], 0, WC_MD5_BLOCK_SIZE - md5->buffLen); 00351 md5->buffLen += WC_MD5_BLOCK_SIZE - md5->buffLen; 00352 00353 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00354 ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE); 00355 #endif 00356 XTRANSFORM(md5, local); 00357 md5->buffLen = 0; 00358 } 00359 XMEMSET(&local[md5->buffLen], 0, WC_MD5_PAD_SIZE - md5->buffLen); 00360 00361 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA) 00362 ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE); 00363 #endif 00364 00365 /* put lengths in bits */ 00366 md5->hiLen = (md5->loLen >> (8*sizeof(md5->loLen) - 3)) + 00367 (md5->hiLen << 3); 00368 md5->loLen = md5->loLen << 3; 00369 00370 /* store lengths */ 00371 /* ! length ordering dependent on digest endian type ! */ 00372 XMEMCPY(&local[WC_MD5_PAD_SIZE], &md5->loLen, sizeof(word32)); 00373 XMEMCPY(&local[WC_MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32)); 00374 00375 /* final transform and result to hash */ 00376 XTRANSFORM(md5, local); 00377 #ifdef BIG_ENDIAN_ORDER 00378 ByteReverseWords(md5->digest, md5->digest, WC_MD5_DIGEST_SIZE); 00379 #endif 00380 XMEMCPY(hash, md5->digest, WC_MD5_DIGEST_SIZE); 00381 00382 return _InitMd5(md5); /* reset state */ 00383 } 00384 #endif /* !HAVE_MD5_CUST_API */ 00385 00386 00387 int wc_InitMd5(wc_Md5* md5) 00388 { 00389 if (md5 == NULL) { 00390 return BAD_FUNC_ARG; 00391 } 00392 return wc_InitMd5_ex(md5, NULL, INVALID_DEVID); 00393 } 00394 00395 void wc_Md5Free(wc_Md5* md5) 00396 { 00397 if (md5 == NULL) 00398 return; 00399 #if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5) 00400 wolfAsync_DevCtxFree(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5); 00401 #endif /* WOLFSSL_ASYNC_CRYPT */ 00402 } 00403 00404 int wc_Md5GetHash(wc_Md5* md5, byte* hash) 00405 { 00406 int ret; 00407 wc_Md5 tmpMd5; 00408 00409 if (md5 == NULL || hash == NULL) 00410 return BAD_FUNC_ARG; 00411 00412 ret = wc_Md5Copy(md5, &tmpMd5); 00413 if (ret == 0) { 00414 ret = wc_Md5Final(&tmpMd5, hash); 00415 } 00416 00417 return ret; 00418 } 00419 00420 int wc_Md5Copy(wc_Md5* src, wc_Md5* dst) 00421 { 00422 int ret = 0; 00423 00424 if (src == NULL || dst == NULL) 00425 return BAD_FUNC_ARG; 00426 00427 XMEMCPY(dst, src, sizeof(wc_Md5)); 00428 00429 #ifdef WOLFSSL_ASYNC_CRYPT 00430 ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev); 00431 #endif 00432 #ifdef WOLFSSL_PIC32MZ_HASH 00433 ret = wc_Pic32HashCopy(&src->cache, &dst->cache); 00434 #endif 00435 00436 return ret; 00437 } 00438 00439 #endif /* WOLFSSL_TI_HASH */ 00440 #endif /* NO_MD5 */ 00441
Generated on Tue Jul 12 2022 16:58:06 by
1.7.2