PolarSSL v1.2.9
md5.c
Go to the documentation of this file.
1 /*
2  * RFC 1321 compliant MD5 implementation
3  *
4  * Copyright (C) 2006-2013, 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 #include "polarssl/config.h"
32 
33 #if defined(POLARSSL_MD5_C)
34 
35 #include "polarssl/md5.h"
36 
37 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
38 #include <stdio.h>
39 #endif
40 
41 #if !defined(POLARSSL_MD5_ALT)
42 
43 /*
44  * 32-bit integer manipulation macros (little endian)
45  */
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 ); \
53 }
54 #endif
55 
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 ); \
63 }
64 #endif
65 
66 /*
67  * MD5 context setup
68  */
69 void md5_starts( md5_context *ctx )
70 {
71  ctx->total[0] = 0;
72  ctx->total[1] = 0;
73 
74  ctx->state[0] = 0x67452301;
75  ctx->state[1] = 0xEFCDAB89;
76  ctx->state[2] = 0x98BADCFE;
77  ctx->state[3] = 0x10325476;
78 }
79 
80 void md5_process( md5_context *ctx, const unsigned char data[64] )
81 {
82  uint32_t X[16], A, B, C, D;
83 
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 );
100 
101 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
102 
103 #define P(a,b,c,d,k,s,t) \
104 { \
105  a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
106 }
107 
108  A = ctx->state[0];
109  B = ctx->state[1];
110  C = ctx->state[2];
111  D = ctx->state[3];
112 
113 #define F(x,y,z) (z ^ (x & (y ^ z)))
114 
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 );
131 
132 #undef F
133 
134 #define F(x,y,z) (y ^ (z & (x ^ y)))
135 
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 );
152 
153 #undef F
154 
155 #define F(x,y,z) (x ^ y ^ z)
156 
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 );
173 
174 #undef F
175 
176 #define F(x,y,z) (y ^ (x | ~z))
177 
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 );
194 
195 #undef F
196 
197  ctx->state[0] += A;
198  ctx->state[1] += B;
199  ctx->state[2] += C;
200  ctx->state[3] += D;
201 }
202 
203 /*
204  * MD5 process buffer
205  */
206 void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
207 {
208  size_t fill;
209  uint32_t left;
210 
211  if( ilen <= 0 )
212  return;
213 
214  left = ctx->total[0] & 0x3F;
215  fill = 64 - left;
216 
217  ctx->total[0] += (uint32_t) ilen;
218  ctx->total[0] &= 0xFFFFFFFF;
219 
220  if( ctx->total[0] < (uint32_t) ilen )
221  ctx->total[1]++;
222 
223  if( left && ilen >= fill )
224  {
225  memcpy( (void *) (ctx->buffer + left), input, fill );
226  md5_process( ctx, ctx->buffer );
227  input += fill;
228  ilen -= fill;
229  left = 0;
230  }
231 
232  while( ilen >= 64 )
233  {
234  md5_process( ctx, input );
235  input += 64;
236  ilen -= 64;
237  }
238 
239  if( ilen > 0 )
240  {
241  memcpy( (void *) (ctx->buffer + left), input, ilen );
242  }
243 }
244 
245 static const unsigned char md5_padding[64] =
246 {
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
251 };
252 
253 /*
254  * MD5 final digest
255  */
256 void md5_finish( md5_context *ctx, unsigned char output[16] )
257 {
258  uint32_t last, padn;
259  uint32_t high, low;
260  unsigned char msglen[8];
261 
262  high = ( ctx->total[0] >> 29 )
263  | ( ctx->total[1] << 3 );
264  low = ( ctx->total[0] << 3 );
265 
266  PUT_UINT32_LE( low, msglen, 0 );
267  PUT_UINT32_LE( high, msglen, 4 );
268 
269  last = ctx->total[0] & 0x3F;
270  padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
271 
272  md5_update( ctx, md5_padding, padn );
273  md5_update( ctx, msglen, 8 );
274 
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 );
279 }
280 
281 #endif /* !POLARSSL_MD5_ALT */
282 
283 /*
284  * output = MD5( input buffer )
285  */
286 void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
287 {
288  md5_context ctx;
289 
290  md5_starts( &ctx );
291  md5_update( &ctx, input, ilen );
292  md5_finish( &ctx, output );
293 
294  memset( &ctx, 0, sizeof( md5_context ) );
295 }
296 
297 #if defined(POLARSSL_FS_IO)
298 /*
299  * output = MD5( file contents )
300  */
301 int md5_file( const char *path, unsigned char output[16] )
302 {
303  FILE *f;
304  size_t n;
305  md5_context ctx;
306  unsigned char buf[1024];
307 
308  if( ( f = fopen( path, "rb" ) ) == NULL )
310 
311  md5_starts( &ctx );
312 
313  while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
314  md5_update( &ctx, buf, n );
315 
316  md5_finish( &ctx, output );
317 
318  memset( &ctx, 0, sizeof( md5_context ) );
319 
320  if( ferror( f ) != 0 )
321  {
322  fclose( f );
324  }
325 
326  fclose( f );
327  return( 0 );
328 }
329 #endif /* POLARSSL_FS_IO */
330 
331 /*
332  * MD5 HMAC context setup
333  */
334 void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen )
335 {
336  size_t i;
337  unsigned char sum[16];
338 
339  if( keylen > 64 )
340  {
341  md5( key, keylen, sum );
342  keylen = 16;
343  key = sum;
344  }
345 
346  memset( ctx->ipad, 0x36, 64 );
347  memset( ctx->opad, 0x5C, 64 );
348 
349  for( i = 0; i < keylen; i++ )
350  {
351  ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
352  ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
353  }
354 
355  md5_starts( ctx );
356  md5_update( ctx, ctx->ipad, 64 );
357 
358  memset( sum, 0, sizeof( sum ) );
359 }
360 
361 /*
362  * MD5 HMAC process buffer
363  */
364 void md5_hmac_update( md5_context *ctx, const unsigned char *input, size_t ilen )
365 {
366  md5_update( ctx, input, ilen );
367 }
368 
369 /*
370  * MD5 HMAC final digest
371  */
372 void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
373 {
374  unsigned char tmpbuf[16];
375 
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 );
381 
382  memset( tmpbuf, 0, sizeof( tmpbuf ) );
383 }
384 
385 /*
386  * MD5 HMAC context reset
387  */
388 void md5_hmac_reset( md5_context *ctx )
389 {
390  md5_starts( ctx );
391  md5_update( ctx, ctx->ipad, 64 );
392 }
393 
394 /*
395  * output = HMAC-MD5( hmac key, input buffer )
396  */
397 void md5_hmac( const unsigned char *key, size_t keylen,
398  const unsigned char *input, size_t ilen,
399  unsigned char output[16] )
400 {
401  md5_context ctx;
402 
403  md5_hmac_starts( &ctx, key, keylen );
404  md5_hmac_update( &ctx, input, ilen );
405  md5_hmac_finish( &ctx, output );
406 
407  memset( &ctx, 0, sizeof( md5_context ) );
408 }
409 
410 #if defined(POLARSSL_SELF_TEST)
411 /*
412  * RFC 1321 test vectors
413  */
414 static unsigned char md5_test_buf[7][81] =
415 {
416  { "" },
417  { "a" },
418  { "abc" },
419  { "message digest" },
420  { "abcdefghijklmnopqrstuvwxyz" },
421  { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
422  { "12345678901234567890123456789012345678901234567890123456789012" \
423  "345678901234567890" }
424 };
425 
426 static const int md5_test_buflen[7] =
427 {
428  0, 1, 3, 14, 26, 62, 80
429 };
430 
431 static const unsigned char md5_test_sum[7][16] =
432 {
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 }
447 };
448 
449 /*
450  * RFC 2202 test vectors
451  */
452 static unsigned char md5_hmac_test_key[7][26] =
453 {
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  { "" }
462 };
463 
464 static const int md5_hmac_test_keylen[7] =
465 {
466  16, 4, 16, 25, 16, 80, 80
467 };
468 
469 static unsigned char md5_hmac_test_buf[7][74] =
470 {
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" }
487 };
488 
489 static const int md5_hmac_test_buflen[7] =
490 {
491  8, 28, 50, 50, 20, 54, 73
492 };
493 
494 static const unsigned char md5_hmac_test_sum[7][16] =
495 {
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 }
510 };
511 
512 /*
513  * Checkup routine
514  */
515 int md5_self_test( int verbose )
516 {
517  int i, buflen;
518  unsigned char buf[1024];
519  unsigned char md5sum[16];
520  md5_context ctx;
521 
522  for( i = 0; i < 7; i++ )
523  {
524  if( verbose != 0 )
525  printf( " MD5 test #%d: ", i + 1 );
526 
527  md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
528 
529  if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
530  {
531  if( verbose != 0 )
532  printf( "failed\n" );
533 
534  return( 1 );
535  }
536 
537  if( verbose != 0 )
538  printf( "passed\n" );
539  }
540 
541  if( verbose != 0 )
542  printf( "\n" );
543 
544  for( i = 0; i < 7; i++ )
545  {
546  if( verbose != 0 )
547  printf( " HMAC-MD5 test #%d: ", i + 1 );
548 
549  if( i == 5 || i == 6 )
550  {
551  memset( buf, '\xAA', buflen = 80 );
552  md5_hmac_starts( &ctx, buf, buflen );
553  }
554  else
555  md5_hmac_starts( &ctx, md5_hmac_test_key[i],
556  md5_hmac_test_keylen[i] );
557 
558  md5_hmac_update( &ctx, md5_hmac_test_buf[i],
559  md5_hmac_test_buflen[i] );
560 
561  md5_hmac_finish( &ctx, md5sum );
562 
563  buflen = ( i == 4 ) ? 12 : 16;
564 
565  if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
566  {
567  if( verbose != 0 )
568  printf( "failed\n" );
569 
570  return( 1 );
571  }
572 
573  if( verbose != 0 )
574  printf( "passed\n" );
575  }
576 
577  if( verbose != 0 )
578  printf( "\n" );
579 
580  return( 0 );
581 }
582 
583 #endif
584 
585 #endif
unsigned char buffer[64]
Definition: md5.h:54
unsigned char opad[64]
Definition: md5.h:57
Configuration options (set of defines)
#define POLARSSL_ERR_MD5_FILE_IO_ERROR
Read/write error in file.
Definition: md5.h:41
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.
unsigned char ipad[64]
Definition: md5.h:56
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:50
uint32_t total[2]
Definition: md5.h:52
uint32_t state[4]
Definition: md5.h:53
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 )