PolarSSL v1.3.9
md5.c
Go to the documentation of this file.
1 /*
2  * RFC 1321 compliant MD5 implementation
3  *
4  * Copyright (C) 2006-2014, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
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.
15  *
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.
20  *
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.
24  */
25 /*
26  * The MD5 algorithm was designed by Ron Rivest in 1991.
27  *
28  * http://www.ietf.org/rfc/rfc1321.txt
29  */
30 
31 #if !defined(POLARSSL_CONFIG_FILE)
32 #include "polarssl/config.h"
33 #else
34 #include POLARSSL_CONFIG_FILE
35 #endif
36 
37 #if defined(POLARSSL_MD5_C)
38 
39 #include "polarssl/md5.h"
40 
41 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
42 #include <stdio.h>
43 #endif
44 
45 #if defined(POLARSSL_PLATFORM_C)
46 #include "polarssl/platform.h"
47 #else
48 #define polarssl_printf printf
49 #endif
50 
51 /* Implementation that should never be optimized out by the compiler */
52 static void polarssl_zeroize( void *v, size_t n ) {
53  volatile unsigned char *p = v; while( n-- ) *p++ = 0;
54 }
55 
56 #if !defined(POLARSSL_MD5_ALT)
57 
58 /*
59  * 32-bit integer manipulation macros (little endian)
60  */
61 #ifndef GET_UINT32_LE
62 #define GET_UINT32_LE(n,b,i) \
63 { \
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 ); \
68 }
69 #endif
70 
71 #ifndef PUT_UINT32_LE
72 #define PUT_UINT32_LE(n,b,i) \
73 { \
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 ); \
78 }
79 #endif
80 
81 void md5_init( md5_context *ctx )
82 {
83  memset( ctx, 0, sizeof( md5_context ) );
84 }
85 
86 void md5_free( md5_context *ctx )
87 {
88  if( ctx == NULL )
89  return;
90 
91  polarssl_zeroize( ctx, sizeof( md5_context ) );
92 }
93 
94 /*
95  * MD5 context setup
96  */
97 void md5_starts( md5_context *ctx )
98 {
99  ctx->total[0] = 0;
100  ctx->total[1] = 0;
101 
102  ctx->state[0] = 0x67452301;
103  ctx->state[1] = 0xEFCDAB89;
104  ctx->state[2] = 0x98BADCFE;
105  ctx->state[3] = 0x10325476;
106 }
107 
108 void md5_process( md5_context *ctx, const unsigned char data[64] )
109 {
110  uint32_t X[16], A, B, C, D;
111 
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 );
128 
129 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
130 
131 #define P(a,b,c,d,k,s,t) \
132 { \
133  a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
134 }
135 
136  A = ctx->state[0];
137  B = ctx->state[1];
138  C = ctx->state[2];
139  D = ctx->state[3];
140 
141 #define F(x,y,z) (z ^ (x & (y ^ z)))
142 
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 );
159 
160 #undef F
161 
162 #define F(x,y,z) (y ^ (z & (x ^ y)))
163 
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 );
180 
181 #undef F
182 
183 #define F(x,y,z) (x ^ y ^ z)
184 
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 );
201 
202 #undef F
203 
204 #define F(x,y,z) (y ^ (x | ~z))
205 
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 );
222 
223 #undef F
224 
225  ctx->state[0] += A;
226  ctx->state[1] += B;
227  ctx->state[2] += C;
228  ctx->state[3] += D;
229 }
230 
231 /*
232  * MD5 process buffer
233  */
234 void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
235 {
236  size_t fill;
237  uint32_t left;
238 
239  if( ilen == 0 )
240  return;
241 
242  left = ctx->total[0] & 0x3F;
243  fill = 64 - left;
244 
245  ctx->total[0] += (uint32_t) ilen;
246  ctx->total[0] &= 0xFFFFFFFF;
247 
248  if( ctx->total[0] < (uint32_t) ilen )
249  ctx->total[1]++;
250 
251  if( left && ilen >= fill )
252  {
253  memcpy( (void *) (ctx->buffer + left), input, fill );
254  md5_process( ctx, ctx->buffer );
255  input += fill;
256  ilen -= fill;
257  left = 0;
258  }
259 
260  while( ilen >= 64 )
261  {
262  md5_process( ctx, input );
263  input += 64;
264  ilen -= 64;
265  }
266 
267  if( ilen > 0 )
268  {
269  memcpy( (void *) (ctx->buffer + left), input, ilen );
270  }
271 }
272 
273 static const unsigned char md5_padding[64] =
274 {
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
279 };
280 
281 /*
282  * MD5 final digest
283  */
284 void md5_finish( md5_context *ctx, unsigned char output[16] )
285 {
286  uint32_t last, padn;
287  uint32_t high, low;
288  unsigned char msglen[8];
289 
290  high = ( ctx->total[0] >> 29 )
291  | ( ctx->total[1] << 3 );
292  low = ( ctx->total[0] << 3 );
293 
294  PUT_UINT32_LE( low, msglen, 0 );
295  PUT_UINT32_LE( high, msglen, 4 );
296 
297  last = ctx->total[0] & 0x3F;
298  padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
299 
300  md5_update( ctx, md5_padding, padn );
301  md5_update( ctx, msglen, 8 );
302 
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 );
307 }
308 
309 #endif /* !POLARSSL_MD5_ALT */
310 
311 /*
312  * output = MD5( input buffer )
313  */
314 void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
315 {
316  md5_context ctx;
317 
318  md5_init( &ctx );
319  md5_starts( &ctx );
320  md5_update( &ctx, input, ilen );
321  md5_finish( &ctx, output );
322  md5_free( &ctx );
323 }
324 
325 #if defined(POLARSSL_FS_IO)
326 /*
327  * output = MD5( file contents )
328  */
329 int md5_file( const char *path, unsigned char output[16] )
330 {
331  FILE *f;
332  size_t n;
333  md5_context ctx;
334  unsigned char buf[1024];
335 
336  if( ( f = fopen( path, "rb" ) ) == NULL )
338 
339  md5_init( &ctx );
340  md5_starts( &ctx );
341 
342  while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
343  md5_update( &ctx, buf, n );
344 
345  md5_finish( &ctx, output );
346  md5_free( &ctx );
347 
348  if( ferror( f ) != 0 )
349  {
350  fclose( f );
352  }
353 
354  fclose( f );
355  return( 0 );
356 }
357 #endif /* POLARSSL_FS_IO */
358 
359 /*
360  * MD5 HMAC context setup
361  */
362 void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
363  size_t keylen )
364 {
365  size_t i;
366  unsigned char sum[16];
367 
368  if( keylen > 64 )
369  {
370  md5( key, keylen, sum );
371  keylen = 16;
372  key = sum;
373  }
374 
375  memset( ctx->ipad, 0x36, 64 );
376  memset( ctx->opad, 0x5C, 64 );
377 
378  for( i = 0; i < keylen; i++ )
379  {
380  ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
381  ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
382  }
383 
384  md5_starts( ctx );
385  md5_update( ctx, ctx->ipad, 64 );
386 
387  polarssl_zeroize( sum, sizeof( sum ) );
388 }
389 
390 /*
391  * MD5 HMAC process buffer
392  */
393 void md5_hmac_update( md5_context *ctx, const unsigned char *input,
394  size_t ilen )
395 {
396  md5_update( ctx, input, ilen );
397 }
398 
399 /*
400  * MD5 HMAC final digest
401  */
402 void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
403 {
404  unsigned char tmpbuf[16];
405 
406  md5_finish( ctx, tmpbuf );
407  md5_starts( ctx );
408  md5_update( ctx, ctx->opad, 64 );
409  md5_update( ctx, tmpbuf, 16 );
410  md5_finish( ctx, output );
411 
412  polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
413 }
414 
415 /*
416  * MD5 HMAC context reset
417  */
418 void md5_hmac_reset( md5_context *ctx )
419 {
420  md5_starts( ctx );
421  md5_update( ctx, ctx->ipad, 64 );
422 }
423 
424 /*
425  * output = HMAC-MD5( hmac key, input buffer )
426  */
427 void md5_hmac( const unsigned char *key, size_t keylen,
428  const unsigned char *input, size_t ilen,
429  unsigned char output[16] )
430 {
431  md5_context ctx;
432 
433  md5_init( &ctx );
434  md5_hmac_starts( &ctx, key, keylen );
435  md5_hmac_update( &ctx, input, ilen );
436  md5_hmac_finish( &ctx, output );
437  md5_free( &ctx );
438 }
439 
440 #if defined(POLARSSL_SELF_TEST)
441 /*
442  * RFC 1321 test vectors
443  */
444 static unsigned char md5_test_buf[7][81] =
445 {
446  { "" },
447  { "a" },
448  { "abc" },
449  { "message digest" },
450  { "abcdefghijklmnopqrstuvwxyz" },
451  { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
452  { "12345678901234567890123456789012345678901234567890123456789012" \
453  "345678901234567890" }
454 };
455 
456 static const int md5_test_buflen[7] =
457 {
458  0, 1, 3, 14, 26, 62, 80
459 };
460 
461 static const unsigned char md5_test_sum[7][16] =
462 {
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 }
477 };
478 
479 /*
480  * RFC 2202 test vectors
481  */
482 static unsigned char md5_hmac_test_key[7][26] =
483 {
484  { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
485  { "Jefe" },
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" },
490  { "" }, /* 0xAA 80 times */
491  { "" }
492 };
493 
494 static const int md5_hmac_test_keylen[7] =
495 {
496  16, 4, 16, 25, 16, 80, 80
497 };
498 
499 static unsigned char md5_hmac_test_buf[7][74] =
500 {
501  { "Hi There" },
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" }
517 };
518 
519 static const int md5_hmac_test_buflen[7] =
520 {
521  8, 28, 50, 50, 20, 54, 73
522 };
523 
524 static const unsigned char md5_hmac_test_sum[7][16] =
525 {
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 }
540 };
541 
542 /*
543  * Checkup routine
544  */
545 int md5_self_test( int verbose )
546 {
547  int i, buflen;
548  unsigned char buf[1024];
549  unsigned char md5sum[16];
550  md5_context ctx;
551 
552  for( i = 0; i < 7; i++ )
553  {
554  if( verbose != 0 )
555  polarssl_printf( " MD5 test #%d: ", i + 1 );
556 
557  md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
558 
559  if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
560  {
561  if( verbose != 0 )
562  polarssl_printf( "failed\n" );
563 
564  return( 1 );
565  }
566 
567  if( verbose != 0 )
568  polarssl_printf( "passed\n" );
569  }
570 
571  if( verbose != 0 )
572  polarssl_printf( "\n" );
573 
574  for( i = 0; i < 7; i++ )
575  {
576  if( verbose != 0 )
577  polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
578 
579  if( i == 5 || i == 6 )
580  {
581  memset( buf, '\xAA', buflen = 80 );
582  md5_hmac_starts( &ctx, buf, buflen );
583  }
584  else
585  md5_hmac_starts( &ctx, md5_hmac_test_key[i],
586  md5_hmac_test_keylen[i] );
587 
588  md5_hmac_update( &ctx, md5_hmac_test_buf[i],
589  md5_hmac_test_buflen[i] );
590 
591  md5_hmac_finish( &ctx, md5sum );
592 
593  buflen = ( i == 4 ) ? 12 : 16;
594 
595  if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
596  {
597  if( verbose != 0 )
598  polarssl_printf( "failed\n" );
599 
600  return( 1 );
601  }
602 
603  if( verbose != 0 )
604  polarssl_printf( "passed\n" );
605  }
606 
607  if( verbose != 0 )
608  polarssl_printf( "\n" );
609 
610  return( 0 );
611 }
612 
613 #endif /* POLARSSL_SELF_TEST */
614 
615 #endif /* POLARSSL_MD5_C */
unsigned char buffer[64]
Definition: md5.h:62
#define polarssl_printf
unsigned char opad[64]
Definition: md5.h:65
Configuration options (set of defines)
#define POLARSSL_ERR_MD5_FILE_IO_ERROR
Read/write error in file.
Definition: md5.h:45
void md5_finish(md5_context *ctx, unsigned char output[16])
MD5 final digest.
PolarSSL Platform abstraction layer.
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.
unsigned char ipad[64]
Definition: md5.h:64
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.
MD5 context structure.
Definition: md5.h:58
uint32_t total[2]
Definition: md5.h:60
void md5_init(md5_context *ctx)
Initialize MD5 context.
uint32_t state[4]
Definition: md5.h:61
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 )