blob: 2984b1d2210bd1a1b52e1afa4f55ce8f358ec665 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1321 compliant MD5 implementation
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * 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
Paul Bakker40e46942009-01-03 21:51:57 +000031#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Paul Bakker40e46942009-01-03 21:51:57 +000033#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker40e46942009-01-03 21:51:57 +000035#include "polarssl/md5.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
37#include <string.h>
38#include <stdio.h>
39
40/*
41 * 32-bit integer manipulation macros (little endian)
42 */
43#ifndef GET_ULONG_LE
44#define GET_ULONG_LE(n,b,i) \
45{ \
46 (n) = ( (unsigned long) (b)[(i) ] ) \
47 | ( (unsigned long) (b)[(i) + 1] << 8 ) \
48 | ( (unsigned long) (b)[(i) + 2] << 16 ) \
49 | ( (unsigned long) (b)[(i) + 3] << 24 ); \
50}
51#endif
52
53#ifndef PUT_ULONG_LE
54#define PUT_ULONG_LE(n,b,i) \
55{ \
56 (b)[(i) ] = (unsigned char) ( (n) ); \
57 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
58 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
59 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
60}
61#endif
62
63/*
64 * MD5 context setup
65 */
66void md5_starts( md5_context *ctx )
67{
68 ctx->total[0] = 0;
69 ctx->total[1] = 0;
70
71 ctx->state[0] = 0x67452301;
72 ctx->state[1] = 0xEFCDAB89;
73 ctx->state[2] = 0x98BADCFE;
74 ctx->state[3] = 0x10325476;
75}
76
Paul Bakkerff60ee62010-03-16 21:09:09 +000077static void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000078{
79 unsigned long X[16], A, B, C, D;
80
81 GET_ULONG_LE( X[ 0], data, 0 );
82 GET_ULONG_LE( X[ 1], data, 4 );
83 GET_ULONG_LE( X[ 2], data, 8 );
84 GET_ULONG_LE( X[ 3], data, 12 );
85 GET_ULONG_LE( X[ 4], data, 16 );
86 GET_ULONG_LE( X[ 5], data, 20 );
87 GET_ULONG_LE( X[ 6], data, 24 );
88 GET_ULONG_LE( X[ 7], data, 28 );
89 GET_ULONG_LE( X[ 8], data, 32 );
90 GET_ULONG_LE( X[ 9], data, 36 );
91 GET_ULONG_LE( X[10], data, 40 );
92 GET_ULONG_LE( X[11], data, 44 );
93 GET_ULONG_LE( X[12], data, 48 );
94 GET_ULONG_LE( X[13], data, 52 );
95 GET_ULONG_LE( X[14], data, 56 );
96 GET_ULONG_LE( X[15], data, 60 );
97
98#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
99
100#define P(a,b,c,d,k,s,t) \
101{ \
102 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
103}
104
105 A = ctx->state[0];
106 B = ctx->state[1];
107 C = ctx->state[2];
108 D = ctx->state[3];
109
110#define F(x,y,z) (z ^ (x & (y ^ z)))
111
112 P( A, B, C, D, 0, 7, 0xD76AA478 );
113 P( D, A, B, C, 1, 12, 0xE8C7B756 );
114 P( C, D, A, B, 2, 17, 0x242070DB );
115 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
116 P( A, B, C, D, 4, 7, 0xF57C0FAF );
117 P( D, A, B, C, 5, 12, 0x4787C62A );
118 P( C, D, A, B, 6, 17, 0xA8304613 );
119 P( B, C, D, A, 7, 22, 0xFD469501 );
120 P( A, B, C, D, 8, 7, 0x698098D8 );
121 P( D, A, B, C, 9, 12, 0x8B44F7AF );
122 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
123 P( B, C, D, A, 11, 22, 0x895CD7BE );
124 P( A, B, C, D, 12, 7, 0x6B901122 );
125 P( D, A, B, C, 13, 12, 0xFD987193 );
126 P( C, D, A, B, 14, 17, 0xA679438E );
127 P( B, C, D, A, 15, 22, 0x49B40821 );
128
129#undef F
130
131#define F(x,y,z) (y ^ (z & (x ^ y)))
132
133 P( A, B, C, D, 1, 5, 0xF61E2562 );
134 P( D, A, B, C, 6, 9, 0xC040B340 );
135 P( C, D, A, B, 11, 14, 0x265E5A51 );
136 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
137 P( A, B, C, D, 5, 5, 0xD62F105D );
138 P( D, A, B, C, 10, 9, 0x02441453 );
139 P( C, D, A, B, 15, 14, 0xD8A1E681 );
140 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
141 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
142 P( D, A, B, C, 14, 9, 0xC33707D6 );
143 P( C, D, A, B, 3, 14, 0xF4D50D87 );
144 P( B, C, D, A, 8, 20, 0x455A14ED );
145 P( A, B, C, D, 13, 5, 0xA9E3E905 );
146 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
147 P( C, D, A, B, 7, 14, 0x676F02D9 );
148 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
149
150#undef F
151
152#define F(x,y,z) (x ^ y ^ z)
153
154 P( A, B, C, D, 5, 4, 0xFFFA3942 );
155 P( D, A, B, C, 8, 11, 0x8771F681 );
156 P( C, D, A, B, 11, 16, 0x6D9D6122 );
157 P( B, C, D, A, 14, 23, 0xFDE5380C );
158 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
159 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
160 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
161 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
162 P( A, B, C, D, 13, 4, 0x289B7EC6 );
163 P( D, A, B, C, 0, 11, 0xEAA127FA );
164 P( C, D, A, B, 3, 16, 0xD4EF3085 );
165 P( B, C, D, A, 6, 23, 0x04881D05 );
166 P( A, B, C, D, 9, 4, 0xD9D4D039 );
167 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
168 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
169 P( B, C, D, A, 2, 23, 0xC4AC5665 );
170
171#undef F
172
173#define F(x,y,z) (y ^ (x | ~z))
174
175 P( A, B, C, D, 0, 6, 0xF4292244 );
176 P( D, A, B, C, 7, 10, 0x432AFF97 );
177 P( C, D, A, B, 14, 15, 0xAB9423A7 );
178 P( B, C, D, A, 5, 21, 0xFC93A039 );
179 P( A, B, C, D, 12, 6, 0x655B59C3 );
180 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
181 P( C, D, A, B, 10, 15, 0xFFEFF47D );
182 P( B, C, D, A, 1, 21, 0x85845DD1 );
183 P( A, B, C, D, 8, 6, 0x6FA87E4F );
184 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
185 P( C, D, A, B, 6, 15, 0xA3014314 );
186 P( B, C, D, A, 13, 21, 0x4E0811A1 );
187 P( A, B, C, D, 4, 6, 0xF7537E82 );
188 P( D, A, B, C, 11, 10, 0xBD3AF235 );
189 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
190 P( B, C, D, A, 9, 21, 0xEB86D391 );
191
192#undef F
193
194 ctx->state[0] += A;
195 ctx->state[1] += B;
196 ctx->state[2] += C;
197 ctx->state[3] += D;
198}
199
200/*
201 * MD5 process buffer
202 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000203void md5_update( md5_context *ctx, const unsigned char *input, int ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000204{
205 int fill;
206 unsigned long left;
207
208 if( ilen <= 0 )
209 return;
210
211 left = ctx->total[0] & 0x3F;
212 fill = 64 - left;
213
214 ctx->total[0] += ilen;
215 ctx->total[0] &= 0xFFFFFFFF;
216
217 if( ctx->total[0] < (unsigned long) ilen )
218 ctx->total[1]++;
219
220 if( left && ilen >= fill )
221 {
222 memcpy( (void *) (ctx->buffer + left),
223 (void *) input, fill );
224 md5_process( ctx, ctx->buffer );
225 input += fill;
226 ilen -= fill;
227 left = 0;
228 }
229
230 while( ilen >= 64 )
231 {
232 md5_process( ctx, input );
233 input += 64;
234 ilen -= 64;
235 }
236
237 if( ilen > 0 )
238 {
239 memcpy( (void *) (ctx->buffer + left),
240 (void *) input, ilen );
241 }
242}
243
244static const unsigned char md5_padding[64] =
245{
246 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
247 0, 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};
251
252/*
253 * MD5 final digest
254 */
255void md5_finish( md5_context *ctx, unsigned char output[16] )
256{
257 unsigned long last, padn;
258 unsigned long high, low;
259 unsigned char msglen[8];
260
261 high = ( ctx->total[0] >> 29 )
262 | ( ctx->total[1] << 3 );
263 low = ( ctx->total[0] << 3 );
264
265 PUT_ULONG_LE( low, msglen, 0 );
266 PUT_ULONG_LE( high, msglen, 4 );
267
268 last = ctx->total[0] & 0x3F;
269 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
270
271 md5_update( ctx, (unsigned char *) md5_padding, padn );
272 md5_update( ctx, msglen, 8 );
273
274 PUT_ULONG_LE( ctx->state[0], output, 0 );
275 PUT_ULONG_LE( ctx->state[1], output, 4 );
276 PUT_ULONG_LE( ctx->state[2], output, 8 );
277 PUT_ULONG_LE( ctx->state[3], output, 12 );
278}
279
280/*
281 * output = MD5( input buffer )
282 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000283void md5( const unsigned char *input, int ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000284{
285 md5_context ctx;
286
287 md5_starts( &ctx );
288 md5_update( &ctx, input, ilen );
289 md5_finish( &ctx, output );
290
291 memset( &ctx, 0, sizeof( md5_context ) );
292}
293
294/*
295 * output = MD5( file contents )
296 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000297int md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000298{
299 FILE *f;
300 size_t n;
301 md5_context ctx;
302 unsigned char buf[1024];
303
304 if( ( f = fopen( path, "rb" ) ) == NULL )
305 return( 1 );
306
307 md5_starts( &ctx );
308
309 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
310 md5_update( &ctx, buf, (int) n );
311
312 md5_finish( &ctx, output );
313
314 memset( &ctx, 0, sizeof( md5_context ) );
315
316 if( ferror( f ) != 0 )
317 {
318 fclose( f );
319 return( 2 );
320 }
321
322 fclose( f );
323 return( 0 );
324}
325
326/*
327 * MD5 HMAC context setup
328 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000329void md5_hmac_starts( md5_context *ctx, const unsigned char *key, int keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000330{
331 int i;
332 unsigned char sum[16];
333
334 if( keylen > 64 )
335 {
336 md5( key, keylen, sum );
337 keylen = 16;
338 key = sum;
339 }
340
341 memset( ctx->ipad, 0x36, 64 );
342 memset( ctx->opad, 0x5C, 64 );
343
344 for( i = 0; i < keylen; i++ )
345 {
346 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
347 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
348 }
349
350 md5_starts( ctx );
351 md5_update( ctx, ctx->ipad, 64 );
352
353 memset( sum, 0, sizeof( sum ) );
354}
355
356/*
357 * MD5 HMAC process buffer
358 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000359void md5_hmac_update( md5_context *ctx, const unsigned char *input, int ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000360{
361 md5_update( ctx, input, ilen );
362}
363
364/*
365 * MD5 HMAC final digest
366 */
367void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
368{
369 unsigned char tmpbuf[16];
370
371 md5_finish( ctx, tmpbuf );
372 md5_starts( ctx );
373 md5_update( ctx, ctx->opad, 64 );
374 md5_update( ctx, tmpbuf, 16 );
375 md5_finish( ctx, output );
376
377 memset( tmpbuf, 0, sizeof( tmpbuf ) );
378}
379
380/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000381 * MD5 HMAC context reset
382 */
383void md5_hmac_reset( md5_context *ctx )
384{
385 md5_starts( ctx );
386 md5_update( ctx, ctx->ipad, 64 );
387}
388
389/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000390 * output = HMAC-MD5( hmac key, input buffer )
391 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000392void md5_hmac( const unsigned char *key, int keylen,
393 const unsigned char *input, int ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 unsigned char output[16] )
395{
396 md5_context ctx;
397
398 md5_hmac_starts( &ctx, key, keylen );
399 md5_hmac_update( &ctx, input, ilen );
400 md5_hmac_finish( &ctx, output );
401
402 memset( &ctx, 0, sizeof( md5_context ) );
403}
404
Paul Bakker40e46942009-01-03 21:51:57 +0000405#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000406/*
407 * RFC 1321 test vectors
408 */
409static unsigned char md5_test_buf[7][81] =
410{
411 { "" },
412 { "a" },
413 { "abc" },
414 { "message digest" },
415 { "abcdefghijklmnopqrstuvwxyz" },
416 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
417 { "12345678901234567890123456789012345678901234567890123456789012" \
418 "345678901234567890" }
419};
420
421static const int md5_test_buflen[7] =
422{
423 0, 1, 3, 14, 26, 62, 80
424};
425
426static const unsigned char md5_test_sum[7][16] =
427{
428 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
429 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
430 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
431 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
432 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
433 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
434 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
435 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
436 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
437 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
438 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
439 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
440 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
441 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
442};
443
444/*
445 * RFC 2202 test vectors
446 */
447static unsigned char md5_hmac_test_key[7][26] =
448{
449 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
450 { "Jefe" },
451 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
452 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
453 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
454 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
455 { "" }, /* 0xAA 80 times */
456 { "" }
457};
458
459static const int md5_hmac_test_keylen[7] =
460{
461 16, 4, 16, 25, 16, 80, 80
462};
463
464static unsigned char md5_hmac_test_buf[7][74] =
465{
466 { "Hi There" },
467 { "what do ya want for nothing?" },
468 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
469 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
470 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
471 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
472 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
473 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
474 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
475 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
476 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
477 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
478 { "Test With Truncation" },
479 { "Test Using Larger Than Block-Size Key - Hash Key First" },
480 { "Test Using Larger Than Block-Size Key and Larger"
481 " Than One Block-Size Data" }
482};
483
484static const int md5_hmac_test_buflen[7] =
485{
486 8, 28, 50, 50, 20, 54, 73
487};
488
489static const unsigned char md5_hmac_test_sum[7][16] =
490{
491 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
492 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
493 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
494 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
495 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
496 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
497 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
498 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
499 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
500 0xF9, 0xBA, 0xB9, 0x95 },
501 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
502 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
503 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
504 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
505};
506
507/*
508 * Checkup routine
509 */
510int md5_self_test( int verbose )
511{
512 int i, buflen;
513 unsigned char buf[1024];
514 unsigned char md5sum[16];
515 md5_context ctx;
516
517 for( i = 0; i < 7; i++ )
518 {
519 if( verbose != 0 )
520 printf( " MD5 test #%d: ", i + 1 );
521
522 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
523
524 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
525 {
526 if( verbose != 0 )
527 printf( "failed\n" );
528
529 return( 1 );
530 }
531
532 if( verbose != 0 )
533 printf( "passed\n" );
534 }
535
536 if( verbose != 0 )
537 printf( "\n" );
538
539 for( i = 0; i < 7; i++ )
540 {
541 if( verbose != 0 )
542 printf( " HMAC-MD5 test #%d: ", i + 1 );
543
544 if( i == 5 || i == 6 )
545 {
546 memset( buf, '\xAA', buflen = 80 );
547 md5_hmac_starts( &ctx, buf, buflen );
548 }
549 else
550 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
551 md5_hmac_test_keylen[i] );
552
553 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
554 md5_hmac_test_buflen[i] );
555
556 md5_hmac_finish( &ctx, md5sum );
557
558 buflen = ( i == 4 ) ? 12 : 16;
559
560 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
561 {
562 if( verbose != 0 )
563 printf( "failed\n" );
564
565 return( 1 );
566 }
567
568 if( verbose != 0 )
569 printf( "passed\n" );
570 }
571
572 if( verbose != 0 )
573 printf( "\n" );
574
575 return( 0 );
576}
577
578#endif
579
580#endif