1 // SPDX-License-Identifier: Apache-2.0 2 /* 3 * RFC 1321 compliant MD5 implementation 4 * 5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); you may 8 * not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 * This file is part of mbed TLS (https://tls.mbed.org) 20 */ 21 /* 22 * The MD5 algorithm was designed by Ron Rivest in 1991. 23 * 24 * http://www.ietf.org/rfc/rfc1321.txt 25 */ 26 27 #if !defined(MBEDTLS_CONFIG_FILE) 28 #include "mbedtls/config.h" 29 #else 30 #include MBEDTLS_CONFIG_FILE 31 #endif 32 33 #if defined(MBEDTLS_MD5_C) 34 35 #include "mbedtls/md5.h" 36 37 #include <string.h> 38 39 #if defined(MBEDTLS_SELF_TEST) 40 #if defined(MBEDTLS_PLATFORM_C) 41 #include "mbedtls/platform.h" 42 #else 43 #include <stdio.h> 44 #define mbedtls_printf printf 45 #endif /* MBEDTLS_PLATFORM_C */ 46 #endif /* MBEDTLS_SELF_TEST */ 47 48 #if !defined(MBEDTLS_MD5_ALT) 49 50 /* Implementation that should never be optimized out by the compiler */ 51 static void mbedtls_zeroize( void *v, size_t n ) { 52 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 53 } 54 55 /* 56 * 32-bit integer manipulation macros (little endian) 57 */ 58 #ifndef GET_UINT32_LE 59 #define GET_UINT32_LE(n,b,i) \ 60 { \ 61 (n) = ( (uint32_t) (b)[(i) ] ) \ 62 | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 63 | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 64 | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 65 } 66 #endif 67 68 #ifndef PUT_UINT32_LE 69 #define PUT_UINT32_LE(n,b,i) \ 70 { \ 71 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ 72 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ 73 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ 74 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ 75 } 76 #endif 77 78 void mbedtls_md5_init( mbedtls_md5_context *ctx ) 79 { 80 memset( ctx, 0, sizeof( mbedtls_md5_context ) ); 81 } 82 83 void mbedtls_md5_free( mbedtls_md5_context *ctx ) 84 { 85 if( ctx == NULL ) 86 return; 87 88 mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) ); 89 } 90 91 void mbedtls_md5_clone( mbedtls_md5_context *dst, 92 const mbedtls_md5_context *src ) 93 { 94 *dst = *src; 95 } 96 97 /* 98 * MD5 context setup 99 */ 100 void mbedtls_md5_starts( mbedtls_md5_context *ctx ) 101 { 102 ctx->total[0] = 0; 103 ctx->total[1] = 0; 104 105 ctx->state[0] = 0x67452301; 106 ctx->state[1] = 0xEFCDAB89; 107 ctx->state[2] = 0x98BADCFE; 108 ctx->state[3] = 0x10325476; 109 } 110 111 #if !defined(MBEDTLS_MD5_PROCESS_ALT) 112 void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ) 113 { 114 uint32_t X[16], A, B, C, D; 115 116 GET_UINT32_LE( X[ 0], data, 0 ); 117 GET_UINT32_LE( X[ 1], data, 4 ); 118 GET_UINT32_LE( X[ 2], data, 8 ); 119 GET_UINT32_LE( X[ 3], data, 12 ); 120 GET_UINT32_LE( X[ 4], data, 16 ); 121 GET_UINT32_LE( X[ 5], data, 20 ); 122 GET_UINT32_LE( X[ 6], data, 24 ); 123 GET_UINT32_LE( X[ 7], data, 28 ); 124 GET_UINT32_LE( X[ 8], data, 32 ); 125 GET_UINT32_LE( X[ 9], data, 36 ); 126 GET_UINT32_LE( X[10], data, 40 ); 127 GET_UINT32_LE( X[11], data, 44 ); 128 GET_UINT32_LE( X[12], data, 48 ); 129 GET_UINT32_LE( X[13], data, 52 ); 130 GET_UINT32_LE( X[14], data, 56 ); 131 GET_UINT32_LE( X[15], data, 60 ); 132 133 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 134 135 #define P(a,b,c,d,k,s,t) \ 136 { \ 137 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ 138 } 139 140 A = ctx->state[0]; 141 B = ctx->state[1]; 142 C = ctx->state[2]; 143 D = ctx->state[3]; 144 145 #define F(x,y,z) (z ^ (x & (y ^ z))) 146 147 P( A, B, C, D, 0, 7, 0xD76AA478 ); 148 P( D, A, B, C, 1, 12, 0xE8C7B756 ); 149 P( C, D, A, B, 2, 17, 0x242070DB ); 150 P( B, C, D, A, 3, 22, 0xC1BDCEEE ); 151 P( A, B, C, D, 4, 7, 0xF57C0FAF ); 152 P( D, A, B, C, 5, 12, 0x4787C62A ); 153 P( C, D, A, B, 6, 17, 0xA8304613 ); 154 P( B, C, D, A, 7, 22, 0xFD469501 ); 155 P( A, B, C, D, 8, 7, 0x698098D8 ); 156 P( D, A, B, C, 9, 12, 0x8B44F7AF ); 157 P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); 158 P( B, C, D, A, 11, 22, 0x895CD7BE ); 159 P( A, B, C, D, 12, 7, 0x6B901122 ); 160 P( D, A, B, C, 13, 12, 0xFD987193 ); 161 P( C, D, A, B, 14, 17, 0xA679438E ); 162 P( B, C, D, A, 15, 22, 0x49B40821 ); 163 164 #undef F 165 166 #define F(x,y,z) (y ^ (z & (x ^ y))) 167 168 P( A, B, C, D, 1, 5, 0xF61E2562 ); 169 P( D, A, B, C, 6, 9, 0xC040B340 ); 170 P( C, D, A, B, 11, 14, 0x265E5A51 ); 171 P( B, C, D, A, 0, 20, 0xE9B6C7AA ); 172 P( A, B, C, D, 5, 5, 0xD62F105D ); 173 P( D, A, B, C, 10, 9, 0x02441453 ); 174 P( C, D, A, B, 15, 14, 0xD8A1E681 ); 175 P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); 176 P( A, B, C, D, 9, 5, 0x21E1CDE6 ); 177 P( D, A, B, C, 14, 9, 0xC33707D6 ); 178 P( C, D, A, B, 3, 14, 0xF4D50D87 ); 179 P( B, C, D, A, 8, 20, 0x455A14ED ); 180 P( A, B, C, D, 13, 5, 0xA9E3E905 ); 181 P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); 182 P( C, D, A, B, 7, 14, 0x676F02D9 ); 183 P( B, C, D, A, 12, 20, 0x8D2A4C8A ); 184 185 #undef F 186 187 #define F(x,y,z) (x ^ y ^ z) 188 189 P( A, B, C, D, 5, 4, 0xFFFA3942 ); 190 P( D, A, B, C, 8, 11, 0x8771F681 ); 191 P( C, D, A, B, 11, 16, 0x6D9D6122 ); 192 P( B, C, D, A, 14, 23, 0xFDE5380C ); 193 P( A, B, C, D, 1, 4, 0xA4BEEA44 ); 194 P( D, A, B, C, 4, 11, 0x4BDECFA9 ); 195 P( C, D, A, B, 7, 16, 0xF6BB4B60 ); 196 P( B, C, D, A, 10, 23, 0xBEBFBC70 ); 197 P( A, B, C, D, 13, 4, 0x289B7EC6 ); 198 P( D, A, B, C, 0, 11, 0xEAA127FA ); 199 P( C, D, A, B, 3, 16, 0xD4EF3085 ); 200 P( B, C, D, A, 6, 23, 0x04881D05 ); 201 P( A, B, C, D, 9, 4, 0xD9D4D039 ); 202 P( D, A, B, C, 12, 11, 0xE6DB99E5 ); 203 P( C, D, A, B, 15, 16, 0x1FA27CF8 ); 204 P( B, C, D, A, 2, 23, 0xC4AC5665 ); 205 206 #undef F 207 208 #define F(x,y,z) (y ^ (x | ~z)) 209 210 P( A, B, C, D, 0, 6, 0xF4292244 ); 211 P( D, A, B, C, 7, 10, 0x432AFF97 ); 212 P( C, D, A, B, 14, 15, 0xAB9423A7 ); 213 P( B, C, D, A, 5, 21, 0xFC93A039 ); 214 P( A, B, C, D, 12, 6, 0x655B59C3 ); 215 P( D, A, B, C, 3, 10, 0x8F0CCC92 ); 216 P( C, D, A, B, 10, 15, 0xFFEFF47D ); 217 P( B, C, D, A, 1, 21, 0x85845DD1 ); 218 P( A, B, C, D, 8, 6, 0x6FA87E4F ); 219 P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); 220 P( C, D, A, B, 6, 15, 0xA3014314 ); 221 P( B, C, D, A, 13, 21, 0x4E0811A1 ); 222 P( A, B, C, D, 4, 6, 0xF7537E82 ); 223 P( D, A, B, C, 11, 10, 0xBD3AF235 ); 224 P( C, D, A, B, 2, 15, 0x2AD7D2BB ); 225 P( B, C, D, A, 9, 21, 0xEB86D391 ); 226 227 #undef F 228 229 ctx->state[0] += A; 230 ctx->state[1] += B; 231 ctx->state[2] += C; 232 ctx->state[3] += D; 233 } 234 #endif /* !MBEDTLS_MD5_PROCESS_ALT */ 235 236 /* 237 * MD5 process buffer 238 */ 239 void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen ) 240 { 241 size_t fill; 242 uint32_t left; 243 244 if( ilen == 0 ) 245 return; 246 247 left = ctx->total[0] & 0x3F; 248 fill = 64 - left; 249 250 ctx->total[0] += (uint32_t) ilen; 251 ctx->total[0] &= 0xFFFFFFFF; 252 253 if( ctx->total[0] < (uint32_t) ilen ) 254 ctx->total[1]++; 255 256 if( left && ilen >= fill ) 257 { 258 memcpy( (void *) (ctx->buffer + left), input, fill ); 259 mbedtls_md5_process( ctx, ctx->buffer ); 260 input += fill; 261 ilen -= fill; 262 left = 0; 263 } 264 265 while( ilen >= 64 ) 266 { 267 mbedtls_md5_process( ctx, input ); 268 input += 64; 269 ilen -= 64; 270 } 271 272 if( ilen > 0 ) 273 { 274 memcpy( (void *) (ctx->buffer + left), input, ilen ); 275 } 276 } 277 278 static const unsigned char md5_padding[64] = 279 { 280 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 284 }; 285 286 /* 287 * MD5 final digest 288 */ 289 void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ) 290 { 291 uint32_t last, padn; 292 uint32_t high, low; 293 unsigned char msglen[8]; 294 295 high = ( ctx->total[0] >> 29 ) 296 | ( ctx->total[1] << 3 ); 297 low = ( ctx->total[0] << 3 ); 298 299 PUT_UINT32_LE( low, msglen, 0 ); 300 PUT_UINT32_LE( high, msglen, 4 ); 301 302 last = ctx->total[0] & 0x3F; 303 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 304 305 mbedtls_md5_update( ctx, md5_padding, padn ); 306 mbedtls_md5_update( ctx, msglen, 8 ); 307 308 PUT_UINT32_LE( ctx->state[0], output, 0 ); 309 PUT_UINT32_LE( ctx->state[1], output, 4 ); 310 PUT_UINT32_LE( ctx->state[2], output, 8 ); 311 PUT_UINT32_LE( ctx->state[3], output, 12 ); 312 } 313 314 #endif /* !MBEDTLS_MD5_ALT */ 315 316 /* 317 * output = MD5( input buffer ) 318 */ 319 void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) 320 { 321 mbedtls_md5_context ctx; 322 323 mbedtls_md5_init( &ctx ); 324 mbedtls_md5_starts( &ctx ); 325 mbedtls_md5_update( &ctx, input, ilen ); 326 mbedtls_md5_finish( &ctx, output ); 327 mbedtls_md5_free( &ctx ); 328 } 329 330 #if defined(MBEDTLS_SELF_TEST) 331 /* 332 * RFC 1321 test vectors 333 */ 334 static const unsigned char md5_test_buf[7][81] = 335 { 336 { "" }, 337 { "a" }, 338 { "abc" }, 339 { "message digest" }, 340 { "abcdefghijklmnopqrstuvwxyz" }, 341 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 342 { "12345678901234567890123456789012345678901234567890123456789012" \ 343 "345678901234567890" } 344 }; 345 346 static const int md5_test_buflen[7] = 347 { 348 0, 1, 3, 14, 26, 62, 80 349 }; 350 351 static const unsigned char md5_test_sum[7][16] = 352 { 353 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, 354 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, 355 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, 356 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, 357 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, 358 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, 359 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, 360 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, 361 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, 362 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, 363 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, 364 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, 365 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, 366 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } 367 }; 368 369 /* 370 * Checkup routine 371 */ 372 int mbedtls_md5_self_test( int verbose ) 373 { 374 int i; 375 unsigned char md5sum[16]; 376 377 for( i = 0; i < 7; i++ ) 378 { 379 if( verbose != 0 ) 380 mbedtls_printf( " MD5 test #%d: ", i + 1 ); 381 382 mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); 383 384 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) 385 { 386 if( verbose != 0 ) 387 mbedtls_printf( "failed\n" ); 388 389 return( 1 ); 390 } 391 392 if( verbose != 0 ) 393 mbedtls_printf( "passed\n" ); 394 } 395 396 if( verbose != 0 ) 397 mbedtls_printf( "\n" ); 398 399 return( 0 ); 400 } 401 402 #endif /* MBEDTLS_SELF_TEST */ 403 404 #endif /* MBEDTLS_MD5_C */ 405