blob: 88d50c6c907362db6fa59aed8263fbaf7aae9e35 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1321 compliant MD5 implementation
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, 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
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000032#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020033#else
34#include POLARSSL_CONFIG_FILE
35#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker40e46942009-01-03 21:51:57 +000037#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#include "polarssl/md5.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker335db3f2011-04-25 15:28:35 +000041#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000042#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000043#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000044
Paul Bakker7dc4c442014-02-01 22:50:26 +010045#if defined(POLARSSL_PLATFORM_C)
46#include "polarssl/platform.h"
47#else
48#define polarssl_printf printf
49#endif
50
Paul Bakker90995b52013-06-24 19:20:35 +020051#if !defined(POLARSSL_MD5_ALT)
52
Paul Bakker5121ce52009-01-03 21:22:43 +000053/*
54 * 32-bit integer manipulation macros (little endian)
55 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000056#ifndef GET_UINT32_LE
57#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000058{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000059 (n) = ( (uint32_t) (b)[(i) ] ) \
60 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
61 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
62 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000063}
64#endif
65
Paul Bakker5c2364c2012-10-01 14:41:15 +000066#ifndef PUT_UINT32_LE
67#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000068{ \
69 (b)[(i) ] = (unsigned char) ( (n) ); \
70 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
71 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
72 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
73}
74#endif
75
76/*
77 * MD5 context setup
78 */
79void md5_starts( md5_context *ctx )
80{
81 ctx->total[0] = 0;
82 ctx->total[1] = 0;
83
84 ctx->state[0] = 0x67452301;
85 ctx->state[1] = 0xEFCDAB89;
86 ctx->state[2] = 0x98BADCFE;
87 ctx->state[3] = 0x10325476;
88}
89
Paul Bakkere47b34b2013-02-27 14:48:00 +010090void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000091{
Paul Bakker5c2364c2012-10-01 14:41:15 +000092 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000093
Paul Bakker5c2364c2012-10-01 14:41:15 +000094 GET_UINT32_LE( X[ 0], data, 0 );
95 GET_UINT32_LE( X[ 1], data, 4 );
96 GET_UINT32_LE( X[ 2], data, 8 );
97 GET_UINT32_LE( X[ 3], data, 12 );
98 GET_UINT32_LE( X[ 4], data, 16 );
99 GET_UINT32_LE( X[ 5], data, 20 );
100 GET_UINT32_LE( X[ 6], data, 24 );
101 GET_UINT32_LE( X[ 7], data, 28 );
102 GET_UINT32_LE( X[ 8], data, 32 );
103 GET_UINT32_LE( X[ 9], data, 36 );
104 GET_UINT32_LE( X[10], data, 40 );
105 GET_UINT32_LE( X[11], data, 44 );
106 GET_UINT32_LE( X[12], data, 48 );
107 GET_UINT32_LE( X[13], data, 52 );
108 GET_UINT32_LE( X[14], data, 56 );
109 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000110
111#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
112
113#define P(a,b,c,d,k,s,t) \
114{ \
115 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
116}
117
118 A = ctx->state[0];
119 B = ctx->state[1];
120 C = ctx->state[2];
121 D = ctx->state[3];
122
123#define F(x,y,z) (z ^ (x & (y ^ z)))
124
125 P( A, B, C, D, 0, 7, 0xD76AA478 );
126 P( D, A, B, C, 1, 12, 0xE8C7B756 );
127 P( C, D, A, B, 2, 17, 0x242070DB );
128 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
129 P( A, B, C, D, 4, 7, 0xF57C0FAF );
130 P( D, A, B, C, 5, 12, 0x4787C62A );
131 P( C, D, A, B, 6, 17, 0xA8304613 );
132 P( B, C, D, A, 7, 22, 0xFD469501 );
133 P( A, B, C, D, 8, 7, 0x698098D8 );
134 P( D, A, B, C, 9, 12, 0x8B44F7AF );
135 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
136 P( B, C, D, A, 11, 22, 0x895CD7BE );
137 P( A, B, C, D, 12, 7, 0x6B901122 );
138 P( D, A, B, C, 13, 12, 0xFD987193 );
139 P( C, D, A, B, 14, 17, 0xA679438E );
140 P( B, C, D, A, 15, 22, 0x49B40821 );
141
142#undef F
143
144#define F(x,y,z) (y ^ (z & (x ^ y)))
145
146 P( A, B, C, D, 1, 5, 0xF61E2562 );
147 P( D, A, B, C, 6, 9, 0xC040B340 );
148 P( C, D, A, B, 11, 14, 0x265E5A51 );
149 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
150 P( A, B, C, D, 5, 5, 0xD62F105D );
151 P( D, A, B, C, 10, 9, 0x02441453 );
152 P( C, D, A, B, 15, 14, 0xD8A1E681 );
153 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
154 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
155 P( D, A, B, C, 14, 9, 0xC33707D6 );
156 P( C, D, A, B, 3, 14, 0xF4D50D87 );
157 P( B, C, D, A, 8, 20, 0x455A14ED );
158 P( A, B, C, D, 13, 5, 0xA9E3E905 );
159 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
160 P( C, D, A, B, 7, 14, 0x676F02D9 );
161 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
162
163#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200164
Paul Bakker5121ce52009-01-03 21:22:43 +0000165#define F(x,y,z) (x ^ y ^ z)
166
167 P( A, B, C, D, 5, 4, 0xFFFA3942 );
168 P( D, A, B, C, 8, 11, 0x8771F681 );
169 P( C, D, A, B, 11, 16, 0x6D9D6122 );
170 P( B, C, D, A, 14, 23, 0xFDE5380C );
171 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
172 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
173 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
174 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
175 P( A, B, C, D, 13, 4, 0x289B7EC6 );
176 P( D, A, B, C, 0, 11, 0xEAA127FA );
177 P( C, D, A, B, 3, 16, 0xD4EF3085 );
178 P( B, C, D, A, 6, 23, 0x04881D05 );
179 P( A, B, C, D, 9, 4, 0xD9D4D039 );
180 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
181 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
182 P( B, C, D, A, 2, 23, 0xC4AC5665 );
183
184#undef F
185
186#define F(x,y,z) (y ^ (x | ~z))
187
188 P( A, B, C, D, 0, 6, 0xF4292244 );
189 P( D, A, B, C, 7, 10, 0x432AFF97 );
190 P( C, D, A, B, 14, 15, 0xAB9423A7 );
191 P( B, C, D, A, 5, 21, 0xFC93A039 );
192 P( A, B, C, D, 12, 6, 0x655B59C3 );
193 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
194 P( C, D, A, B, 10, 15, 0xFFEFF47D );
195 P( B, C, D, A, 1, 21, 0x85845DD1 );
196 P( A, B, C, D, 8, 6, 0x6FA87E4F );
197 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
198 P( C, D, A, B, 6, 15, 0xA3014314 );
199 P( B, C, D, A, 13, 21, 0x4E0811A1 );
200 P( A, B, C, D, 4, 6, 0xF7537E82 );
201 P( D, A, B, C, 11, 10, 0xBD3AF235 );
202 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
203 P( B, C, D, A, 9, 21, 0xEB86D391 );
204
205#undef F
206
207 ctx->state[0] += A;
208 ctx->state[1] += B;
209 ctx->state[2] += C;
210 ctx->state[3] += D;
211}
212
213/*
214 * MD5 process buffer
215 */
Paul Bakker23986e52011-04-24 08:57:21 +0000216void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000217{
Paul Bakker23986e52011-04-24 08:57:21 +0000218 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000219 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000220
221 if( ilen <= 0 )
222 return;
223
224 left = ctx->total[0] & 0x3F;
225 fill = 64 - left;
226
Paul Bakker5c2364c2012-10-01 14:41:15 +0000227 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000228 ctx->total[0] &= 0xFFFFFFFF;
229
Paul Bakker5c2364c2012-10-01 14:41:15 +0000230 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000231 ctx->total[1]++;
232
233 if( left && ilen >= fill )
234 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200235 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000236 md5_process( ctx, ctx->buffer );
237 input += fill;
238 ilen -= fill;
239 left = 0;
240 }
241
242 while( ilen >= 64 )
243 {
244 md5_process( ctx, input );
245 input += 64;
246 ilen -= 64;
247 }
248
249 if( ilen > 0 )
250 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200251 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000252 }
253}
254
255static const unsigned char md5_padding[64] =
256{
257 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
261};
262
263/*
264 * MD5 final digest
265 */
266void md5_finish( md5_context *ctx, unsigned char output[16] )
267{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000268 uint32_t last, padn;
269 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 unsigned char msglen[8];
271
272 high = ( ctx->total[0] >> 29 )
273 | ( ctx->total[1] << 3 );
274 low = ( ctx->total[0] << 3 );
275
Paul Bakker5c2364c2012-10-01 14:41:15 +0000276 PUT_UINT32_LE( low, msglen, 0 );
277 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000278
279 last = ctx->total[0] & 0x3F;
280 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
281
Paul Bakker3c2122f2013-06-24 19:03:14 +0200282 md5_update( ctx, md5_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 md5_update( ctx, msglen, 8 );
284
Paul Bakker5c2364c2012-10-01 14:41:15 +0000285 PUT_UINT32_LE( ctx->state[0], output, 0 );
286 PUT_UINT32_LE( ctx->state[1], output, 4 );
287 PUT_UINT32_LE( ctx->state[2], output, 8 );
288 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000289}
290
Paul Bakker90995b52013-06-24 19:20:35 +0200291#endif /* !POLARSSL_MD5_ALT */
292
Paul Bakker5121ce52009-01-03 21:22:43 +0000293/*
294 * output = MD5( input buffer )
295 */
Paul Bakker23986e52011-04-24 08:57:21 +0000296void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000297{
298 md5_context ctx;
299
300 md5_starts( &ctx );
301 md5_update( &ctx, input, ilen );
302 md5_finish( &ctx, output );
303
304 memset( &ctx, 0, sizeof( md5_context ) );
305}
306
Paul Bakker335db3f2011-04-25 15:28:35 +0000307#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000308/*
309 * output = MD5( file contents )
310 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000311int md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000312{
313 FILE *f;
314 size_t n;
315 md5_context ctx;
316 unsigned char buf[1024];
317
318 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000319 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000320
321 md5_starts( &ctx );
322
323 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000324 md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000325
326 md5_finish( &ctx, output );
327
328 memset( &ctx, 0, sizeof( md5_context ) );
329
330 if( ferror( f ) != 0 )
331 {
332 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000333 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000334 }
335
336 fclose( f );
337 return( 0 );
338}
Paul Bakker335db3f2011-04-25 15:28:35 +0000339#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
341/*
342 * MD5 HMAC context setup
343 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200344void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
345 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000346{
Paul Bakker23986e52011-04-24 08:57:21 +0000347 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000348 unsigned char sum[16];
349
350 if( keylen > 64 )
351 {
352 md5( key, keylen, sum );
353 keylen = 16;
354 key = sum;
355 }
356
357 memset( ctx->ipad, 0x36, 64 );
358 memset( ctx->opad, 0x5C, 64 );
359
360 for( i = 0; i < keylen; i++ )
361 {
362 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
363 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
364 }
365
366 md5_starts( ctx );
367 md5_update( ctx, ctx->ipad, 64 );
368
369 memset( sum, 0, sizeof( sum ) );
370}
371
372/*
373 * MD5 HMAC process buffer
374 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200375void md5_hmac_update( md5_context *ctx, const unsigned char *input,
376 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000377{
378 md5_update( ctx, input, ilen );
379}
380
381/*
382 * MD5 HMAC final digest
383 */
384void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
385{
386 unsigned char tmpbuf[16];
387
388 md5_finish( ctx, tmpbuf );
389 md5_starts( ctx );
390 md5_update( ctx, ctx->opad, 64 );
391 md5_update( ctx, tmpbuf, 16 );
392 md5_finish( ctx, output );
393
394 memset( tmpbuf, 0, sizeof( tmpbuf ) );
395}
396
397/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000398 * MD5 HMAC context reset
399 */
400void md5_hmac_reset( md5_context *ctx )
401{
402 md5_starts( ctx );
403 md5_update( ctx, ctx->ipad, 64 );
404}
405
406/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000407 * output = HMAC-MD5( hmac key, input buffer )
408 */
Paul Bakker23986e52011-04-24 08:57:21 +0000409void md5_hmac( const unsigned char *key, size_t keylen,
410 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 unsigned char output[16] )
412{
413 md5_context ctx;
414
415 md5_hmac_starts( &ctx, key, keylen );
416 md5_hmac_update( &ctx, input, ilen );
417 md5_hmac_finish( &ctx, output );
418
419 memset( &ctx, 0, sizeof( md5_context ) );
420}
421
Paul Bakker40e46942009-01-03 21:51:57 +0000422#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000423/*
424 * RFC 1321 test vectors
425 */
426static unsigned char md5_test_buf[7][81] =
427{
Paul Bakker9af723c2014-05-01 13:03:14 +0200428 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 { "a" },
430 { "abc" },
431 { "message digest" },
432 { "abcdefghijklmnopqrstuvwxyz" },
433 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
434 { "12345678901234567890123456789012345678901234567890123456789012" \
435 "345678901234567890" }
436};
437
438static const int md5_test_buflen[7] =
439{
440 0, 1, 3, 14, 26, 62, 80
441};
442
443static const unsigned char md5_test_sum[7][16] =
444{
445 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
446 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
447 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
448 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
449 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
450 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
451 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
452 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
453 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
454 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
455 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
456 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
457 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
458 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
459};
460
461/*
462 * RFC 2202 test vectors
463 */
464static unsigned char md5_hmac_test_key[7][26] =
465{
466 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
467 { "Jefe" },
468 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
469 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
470 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
471 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
472 { "" }, /* 0xAA 80 times */
473 { "" }
474};
475
476static const int md5_hmac_test_keylen[7] =
477{
478 16, 4, 16, 25, 16, 80, 80
479};
480
481static unsigned char md5_hmac_test_buf[7][74] =
482{
483 { "Hi There" },
484 { "what do ya want for nothing?" },
485 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
486 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
487 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
488 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
489 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
490 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
491 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
492 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
493 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
494 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
495 { "Test With Truncation" },
496 { "Test Using Larger Than Block-Size Key - Hash Key First" },
497 { "Test Using Larger Than Block-Size Key and Larger"
498 " Than One Block-Size Data" }
499};
500
501static const int md5_hmac_test_buflen[7] =
502{
503 8, 28, 50, 50, 20, 54, 73
504};
505
506static const unsigned char md5_hmac_test_sum[7][16] =
507{
508 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
509 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
510 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
511 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
512 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
513 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
514 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
515 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
516 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
517 0xF9, 0xBA, 0xB9, 0x95 },
518 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
519 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
520 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
521 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
522};
523
524/*
525 * Checkup routine
526 */
527int md5_self_test( int verbose )
528{
529 int i, buflen;
530 unsigned char buf[1024];
531 unsigned char md5sum[16];
532 md5_context ctx;
533
534 for( i = 0; i < 7; i++ )
535 {
536 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100537 polarssl_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000538
539 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
540
541 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
542 {
543 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100544 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000545
546 return( 1 );
547 }
548
549 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100550 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000551 }
552
553 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100554 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 for( i = 0; i < 7; i++ )
557 {
558 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100559 polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 if( i == 5 || i == 6 )
562 {
563 memset( buf, '\xAA', buflen = 80 );
564 md5_hmac_starts( &ctx, buf, buflen );
565 }
566 else
567 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
568 md5_hmac_test_keylen[i] );
569
570 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
571 md5_hmac_test_buflen[i] );
572
573 md5_hmac_finish( &ctx, md5sum );
574
575 buflen = ( i == 4 ) ? 12 : 16;
576
577 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
578 {
579 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100580 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000581
582 return( 1 );
583 }
584
585 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100586 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 }
588
589 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100590 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000591
592 return( 0 );
593}
594
Paul Bakker9af723c2014-05-01 13:03:14 +0200595#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000596
Paul Bakker9af723c2014-05-01 13:03:14 +0200597#endif /* POLARSSL_MD5_C */