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