blob: 6ceab8a288b4d294179bd6aaca319f50f1de09c0 [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
164
165#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 Bakker23986e52011-04-24 08:57:21 +0000344void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000345{
Paul Bakker23986e52011-04-24 08:57:21 +0000346 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000347 unsigned char sum[16];
348
349 if( keylen > 64 )
350 {
351 md5( key, keylen, sum );
352 keylen = 16;
353 key = sum;
354 }
355
356 memset( ctx->ipad, 0x36, 64 );
357 memset( ctx->opad, 0x5C, 64 );
358
359 for( i = 0; i < keylen; i++ )
360 {
361 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
362 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
363 }
364
365 md5_starts( ctx );
366 md5_update( ctx, ctx->ipad, 64 );
367
368 memset( sum, 0, sizeof( sum ) );
369}
370
371/*
372 * MD5 HMAC process buffer
373 */
Paul Bakker23986e52011-04-24 08:57:21 +0000374void md5_hmac_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000375{
376 md5_update( ctx, input, ilen );
377}
378
379/*
380 * MD5 HMAC final digest
381 */
382void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
383{
384 unsigned char tmpbuf[16];
385
386 md5_finish( ctx, tmpbuf );
387 md5_starts( ctx );
388 md5_update( ctx, ctx->opad, 64 );
389 md5_update( ctx, tmpbuf, 16 );
390 md5_finish( ctx, output );
391
392 memset( tmpbuf, 0, sizeof( tmpbuf ) );
393}
394
395/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000396 * MD5 HMAC context reset
397 */
398void md5_hmac_reset( md5_context *ctx )
399{
400 md5_starts( ctx );
401 md5_update( ctx, ctx->ipad, 64 );
402}
403
404/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 * output = HMAC-MD5( hmac key, input buffer )
406 */
Paul Bakker23986e52011-04-24 08:57:21 +0000407void md5_hmac( const unsigned char *key, size_t keylen,
408 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000409 unsigned char output[16] )
410{
411 md5_context ctx;
412
413 md5_hmac_starts( &ctx, key, keylen );
414 md5_hmac_update( &ctx, input, ilen );
415 md5_hmac_finish( &ctx, output );
416
417 memset( &ctx, 0, sizeof( md5_context ) );
418}
419
Paul Bakker40e46942009-01-03 21:51:57 +0000420#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000421/*
422 * RFC 1321 test vectors
423 */
424static unsigned char md5_test_buf[7][81] =
425{
426 { "" },
427 { "a" },
428 { "abc" },
429 { "message digest" },
430 { "abcdefghijklmnopqrstuvwxyz" },
431 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
432 { "12345678901234567890123456789012345678901234567890123456789012" \
433 "345678901234567890" }
434};
435
436static const int md5_test_buflen[7] =
437{
438 0, 1, 3, 14, 26, 62, 80
439};
440
441static const unsigned char md5_test_sum[7][16] =
442{
443 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
444 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
445 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
446 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
447 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
448 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
449 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
450 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
451 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
452 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
453 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
454 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
455 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
456 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
457};
458
459/*
460 * RFC 2202 test vectors
461 */
462static unsigned char md5_hmac_test_key[7][26] =
463{
464 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
465 { "Jefe" },
466 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
467 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
468 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
469 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
470 { "" }, /* 0xAA 80 times */
471 { "" }
472};
473
474static const int md5_hmac_test_keylen[7] =
475{
476 16, 4, 16, 25, 16, 80, 80
477};
478
479static unsigned char md5_hmac_test_buf[7][74] =
480{
481 { "Hi There" },
482 { "what do ya want for nothing?" },
483 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
484 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
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 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
489 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
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 { "Test With Truncation" },
494 { "Test Using Larger Than Block-Size Key - Hash Key First" },
495 { "Test Using Larger Than Block-Size Key and Larger"
496 " Than One Block-Size Data" }
497};
498
499static const int md5_hmac_test_buflen[7] =
500{
501 8, 28, 50, 50, 20, 54, 73
502};
503
504static const unsigned char md5_hmac_test_sum[7][16] =
505{
506 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
507 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
508 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
509 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
510 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
511 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
512 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
513 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
514 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
515 0xF9, 0xBA, 0xB9, 0x95 },
516 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
517 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
518 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
519 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
520};
521
522/*
523 * Checkup routine
524 */
525int md5_self_test( int verbose )
526{
527 int i, buflen;
528 unsigned char buf[1024];
529 unsigned char md5sum[16];
530 md5_context ctx;
531
532 for( i = 0; i < 7; i++ )
533 {
534 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100535 polarssl_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000536
537 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
538
539 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
540 {
541 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100542 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
544 return( 1 );
545 }
546
547 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100548 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000549 }
550
551 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100552 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000553
554 for( i = 0; i < 7; i++ )
555 {
556 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100557 polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
559 if( i == 5 || i == 6 )
560 {
561 memset( buf, '\xAA', buflen = 80 );
562 md5_hmac_starts( &ctx, buf, buflen );
563 }
564 else
565 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
566 md5_hmac_test_keylen[i] );
567
568 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
569 md5_hmac_test_buflen[i] );
570
571 md5_hmac_finish( &ctx, md5sum );
572
573 buflen = ( i == 4 ) ? 12 : 16;
574
575 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
576 {
577 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100578 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000579
580 return( 1 );
581 }
582
583 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100584 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000585 }
586
587 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100588 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000589
590 return( 0 );
591}
592
593#endif
594
595#endif