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 /* 00002 * RFC 1321 compliant MD5 implementation 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 /* 00022 * The MD5 algorithm was designed by Ron Rivest in 1991. 00023 * 00024 * http://www.ietf.org/rfc/rfc1321.txt 00025 */ 00026 00027 #if !defined(MBEDTLS_CONFIG_FILE) 00028 #include "mbedtls/config.h" 00029 #else 00030 #include MBEDTLS_CONFIG_FILE 00031 #endif 00032 00033 #if defined(MBEDTLS_MD5_C) 00034 00035 #include "mbedtls/md5.h" 00036 00037 #include <string.h> 00038 00039 #if defined(MBEDTLS_SELF_TEST) 00040 #if defined(MBEDTLS_PLATFORM_C) 00041 #include "mbedtls/platform.h" 00042 #else 00043 #include <stdio.h> 00044 #define mbedtls_printf printf 00045 #endif /* MBEDTLS_PLATFORM_C */ 00046 #endif /* MBEDTLS_SELF_TEST */ 00047 00048 #if !defined(MBEDTLS_MD5_ALT) 00049 00050 /* Implementation that should never be optimized out by the compiler */ 00051 static void mbedtls_zeroize( void *v, size_t n ) { 00052 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00053 } 00054 00055 /* 00056 * 32-bit integer manipulation macros (little endian) 00057 */ 00058 #ifndef GET_UINT32_LE 00059 #define GET_UINT32_LE(n,b,i) \ 00060 { \ 00061 (n) = ( (uint32_t) (b)[(i) ] ) \ 00062 | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 00063 | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 00064 | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 00065 } 00066 #endif 00067 00068 #ifndef PUT_UINT32_LE 00069 #define PUT_UINT32_LE(n,b,i) \ 00070 { \ 00071 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ 00072 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ 00073 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ 00074 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ 00075 } 00076 #endif 00077 00078 void mbedtls_md5_init( mbedtls_md5_context *ctx ) 00079 { 00080 memset( ctx, 0, sizeof( mbedtls_md5_context ) ); 00081 } 00082 00083 void mbedtls_md5_free( mbedtls_md5_context *ctx ) 00084 { 00085 if( ctx == NULL ) 00086 return; 00087 00088 mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) ); 00089 } 00090 00091 void mbedtls_md5_clone( mbedtls_md5_context *dst, 00092 const mbedtls_md5_context *src ) 00093 { 00094 *dst = *src; 00095 } 00096 00097 /* 00098 * MD5 context setup 00099 */ 00100 int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx ) 00101 { 00102 ctx->total [0] = 0; 00103 ctx->total [1] = 0; 00104 00105 ctx->state [0] = 0x67452301; 00106 ctx->state [1] = 0xEFCDAB89; 00107 ctx->state [2] = 0x98BADCFE; 00108 ctx->state [3] = 0x10325476; 00109 00110 return( 0 ); 00111 } 00112 00113 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00114 void mbedtls_md5_starts( mbedtls_md5_context *ctx ) 00115 { 00116 mbedtls_md5_starts_ret( ctx ); 00117 } 00118 #endif 00119 00120 #if !defined(MBEDTLS_MD5_PROCESS_ALT) 00121 int mbedtls_internal_md5_process( mbedtls_md5_context *ctx, 00122 const unsigned char data[64] ) 00123 { 00124 uint32_t X[16], A, B, C, D; 00125 00126 GET_UINT32_LE( X[ 0], data, 0 ); 00127 GET_UINT32_LE( X[ 1], data, 4 ); 00128 GET_UINT32_LE( X[ 2], data, 8 ); 00129 GET_UINT32_LE( X[ 3], data, 12 ); 00130 GET_UINT32_LE( X[ 4], data, 16 ); 00131 GET_UINT32_LE( X[ 5], data, 20 ); 00132 GET_UINT32_LE( X[ 6], data, 24 ); 00133 GET_UINT32_LE( X[ 7], data, 28 ); 00134 GET_UINT32_LE( X[ 8], data, 32 ); 00135 GET_UINT32_LE( X[ 9], data, 36 ); 00136 GET_UINT32_LE( X[10], data, 40 ); 00137 GET_UINT32_LE( X[11], data, 44 ); 00138 GET_UINT32_LE( X[12], data, 48 ); 00139 GET_UINT32_LE( X[13], data, 52 ); 00140 GET_UINT32_LE( X[14], data, 56 ); 00141 GET_UINT32_LE( X[15], data, 60 ); 00142 00143 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 00144 00145 #define P(a,b,c,d,k,s,t) \ 00146 { \ 00147 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ 00148 } 00149 00150 A = ctx->state [0]; 00151 B = ctx->state [1]; 00152 C = ctx->state [2]; 00153 D = ctx->state [3]; 00154 00155 #define F(x,y,z) (z ^ (x & (y ^ z))) 00156 00157 P( A, B, C, D, 0, 7, 0xD76AA478 ); 00158 P( D, A, B, C, 1, 12, 0xE8C7B756 ); 00159 P( C, D, A, B, 2, 17, 0x242070DB ); 00160 P( B, C, D, A, 3, 22, 0xC1BDCEEE ); 00161 P( A, B, C, D, 4, 7, 0xF57C0FAF ); 00162 P( D, A, B, C, 5, 12, 0x4787C62A ); 00163 P( C, D, A, B, 6, 17, 0xA8304613 ); 00164 P( B, C, D, A, 7, 22, 0xFD469501 ); 00165 P( A, B, C, D, 8, 7, 0x698098D8 ); 00166 P( D, A, B, C, 9, 12, 0x8B44F7AF ); 00167 P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); 00168 P( B, C, D, A, 11, 22, 0x895CD7BE ); 00169 P( A, B, C, D, 12, 7, 0x6B901122 ); 00170 P( D, A, B, C, 13, 12, 0xFD987193 ); 00171 P( C, D, A, B, 14, 17, 0xA679438E ); 00172 P( B, C, D, A, 15, 22, 0x49B40821 ); 00173 00174 #undef F 00175 00176 #define F(x,y,z) (y ^ (z & (x ^ y))) 00177 00178 P( A, B, C, D, 1, 5, 0xF61E2562 ); 00179 P( D, A, B, C, 6, 9, 0xC040B340 ); 00180 P( C, D, A, B, 11, 14, 0x265E5A51 ); 00181 P( B, C, D, A, 0, 20, 0xE9B6C7AA ); 00182 P( A, B, C, D, 5, 5, 0xD62F105D ); 00183 P( D, A, B, C, 10, 9, 0x02441453 ); 00184 P( C, D, A, B, 15, 14, 0xD8A1E681 ); 00185 P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); 00186 P( A, B, C, D, 9, 5, 0x21E1CDE6 ); 00187 P( D, A, B, C, 14, 9, 0xC33707D6 ); 00188 P( C, D, A, B, 3, 14, 0xF4D50D87 ); 00189 P( B, C, D, A, 8, 20, 0x455A14ED ); 00190 P( A, B, C, D, 13, 5, 0xA9E3E905 ); 00191 P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); 00192 P( C, D, A, B, 7, 14, 0x676F02D9 ); 00193 P( B, C, D, A, 12, 20, 0x8D2A4C8A ); 00194 00195 #undef F 00196 00197 #define F(x,y,z) (x ^ y ^ z) 00198 00199 P( A, B, C, D, 5, 4, 0xFFFA3942 ); 00200 P( D, A, B, C, 8, 11, 0x8771F681 ); 00201 P( C, D, A, B, 11, 16, 0x6D9D6122 ); 00202 P( B, C, D, A, 14, 23, 0xFDE5380C ); 00203 P( A, B, C, D, 1, 4, 0xA4BEEA44 ); 00204 P( D, A, B, C, 4, 11, 0x4BDECFA9 ); 00205 P( C, D, A, B, 7, 16, 0xF6BB4B60 ); 00206 P( B, C, D, A, 10, 23, 0xBEBFBC70 ); 00207 P( A, B, C, D, 13, 4, 0x289B7EC6 ); 00208 P( D, A, B, C, 0, 11, 0xEAA127FA ); 00209 P( C, D, A, B, 3, 16, 0xD4EF3085 ); 00210 P( B, C, D, A, 6, 23, 0x04881D05 ); 00211 P( A, B, C, D, 9, 4, 0xD9D4D039 ); 00212 P( D, A, B, C, 12, 11, 0xE6DB99E5 ); 00213 P( C, D, A, B, 15, 16, 0x1FA27CF8 ); 00214 P( B, C, D, A, 2, 23, 0xC4AC5665 ); 00215 00216 #undef F 00217 00218 #define F(x,y,z) (y ^ (x | ~z)) 00219 00220 P( A, B, C, D, 0, 6, 0xF4292244 ); 00221 P( D, A, B, C, 7, 10, 0x432AFF97 ); 00222 P( C, D, A, B, 14, 15, 0xAB9423A7 ); 00223 P( B, C, D, A, 5, 21, 0xFC93A039 ); 00224 P( A, B, C, D, 12, 6, 0x655B59C3 ); 00225 P( D, A, B, C, 3, 10, 0x8F0CCC92 ); 00226 P( C, D, A, B, 10, 15, 0xFFEFF47D ); 00227 P( B, C, D, A, 1, 21, 0x85845DD1 ); 00228 P( A, B, C, D, 8, 6, 0x6FA87E4F ); 00229 P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); 00230 P( C, D, A, B, 6, 15, 0xA3014314 ); 00231 P( B, C, D, A, 13, 21, 0x4E0811A1 ); 00232 P( A, B, C, D, 4, 6, 0xF7537E82 ); 00233 P( D, A, B, C, 11, 10, 0xBD3AF235 ); 00234 P( C, D, A, B, 2, 15, 0x2AD7D2BB ); 00235 P( B, C, D, A, 9, 21, 0xEB86D391 ); 00236 00237 #undef F 00238 00239 ctx->state [0] += A; 00240 ctx->state [1] += B; 00241 ctx->state [2] += C; 00242 ctx->state [3] += D; 00243 00244 return( 0 ); 00245 } 00246 00247 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00248 void mbedtls_md5_process( mbedtls_md5_context *ctx, 00249 const unsigned char data[64] ) 00250 { 00251 mbedtls_internal_md5_process( ctx, data ); 00252 } 00253 #endif 00254 #endif /* !MBEDTLS_MD5_PROCESS_ALT */ 00255 00256 /* 00257 * MD5 process buffer 00258 */ 00259 int mbedtls_md5_update_ret( mbedtls_md5_context *ctx, 00260 const unsigned char *input, 00261 size_t ilen ) 00262 { 00263 int ret; 00264 size_t fill; 00265 uint32_t left; 00266 00267 if( ilen == 0 ) 00268 return( 0 ); 00269 00270 left = ctx->total [0] & 0x3F; 00271 fill = 64 - left; 00272 00273 ctx->total [0] += (uint32_t) ilen; 00274 ctx->total [0] &= 0xFFFFFFFF; 00275 00276 if( ctx->total [0] < (uint32_t) ilen ) 00277 ctx->total [1]++; 00278 00279 if( left && ilen >= fill ) 00280 { 00281 memcpy( (void *) (ctx->buffer + left), input, fill ); 00282 if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 ) 00283 return( ret ); 00284 00285 input += fill; 00286 ilen -= fill; 00287 left = 0; 00288 } 00289 00290 while( ilen >= 64 ) 00291 { 00292 if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 ) 00293 return( ret ); 00294 00295 input += 64; 00296 ilen -= 64; 00297 } 00298 00299 if( ilen > 0 ) 00300 { 00301 memcpy( (void *) (ctx->buffer + left), input, ilen ); 00302 } 00303 00304 return( 0 ); 00305 } 00306 00307 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00308 void mbedtls_md5_update( mbedtls_md5_context *ctx, 00309 const unsigned char *input, 00310 size_t ilen ) 00311 { 00312 mbedtls_md5_update_ret( ctx, input, ilen ); 00313 } 00314 #endif 00315 00316 static const unsigned char md5_padding[64] = 00317 { 00318 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00322 }; 00323 00324 /* 00325 * MD5 final digest 00326 */ 00327 int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx, 00328 unsigned char output[16] ) 00329 { 00330 int ret; 00331 uint32_t last, padn; 00332 uint32_t high, low; 00333 unsigned char msglen[8]; 00334 00335 high = ( ctx->total [0] >> 29 ) 00336 | ( ctx->total [1] << 3 ); 00337 low = ( ctx->total [0] << 3 ); 00338 00339 PUT_UINT32_LE( low, msglen, 0 ); 00340 PUT_UINT32_LE( high, msglen, 4 ); 00341 00342 last = ctx->total [0] & 0x3F; 00343 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 00344 00345 if( ( ret = mbedtls_md5_update_ret( ctx, md5_padding, padn ) ) != 0 ) 00346 return( ret ); 00347 00348 if( ( ret = mbedtls_md5_update_ret( ctx, msglen, 8 ) ) != 0 ) 00349 return( ret ); 00350 00351 PUT_UINT32_LE( ctx->state [0], output, 0 ); 00352 PUT_UINT32_LE( ctx->state [1], output, 4 ); 00353 PUT_UINT32_LE( ctx->state [2], output, 8 ); 00354 PUT_UINT32_LE( ctx->state [3], output, 12 ); 00355 00356 return( 0 ); 00357 } 00358 00359 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00360 void mbedtls_md5_finish( mbedtls_md5_context *ctx, 00361 unsigned char output[16] ) 00362 { 00363 mbedtls_md5_finish_ret( ctx, output ); 00364 } 00365 #endif 00366 00367 #endif /* !MBEDTLS_MD5_ALT */ 00368 00369 /* 00370 * output = MD5( input buffer ) 00371 */ 00372 int mbedtls_md5_ret( const unsigned char *input, 00373 size_t ilen, 00374 unsigned char output[16] ) 00375 { 00376 int ret; 00377 mbedtls_md5_context ctx; 00378 00379 mbedtls_md5_init( &ctx ); 00380 00381 if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 ) 00382 goto exit; 00383 00384 if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 ) 00385 goto exit; 00386 00387 if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 ) 00388 goto exit; 00389 00390 exit: 00391 mbedtls_md5_free( &ctx ); 00392 00393 return( ret ); 00394 } 00395 00396 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00397 void mbedtls_md5( const unsigned char *input, 00398 size_t ilen, 00399 unsigned char output[16] ) 00400 { 00401 mbedtls_md5_ret( input, ilen, output ); 00402 } 00403 #endif 00404 00405 #if defined(MBEDTLS_SELF_TEST) 00406 /* 00407 * RFC 1321 test vectors 00408 */ 00409 static const unsigned char md5_test_buf[7][81] = 00410 { 00411 { "" }, 00412 { "a" }, 00413 { "abc" }, 00414 { "message digest" }, 00415 { "abcdefghijklmnopqrstuvwxyz" }, 00416 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 00417 { "12345678901234567890123456789012345678901234567890123456789012" 00418 "345678901234567890" } 00419 }; 00420 00421 static const size_t md5_test_buflen[7] = 00422 { 00423 0, 1, 3, 14, 26, 62, 80 00424 }; 00425 00426 static const unsigned char md5_test_sum[7][16] = 00427 { 00428 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, 00429 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, 00430 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, 00431 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, 00432 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, 00433 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, 00434 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, 00435 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, 00436 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, 00437 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, 00438 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, 00439 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, 00440 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, 00441 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } 00442 }; 00443 00444 /* 00445 * Checkup routine 00446 */ 00447 int mbedtls_md5_self_test( int verbose ) 00448 { 00449 int i, ret = 0; 00450 unsigned char md5sum[16]; 00451 00452 for( i = 0; i < 7; i++ ) 00453 { 00454 if( verbose != 0 ) 00455 mbedtls_printf( " MD5 test #%d: ", i + 1 ); 00456 00457 ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum ); 00458 if( ret != 0 ) 00459 goto fail; 00460 00461 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) 00462 { 00463 ret = 1; 00464 goto fail; 00465 } 00466 00467 if( verbose != 0 ) 00468 mbedtls_printf( "passed\n" ); 00469 } 00470 00471 if( verbose != 0 ) 00472 mbedtls_printf( "\n" ); 00473 00474 return( 0 ); 00475 00476 fail: 00477 if( verbose != 0 ) 00478 mbedtls_printf( "failed\n" ); 00479 00480 return( ret ); 00481 } 00482 00483 #endif /* MBEDTLS_SELF_TEST */ 00484 00485 #endif /* MBEDTLS_MD5_C */
Generated on Tue Jul 12 2022 12:22:12 by
