2 * RFC 1321 compliant MD5 implementation
4 * Copyright (C) 2006-2013, Brainspark B.V.
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 * The MD5 algorithm was designed by Ron Rivest in 1991.
28 * http://www.ietf.org/rfc/rfc1321.txt
33 #if defined(POLARSSL_MD5_C)
37 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
41 #if !defined(POLARSSL_MD5_ALT)
44 * 32-bit integer manipulation macros (little endian)
47 #define GET_UINT32_LE(n,b,i) \
49 (n) = ( (uint32_t) (b)[(i) ] ) \
50 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
51 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
52 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
57 #define PUT_UINT32_LE(n,b,i) \
59 (b)[(i) ] = (unsigned char) ( (n) ); \
60 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
61 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
62 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
69 void md5_starts( md5_context
*ctx
)
74 ctx
->state
[0] = 0x67452301;
75 ctx
->state
[1] = 0xEFCDAB89;
76 ctx
->state
[2] = 0x98BADCFE;
77 ctx
->state
[3] = 0x10325476;
80 void md5_process( md5_context
*ctx
, const unsigned char data
[64] )
82 uint32_t X
[16], A
, B
, C
, D
;
84 GET_UINT32_LE( X
[ 0], data
, 0 );
85 GET_UINT32_LE( X
[ 1], data
, 4 );
86 GET_UINT32_LE( X
[ 2], data
, 8 );
87 GET_UINT32_LE( X
[ 3], data
, 12 );
88 GET_UINT32_LE( X
[ 4], data
, 16 );
89 GET_UINT32_LE( X
[ 5], data
, 20 );
90 GET_UINT32_LE( X
[ 6], data
, 24 );
91 GET_UINT32_LE( X
[ 7], data
, 28 );
92 GET_UINT32_LE( X
[ 8], data
, 32 );
93 GET_UINT32_LE( X
[ 9], data
, 36 );
94 GET_UINT32_LE( X
[10], data
, 40 );
95 GET_UINT32_LE( X
[11], data
, 44 );
96 GET_UINT32_LE( X
[12], data
, 48 );
97 GET_UINT32_LE( X
[13], data
, 52 );
98 GET_UINT32_LE( X
[14], data
, 56 );
99 GET_UINT32_LE( X
[15], data
, 60 );
101 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
103 #define P(a,b,c,d,k,s,t) \
105 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
113 #define F(x,y,z) (z ^ (x & (y ^ z)))
115 P( A
, B
, C
, D
, 0, 7, 0xD76AA478 );
116 P( D
, A
, B
, C
, 1, 12, 0xE8C7B756 );
117 P( C
, D
, A
, B
, 2, 17, 0x242070DB );
118 P( B
, C
, D
, A
, 3, 22, 0xC1BDCEEE );
119 P( A
, B
, C
, D
, 4, 7, 0xF57C0FAF );
120 P( D
, A
, B
, C
, 5, 12, 0x4787C62A );
121 P( C
, D
, A
, B
, 6, 17, 0xA8304613 );
122 P( B
, C
, D
, A
, 7, 22, 0xFD469501 );
123 P( A
, B
, C
, D
, 8, 7, 0x698098D8 );
124 P( D
, A
, B
, C
, 9, 12, 0x8B44F7AF );
125 P( C
, D
, A
, B
, 10, 17, 0xFFFF5BB1 );
126 P( B
, C
, D
, A
, 11, 22, 0x895CD7BE );
127 P( A
, B
, C
, D
, 12, 7, 0x6B901122 );
128 P( D
, A
, B
, C
, 13, 12, 0xFD987193 );
129 P( C
, D
, A
, B
, 14, 17, 0xA679438E );
130 P( B
, C
, D
, A
, 15, 22, 0x49B40821 );
134 #define F(x,y,z) (y ^ (z & (x ^ y)))
136 P( A
, B
, C
, D
, 1, 5, 0xF61E2562 );
137 P( D
, A
, B
, C
, 6, 9, 0xC040B340 );
138 P( C
, D
, A
, B
, 11, 14, 0x265E5A51 );
139 P( B
, C
, D
, A
, 0, 20, 0xE9B6C7AA );
140 P( A
, B
, C
, D
, 5, 5, 0xD62F105D );
141 P( D
, A
, B
, C
, 10, 9, 0x02441453 );
142 P( C
, D
, A
, B
, 15, 14, 0xD8A1E681 );
143 P( B
, C
, D
, A
, 4, 20, 0xE7D3FBC8 );
144 P( A
, B
, C
, D
, 9, 5, 0x21E1CDE6 );
145 P( D
, A
, B
, C
, 14, 9, 0xC33707D6 );
146 P( C
, D
, A
, B
, 3, 14, 0xF4D50D87 );
147 P( B
, C
, D
, A
, 8, 20, 0x455A14ED );
148 P( A
, B
, C
, D
, 13, 5, 0xA9E3E905 );
149 P( D
, A
, B
, C
, 2, 9, 0xFCEFA3F8 );
150 P( C
, D
, A
, B
, 7, 14, 0x676F02D9 );
151 P( B
, C
, D
, A
, 12, 20, 0x8D2A4C8A );
155 #define F(x,y,z) (x ^ y ^ z)
157 P( A
, B
, C
, D
, 5, 4, 0xFFFA3942 );
158 P( D
, A
, B
, C
, 8, 11, 0x8771F681 );
159 P( C
, D
, A
, B
, 11, 16, 0x6D9D6122 );
160 P( B
, C
, D
, A
, 14, 23, 0xFDE5380C );
161 P( A
, B
, C
, D
, 1, 4, 0xA4BEEA44 );
162 P( D
, A
, B
, C
, 4, 11, 0x4BDECFA9 );
163 P( C
, D
, A
, B
, 7, 16, 0xF6BB4B60 );
164 P( B
, C
, D
, A
, 10, 23, 0xBEBFBC70 );
165 P( A
, B
, C
, D
, 13, 4, 0x289B7EC6 );
166 P( D
, A
, B
, C
, 0, 11, 0xEAA127FA );
167 P( C
, D
, A
, B
, 3, 16, 0xD4EF3085 );
168 P( B
, C
, D
, A
, 6, 23, 0x04881D05 );
169 P( A
, B
, C
, D
, 9, 4, 0xD9D4D039 );
170 P( D
, A
, B
, C
, 12, 11, 0xE6DB99E5 );
171 P( C
, D
, A
, B
, 15, 16, 0x1FA27CF8 );
172 P( B
, C
, D
, A
, 2, 23, 0xC4AC5665 );
176 #define F(x,y,z) (y ^ (x | ~z))
178 P( A
, B
, C
, D
, 0, 6, 0xF4292244 );
179 P( D
, A
, B
, C
, 7, 10, 0x432AFF97 );
180 P( C
, D
, A
, B
, 14, 15, 0xAB9423A7 );
181 P( B
, C
, D
, A
, 5, 21, 0xFC93A039 );
182 P( A
, B
, C
, D
, 12, 6, 0x655B59C3 );
183 P( D
, A
, B
, C
, 3, 10, 0x8F0CCC92 );
184 P( C
, D
, A
, B
, 10, 15, 0xFFEFF47D );
185 P( B
, C
, D
, A
, 1, 21, 0x85845DD1 );
186 P( A
, B
, C
, D
, 8, 6, 0x6FA87E4F );
187 P( D
, A
, B
, C
, 15, 10, 0xFE2CE6E0 );
188 P( C
, D
, A
, B
, 6, 15, 0xA3014314 );
189 P( B
, C
, D
, A
, 13, 21, 0x4E0811A1 );
190 P( A
, B
, C
, D
, 4, 6, 0xF7537E82 );
191 P( D
, A
, B
, C
, 11, 10, 0xBD3AF235 );
192 P( C
, D
, A
, B
, 2, 15, 0x2AD7D2BB );
193 P( B
, C
, D
, A
, 9, 21, 0xEB86D391 );
206 void md5_update( md5_context
*ctx
, const unsigned char *input
, size_t ilen
)
214 left
= ctx
->total
[0] & 0x3F;
217 ctx
->total
[0] += (uint32_t) ilen
;
218 ctx
->total
[0] &= 0xFFFFFFFF;
220 if( ctx
->total
[0] < (uint32_t) ilen
)
223 if( left
&& ilen
>= fill
)
225 memcpy( (void *) (ctx
->buffer
+ left
), input
, fill
);
226 md5_process( ctx
, ctx
->buffer
);
234 md5_process( ctx
, input
);
241 memcpy( (void *) (ctx
->buffer
+ left
), input
, ilen
);
245 static const unsigned char md5_padding
[64] =
247 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
249 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
256 void md5_finish( md5_context
*ctx
, unsigned char output
[16] )
260 unsigned char msglen
[8];
262 high
= ( ctx
->total
[0] >> 29 )
263 | ( ctx
->total
[1] << 3 );
264 low
= ( ctx
->total
[0] << 3 );
266 PUT_UINT32_LE( low
, msglen
, 0 );
267 PUT_UINT32_LE( high
, msglen
, 4 );
269 last
= ctx
->total
[0] & 0x3F;
270 padn
= ( last
< 56 ) ? ( 56 - last
) : ( 120 - last
);
272 md5_update( ctx
, md5_padding
, padn
);
273 md5_update( ctx
, msglen
, 8 );
275 PUT_UINT32_LE( ctx
->state
[0], output
, 0 );
276 PUT_UINT32_LE( ctx
->state
[1], output
, 4 );
277 PUT_UINT32_LE( ctx
->state
[2], output
, 8 );
278 PUT_UINT32_LE( ctx
->state
[3], output
, 12 );
281 #endif /* !POLARSSL_MD5_ALT */
284 * output = MD5( input buffer )
286 void md5( const unsigned char *input
, size_t ilen
, unsigned char output
[16] )
291 md5_update( &ctx
, input
, ilen
);
292 md5_finish( &ctx
, output
);
294 memset( &ctx
, 0, sizeof( md5_context
) );
297 #if defined(POLARSSL_FS_IO)
299 * output = MD5( file contents )
301 int md5_file( const char *path
, unsigned char output
[16] )
306 unsigned char buf
[1024];
308 if( ( f
= fopen( path
, "rb" ) ) == NULL
)
309 return( POLARSSL_ERR_MD5_FILE_IO_ERROR
);
313 while( ( n
= fread( buf
, 1, sizeof( buf
), f
) ) > 0 )
314 md5_update( &ctx
, buf
, n
);
316 md5_finish( &ctx
, output
);
318 memset( &ctx
, 0, sizeof( md5_context
) );
320 if( ferror( f
) != 0 )
323 return( POLARSSL_ERR_MD5_FILE_IO_ERROR
);
329 #endif /* POLARSSL_FS_IO */
332 * MD5 HMAC context setup
334 void md5_hmac_starts( md5_context
*ctx
, const unsigned char *key
, size_t keylen
)
337 unsigned char sum
[16];
341 md5( key
, keylen
, sum
);
346 memset( ctx
->ipad
, 0x36, 64 );
347 memset( ctx
->opad
, 0x5C, 64 );
349 for( i
= 0; i
< keylen
; i
++ )
351 ctx
->ipad
[i
] = (unsigned char)( ctx
->ipad
[i
] ^ key
[i
] );
352 ctx
->opad
[i
] = (unsigned char)( ctx
->opad
[i
] ^ key
[i
] );
356 md5_update( ctx
, ctx
->ipad
, 64 );
358 memset( sum
, 0, sizeof( sum
) );
362 * MD5 HMAC process buffer
364 void md5_hmac_update( md5_context
*ctx
, const unsigned char *input
, size_t ilen
)
366 md5_update( ctx
, input
, ilen
);
370 * MD5 HMAC final digest
372 void md5_hmac_finish( md5_context
*ctx
, unsigned char output
[16] )
374 unsigned char tmpbuf
[16];
376 md5_finish( ctx
, tmpbuf
);
378 md5_update( ctx
, ctx
->opad
, 64 );
379 md5_update( ctx
, tmpbuf
, 16 );
380 md5_finish( ctx
, output
);
382 memset( tmpbuf
, 0, sizeof( tmpbuf
) );
386 * MD5 HMAC context reset
388 void md5_hmac_reset( md5_context
*ctx
)
391 md5_update( ctx
, ctx
->ipad
, 64 );
395 * output = HMAC-MD5( hmac key, input buffer )
397 void md5_hmac( const unsigned char *key
, size_t keylen
,
398 const unsigned char *input
, size_t ilen
,
399 unsigned char output
[16] )
403 md5_hmac_starts( &ctx
, key
, keylen
);
404 md5_hmac_update( &ctx
, input
, ilen
);
405 md5_hmac_finish( &ctx
, output
);
407 memset( &ctx
, 0, sizeof( md5_context
) );
410 #if defined(POLARSSL_SELF_TEST)
412 * RFC 1321 test vectors
414 static unsigned char md5_test_buf
[7][81] =
419 { "message digest" },
420 { "abcdefghijklmnopqrstuvwxyz" },
421 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
422 { "12345678901234567890123456789012345678901234567890123456789012" \
423 "345678901234567890" }
426 static const int md5_test_buflen
[7] =
428 0, 1, 3, 14, 26, 62, 80
431 static const unsigned char md5_test_sum
[7][16] =
433 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
434 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
435 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
436 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
437 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
438 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
439 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
440 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
441 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
442 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
443 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
444 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
445 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
446 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
450 * RFC 2202 test vectors
452 static unsigned char md5_hmac_test_key
[7][26] =
454 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
456 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
457 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
458 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
459 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
460 { "" }, /* 0xAA 80 times */
464 static const int md5_hmac_test_keylen
[7] =
466 16, 4, 16, 25, 16, 80, 80
469 static unsigned char md5_hmac_test_buf
[7][74] =
472 { "what do ya want for nothing?" },
473 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
474 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
475 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
476 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
477 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
478 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
479 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
480 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
481 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
482 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
483 { "Test With Truncation" },
484 { "Test Using Larger Than Block-Size Key - Hash Key First" },
485 { "Test Using Larger Than Block-Size Key and Larger"
486 " Than One Block-Size Data" }
489 static const int md5_hmac_test_buflen
[7] =
491 8, 28, 50, 50, 20, 54, 73
494 static const unsigned char md5_hmac_test_sum
[7][16] =
496 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
497 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
498 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
499 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
500 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
501 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
502 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
503 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
504 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
505 0xF9, 0xBA, 0xB9, 0x95 },
506 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
507 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
508 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
509 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
515 int md5_self_test( int verbose
)
518 unsigned char buf
[1024];
519 unsigned char md5sum
[16];
522 for( i
= 0; i
< 7; i
++ )
525 printf( " MD5 test #%d: ", i
+ 1 );
527 md5( md5_test_buf
[i
], md5_test_buflen
[i
], md5sum
);
529 if( memcmp( md5sum
, md5_test_sum
[i
], 16 ) != 0 )
532 printf( "failed\n" );
538 printf( "passed\n" );
544 for( i
= 0; i
< 7; i
++ )
547 printf( " HMAC-MD5 test #%d: ", i
+ 1 );
549 if( i
== 5 || i
== 6 )
551 memset( buf
, '\xAA', buflen
= 80 );
552 md5_hmac_starts( &ctx
, buf
, buflen
);
555 md5_hmac_starts( &ctx
, md5_hmac_test_key
[i
],
556 md5_hmac_test_keylen
[i
] );
558 md5_hmac_update( &ctx
, md5_hmac_test_buf
[i
],
559 md5_hmac_test_buflen
[i
] );
561 md5_hmac_finish( &ctx
, md5sum
);
563 buflen
= ( i
== 4 ) ? 12 : 16;
565 if( memcmp( md5sum
, md5_hmac_test_sum
[i
], buflen
) != 0 )
568 printf( "failed\n" );
574 printf( "passed\n" );