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-2016 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 #else 00035 00036 #ifdef WOLFSSL_PIC32MZ_HASH 00037 #define wc_InitMd5 wc_InitMd5_sw 00038 #define wc_Md5Update wc_Md5Update_sw 00039 #define wc_Md5Final wc_Md5Final_sw 00040 #endif 00041 00042 #include <wolfssl/wolfcrypt/md5.h> 00043 #include <wolfssl/wolfcrypt/error-crypt.h> 00044 00045 #ifdef NO_INLINE 00046 #include <wolfssl/wolfcrypt/misc.h> 00047 #else 00048 #include <wolfcrypt/src/misc.c> 00049 #endif 00050 00051 #ifdef FREESCALE_MMCAU 00052 #include "cau_api.h" 00053 #define XTRANSFORM(S,B) Transform((S), (B)) 00054 #else 00055 #define XTRANSFORM(S,B) Transform((S)) 00056 #endif 00057 00058 00059 #ifdef STM32F2_HASH 00060 /* 00061 * STM32F2 hardware MD5 support through the STM32F2 standard peripheral 00062 * library. Documentation located in STM32F2xx Standard Peripheral Library 00063 * document (See note in README). 00064 */ 00065 #include "stm32f2xx.h" 00066 00067 void wc_InitMd5(Md5* md5) 00068 { 00069 /* STM32F2 struct notes: 00070 * md5->buffer = first 4 bytes used to hold partial block if needed 00071 * md5->buffLen = num bytes currently stored in md5->buffer 00072 * md5->loLen = num bytes that have been written to STM32 FIFO 00073 */ 00074 XMEMSET(md5->buffer, 0, MD5_REG_SIZE); 00075 00076 md5->buffLen = 0; 00077 md5->loLen = 0; 00078 00079 /* initialize HASH peripheral */ 00080 HASH_DeInit(); 00081 00082 /* configure algo used, algo mode, datatype */ 00083 HASH->CR &= ~ (HASH_CR_ALGO | HASH_CR_DATATYPE | HASH_CR_MODE); 00084 HASH->CR |= (HASH_AlgoSelection_MD5 | HASH_AlgoMode_HASH 00085 | HASH_DataType_8b); 00086 00087 /* reset HASH processor */ 00088 HASH->CR |= HASH_CR_INIT; 00089 } 00090 00091 void wc_Md5Update(Md5* md5, const byte* data, word32 len) 00092 { 00093 word32 i = 0; 00094 word32 fill = 0; 00095 word32 diff = 0; 00096 00097 /* if saved partial block is available */ 00098 if (md5->buffLen > 0) { 00099 fill = 4 - md5->buffLen; 00100 00101 /* if enough data to fill, fill and push to FIFO */ 00102 if (fill <= len) { 00103 XMEMCPY((byte*)md5->buffer + md5->buffLen, data, fill); 00104 HASH_DataIn(*(uint32_t*)md5->buffer); 00105 00106 data += fill; 00107 len -= fill; 00108 md5->loLen += 4; 00109 md5->buffLen = 0; 00110 } else { 00111 /* append partial to existing stored block */ 00112 XMEMCPY((byte*)md5->buffer + md5->buffLen, data, len); 00113 md5->buffLen += len; 00114 return; 00115 } 00116 } 00117 00118 /* write input block in the IN FIFO */ 00119 for (i = 0; i < len; i += 4) 00120 { 00121 diff = len - i; 00122 if (diff < 4) { 00123 /* store incomplete last block, not yet in FIFO */ 00124 XMEMSET(md5->buffer, 0, MD5_REG_SIZE); 00125 XMEMCPY((byte*)md5->buffer, data, diff); 00126 md5->buffLen = diff; 00127 } else { 00128 HASH_DataIn(*(uint32_t*)data); 00129 data+=4; 00130 } 00131 } 00132 00133 /* keep track of total data length thus far */ 00134 md5->loLen += (len - md5->buffLen); 00135 } 00136 00137 void wc_Md5Final(Md5* md5, byte* hash) 00138 { 00139 __IO uint16_t nbvalidbitsdata = 0; 00140 00141 /* finish reading any trailing bytes into FIFO */ 00142 if (md5->buffLen > 0) { 00143 HASH_DataIn(*(uint32_t*)md5->buffer); 00144 md5->loLen += md5->buffLen; 00145 } 00146 00147 /* calculate number of valid bits in last word of input data */ 00148 nbvalidbitsdata = 8 * (md5->loLen % MD5_REG_SIZE); 00149 00150 /* configure number of valid bits in last word of the data */ 00151 HASH_SetLastWordValidBitsNbr(nbvalidbitsdata); 00152 00153 /* start HASH processor */ 00154 HASH_StartDigest(); 00155 00156 /* wait until Busy flag == RESET */ 00157 while (HASH_GetFlagStatus(HASH_FLAG_BUSY) != RESET) {} 00158 00159 /* read message digest */ 00160 md5->digest[0] = HASH->HR[0]; 00161 md5->digest[1] = HASH->HR[1]; 00162 md5->digest[2] = HASH->HR[2]; 00163 md5->digest[3] = HASH->HR[3]; 00164 00165 ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE); 00166 00167 XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE); 00168 00169 wc_InitMd5(md5); /* reset state */ 00170 } 00171 00172 #else /* CTaoCrypt software implementation */ 00173 00174 #ifndef WOLFSSL_HAVE_MIN 00175 #define WOLFSSL_HAVE_MIN 00176 00177 static INLINE word32 min(word32 a, word32 b) 00178 { 00179 return a > b ? b : a; 00180 } 00181 00182 #endif /* WOLFSSL_HAVE_MIN */ 00183 00184 void wc_InitMd5(Md5* md5) 00185 { 00186 md5->digest[0] = 0x67452301L; 00187 md5->digest[1] = 0xefcdab89L; 00188 md5->digest[2] = 0x98badcfeL; 00189 md5->digest[3] = 0x10325476L; 00190 00191 md5->buffLen = 0; 00192 md5->loLen = 0; 00193 md5->hiLen = 0; 00194 } 00195 00196 #ifdef FREESCALE_MMCAU 00197 static int Transform(Md5* md5, byte* data) 00198 { 00199 int ret = wolfSSL_CryptHwMutexLock(); 00200 if(ret == 0) { 00201 cau_md5_hash_n(data, 1, (unsigned char*)md5->digest); 00202 wolfSSL_CryptHwMutexUnLock(); 00203 } 00204 return ret; 00205 } 00206 #endif /* FREESCALE_MMCAU */ 00207 00208 #ifndef FREESCALE_MMCAU 00209 00210 static void Transform(Md5* md5) 00211 { 00212 #define F1(x, y, z) (z ^ (x & (y ^ z))) 00213 #define F2(x, y, z) F1(z, x, y) 00214 #define F3(x, y, z) (x ^ y ^ z) 00215 #define F4(x, y, z) (y ^ (x | ~z)) 00216 00217 #define MD5STEP(f, w, x, y, z, data, s) \ 00218 w = rotlFixed(w + f(x, y, z) + data, s) + x 00219 00220 /* Copy context->state[] to working vars */ 00221 word32 a = md5->digest[0]; 00222 word32 b = md5->digest[1]; 00223 word32 c = md5->digest[2]; 00224 word32 d = md5->digest[3]; 00225 00226 MD5STEP(F1, a, b, c, d, md5->buffer[0] + 0xd76aa478, 7); 00227 MD5STEP(F1, d, a, b, c, md5->buffer[1] + 0xe8c7b756, 12); 00228 MD5STEP(F1, c, d, a, b, md5->buffer[2] + 0x242070db, 17); 00229 MD5STEP(F1, b, c, d, a, md5->buffer[3] + 0xc1bdceee, 22); 00230 MD5STEP(F1, a, b, c, d, md5->buffer[4] + 0xf57c0faf, 7); 00231 MD5STEP(F1, d, a, b, c, md5->buffer[5] + 0x4787c62a, 12); 00232 MD5STEP(F1, c, d, a, b, md5->buffer[6] + 0xa8304613, 17); 00233 MD5STEP(F1, b, c, d, a, md5->buffer[7] + 0xfd469501, 22); 00234 MD5STEP(F1, a, b, c, d, md5->buffer[8] + 0x698098d8, 7); 00235 MD5STEP(F1, d, a, b, c, md5->buffer[9] + 0x8b44f7af, 12); 00236 MD5STEP(F1, c, d, a, b, md5->buffer[10] + 0xffff5bb1, 17); 00237 MD5STEP(F1, b, c, d, a, md5->buffer[11] + 0x895cd7be, 22); 00238 MD5STEP(F1, a, b, c, d, md5->buffer[12] + 0x6b901122, 7); 00239 MD5STEP(F1, d, a, b, c, md5->buffer[13] + 0xfd987193, 12); 00240 MD5STEP(F1, c, d, a, b, md5->buffer[14] + 0xa679438e, 17); 00241 MD5STEP(F1, b, c, d, a, md5->buffer[15] + 0x49b40821, 22); 00242 00243 MD5STEP(F2, a, b, c, d, md5->buffer[1] + 0xf61e2562, 5); 00244 MD5STEP(F2, d, a, b, c, md5->buffer[6] + 0xc040b340, 9); 00245 MD5STEP(F2, c, d, a, b, md5->buffer[11] + 0x265e5a51, 14); 00246 MD5STEP(F2, b, c, d, a, md5->buffer[0] + 0xe9b6c7aa, 20); 00247 MD5STEP(F2, a, b, c, d, md5->buffer[5] + 0xd62f105d, 5); 00248 MD5STEP(F2, d, a, b, c, md5->buffer[10] + 0x02441453, 9); 00249 MD5STEP(F2, c, d, a, b, md5->buffer[15] + 0xd8a1e681, 14); 00250 MD5STEP(F2, b, c, d, a, md5->buffer[4] + 0xe7d3fbc8, 20); 00251 MD5STEP(F2, a, b, c, d, md5->buffer[9] + 0x21e1cde6, 5); 00252 MD5STEP(F2, d, a, b, c, md5->buffer[14] + 0xc33707d6, 9); 00253 MD5STEP(F2, c, d, a, b, md5->buffer[3] + 0xf4d50d87, 14); 00254 MD5STEP(F2, b, c, d, a, md5->buffer[8] + 0x455a14ed, 20); 00255 MD5STEP(F2, a, b, c, d, md5->buffer[13] + 0xa9e3e905, 5); 00256 MD5STEP(F2, d, a, b, c, md5->buffer[2] + 0xfcefa3f8, 9); 00257 MD5STEP(F2, c, d, a, b, md5->buffer[7] + 0x676f02d9, 14); 00258 MD5STEP(F2, b, c, d, a, md5->buffer[12] + 0x8d2a4c8a, 20); 00259 00260 MD5STEP(F3, a, b, c, d, md5->buffer[5] + 0xfffa3942, 4); 00261 MD5STEP(F3, d, a, b, c, md5->buffer[8] + 0x8771f681, 11); 00262 MD5STEP(F3, c, d, a, b, md5->buffer[11] + 0x6d9d6122, 16); 00263 MD5STEP(F3, b, c, d, a, md5->buffer[14] + 0xfde5380c, 23); 00264 MD5STEP(F3, a, b, c, d, md5->buffer[1] + 0xa4beea44, 4); 00265 MD5STEP(F3, d, a, b, c, md5->buffer[4] + 0x4bdecfa9, 11); 00266 MD5STEP(F3, c, d, a, b, md5->buffer[7] + 0xf6bb4b60, 16); 00267 MD5STEP(F3, b, c, d, a, md5->buffer[10] + 0xbebfbc70, 23); 00268 MD5STEP(F3, a, b, c, d, md5->buffer[13] + 0x289b7ec6, 4); 00269 MD5STEP(F3, d, a, b, c, md5->buffer[0] + 0xeaa127fa, 11); 00270 MD5STEP(F3, c, d, a, b, md5->buffer[3] + 0xd4ef3085, 16); 00271 MD5STEP(F3, b, c, d, a, md5->buffer[6] + 0x04881d05, 23); 00272 MD5STEP(F3, a, b, c, d, md5->buffer[9] + 0xd9d4d039, 4); 00273 MD5STEP(F3, d, a, b, c, md5->buffer[12] + 0xe6db99e5, 11); 00274 MD5STEP(F3, c, d, a, b, md5->buffer[15] + 0x1fa27cf8, 16); 00275 MD5STEP(F3, b, c, d, a, md5->buffer[2] + 0xc4ac5665, 23); 00276 00277 MD5STEP(F4, a, b, c, d, md5->buffer[0] + 0xf4292244, 6); 00278 MD5STEP(F4, d, a, b, c, md5->buffer[7] + 0x432aff97, 10); 00279 MD5STEP(F4, c, d, a, b, md5->buffer[14] + 0xab9423a7, 15); 00280 MD5STEP(F4, b, c, d, a, md5->buffer[5] + 0xfc93a039, 21); 00281 MD5STEP(F4, a, b, c, d, md5->buffer[12] + 0x655b59c3, 6); 00282 MD5STEP(F4, d, a, b, c, md5->buffer[3] + 0x8f0ccc92, 10); 00283 MD5STEP(F4, c, d, a, b, md5->buffer[10] + 0xffeff47d, 15); 00284 MD5STEP(F4, b, c, d, a, md5->buffer[1] + 0x85845dd1, 21); 00285 MD5STEP(F4, a, b, c, d, md5->buffer[8] + 0x6fa87e4f, 6); 00286 MD5STEP(F4, d, a, b, c, md5->buffer[15] + 0xfe2ce6e0, 10); 00287 MD5STEP(F4, c, d, a, b, md5->buffer[6] + 0xa3014314, 15); 00288 MD5STEP(F4, b, c, d, a, md5->buffer[13] + 0x4e0811a1, 21); 00289 MD5STEP(F4, a, b, c, d, md5->buffer[4] + 0xf7537e82, 6); 00290 MD5STEP(F4, d, a, b, c, md5->buffer[11] + 0xbd3af235, 10); 00291 MD5STEP(F4, c, d, a, b, md5->buffer[2] + 0x2ad7d2bb, 15); 00292 MD5STEP(F4, b, c, d, a, md5->buffer[9] + 0xeb86d391, 21); 00293 00294 /* Add the working vars back into digest state[] */ 00295 md5->digest[0] += a; 00296 md5->digest[1] += b; 00297 md5->digest[2] += c; 00298 md5->digest[3] += d; 00299 } 00300 00301 #endif /* FREESCALE_MMCAU */ 00302 00303 00304 static INLINE void AddLength(Md5* md5, word32 len) 00305 { 00306 word32 tmp = md5->loLen; 00307 if ( (md5->loLen += len) < tmp) 00308 md5->hiLen++; /* carry low to high */ 00309 } 00310 00311 00312 void wc_Md5Update(Md5* md5, const byte* data, word32 len) 00313 { 00314 /* do block size increments */ 00315 byte* local = (byte*)md5->buffer; 00316 00317 while (len) { 00318 word32 add = min(len, MD5_BLOCK_SIZE - md5->buffLen); 00319 XMEMCPY(&local[md5->buffLen], data, add); 00320 00321 md5->buffLen += add; 00322 data += add; 00323 len -= add; 00324 00325 if (md5->buffLen == MD5_BLOCK_SIZE) { 00326 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) 00327 ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); 00328 #endif 00329 XTRANSFORM(md5, local); 00330 AddLength(md5, MD5_BLOCK_SIZE); 00331 md5->buffLen = 0; 00332 } 00333 } 00334 } 00335 00336 00337 void wc_Md5Final(Md5* md5, byte* hash) 00338 { 00339 byte* local = (byte*)md5->buffer; 00340 00341 AddLength(md5, md5->buffLen); /* before adding pads */ 00342 00343 local[md5->buffLen++] = 0x80; /* add 1 */ 00344 00345 /* pad with zeros */ 00346 if (md5->buffLen > MD5_PAD_SIZE) { 00347 XMEMSET(&local[md5->buffLen], 0, MD5_BLOCK_SIZE - md5->buffLen); 00348 md5->buffLen += MD5_BLOCK_SIZE - md5->buffLen; 00349 00350 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) 00351 ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); 00352 #endif 00353 XTRANSFORM(md5, local); 00354 md5->buffLen = 0; 00355 } 00356 XMEMSET(&local[md5->buffLen], 0, MD5_PAD_SIZE - md5->buffLen); 00357 00358 /* put lengths in bits */ 00359 md5->hiLen = (md5->loLen >> (8*sizeof(md5->loLen) - 3)) + 00360 (md5->hiLen << 3); 00361 md5->loLen = md5->loLen << 3; 00362 00363 /* store lengths */ 00364 #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU) 00365 ByteReverseWords(md5->buffer, md5->buffer, MD5_BLOCK_SIZE); 00366 #endif 00367 /* ! length ordering dependent on digest endian type ! */ 00368 XMEMCPY(&local[MD5_PAD_SIZE], &md5->loLen, sizeof(word32)); 00369 XMEMCPY(&local[MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32)); 00370 00371 XTRANSFORM(md5, local); 00372 #ifdef BIG_ENDIAN_ORDER 00373 ByteReverseWords(md5->digest, md5->digest, MD5_DIGEST_SIZE); 00374 #endif 00375 XMEMCPY(hash, md5->digest, MD5_DIGEST_SIZE); 00376 00377 wc_InitMd5(md5); /* reset state */ 00378 } 00379 00380 #endif /* STM32F2_HASH */ 00381 00382 00383 int wc_Md5Hash(const byte* data, word32 len, byte* hash) 00384 { 00385 #ifdef WOLFSSL_SMALL_STACK 00386 Md5* md5; 00387 #else 00388 Md5 md5[1]; 00389 #endif 00390 00391 #ifdef WOLFSSL_SMALL_STACK 00392 md5 = (Md5*)XMALLOC(sizeof(Md5), NULL, DYNAMIC_TYPE_TMP_BUFFER); 00393 if (md5 == NULL) 00394 return MEMORY_E; 00395 #endif 00396 00397 wc_InitMd5(md5); 00398 wc_Md5Update(md5, data, len); 00399 wc_Md5Final(md5, hash); 00400 00401 #ifdef WOLFSSL_SMALL_STACK 00402 XFREE(md5, NULL, DYNAMIC_TYPE_TMP_BUFFER); 00403 #endif 00404 00405 return 0; 00406 } 00407 00408 #endif /* WOLFSSL_TI_HASH */ 00409 00410 #endif /* NO_MD5 */ 00411
Generated on Tue Jul 12 2022 15:55:20 by
1.7.2