blob: 3097aeb5c0d92e471f24c39363f06316c4618f50 [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
Paul Bakker335db3f2011-04-25 15:28:35 +000037#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000038#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000039#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000040
41/*
42 * 32-bit integer manipulation macros (little endian)
43 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000044#ifndef GET_UINT32_LE
45#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000046{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000047 (n) = ( (uint32_t) (b)[(i) ] ) \
48 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
49 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
50 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000051}
52#endif
53
Paul Bakker5c2364c2012-10-01 14:41:15 +000054#ifndef PUT_UINT32_LE
55#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000056{ \
57 (b)[(i) ] = (unsigned char) ( (n) ); \
58 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
59 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
60 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
61}
62#endif
63
64/*
65 * MD5 context setup
66 */
67void md5_starts( md5_context *ctx )
68{
69 ctx->total[0] = 0;
70 ctx->total[1] = 0;
71
72 ctx->state[0] = 0x67452301;
73 ctx->state[1] = 0xEFCDAB89;
74 ctx->state[2] = 0x98BADCFE;
75 ctx->state[3] = 0x10325476;
76}
77
Paul Bakkere47b34b2013-02-27 14:48:00 +010078void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000079{
Paul Bakker5c2364c2012-10-01 14:41:15 +000080 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000081
Paul Bakker5c2364c2012-10-01 14:41:15 +000082 GET_UINT32_LE( X[ 0], data, 0 );
83 GET_UINT32_LE( X[ 1], data, 4 );
84 GET_UINT32_LE( X[ 2], data, 8 );
85 GET_UINT32_LE( X[ 3], data, 12 );
86 GET_UINT32_LE( X[ 4], data, 16 );
87 GET_UINT32_LE( X[ 5], data, 20 );
88 GET_UINT32_LE( X[ 6], data, 24 );
89 GET_UINT32_LE( X[ 7], data, 28 );
90 GET_UINT32_LE( X[ 8], data, 32 );
91 GET_UINT32_LE( X[ 9], data, 36 );
92 GET_UINT32_LE( X[10], data, 40 );
93 GET_UINT32_LE( X[11], data, 44 );
94 GET_UINT32_LE( X[12], data, 48 );
95 GET_UINT32_LE( X[13], data, 52 );
96 GET_UINT32_LE( X[14], data, 56 );
97 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +000098
99#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
100
101#define P(a,b,c,d,k,s,t) \
102{ \
103 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
104}
105
106 A = ctx->state[0];
107 B = ctx->state[1];
108 C = ctx->state[2];
109 D = ctx->state[3];
110
111#define F(x,y,z) (z ^ (x & (y ^ z)))
112
113 P( A, B, C, D, 0, 7, 0xD76AA478 );
114 P( D, A, B, C, 1, 12, 0xE8C7B756 );
115 P( C, D, A, B, 2, 17, 0x242070DB );
116 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
117 P( A, B, C, D, 4, 7, 0xF57C0FAF );
118 P( D, A, B, C, 5, 12, 0x4787C62A );
119 P( C, D, A, B, 6, 17, 0xA8304613 );
120 P( B, C, D, A, 7, 22, 0xFD469501 );
121 P( A, B, C, D, 8, 7, 0x698098D8 );
122 P( D, A, B, C, 9, 12, 0x8B44F7AF );
123 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
124 P( B, C, D, A, 11, 22, 0x895CD7BE );
125 P( A, B, C, D, 12, 7, 0x6B901122 );
126 P( D, A, B, C, 13, 12, 0xFD987193 );
127 P( C, D, A, B, 14, 17, 0xA679438E );
128 P( B, C, D, A, 15, 22, 0x49B40821 );
129
130#undef F
131
132#define F(x,y,z) (y ^ (z & (x ^ y)))
133
134 P( A, B, C, D, 1, 5, 0xF61E2562 );
135 P( D, A, B, C, 6, 9, 0xC040B340 );
136 P( C, D, A, B, 11, 14, 0x265E5A51 );
137 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
138 P( A, B, C, D, 5, 5, 0xD62F105D );
139 P( D, A, B, C, 10, 9, 0x02441453 );
140 P( C, D, A, B, 15, 14, 0xD8A1E681 );
141 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
142 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
143 P( D, A, B, C, 14, 9, 0xC33707D6 );
144 P( C, D, A, B, 3, 14, 0xF4D50D87 );
145 P( B, C, D, A, 8, 20, 0x455A14ED );
146 P( A, B, C, D, 13, 5, 0xA9E3E905 );
147 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
148 P( C, D, A, B, 7, 14, 0x676F02D9 );
149 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
150
151#undef F
152
153#define F(x,y,z) (x ^ y ^ z)
154
155 P( A, B, C, D, 5, 4, 0xFFFA3942 );
156 P( D, A, B, C, 8, 11, 0x8771F681 );
157 P( C, D, A, B, 11, 16, 0x6D9D6122 );
158 P( B, C, D, A, 14, 23, 0xFDE5380C );
159 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
160 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
161 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
162 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
163 P( A, B, C, D, 13, 4, 0x289B7EC6 );
164 P( D, A, B, C, 0, 11, 0xEAA127FA );
165 P( C, D, A, B, 3, 16, 0xD4EF3085 );
166 P( B, C, D, A, 6, 23, 0x04881D05 );
167 P( A, B, C, D, 9, 4, 0xD9D4D039 );
168 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
169 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
170 P( B, C, D, A, 2, 23, 0xC4AC5665 );
171
172#undef F
173
174#define F(x,y,z) (y ^ (x | ~z))
175
176 P( A, B, C, D, 0, 6, 0xF4292244 );
177 P( D, A, B, C, 7, 10, 0x432AFF97 );
178 P( C, D, A, B, 14, 15, 0xAB9423A7 );
179 P( B, C, D, A, 5, 21, 0xFC93A039 );
180 P( A, B, C, D, 12, 6, 0x655B59C3 );
181 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
182 P( C, D, A, B, 10, 15, 0xFFEFF47D );
183 P( B, C, D, A, 1, 21, 0x85845DD1 );
184 P( A, B, C, D, 8, 6, 0x6FA87E4F );
185 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
186 P( C, D, A, B, 6, 15, 0xA3014314 );
187 P( B, C, D, A, 13, 21, 0x4E0811A1 );
188 P( A, B, C, D, 4, 6, 0xF7537E82 );
189 P( D, A, B, C, 11, 10, 0xBD3AF235 );
190 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
191 P( B, C, D, A, 9, 21, 0xEB86D391 );
192
193#undef F
194
195 ctx->state[0] += A;
196 ctx->state[1] += B;
197 ctx->state[2] += C;
198 ctx->state[3] += D;
199}
200
201/*
202 * MD5 process buffer
203 */
Paul Bakker23986e52011-04-24 08:57:21 +0000204void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000205{
Paul Bakker23986e52011-04-24 08:57:21 +0000206 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000207 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000208
209 if( ilen <= 0 )
210 return;
211
212 left = ctx->total[0] & 0x3F;
213 fill = 64 - left;
214
Paul Bakker5c2364c2012-10-01 14:41:15 +0000215 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000216 ctx->total[0] &= 0xFFFFFFFF;
217
Paul Bakker5c2364c2012-10-01 14:41:15 +0000218 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000219 ctx->total[1]++;
220
221 if( left && ilen >= fill )
222 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200223 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000224 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 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200239 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 }
241}
242
243static const unsigned char md5_padding[64] =
244{
245 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246 0, 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};
250
251/*
252 * MD5 final digest
253 */
254void md5_finish( md5_context *ctx, unsigned char output[16] )
255{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000256 uint32_t last, padn;
257 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 unsigned char msglen[8];
259
260 high = ( ctx->total[0] >> 29 )
261 | ( ctx->total[1] << 3 );
262 low = ( ctx->total[0] << 3 );
263
Paul Bakker5c2364c2012-10-01 14:41:15 +0000264 PUT_UINT32_LE( low, msglen, 0 );
265 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
267 last = ctx->total[0] & 0x3F;
268 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
269
Paul Bakker3c2122f2013-06-24 19:03:14 +0200270 md5_update( ctx, md5_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 md5_update( ctx, msglen, 8 );
272
Paul Bakker5c2364c2012-10-01 14:41:15 +0000273 PUT_UINT32_LE( ctx->state[0], output, 0 );
274 PUT_UINT32_LE( ctx->state[1], output, 4 );
275 PUT_UINT32_LE( ctx->state[2], output, 8 );
276 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000277}
278
279/*
280 * output = MD5( input buffer )
281 */
Paul Bakker23986e52011-04-24 08:57:21 +0000282void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000283{
284 md5_context ctx;
285
286 md5_starts( &ctx );
287 md5_update( &ctx, input, ilen );
288 md5_finish( &ctx, output );
289
290 memset( &ctx, 0, sizeof( md5_context ) );
291}
292
Paul Bakker335db3f2011-04-25 15:28:35 +0000293#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000294/*
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 )
Paul Bakker69e095c2011-12-10 21:55:01 +0000305 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
307 md5_starts( &ctx );
308
309 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000310 md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311
312 md5_finish( &ctx, output );
313
314 memset( &ctx, 0, sizeof( md5_context ) );
315
316 if( ferror( f ) != 0 )
317 {
318 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000319 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000320 }
321
322 fclose( f );
323 return( 0 );
324}
Paul Bakker335db3f2011-04-25 15:28:35 +0000325#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
327/*
328 * MD5 HMAC context setup
329 */
Paul Bakker23986e52011-04-24 08:57:21 +0000330void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000331{
Paul Bakker23986e52011-04-24 08:57:21 +0000332 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000333 unsigned char sum[16];
334
335 if( keylen > 64 )
336 {
337 md5( key, keylen, sum );
338 keylen = 16;
339 key = sum;
340 }
341
342 memset( ctx->ipad, 0x36, 64 );
343 memset( ctx->opad, 0x5C, 64 );
344
345 for( i = 0; i < keylen; i++ )
346 {
347 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
348 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
349 }
350
351 md5_starts( ctx );
352 md5_update( ctx, ctx->ipad, 64 );
353
354 memset( sum, 0, sizeof( sum ) );
355}
356
357/*
358 * MD5 HMAC process buffer
359 */
Paul Bakker23986e52011-04-24 08:57:21 +0000360void md5_hmac_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000361{
362 md5_update( ctx, input, ilen );
363}
364
365/*
366 * MD5 HMAC final digest
367 */
368void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
369{
370 unsigned char tmpbuf[16];
371
372 md5_finish( ctx, tmpbuf );
373 md5_starts( ctx );
374 md5_update( ctx, ctx->opad, 64 );
375 md5_update( ctx, tmpbuf, 16 );
376 md5_finish( ctx, output );
377
378 memset( tmpbuf, 0, sizeof( tmpbuf ) );
379}
380
381/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000382 * MD5 HMAC context reset
383 */
384void md5_hmac_reset( md5_context *ctx )
385{
386 md5_starts( ctx );
387 md5_update( ctx, ctx->ipad, 64 );
388}
389
390/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000391 * output = HMAC-MD5( hmac key, input buffer )
392 */
Paul Bakker23986e52011-04-24 08:57:21 +0000393void md5_hmac( const unsigned char *key, size_t keylen,
394 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 unsigned char output[16] )
396{
397 md5_context ctx;
398
399 md5_hmac_starts( &ctx, key, keylen );
400 md5_hmac_update( &ctx, input, ilen );
401 md5_hmac_finish( &ctx, output );
402
403 memset( &ctx, 0, sizeof( md5_context ) );
404}
405
Paul Bakker40e46942009-01-03 21:51:57 +0000406#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000407/*
408 * RFC 1321 test vectors
409 */
410static unsigned char md5_test_buf[7][81] =
411{
412 { "" },
413 { "a" },
414 { "abc" },
415 { "message digest" },
416 { "abcdefghijklmnopqrstuvwxyz" },
417 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
418 { "12345678901234567890123456789012345678901234567890123456789012" \
419 "345678901234567890" }
420};
421
422static const int md5_test_buflen[7] =
423{
424 0, 1, 3, 14, 26, 62, 80
425};
426
427static const unsigned char md5_test_sum[7][16] =
428{
429 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
430 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
431 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
432 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
433 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
434 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
435 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
436 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
437 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
438 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
439 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
440 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
441 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
442 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
443};
444
445/*
446 * RFC 2202 test vectors
447 */
448static unsigned char md5_hmac_test_key[7][26] =
449{
450 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
451 { "Jefe" },
452 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
453 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
454 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
455 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
456 { "" }, /* 0xAA 80 times */
457 { "" }
458};
459
460static const int md5_hmac_test_keylen[7] =
461{
462 16, 4, 16, 25, 16, 80, 80
463};
464
465static unsigned char md5_hmac_test_buf[7][74] =
466{
467 { "Hi There" },
468 { "what do ya want for nothing?" },
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 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
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 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
479 { "Test With Truncation" },
480 { "Test Using Larger Than Block-Size Key - Hash Key First" },
481 { "Test Using Larger Than Block-Size Key and Larger"
482 " Than One Block-Size Data" }
483};
484
485static const int md5_hmac_test_buflen[7] =
486{
487 8, 28, 50, 50, 20, 54, 73
488};
489
490static const unsigned char md5_hmac_test_sum[7][16] =
491{
492 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
493 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
494 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
495 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
496 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
497 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
498 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
499 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
500 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
501 0xF9, 0xBA, 0xB9, 0x95 },
502 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
503 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
504 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
505 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
506};
507
508/*
509 * Checkup routine
510 */
511int md5_self_test( int verbose )
512{
513 int i, buflen;
514 unsigned char buf[1024];
515 unsigned char md5sum[16];
516 md5_context ctx;
517
518 for( i = 0; i < 7; i++ )
519 {
520 if( verbose != 0 )
521 printf( " MD5 test #%d: ", i + 1 );
522
523 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
524
525 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
526 {
527 if( verbose != 0 )
528 printf( "failed\n" );
529
530 return( 1 );
531 }
532
533 if( verbose != 0 )
534 printf( "passed\n" );
535 }
536
537 if( verbose != 0 )
538 printf( "\n" );
539
540 for( i = 0; i < 7; i++ )
541 {
542 if( verbose != 0 )
543 printf( " HMAC-MD5 test #%d: ", i + 1 );
544
545 if( i == 5 || i == 6 )
546 {
547 memset( buf, '\xAA', buflen = 80 );
548 md5_hmac_starts( &ctx, buf, buflen );
549 }
550 else
551 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
552 md5_hmac_test_keylen[i] );
553
554 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
555 md5_hmac_test_buflen[i] );
556
557 md5_hmac_finish( &ctx, md5sum );
558
559 buflen = ( i == 4 ) ? 12 : 16;
560
561 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
562 {
563 if( verbose != 0 )
564 printf( "failed\n" );
565
566 return( 1 );
567 }
568
569 if( verbose != 0 )
570 printf( "passed\n" );
571 }
572
573 if( verbose != 0 )
574 printf( "\n" );
575
576 return( 0 );
577}
578
579#endif
580
581#endif