PolarSSL v1.3.7
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 #if !defined(POLARSSL_MD5_ALT)
52 
53 /*
54  * 32-bit integer manipulation macros (little endian)
55  */
56 #ifndef GET_UINT32_LE
57 #define GET_UINT32_LE(n,b,i) \
58 { \
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 ); \
63 }
64 #endif
65 
66 #ifndef PUT_UINT32_LE
67 #define PUT_UINT32_LE(n,b,i) \
68 { \
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 ); \
73 }
74 #endif
75 
76 /*
77  * MD5 context setup
78  */
79 void md5_starts( md5_context *ctx )
80 {
81  ctx->total[0] = 0;
82  ctx->total[1] = 0;
83 
84  ctx->state[0] = 0x67452301;
85  ctx->state[1] = 0xEFCDAB89;
86  ctx->state[2] = 0x98BADCFE;
87  ctx->state[3] = 0x10325476;
88 }
89 
90 void md5_process( md5_context *ctx, const unsigned char data[64] )
91 {
92  uint32_t X[16], A, B, C, D;
93 
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 );
110 
111 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
112 
113 #define P(a,b,c,d,k,s,t) \
114 { \
115  a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
116 }
117 
118  A = ctx->state[0];
119  B = ctx->state[1];
120  C = ctx->state[2];
121  D = ctx->state[3];
122 
123 #define F(x,y,z) (z ^ (x & (y ^ z)))
124 
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 );
141 
142 #undef F
143 
144 #define F(x,y,z) (y ^ (z & (x ^ y)))
145 
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 );
162 
163 #undef F
164 
165 #define F(x,y,z) (x ^ y ^ z)
166 
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 );
183 
184 #undef F
185 
186 #define F(x,y,z) (y ^ (x | ~z))
187 
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 );
204 
205 #undef F
206 
207  ctx->state[0] += A;
208  ctx->state[1] += B;
209  ctx->state[2] += C;
210  ctx->state[3] += D;
211 }
212 
213 /*
214  * MD5 process buffer
215  */
216 void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
217 {
218  size_t fill;
219  uint32_t left;
220 
221  if( ilen <= 0 )
222  return;
223 
224  left = ctx->total[0] & 0x3F;
225  fill = 64 - left;
226 
227  ctx->total[0] += (uint32_t) ilen;
228  ctx->total[0] &= 0xFFFFFFFF;
229 
230  if( ctx->total[0] < (uint32_t) ilen )
231  ctx->total[1]++;
232 
233  if( left && ilen >= fill )
234  {
235  memcpy( (void *) (ctx->buffer + left), input, fill );
236  md5_process( ctx, ctx->buffer );
237  input += fill;
238  ilen -= fill;
239  left = 0;
240  }
241 
242  while( ilen >= 64 )
243  {
244  md5_process( ctx, input );
245  input += 64;
246  ilen -= 64;
247  }
248 
249  if( ilen > 0 )
250  {
251  memcpy( (void *) (ctx->buffer + left), input, ilen );
252  }
253 }
254 
255 static const unsigned char md5_padding[64] =
256 {
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
261 };
262 
263 /*
264  * MD5 final digest
265  */
266 void md5_finish( md5_context *ctx, unsigned char output[16] )
267 {
268  uint32_t last, padn;
269  uint32_t high, low;
270  unsigned char msglen[8];
271 
272  high = ( ctx->total[0] >> 29 )
273  | ( ctx->total[1] << 3 );
274  low = ( ctx->total[0] << 3 );
275 
276  PUT_UINT32_LE( low, msglen, 0 );
277  PUT_UINT32_LE( high, msglen, 4 );
278 
279  last = ctx->total[0] & 0x3F;
280  padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
281 
282  md5_update( ctx, md5_padding, padn );
283  md5_update( ctx, msglen, 8 );
284 
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 );
289 }
290 
291 #endif /* !POLARSSL_MD5_ALT */
292 
293 /*
294  * output = MD5( input buffer )
295  */
296 void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
297 {
298  md5_context ctx;
299 
300  md5_starts( &ctx );
301  md5_update( &ctx, input, ilen );
302  md5_finish( &ctx, output );
303 
304  memset( &ctx, 0, sizeof( md5_context ) );
305 }
306 
307 #if defined(POLARSSL_FS_IO)
308 /*
309  * output = MD5( file contents )
310  */
311 int md5_file( const char *path, unsigned char output[16] )
312 {
313  FILE *f;
314  size_t n;
315  md5_context ctx;
316  unsigned char buf[1024];
317 
318  if( ( f = fopen( path, "rb" ) ) == NULL )
320 
321  md5_starts( &ctx );
322 
323  while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
324  md5_update( &ctx, buf, n );
325 
326  md5_finish( &ctx, output );
327 
328  memset( &ctx, 0, sizeof( md5_context ) );
329 
330  if( ferror( f ) != 0 )
331  {
332  fclose( f );
334  }
335 
336  fclose( f );
337  return( 0 );
338 }
339 #endif /* POLARSSL_FS_IO */
340 
341 /*
342  * MD5 HMAC context setup
343  */
344 void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
345  size_t keylen )
346 {
347  size_t i;
348  unsigned char sum[16];
349 
350  if( keylen > 64 )
351  {
352  md5( key, keylen, sum );
353  keylen = 16;
354  key = sum;
355  }
356 
357  memset( ctx->ipad, 0x36, 64 );
358  memset( ctx->opad, 0x5C, 64 );
359 
360  for( i = 0; i < keylen; i++ )
361  {
362  ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
363  ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
364  }
365 
366  md5_starts( ctx );
367  md5_update( ctx, ctx->ipad, 64 );
368 
369  memset( sum, 0, sizeof( sum ) );
370 }
371 
372 /*
373  * MD5 HMAC process buffer
374  */
375 void md5_hmac_update( md5_context *ctx, const unsigned char *input,
376  size_t ilen )
377 {
378  md5_update( ctx, input, ilen );
379 }
380 
381 /*
382  * MD5 HMAC final digest
383  */
384 void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
385 {
386  unsigned char tmpbuf[16];
387 
388  md5_finish( ctx, tmpbuf );
389  md5_starts( ctx );
390  md5_update( ctx, ctx->opad, 64 );
391  md5_update( ctx, tmpbuf, 16 );
392  md5_finish( ctx, output );
393 
394  memset( tmpbuf, 0, sizeof( tmpbuf ) );
395 }
396 
397 /*
398  * MD5 HMAC context reset
399  */
400 void md5_hmac_reset( md5_context *ctx )
401 {
402  md5_starts( ctx );
403  md5_update( ctx, ctx->ipad, 64 );
404 }
405 
406 /*
407  * output = HMAC-MD5( hmac key, input buffer )
408  */
409 void md5_hmac( const unsigned char *key, size_t keylen,
410  const unsigned char *input, size_t ilen,
411  unsigned char output[16] )
412 {
413  md5_context ctx;
414 
415  md5_hmac_starts( &ctx, key, keylen );
416  md5_hmac_update( &ctx, input, ilen );
417  md5_hmac_finish( &ctx, output );
418 
419  memset( &ctx, 0, sizeof( md5_context ) );
420 }
421 
422 #if defined(POLARSSL_SELF_TEST)
423 /*
424  * RFC 1321 test vectors
425  */
426 static unsigned char md5_test_buf[7][81] =
427 {
428  { "" },
429  { "a" },
430  { "abc" },
431  { "message digest" },
432  { "abcdefghijklmnopqrstuvwxyz" },
433  { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
434  { "12345678901234567890123456789012345678901234567890123456789012" \
435  "345678901234567890" }
436 };
437 
438 static const int md5_test_buflen[7] =
439 {
440  0, 1, 3, 14, 26, 62, 80
441 };
442 
443 static const unsigned char md5_test_sum[7][16] =
444 {
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 }
459 };
460 
461 /*
462  * RFC 2202 test vectors
463  */
464 static unsigned char md5_hmac_test_key[7][26] =
465 {
466  { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
467  { "Jefe" },
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" },
472  { "" }, /* 0xAA 80 times */
473  { "" }
474 };
475 
476 static const int md5_hmac_test_keylen[7] =
477 {
478  16, 4, 16, 25, 16, 80, 80
479 };
480 
481 static unsigned char md5_hmac_test_buf[7][74] =
482 {
483  { "Hi There" },
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" }
499 };
500 
501 static const int md5_hmac_test_buflen[7] =
502 {
503  8, 28, 50, 50, 20, 54, 73
504 };
505 
506 static const unsigned char md5_hmac_test_sum[7][16] =
507 {
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 }
522 };
523 
524 /*
525  * Checkup routine
526  */
527 int md5_self_test( int verbose )
528 {
529  int i, buflen;
530  unsigned char buf[1024];
531  unsigned char md5sum[16];
532  md5_context ctx;
533 
534  for( i = 0; i < 7; i++ )
535  {
536  if( verbose != 0 )
537  polarssl_printf( " MD5 test #%d: ", i + 1 );
538 
539  md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
540 
541  if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
542  {
543  if( verbose != 0 )
544  polarssl_printf( "failed\n" );
545 
546  return( 1 );
547  }
548 
549  if( verbose != 0 )
550  polarssl_printf( "passed\n" );
551  }
552 
553  if( verbose != 0 )
554  polarssl_printf( "\n" );
555 
556  for( i = 0; i < 7; i++ )
557  {
558  if( verbose != 0 )
559  polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
560 
561  if( i == 5 || i == 6 )
562  {
563  memset( buf, '\xAA', buflen = 80 );
564  md5_hmac_starts( &ctx, buf, buflen );
565  }
566  else
567  md5_hmac_starts( &ctx, md5_hmac_test_key[i],
568  md5_hmac_test_keylen[i] );
569 
570  md5_hmac_update( &ctx, md5_hmac_test_buf[i],
571  md5_hmac_test_buflen[i] );
572 
573  md5_hmac_finish( &ctx, md5sum );
574 
575  buflen = ( i == 4 ) ? 12 : 16;
576 
577  if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
578  {
579  if( verbose != 0 )
580  polarssl_printf( "failed\n" );
581 
582  return( 1 );
583  }
584 
585  if( verbose != 0 )
586  polarssl_printf( "passed\n" );
587  }
588 
589  if( verbose != 0 )
590  polarssl_printf( "\n" );
591 
592  return( 0 );
593 }
594 
595 #endif /* POLARSSL_SELF_TEST */
596 
597 #endif /* POLARSSL_MD5_C */
unsigned char buffer[64]
Definition: md5.h:62
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 )
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
uint32_t state[4]
Definition: md5.h:61
#define polarssl_printf
Definition: platform.h:109
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 )