31 #if !defined(POLARSSL_CONFIG_FILE)
34 #include POLARSSL_CONFIG_FILE
37 #if defined(POLARSSL_MD5_C)
41 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
45 #if defined(POLARSSL_PLATFORM_C)
48 #define polarssl_printf printf
51 #if !defined(POLARSSL_MD5_ALT)
57 #define GET_UINT32_LE(n,b,i) \
59 (n) = ( (uint32_t) (b)[(i) ] ) \
60 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
61 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
62 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
67 #define PUT_UINT32_LE(n,b,i) \
69 (b)[(i) ] = (unsigned char) ( (n) ); \
70 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
71 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
72 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
84 ctx->
state[0] = 0x67452301;
85 ctx->
state[1] = 0xEFCDAB89;
86 ctx->
state[2] = 0x98BADCFE;
87 ctx->
state[3] = 0x10325476;
92 uint32_t X[16], A, B, C, D;
94 GET_UINT32_LE( X[ 0], data, 0 );
95 GET_UINT32_LE( X[ 1], data, 4 );
96 GET_UINT32_LE( X[ 2], data, 8 );
97 GET_UINT32_LE( X[ 3], data, 12 );
98 GET_UINT32_LE( X[ 4], data, 16 );
99 GET_UINT32_LE( X[ 5], data, 20 );
100 GET_UINT32_LE( X[ 6], data, 24 );
101 GET_UINT32_LE( X[ 7], data, 28 );
102 GET_UINT32_LE( X[ 8], data, 32 );
103 GET_UINT32_LE( X[ 9], data, 36 );
104 GET_UINT32_LE( X[10], data, 40 );
105 GET_UINT32_LE( X[11], data, 44 );
106 GET_UINT32_LE( X[12], data, 48 );
107 GET_UINT32_LE( X[13], data, 52 );
108 GET_UINT32_LE( X[14], data, 56 );
109 GET_UINT32_LE( X[15], data, 60 );
111 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
113 #define P(a,b,c,d,k,s,t) \
115 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
123 #define F(x,y,z) (z ^ (x & (y ^ z)))
125 P( A, B, C, D, 0, 7, 0xD76AA478 );
126 P( D, A, B, C, 1, 12, 0xE8C7B756 );
127 P( C, D, A, B, 2, 17, 0x242070DB );
128 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
129 P( A, B, C, D, 4, 7, 0xF57C0FAF );
130 P( D, A, B, C, 5, 12, 0x4787C62A );
131 P( C, D, A, B, 6, 17, 0xA8304613 );
132 P( B, C, D, A, 7, 22, 0xFD469501 );
133 P( A, B, C, D, 8, 7, 0x698098D8 );
134 P( D, A, B, C, 9, 12, 0x8B44F7AF );
135 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
136 P( B, C, D, A, 11, 22, 0x895CD7BE );
137 P( A, B, C, D, 12, 7, 0x6B901122 );
138 P( D, A, B, C, 13, 12, 0xFD987193 );
139 P( C, D, A, B, 14, 17, 0xA679438E );
140 P( B, C, D, A, 15, 22, 0x49B40821 );
144 #define F(x,y,z) (y ^ (z & (x ^ y)))
146 P( A, B, C, D, 1, 5, 0xF61E2562 );
147 P( D, A, B, C, 6, 9, 0xC040B340 );
148 P( C, D, A, B, 11, 14, 0x265E5A51 );
149 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
150 P( A, B, C, D, 5, 5, 0xD62F105D );
151 P( D, A, B, C, 10, 9, 0x02441453 );
152 P( C, D, A, B, 15, 14, 0xD8A1E681 );
153 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
154 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
155 P( D, A, B, C, 14, 9, 0xC33707D6 );
156 P( C, D, A, B, 3, 14, 0xF4D50D87 );
157 P( B, C, D, A, 8, 20, 0x455A14ED );
158 P( A, B, C, D, 13, 5, 0xA9E3E905 );
159 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
160 P( C, D, A, B, 7, 14, 0x676F02D9 );
161 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
165 #define F(x,y,z) (x ^ y ^ z)
167 P( A, B, C, D, 5, 4, 0xFFFA3942 );
168 P( D, A, B, C, 8, 11, 0x8771F681 );
169 P( C, D, A, B, 11, 16, 0x6D9D6122 );
170 P( B, C, D, A, 14, 23, 0xFDE5380C );
171 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
172 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
173 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
174 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
175 P( A, B, C, D, 13, 4, 0x289B7EC6 );
176 P( D, A, B, C, 0, 11, 0xEAA127FA );
177 P( C, D, A, B, 3, 16, 0xD4EF3085 );
178 P( B, C, D, A, 6, 23, 0x04881D05 );
179 P( A, B, C, D, 9, 4, 0xD9D4D039 );
180 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
181 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
182 P( B, C, D, A, 2, 23, 0xC4AC5665 );
186 #define F(x,y,z) (y ^ (x | ~z))
188 P( A, B, C, D, 0, 6, 0xF4292244 );
189 P( D, A, B, C, 7, 10, 0x432AFF97 );
190 P( C, D, A, B, 14, 15, 0xAB9423A7 );
191 P( B, C, D, A, 5, 21, 0xFC93A039 );
192 P( A, B, C, D, 12, 6, 0x655B59C3 );
193 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
194 P( C, D, A, B, 10, 15, 0xFFEFF47D );
195 P( B, C, D, A, 1, 21, 0x85845DD1 );
196 P( A, B, C, D, 8, 6, 0x6FA87E4F );
197 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
198 P( C, D, A, B, 6, 15, 0xA3014314 );
199 P( B, C, D, A, 13, 21, 0x4E0811A1 );
200 P( A, B, C, D, 4, 6, 0xF7537E82 );
201 P( D, A, B, C, 11, 10, 0xBD3AF235 );
202 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
203 P( B, C, D, A, 9, 21, 0xEB86D391 );
224 left = ctx->
total[0] & 0x3F;
227 ctx->
total[0] += (uint32_t) ilen;
228 ctx->
total[0] &= 0xFFFFFFFF;
230 if( ctx->
total[0] < (uint32_t) ilen )
233 if( left && ilen >= fill )
235 memcpy( (
void *) (ctx->
buffer + left), input, fill );
251 memcpy( (
void *) (ctx->
buffer + left), input, ilen );
255 static const unsigned char md5_padding[64] =
257 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
270 unsigned char msglen[8];
272 high = ( ctx->
total[0] >> 29 )
273 | ( ctx->
total[1] << 3 );
274 low = ( ctx->
total[0] << 3 );
276 PUT_UINT32_LE( low, msglen, 0 );
277 PUT_UINT32_LE( high, msglen, 4 );
279 last = ctx->
total[0] & 0x3F;
280 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
285 PUT_UINT32_LE( ctx->
state[0], output, 0 );
286 PUT_UINT32_LE( ctx->
state[1], output, 4 );
287 PUT_UINT32_LE( ctx->
state[2], output, 8 );
288 PUT_UINT32_LE( ctx->
state[3], output, 12 );
296 void md5(
const unsigned char *input,
size_t ilen,
unsigned char output[16] )
307 #if defined(POLARSSL_FS_IO)
311 int md5_file(
const char *path,
unsigned char output[16] )
316 unsigned char buf[1024];
318 if( ( f = fopen( path,
"rb" ) ) == NULL )
323 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
330 if( ferror( f ) != 0 )
348 unsigned char sum[16];
352 md5( key, keylen, sum );
357 memset( ctx->
ipad, 0x36, 64 );
358 memset( ctx->
opad, 0x5C, 64 );
360 for( i = 0; i < keylen; i++ )
362 ctx->
ipad[i] = (
unsigned char)( ctx->
ipad[i] ^ key[i] );
363 ctx->
opad[i] = (
unsigned char)( ctx->
opad[i] ^ key[i] );
369 memset( sum, 0,
sizeof( sum ) );
386 unsigned char tmpbuf[16];
394 memset( tmpbuf, 0,
sizeof( tmpbuf ) );
409 void md5_hmac(
const unsigned char *key,
size_t keylen,
410 const unsigned char *input,
size_t ilen,
411 unsigned char output[16] )
422 #if defined(POLARSSL_SELF_TEST)
426 static unsigned char md5_test_buf[7][81] =
431 {
"message digest" },
432 {
"abcdefghijklmnopqrstuvwxyz" },
433 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
434 {
"12345678901234567890123456789012345678901234567890123456789012" \
435 "345678901234567890" }
438 static const int md5_test_buflen[7] =
440 0, 1, 3, 14, 26, 62, 80
443 static const unsigned char md5_test_sum[7][16] =
445 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
446 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
447 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
448 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
449 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
450 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
451 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
452 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
453 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
454 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
455 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
456 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
457 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
458 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
464 static unsigned char md5_hmac_test_key[7][26] =
466 {
"\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
468 {
"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
469 {
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
470 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
471 {
"\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
476 static const int md5_hmac_test_keylen[7] =
478 16, 4, 16, 25, 16, 80, 80
481 static unsigned char md5_hmac_test_buf[7][74] =
484 {
"what do ya want for nothing?" },
485 {
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
486 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
487 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
488 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
489 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
490 {
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
491 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
492 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
493 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
494 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
495 {
"Test With Truncation" },
496 {
"Test Using Larger Than Block-Size Key - Hash Key First" },
497 {
"Test Using Larger Than Block-Size Key and Larger"
498 " Than One Block-Size Data" }
501 static const int md5_hmac_test_buflen[7] =
503 8, 28, 50, 50, 20, 54, 73
506 static const unsigned char md5_hmac_test_sum[7][16] =
508 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
509 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
510 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
511 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
512 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
513 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
514 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
515 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
516 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
517 0xF9, 0xBA, 0xB9, 0x95 },
518 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
519 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
520 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
521 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
530 unsigned char buf[1024];
531 unsigned char md5sum[16];
534 for( i = 0; i < 7; i++ )
539 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
541 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
556 for( i = 0; i < 7; i++ )
561 if( i == 5 || i == 6 )
563 memset( buf,
'\xAA', buflen = 80 );
568 md5_hmac_test_keylen[i] );
571 md5_hmac_test_buflen[i] );
575 buflen = ( i == 4 ) ? 12 : 16;
577 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
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 )