initial commit; it works
[psslcertgen.git] / src / libpolarssl / md5.c
blob2df2ba23a31182c4e50c937ebc834b1d8b0e16aa
1 /*
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>
9 * All rights reserved.
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
31 #include "config.h"
33 #if defined(POLARSSL_MD5_C)
35 #include "md5.h"
37 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
38 #include <stdio.h>
39 #endif
41 #if !defined(POLARSSL_MD5_ALT)
44 * 32-bit integer manipulation macros (little endian)
46 #ifndef GET_UINT32_LE
47 #define GET_UINT32_LE(n,b,i) \
48 { \
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 ); \
54 #endif
56 #ifndef PUT_UINT32_LE
57 #define PUT_UINT32_LE(n,b,i) \
58 { \
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 ); \
64 #endif
67 * MD5 context setup
69 void md5_starts( md5_context *ctx )
71 ctx->total[0] = 0;
72 ctx->total[1] = 0;
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; \
108 A = ctx->state[0];
109 B = ctx->state[1];
110 C = ctx->state[2];
111 D = ctx->state[3];
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 );
132 #undef F
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 );
153 #undef F
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 );
174 #undef F
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 );
195 #undef F
197 ctx->state[0] += A;
198 ctx->state[1] += B;
199 ctx->state[2] += C;
200 ctx->state[3] += D;
204 * MD5 process buffer
206 void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
208 size_t fill;
209 uint32_t left;
211 if( ilen <= 0 )
212 return;
214 left = ctx->total[0] & 0x3F;
215 fill = 64 - left;
217 ctx->total[0] += (uint32_t) ilen;
218 ctx->total[0] &= 0xFFFFFFFF;
220 if( ctx->total[0] < (uint32_t) ilen )
221 ctx->total[1]++;
223 if( left && ilen >= fill )
225 memcpy( (void *) (ctx->buffer + left), input, fill );
226 md5_process( ctx, ctx->buffer );
227 input += fill;
228 ilen -= fill;
229 left = 0;
232 while( ilen >= 64 )
234 md5_process( ctx, input );
235 input += 64;
236 ilen -= 64;
239 if( ilen > 0 )
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
254 * MD5 final digest
256 void md5_finish( md5_context *ctx, unsigned char output[16] )
258 uint32_t last, padn;
259 uint32_t high, low;
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] )
288 md5_context ctx;
290 md5_starts( &ctx );
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] )
303 FILE *f;
304 size_t n;
305 md5_context ctx;
306 unsigned char buf[1024];
308 if( ( f = fopen( path, "rb" ) ) == NULL )
309 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
311 md5_starts( &ctx );
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 )
322 fclose( f );
323 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
326 fclose( f );
327 return( 0 );
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 )
336 size_t i;
337 unsigned char sum[16];
339 if( keylen > 64 )
341 md5( key, keylen, sum );
342 keylen = 16;
343 key = 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] );
355 md5_starts( ctx );
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 );
377 md5_starts( ctx );
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 )
390 md5_starts( 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] )
401 md5_context ctx;
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] =
416 { "" },
417 { "a" },
418 { "abc" },
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" },
455 { "Jefe" },
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 */
461 { "" }
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] =
471 { "Hi There" },
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 }
513 * Checkup routine
515 int md5_self_test( int verbose )
517 int i, buflen;
518 unsigned char buf[1024];
519 unsigned char md5sum[16];
520 md5_context ctx;
522 for( i = 0; i < 7; i++ )
524 if( verbose != 0 )
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 )
531 if( verbose != 0 )
532 printf( "failed\n" );
534 return( 1 );
537 if( verbose != 0 )
538 printf( "passed\n" );
541 if( verbose != 0 )
542 printf( "\n" );
544 for( i = 0; i < 7; i++ )
546 if( verbose != 0 )
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 );
554 else
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 )
567 if( verbose != 0 )
568 printf( "failed\n" );
570 return( 1 );
573 if( verbose != 0 )
574 printf( "passed\n" );
577 if( verbose != 0 )
578 printf( "\n" );
580 return( 0 );
583 #endif
585 #endif