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 */
52static 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
81void md5_init( md5_context *ctx )
82{
83 memset( ctx, 0, sizeof( md5_context ) );
84}
85
86void 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 */
97void 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
108void 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 */
234void 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
273static 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 */
284void 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 */
314void 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 */
329int 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 */
362void 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 */
393void 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 */
402void 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 */
418void 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 */
427void 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 */
444static 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
456static const int md5_test_buflen[7] =
457{
458 0, 1, 3, 14, 26, 62, 80
459};
460
461static 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 */
482static 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
494static const int md5_hmac_test_keylen[7] =
495{
496 16, 4, 16, 25, 16, 80, 80
497};
498
499static 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
519static const int md5_hmac_test_buflen[7] =
520{
521 8, 28, 50, 50, 20, 54, 73
522};
523
524static 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 */
545int 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 */
Configuration options (set of defines)
MD5 message digest algorithm (hash function)
void md5_hmac_finish(md5_context *ctx, unsigned char output[16])
MD5 HMAC 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_process(md5_context *ctx, const unsigned char data[64])
void md5_free(md5_context *ctx)
Clear MD5 context.
int md5_self_test(int verbose)
Checkup routine.
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_finish(md5_context *ctx, unsigned char output[16])
MD5 final digest.
void md5(const unsigned char *input, size_t ilen, unsigned char output[16])
Output = MD5( input buffer )
void md5_hmac_update(md5_context *ctx, const unsigned char *input, size_t ilen)
MD5 HMAC process buffer.
void md5_starts(md5_context *ctx)
MD5 context setup.
int md5_file(const char *path, unsigned char output[16])
Output = MD5( file contents )
#define POLARSSL_ERR_MD5_FILE_IO_ERROR
Read/write error in file.
Definition md5.h:45
void md5_hmac_starts(md5_context *ctx, const unsigned char *key, size_t keylen)
MD5 HMAC context setup.
void md5_hmac_reset(md5_context *ctx)
MD5 HMAC context reset.
PolarSSL Platform abstraction layer.
MD5 context structure.
Definition md5.h:59
uint32_t state[4]
Definition md5.h:61
uint32_t total[2]
Definition md5.h:60
unsigned char buffer[64]
Definition md5.h:62
unsigned char ipad[64]
Definition md5.h:64
unsigned char opad[64]
Definition md5.h:65
#define polarssl_printf