blob: 1d38ba36ed0e37335f2ea9a03fbadc3da6f6a2f6 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1321 compliant MD5 implementation
3 *
Paul Bakker4087c472013-06-12 16:49:10 +02004 * Copyright (C) 2006-2013, 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
Paul Bakker312da332014-06-13 17:20:13 +020041/* Implementation that should never be optimized out by the compiler */
42static void polarssl_zeroize( void *v, size_t n ) {
43 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
44}
45
Paul Bakker4087c472013-06-12 16:49:10 +020046#if !defined(POLARSSL_MD5_ALT)
47
Paul Bakker5121ce52009-01-03 21:22:43 +000048/*
49 * 32-bit integer manipulation macros (little endian)
50 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000051#ifndef GET_UINT32_LE
52#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000053{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000054 (n) = ( (uint32_t) (b)[(i) ] ) \
55 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
56 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
57 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000058}
59#endif
60
Paul Bakker5c2364c2012-10-01 14:41:15 +000061#ifndef PUT_UINT32_LE
62#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000063{ \
64 (b)[(i) ] = (unsigned char) ( (n) ); \
65 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
66 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
67 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
68}
69#endif
70
71/*
72 * MD5 context setup
73 */
74void md5_starts( md5_context *ctx )
75{
76 ctx->total[0] = 0;
77 ctx->total[1] = 0;
78
79 ctx->state[0] = 0x67452301;
80 ctx->state[1] = 0xEFCDAB89;
81 ctx->state[2] = 0x98BADCFE;
82 ctx->state[3] = 0x10325476;
83}
84
Paul Bakkere47b34b2013-02-27 14:48:00 +010085void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000086{
Paul Bakker5c2364c2012-10-01 14:41:15 +000087 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000088
Paul Bakker5c2364c2012-10-01 14:41:15 +000089 GET_UINT32_LE( X[ 0], data, 0 );
90 GET_UINT32_LE( X[ 1], data, 4 );
91 GET_UINT32_LE( X[ 2], data, 8 );
92 GET_UINT32_LE( X[ 3], data, 12 );
93 GET_UINT32_LE( X[ 4], data, 16 );
94 GET_UINT32_LE( X[ 5], data, 20 );
95 GET_UINT32_LE( X[ 6], data, 24 );
96 GET_UINT32_LE( X[ 7], data, 28 );
97 GET_UINT32_LE( X[ 8], data, 32 );
98 GET_UINT32_LE( X[ 9], data, 36 );
99 GET_UINT32_LE( X[10], data, 40 );
100 GET_UINT32_LE( X[11], data, 44 );
101 GET_UINT32_LE( X[12], data, 48 );
102 GET_UINT32_LE( X[13], data, 52 );
103 GET_UINT32_LE( X[14], data, 56 );
104 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000105
106#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
107
108#define P(a,b,c,d,k,s,t) \
109{ \
110 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
111}
112
113 A = ctx->state[0];
114 B = ctx->state[1];
115 C = ctx->state[2];
116 D = ctx->state[3];
117
118#define F(x,y,z) (z ^ (x & (y ^ z)))
119
120 P( A, B, C, D, 0, 7, 0xD76AA478 );
121 P( D, A, B, C, 1, 12, 0xE8C7B756 );
122 P( C, D, A, B, 2, 17, 0x242070DB );
123 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
124 P( A, B, C, D, 4, 7, 0xF57C0FAF );
125 P( D, A, B, C, 5, 12, 0x4787C62A );
126 P( C, D, A, B, 6, 17, 0xA8304613 );
127 P( B, C, D, A, 7, 22, 0xFD469501 );
128 P( A, B, C, D, 8, 7, 0x698098D8 );
129 P( D, A, B, C, 9, 12, 0x8B44F7AF );
130 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
131 P( B, C, D, A, 11, 22, 0x895CD7BE );
132 P( A, B, C, D, 12, 7, 0x6B901122 );
133 P( D, A, B, C, 13, 12, 0xFD987193 );
134 P( C, D, A, B, 14, 17, 0xA679438E );
135 P( B, C, D, A, 15, 22, 0x49B40821 );
136
137#undef F
138
139#define F(x,y,z) (y ^ (z & (x ^ y)))
140
141 P( A, B, C, D, 1, 5, 0xF61E2562 );
142 P( D, A, B, C, 6, 9, 0xC040B340 );
143 P( C, D, A, B, 11, 14, 0x265E5A51 );
144 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
145 P( A, B, C, D, 5, 5, 0xD62F105D );
146 P( D, A, B, C, 10, 9, 0x02441453 );
147 P( C, D, A, B, 15, 14, 0xD8A1E681 );
148 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
149 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
150 P( D, A, B, C, 14, 9, 0xC33707D6 );
151 P( C, D, A, B, 3, 14, 0xF4D50D87 );
152 P( B, C, D, A, 8, 20, 0x455A14ED );
153 P( A, B, C, D, 13, 5, 0xA9E3E905 );
154 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
155 P( C, D, A, B, 7, 14, 0x676F02D9 );
156 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
157
158#undef F
159
160#define F(x,y,z) (x ^ y ^ z)
161
162 P( A, B, C, D, 5, 4, 0xFFFA3942 );
163 P( D, A, B, C, 8, 11, 0x8771F681 );
164 P( C, D, A, B, 11, 16, 0x6D9D6122 );
165 P( B, C, D, A, 14, 23, 0xFDE5380C );
166 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
167 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
168 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
169 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
170 P( A, B, C, D, 13, 4, 0x289B7EC6 );
171 P( D, A, B, C, 0, 11, 0xEAA127FA );
172 P( C, D, A, B, 3, 16, 0xD4EF3085 );
173 P( B, C, D, A, 6, 23, 0x04881D05 );
174 P( A, B, C, D, 9, 4, 0xD9D4D039 );
175 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
176 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
177 P( B, C, D, A, 2, 23, 0xC4AC5665 );
178
179#undef F
180
181#define F(x,y,z) (y ^ (x | ~z))
182
183 P( A, B, C, D, 0, 6, 0xF4292244 );
184 P( D, A, B, C, 7, 10, 0x432AFF97 );
185 P( C, D, A, B, 14, 15, 0xAB9423A7 );
186 P( B, C, D, A, 5, 21, 0xFC93A039 );
187 P( A, B, C, D, 12, 6, 0x655B59C3 );
188 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
189 P( C, D, A, B, 10, 15, 0xFFEFF47D );
190 P( B, C, D, A, 1, 21, 0x85845DD1 );
191 P( A, B, C, D, 8, 6, 0x6FA87E4F );
192 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
193 P( C, D, A, B, 6, 15, 0xA3014314 );
194 P( B, C, D, A, 13, 21, 0x4E0811A1 );
195 P( A, B, C, D, 4, 6, 0xF7537E82 );
196 P( D, A, B, C, 11, 10, 0xBD3AF235 );
197 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
198 P( B, C, D, A, 9, 21, 0xEB86D391 );
199
200#undef F
201
202 ctx->state[0] += A;
203 ctx->state[1] += B;
204 ctx->state[2] += C;
205 ctx->state[3] += D;
206}
207
208/*
209 * MD5 process buffer
210 */
Paul Bakker23986e52011-04-24 08:57:21 +0000211void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000212{
Paul Bakker23986e52011-04-24 08:57:21 +0000213 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000214 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000215
216 if( ilen <= 0 )
217 return;
218
219 left = ctx->total[0] & 0x3F;
220 fill = 64 - left;
221
Paul Bakker5c2364c2012-10-01 14:41:15 +0000222 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000223 ctx->total[0] &= 0xFFFFFFFF;
224
Paul Bakker5c2364c2012-10-01 14:41:15 +0000225 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000226 ctx->total[1]++;
227
228 if( left && ilen >= fill )
229 {
Paul Bakkereae09db2013-06-06 12:35:54 +0200230 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000231 md5_process( ctx, ctx->buffer );
232 input += fill;
233 ilen -= fill;
234 left = 0;
235 }
236
237 while( ilen >= 64 )
238 {
239 md5_process( ctx, input );
240 input += 64;
241 ilen -= 64;
242 }
243
244 if( ilen > 0 )
245 {
Paul Bakkereae09db2013-06-06 12:35:54 +0200246 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000247 }
248}
249
250static const unsigned char md5_padding[64] =
251{
252 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
256};
257
258/*
259 * MD5 final digest
260 */
261void md5_finish( md5_context *ctx, unsigned char output[16] )
262{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000263 uint32_t last, padn;
264 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000265 unsigned char msglen[8];
266
267 high = ( ctx->total[0] >> 29 )
268 | ( ctx->total[1] << 3 );
269 low = ( ctx->total[0] << 3 );
270
Paul Bakker5c2364c2012-10-01 14:41:15 +0000271 PUT_UINT32_LE( low, msglen, 0 );
272 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
274 last = ctx->total[0] & 0x3F;
275 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
276
Paul Bakkereae09db2013-06-06 12:35:54 +0200277 md5_update( ctx, md5_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 md5_update( ctx, msglen, 8 );
279
Paul Bakker5c2364c2012-10-01 14:41:15 +0000280 PUT_UINT32_LE( ctx->state[0], output, 0 );
281 PUT_UINT32_LE( ctx->state[1], output, 4 );
282 PUT_UINT32_LE( ctx->state[2], output, 8 );
283 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000284}
285
Paul Bakker4087c472013-06-12 16:49:10 +0200286#endif /* !POLARSSL_MD5_ALT */
287
Paul Bakker5121ce52009-01-03 21:22:43 +0000288/*
289 * output = MD5( input buffer )
290 */
Paul Bakker23986e52011-04-24 08:57:21 +0000291void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000292{
293 md5_context ctx;
294
295 md5_starts( &ctx );
296 md5_update( &ctx, input, ilen );
297 md5_finish( &ctx, output );
298
Paul Bakker312da332014-06-13 17:20:13 +0200299 polarssl_zeroize( &ctx, sizeof( md5_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000300}
301
Paul Bakker335db3f2011-04-25 15:28:35 +0000302#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000303/*
304 * output = MD5( file contents )
305 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000306int md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000307{
308 FILE *f;
309 size_t n;
310 md5_context ctx;
311 unsigned char buf[1024];
312
313 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000314 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000315
316 md5_starts( &ctx );
317
318 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000319 md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
321 md5_finish( &ctx, output );
322
Paul Bakker312da332014-06-13 17:20:13 +0200323 polarssl_zeroize( &ctx, sizeof( md5_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000324
325 if( ferror( f ) != 0 )
326 {
327 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000328 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 }
330
331 fclose( f );
332 return( 0 );
333}
Paul Bakker335db3f2011-04-25 15:28:35 +0000334#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
336/*
337 * MD5 HMAC context setup
338 */
Paul Bakker23986e52011-04-24 08:57:21 +0000339void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000340{
Paul Bakker23986e52011-04-24 08:57:21 +0000341 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000342 unsigned char sum[16];
343
344 if( keylen > 64 )
345 {
346 md5( key, keylen, sum );
347 keylen = 16;
348 key = sum;
349 }
350
351 memset( ctx->ipad, 0x36, 64 );
352 memset( ctx->opad, 0x5C, 64 );
353
354 for( i = 0; i < keylen; i++ )
355 {
356 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
357 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
358 }
359
360 md5_starts( ctx );
361 md5_update( ctx, ctx->ipad, 64 );
362
Paul Bakker312da332014-06-13 17:20:13 +0200363 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000364}
365
366/*
367 * MD5 HMAC process buffer
368 */
Paul Bakker23986e52011-04-24 08:57:21 +0000369void md5_hmac_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000370{
371 md5_update( ctx, input, ilen );
372}
373
374/*
375 * MD5 HMAC final digest
376 */
377void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
378{
379 unsigned char tmpbuf[16];
380
381 md5_finish( ctx, tmpbuf );
382 md5_starts( ctx );
383 md5_update( ctx, ctx->opad, 64 );
384 md5_update( ctx, tmpbuf, 16 );
385 md5_finish( ctx, output );
386
Paul Bakker312da332014-06-13 17:20:13 +0200387 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000388}
389
390/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000391 * MD5 HMAC context reset
392 */
393void md5_hmac_reset( md5_context *ctx )
394{
395 md5_starts( ctx );
396 md5_update( ctx, ctx->ipad, 64 );
397}
398
399/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000400 * output = HMAC-MD5( hmac key, input buffer )
401 */
Paul Bakker23986e52011-04-24 08:57:21 +0000402void md5_hmac( const unsigned char *key, size_t keylen,
403 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000404 unsigned char output[16] )
405{
406 md5_context ctx;
407
408 md5_hmac_starts( &ctx, key, keylen );
409 md5_hmac_update( &ctx, input, ilen );
410 md5_hmac_finish( &ctx, output );
411
Paul Bakker312da332014-06-13 17:20:13 +0200412 polarssl_zeroize( &ctx, sizeof( md5_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000413}
414
Paul Bakker40e46942009-01-03 21:51:57 +0000415#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000416/*
417 * RFC 1321 test vectors
418 */
419static unsigned char md5_test_buf[7][81] =
420{
421 { "" },
422 { "a" },
423 { "abc" },
424 { "message digest" },
425 { "abcdefghijklmnopqrstuvwxyz" },
426 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
427 { "12345678901234567890123456789012345678901234567890123456789012" \
428 "345678901234567890" }
429};
430
431static const int md5_test_buflen[7] =
432{
433 0, 1, 3, 14, 26, 62, 80
434};
435
436static const unsigned char md5_test_sum[7][16] =
437{
438 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
439 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
440 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
441 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
442 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
443 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
444 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
445 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
446 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
447 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
448 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
449 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
450 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
451 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
452};
453
454/*
455 * RFC 2202 test vectors
456 */
457static unsigned char md5_hmac_test_key[7][26] =
458{
459 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
460 { "Jefe" },
461 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
462 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
463 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
464 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
465 { "" }, /* 0xAA 80 times */
466 { "" }
467};
468
469static const int md5_hmac_test_keylen[7] =
470{
471 16, 4, 16, 25, 16, 80, 80
472};
473
474static unsigned char md5_hmac_test_buf[7][74] =
475{
476 { "Hi There" },
477 { "what do ya want for nothing?" },
478 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
479 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
480 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
481 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
482 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
483 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
484 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
485 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
486 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
487 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
488 { "Test With Truncation" },
489 { "Test Using Larger Than Block-Size Key - Hash Key First" },
490 { "Test Using Larger Than Block-Size Key and Larger"
491 " Than One Block-Size Data" }
492};
493
494static const int md5_hmac_test_buflen[7] =
495{
496 8, 28, 50, 50, 20, 54, 73
497};
498
499static const unsigned char md5_hmac_test_sum[7][16] =
500{
501 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
502 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
503 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
504 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
505 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
506 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
507 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
508 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
509 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
510 0xF9, 0xBA, 0xB9, 0x95 },
511 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
512 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
513 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
514 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
515};
516
517/*
518 * Checkup routine
519 */
520int md5_self_test( int verbose )
521{
522 int i, buflen;
523 unsigned char buf[1024];
524 unsigned char md5sum[16];
525 md5_context ctx;
526
527 for( i = 0; i < 7; i++ )
528 {
529 if( verbose != 0 )
530 printf( " MD5 test #%d: ", i + 1 );
531
532 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
533
534 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
535 {
536 if( verbose != 0 )
537 printf( "failed\n" );
538
539 return( 1 );
540 }
541
542 if( verbose != 0 )
543 printf( "passed\n" );
544 }
545
546 if( verbose != 0 )
547 printf( "\n" );
548
549 for( i = 0; i < 7; i++ )
550 {
551 if( verbose != 0 )
552 printf( " HMAC-MD5 test #%d: ", i + 1 );
553
554 if( i == 5 || i == 6 )
555 {
556 memset( buf, '\xAA', buflen = 80 );
557 md5_hmac_starts( &ctx, buf, buflen );
558 }
559 else
560 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
561 md5_hmac_test_keylen[i] );
562
563 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
564 md5_hmac_test_buflen[i] );
565
566 md5_hmac_finish( &ctx, md5sum );
567
568 buflen = ( i == 4 ) ? 12 : 16;
569
570 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
571 {
572 if( verbose != 0 )
573 printf( "failed\n" );
574
575 return( 1 );
576 }
577
578 if( verbose != 0 )
579 printf( "passed\n" );
580 }
581
582 if( verbose != 0 )
583 printf( "\n" );
584
585 return( 0 );
586}
587
588#endif
589
590#endif