33 #if defined(POLARSSL_MD5_C)
37 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
42 static void polarssl_zeroize(
void *v,
size_t n ) {
43 volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
46 #if !defined(POLARSSL_MD5_ALT)
52 #define GET_UINT32_LE(n,b,i) \
54 (n) = ( (uint32_t) (b)[(i) ] ) \
55 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
56 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
57 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
62 #define PUT_UINT32_LE(n,b,i) \
64 (b)[(i) ] = (unsigned char) ( (n) ); \
65 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
66 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
67 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
79 ctx->
state[0] = 0x67452301;
80 ctx->
state[1] = 0xEFCDAB89;
81 ctx->
state[2] = 0x98BADCFE;
82 ctx->
state[3] = 0x10325476;
87 uint32_t X[16], A, B, C, D;
89 GET_UINT32_LE( X[ 0], data, 0 );
90 GET_UINT32_LE( X[ 1], data, 4 );
91 GET_UINT32_LE( X[ 2], data, 8 );
92 GET_UINT32_LE( X[ 3], data, 12 );
93 GET_UINT32_LE( X[ 4], data, 16 );
94 GET_UINT32_LE( X[ 5], data, 20 );
95 GET_UINT32_LE( X[ 6], data, 24 );
96 GET_UINT32_LE( X[ 7], data, 28 );
97 GET_UINT32_LE( X[ 8], data, 32 );
98 GET_UINT32_LE( X[ 9], data, 36 );
99 GET_UINT32_LE( X[10], data, 40 );
100 GET_UINT32_LE( X[11], data, 44 );
101 GET_UINT32_LE( X[12], data, 48 );
102 GET_UINT32_LE( X[13], data, 52 );
103 GET_UINT32_LE( X[14], data, 56 );
104 GET_UINT32_LE( X[15], data, 60 );
106 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
108 #define P(a,b,c,d,k,s,t) \
110 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
118 #define F(x,y,z) (z ^ (x & (y ^ z)))
120 P( A, B, C, D, 0, 7, 0xD76AA478 );
121 P( D, A, B, C, 1, 12, 0xE8C7B756 );
122 P( C, D, A, B, 2, 17, 0x242070DB );
123 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
124 P( A, B, C, D, 4, 7, 0xF57C0FAF );
125 P( D, A, B, C, 5, 12, 0x4787C62A );
126 P( C, D, A, B, 6, 17, 0xA8304613 );
127 P( B, C, D, A, 7, 22, 0xFD469501 );
128 P( A, B, C, D, 8, 7, 0x698098D8 );
129 P( D, A, B, C, 9, 12, 0x8B44F7AF );
130 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
131 P( B, C, D, A, 11, 22, 0x895CD7BE );
132 P( A, B, C, D, 12, 7, 0x6B901122 );
133 P( D, A, B, C, 13, 12, 0xFD987193 );
134 P( C, D, A, B, 14, 17, 0xA679438E );
135 P( B, C, D, A, 15, 22, 0x49B40821 );
139 #define F(x,y,z) (y ^ (z & (x ^ y)))
141 P( A, B, C, D, 1, 5, 0xF61E2562 );
142 P( D, A, B, C, 6, 9, 0xC040B340 );
143 P( C, D, A, B, 11, 14, 0x265E5A51 );
144 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
145 P( A, B, C, D, 5, 5, 0xD62F105D );
146 P( D, A, B, C, 10, 9, 0x02441453 );
147 P( C, D, A, B, 15, 14, 0xD8A1E681 );
148 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
149 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
150 P( D, A, B, C, 14, 9, 0xC33707D6 );
151 P( C, D, A, B, 3, 14, 0xF4D50D87 );
152 P( B, C, D, A, 8, 20, 0x455A14ED );
153 P( A, B, C, D, 13, 5, 0xA9E3E905 );
154 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
155 P( C, D, A, B, 7, 14, 0x676F02D9 );
156 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
160 #define F(x,y,z) (x ^ y ^ z)
162 P( A, B, C, D, 5, 4, 0xFFFA3942 );
163 P( D, A, B, C, 8, 11, 0x8771F681 );
164 P( C, D, A, B, 11, 16, 0x6D9D6122 );
165 P( B, C, D, A, 14, 23, 0xFDE5380C );
166 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
167 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
168 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
169 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
170 P( A, B, C, D, 13, 4, 0x289B7EC6 );
171 P( D, A, B, C, 0, 11, 0xEAA127FA );
172 P( C, D, A, B, 3, 16, 0xD4EF3085 );
173 P( B, C, D, A, 6, 23, 0x04881D05 );
174 P( A, B, C, D, 9, 4, 0xD9D4D039 );
175 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
176 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
177 P( B, C, D, A, 2, 23, 0xC4AC5665 );
181 #define F(x,y,z) (y ^ (x | ~z))
183 P( A, B, C, D, 0, 6, 0xF4292244 );
184 P( D, A, B, C, 7, 10, 0x432AFF97 );
185 P( C, D, A, B, 14, 15, 0xAB9423A7 );
186 P( B, C, D, A, 5, 21, 0xFC93A039 );
187 P( A, B, C, D, 12, 6, 0x655B59C3 );
188 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
189 P( C, D, A, B, 10, 15, 0xFFEFF47D );
190 P( B, C, D, A, 1, 21, 0x85845DD1 );
191 P( A, B, C, D, 8, 6, 0x6FA87E4F );
192 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
193 P( C, D, A, B, 6, 15, 0xA3014314 );
194 P( B, C, D, A, 13, 21, 0x4E0811A1 );
195 P( A, B, C, D, 4, 6, 0xF7537E82 );
196 P( D, A, B, C, 11, 10, 0xBD3AF235 );
197 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
198 P( B, C, D, A, 9, 21, 0xEB86D391 );
219 left = ctx->
total[0] & 0x3F;
222 ctx->
total[0] += (uint32_t) ilen;
223 ctx->
total[0] &= 0xFFFFFFFF;
225 if( ctx->
total[0] < (uint32_t) ilen )
228 if( left && ilen >= fill )
230 memcpy( (
void *) (ctx->
buffer + left), input, fill );
246 memcpy( (
void *) (ctx->
buffer + left), input, ilen );
250 static const unsigned char md5_padding[64] =
252 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
265 unsigned char msglen[8];
267 high = ( ctx->
total[0] >> 29 )
268 | ( ctx->
total[1] << 3 );
269 low = ( ctx->
total[0] << 3 );
271 PUT_UINT32_LE( low, msglen, 0 );
272 PUT_UINT32_LE( high, msglen, 4 );
274 last = ctx->
total[0] & 0x3F;
275 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
280 PUT_UINT32_LE( ctx->
state[0], output, 0 );
281 PUT_UINT32_LE( ctx->
state[1], output, 4 );
282 PUT_UINT32_LE( ctx->
state[2], output, 8 );
283 PUT_UINT32_LE( ctx->
state[3], output, 12 );
291 void md5(
const unsigned char *input,
size_t ilen,
unsigned char output[16] )
302 #if defined(POLARSSL_FS_IO)
306 int md5_file(
const char *path,
unsigned char output[16] )
311 unsigned char buf[1024];
313 if( ( f = fopen( path,
"rb" ) ) == NULL )
318 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
325 if( ferror( f ) != 0 )
342 unsigned char sum[16];
346 md5( key, keylen, sum );
351 memset( ctx->
ipad, 0x36, 64 );
352 memset( ctx->
opad, 0x5C, 64 );
354 for( i = 0; i < keylen; i++ )
356 ctx->
ipad[i] = (
unsigned char)( ctx->
ipad[i] ^ key[i] );
357 ctx->
opad[i] = (
unsigned char)( ctx->
opad[i] ^ key[i] );
363 polarssl_zeroize( sum,
sizeof( sum ) );
379 unsigned char tmpbuf[16];
387 polarssl_zeroize( tmpbuf,
sizeof( tmpbuf ) );
402 void md5_hmac(
const unsigned char *key,
size_t keylen,
403 const unsigned char *input,
size_t ilen,
404 unsigned char output[16] )
415 #if defined(POLARSSL_SELF_TEST)
419 static unsigned char md5_test_buf[7][81] =
424 {
"message digest" },
425 {
"abcdefghijklmnopqrstuvwxyz" },
426 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
427 {
"12345678901234567890123456789012345678901234567890123456789012" \
428 "345678901234567890" }
431 static const int md5_test_buflen[7] =
433 0, 1, 3, 14, 26, 62, 80
436 static const unsigned char md5_test_sum[7][16] =
438 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
439 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
440 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
441 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
442 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
443 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
444 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
445 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
446 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
447 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
448 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
449 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
450 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
451 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
457 static unsigned char md5_hmac_test_key[7][26] =
459 {
"\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
461 {
"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
462 {
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
463 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
464 {
"\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
469 static const int md5_hmac_test_keylen[7] =
471 16, 4, 16, 25, 16, 80, 80
474 static unsigned char md5_hmac_test_buf[7][74] =
477 {
"what do ya want for nothing?" },
478 {
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
479 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
480 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
481 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
482 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
483 {
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
484 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
485 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
486 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
487 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
488 {
"Test With Truncation" },
489 {
"Test Using Larger Than Block-Size Key - Hash Key First" },
490 {
"Test Using Larger Than Block-Size Key and Larger"
491 " Than One Block-Size Data" }
494 static const int md5_hmac_test_buflen[7] =
496 8, 28, 50, 50, 20, 54, 73
499 static const unsigned char md5_hmac_test_sum[7][16] =
501 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
502 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
503 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
504 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
505 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
506 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
507 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
508 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
509 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
510 0xF9, 0xBA, 0xB9, 0x95 },
511 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
512 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
513 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
514 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
523 unsigned char buf[1024];
524 unsigned char md5sum[16];
527 for( i = 0; i < 7; i++ )
530 printf(
" MD5 test #%d: ", i + 1 );
532 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
534 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
537 printf(
"failed\n" );
543 printf(
"passed\n" );
549 for( i = 0; i < 7; i++ )
552 printf(
" HMAC-MD5 test #%d: ", i + 1 );
554 if( i == 5 || i == 6 )
556 memset( buf,
'\xAA', buflen = 80 );
561 md5_hmac_test_keylen[i] );
564 md5_hmac_test_buflen[i] );
568 buflen = ( i == 4 ) ? 12 : 16;
570 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
573 printf(
"failed\n" );
579 printf(
"passed\n" );
Configuration options (set of defines)
#define POLARSSL_ERR_MD5_FILE_IO_ERROR
Read/write error in file.
void md5_finish(md5_context *ctx, unsigned char output[16])
MD5 final digest.
void md5_hmac(const unsigned char *key, size_t keylen, const unsigned char *input, size_t ilen, unsigned char output[16])
Output = HMAC-MD5( hmac key, input buffer )
int md5_self_test(int verbose)
Checkup routine.
int md5_file(const char *path, unsigned char output[16])
Output = MD5( file contents )
void md5_hmac_starts(md5_context *ctx, const unsigned char *key, size_t keylen)
MD5 HMAC context setup.
void md5_process(md5_context *ctx, const unsigned char data[64])
void md5_hmac_reset(md5_context *ctx)
MD5 HMAC context reset.
void md5_starts(md5_context *ctx)
MD5 context setup.
void md5_hmac_finish(md5_context *ctx, unsigned char output[16])
MD5 HMAC final digest.
void md5_update(md5_context *ctx, const unsigned char *input, size_t ilen)
MD5 process buffer.
void md5_hmac_update(md5_context *ctx, const unsigned char *input, size_t ilen)
MD5 HMAC process buffer.
MD5 message digest algorithm (hash function)
void md5(const unsigned char *input, size_t ilen, unsigned char output[16])
Output = MD5( input buffer )