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
52 static void polarssl_zeroize(
void *v,
size_t n ) {
53 volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
56 #if !defined(POLARSSL_MD5_ALT)
62 #define GET_UINT32_LE(n,b,i) \
64 (n) = ( (uint32_t) (b)[(i) ] ) \
65 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
66 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
67 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
72 #define PUT_UINT32_LE(n,b,i) \
74 (b)[(i) ] = (unsigned char) ( (n) ); \
75 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
76 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
77 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
102 ctx->
state[0] = 0x67452301;
103 ctx->
state[1] = 0xEFCDAB89;
104 ctx->
state[2] = 0x98BADCFE;
105 ctx->
state[3] = 0x10325476;
110 uint32_t X[16], A, B, C, D;
112 GET_UINT32_LE( X[ 0], data, 0 );
113 GET_UINT32_LE( X[ 1], data, 4 );
114 GET_UINT32_LE( X[ 2], data, 8 );
115 GET_UINT32_LE( X[ 3], data, 12 );
116 GET_UINT32_LE( X[ 4], data, 16 );
117 GET_UINT32_LE( X[ 5], data, 20 );
118 GET_UINT32_LE( X[ 6], data, 24 );
119 GET_UINT32_LE( X[ 7], data, 28 );
120 GET_UINT32_LE( X[ 8], data, 32 );
121 GET_UINT32_LE( X[ 9], data, 36 );
122 GET_UINT32_LE( X[10], data, 40 );
123 GET_UINT32_LE( X[11], data, 44 );
124 GET_UINT32_LE( X[12], data, 48 );
125 GET_UINT32_LE( X[13], data, 52 );
126 GET_UINT32_LE( X[14], data, 56 );
127 GET_UINT32_LE( X[15], data, 60 );
129 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
131 #define P(a,b,c,d,k,s,t) \
133 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
141 #define F(x,y,z) (z ^ (x & (y ^ z)))
143 P( A, B, C, D, 0, 7, 0xD76AA478 );
144 P( D, A, B, C, 1, 12, 0xE8C7B756 );
145 P( C, D, A, B, 2, 17, 0x242070DB );
146 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
147 P( A, B, C, D, 4, 7, 0xF57C0FAF );
148 P( D, A, B, C, 5, 12, 0x4787C62A );
149 P( C, D, A, B, 6, 17, 0xA8304613 );
150 P( B, C, D, A, 7, 22, 0xFD469501 );
151 P( A, B, C, D, 8, 7, 0x698098D8 );
152 P( D, A, B, C, 9, 12, 0x8B44F7AF );
153 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
154 P( B, C, D, A, 11, 22, 0x895CD7BE );
155 P( A, B, C, D, 12, 7, 0x6B901122 );
156 P( D, A, B, C, 13, 12, 0xFD987193 );
157 P( C, D, A, B, 14, 17, 0xA679438E );
158 P( B, C, D, A, 15, 22, 0x49B40821 );
162 #define F(x,y,z) (y ^ (z & (x ^ y)))
164 P( A, B, C, D, 1, 5, 0xF61E2562 );
165 P( D, A, B, C, 6, 9, 0xC040B340 );
166 P( C, D, A, B, 11, 14, 0x265E5A51 );
167 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
168 P( A, B, C, D, 5, 5, 0xD62F105D );
169 P( D, A, B, C, 10, 9, 0x02441453 );
170 P( C, D, A, B, 15, 14, 0xD8A1E681 );
171 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
172 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
173 P( D, A, B, C, 14, 9, 0xC33707D6 );
174 P( C, D, A, B, 3, 14, 0xF4D50D87 );
175 P( B, C, D, A, 8, 20, 0x455A14ED );
176 P( A, B, C, D, 13, 5, 0xA9E3E905 );
177 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
178 P( C, D, A, B, 7, 14, 0x676F02D9 );
179 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
183 #define F(x,y,z) (x ^ y ^ z)
185 P( A, B, C, D, 5, 4, 0xFFFA3942 );
186 P( D, A, B, C, 8, 11, 0x8771F681 );
187 P( C, D, A, B, 11, 16, 0x6D9D6122 );
188 P( B, C, D, A, 14, 23, 0xFDE5380C );
189 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
190 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
191 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
192 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
193 P( A, B, C, D, 13, 4, 0x289B7EC6 );
194 P( D, A, B, C, 0, 11, 0xEAA127FA );
195 P( C, D, A, B, 3, 16, 0xD4EF3085 );
196 P( B, C, D, A, 6, 23, 0x04881D05 );
197 P( A, B, C, D, 9, 4, 0xD9D4D039 );
198 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
199 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
200 P( B, C, D, A, 2, 23, 0xC4AC5665 );
204 #define F(x,y,z) (y ^ (x | ~z))
206 P( A, B, C, D, 0, 6, 0xF4292244 );
207 P( D, A, B, C, 7, 10, 0x432AFF97 );
208 P( C, D, A, B, 14, 15, 0xAB9423A7 );
209 P( B, C, D, A, 5, 21, 0xFC93A039 );
210 P( A, B, C, D, 12, 6, 0x655B59C3 );
211 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
212 P( C, D, A, B, 10, 15, 0xFFEFF47D );
213 P( B, C, D, A, 1, 21, 0x85845DD1 );
214 P( A, B, C, D, 8, 6, 0x6FA87E4F );
215 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
216 P( C, D, A, B, 6, 15, 0xA3014314 );
217 P( B, C, D, A, 13, 21, 0x4E0811A1 );
218 P( A, B, C, D, 4, 6, 0xF7537E82 );
219 P( D, A, B, C, 11, 10, 0xBD3AF235 );
220 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
221 P( B, C, D, A, 9, 21, 0xEB86D391 );
242 left = ctx->
total[0] & 0x3F;
245 ctx->
total[0] += (uint32_t) ilen;
246 ctx->
total[0] &= 0xFFFFFFFF;
248 if( ctx->
total[0] < (uint32_t) ilen )
251 if( left && ilen >= fill )
253 memcpy( (
void *) (ctx->
buffer + left), input, fill );
269 memcpy( (
void *) (ctx->
buffer + left), input, ilen );
273 static const unsigned char md5_padding[64] =
275 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
277 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
288 unsigned char msglen[8];
290 high = ( ctx->
total[0] >> 29 )
291 | ( ctx->
total[1] << 3 );
292 low = ( ctx->
total[0] << 3 );
294 PUT_UINT32_LE( low, msglen, 0 );
295 PUT_UINT32_LE( high, msglen, 4 );
297 last = ctx->
total[0] & 0x3F;
298 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
303 PUT_UINT32_LE( ctx->
state[0], output, 0 );
304 PUT_UINT32_LE( ctx->
state[1], output, 4 );
305 PUT_UINT32_LE( ctx->
state[2], output, 8 );
306 PUT_UINT32_LE( ctx->
state[3], output, 12 );
314 void md5(
const unsigned char *input,
size_t ilen,
unsigned char output[16] )
325 #if defined(POLARSSL_FS_IO)
329 int md5_file(
const char *path,
unsigned char output[16] )
334 unsigned char buf[1024];
336 if( ( f = fopen( path,
"rb" ) ) == NULL )
342 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
348 if( ferror( f ) != 0 )
366 unsigned char sum[16];
370 md5( key, keylen, sum );
375 memset( ctx->
ipad, 0x36, 64 );
376 memset( ctx->
opad, 0x5C, 64 );
378 for( i = 0; i < keylen; i++ )
380 ctx->
ipad[i] = (
unsigned char)( ctx->
ipad[i] ^ key[i] );
381 ctx->
opad[i] = (
unsigned char)( ctx->
opad[i] ^ key[i] );
387 polarssl_zeroize( sum,
sizeof( sum ) );
404 unsigned char tmpbuf[16];
412 polarssl_zeroize( tmpbuf,
sizeof( tmpbuf ) );
427 void md5_hmac(
const unsigned char *key,
size_t keylen,
428 const unsigned char *input,
size_t ilen,
429 unsigned char output[16] )
440 #if defined(POLARSSL_SELF_TEST)
444 static unsigned char md5_test_buf[7][81] =
449 {
"message digest" },
450 {
"abcdefghijklmnopqrstuvwxyz" },
451 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
452 {
"12345678901234567890123456789012345678901234567890123456789012" \
453 "345678901234567890" }
456 static const int md5_test_buflen[7] =
458 0, 1, 3, 14, 26, 62, 80
461 static const unsigned char md5_test_sum[7][16] =
463 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
464 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
465 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
466 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
467 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
468 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
469 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
470 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
471 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
472 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
473 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
474 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
475 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
476 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
482 static unsigned char md5_hmac_test_key[7][26] =
484 {
"\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
486 {
"\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
487 {
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
488 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
489 {
"\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
494 static const int md5_hmac_test_keylen[7] =
496 16, 4, 16, 25, 16, 80, 80
499 static unsigned char md5_hmac_test_buf[7][74] =
502 {
"what do ya want for nothing?" },
503 {
"\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
504 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
505 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
506 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
507 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
508 {
"\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
509 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
510 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
511 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
512 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
513 {
"Test With Truncation" },
514 {
"Test Using Larger Than Block-Size Key - Hash Key First" },
515 {
"Test Using Larger Than Block-Size Key and Larger"
516 " Than One Block-Size Data" }
519 static const int md5_hmac_test_buflen[7] =
521 8, 28, 50, 50, 20, 54, 73
524 static const unsigned char md5_hmac_test_sum[7][16] =
526 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
527 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
528 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
529 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
530 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
531 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
532 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
533 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
534 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
535 0xF9, 0xBA, 0xB9, 0x95 },
536 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
537 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
538 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
539 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
548 unsigned char buf[1024];
549 unsigned char md5sum[16];
552 for( i = 0; i < 7; i++ )
557 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
559 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
574 for( i = 0; i < 7; i++ )
579 if( i == 5 || i == 6 )
581 memset( buf,
'\xAA', buflen = 80 );
586 md5_hmac_test_keylen[i] );
589 md5_hmac_test_buflen[i] );
593 buflen = ( i == 4 ) ? 12 : 16;
595 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 )
void md5_free(md5_context *ctx)
Clear MD5 context.
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_init(md5_context *ctx)
Initialize MD5 context.
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 )