blob: c596e43b2ff6091a27e358172be99756cd7d0536 [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
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 Bakker7dc4c442014-02-01 22:50:26 +010041#if defined(POLARSSL_PLATFORM_C)
42#include "polarssl/platform.h"
43#else
44#define polarssl_printf printf
45#endif
46
Paul Bakker90995b52013-06-24 19:20:35 +020047#if !defined(POLARSSL_MD5_ALT)
48
Paul Bakker5121ce52009-01-03 21:22:43 +000049/*
50 * 32-bit integer manipulation macros (little endian)
51 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000052#ifndef GET_UINT32_LE
53#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000054{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000055 (n) = ( (uint32_t) (b)[(i) ] ) \
56 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
57 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
58 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000059}
60#endif
61
Paul Bakker5c2364c2012-10-01 14:41:15 +000062#ifndef PUT_UINT32_LE
63#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000064{ \
65 (b)[(i) ] = (unsigned char) ( (n) ); \
66 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
67 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
68 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
69}
70#endif
71
72/*
73 * MD5 context setup
74 */
75void md5_starts( md5_context *ctx )
76{
77 ctx->total[0] = 0;
78 ctx->total[1] = 0;
79
80 ctx->state[0] = 0x67452301;
81 ctx->state[1] = 0xEFCDAB89;
82 ctx->state[2] = 0x98BADCFE;
83 ctx->state[3] = 0x10325476;
84}
85
Paul Bakkere47b34b2013-02-27 14:48:00 +010086void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000087{
Paul Bakker5c2364c2012-10-01 14:41:15 +000088 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000089
Paul Bakker5c2364c2012-10-01 14:41:15 +000090 GET_UINT32_LE( X[ 0], data, 0 );
91 GET_UINT32_LE( X[ 1], data, 4 );
92 GET_UINT32_LE( X[ 2], data, 8 );
93 GET_UINT32_LE( X[ 3], data, 12 );
94 GET_UINT32_LE( X[ 4], data, 16 );
95 GET_UINT32_LE( X[ 5], data, 20 );
96 GET_UINT32_LE( X[ 6], data, 24 );
97 GET_UINT32_LE( X[ 7], data, 28 );
98 GET_UINT32_LE( X[ 8], data, 32 );
99 GET_UINT32_LE( X[ 9], data, 36 );
100 GET_UINT32_LE( X[10], data, 40 );
101 GET_UINT32_LE( X[11], data, 44 );
102 GET_UINT32_LE( X[12], data, 48 );
103 GET_UINT32_LE( X[13], data, 52 );
104 GET_UINT32_LE( X[14], data, 56 );
105 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000106
107#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
108
109#define P(a,b,c,d,k,s,t) \
110{ \
111 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
112}
113
114 A = ctx->state[0];
115 B = ctx->state[1];
116 C = ctx->state[2];
117 D = ctx->state[3];
118
119#define F(x,y,z) (z ^ (x & (y ^ z)))
120
121 P( A, B, C, D, 0, 7, 0xD76AA478 );
122 P( D, A, B, C, 1, 12, 0xE8C7B756 );
123 P( C, D, A, B, 2, 17, 0x242070DB );
124 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
125 P( A, B, C, D, 4, 7, 0xF57C0FAF );
126 P( D, A, B, C, 5, 12, 0x4787C62A );
127 P( C, D, A, B, 6, 17, 0xA8304613 );
128 P( B, C, D, A, 7, 22, 0xFD469501 );
129 P( A, B, C, D, 8, 7, 0x698098D8 );
130 P( D, A, B, C, 9, 12, 0x8B44F7AF );
131 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
132 P( B, C, D, A, 11, 22, 0x895CD7BE );
133 P( A, B, C, D, 12, 7, 0x6B901122 );
134 P( D, A, B, C, 13, 12, 0xFD987193 );
135 P( C, D, A, B, 14, 17, 0xA679438E );
136 P( B, C, D, A, 15, 22, 0x49B40821 );
137
138#undef F
139
140#define F(x,y,z) (y ^ (z & (x ^ y)))
141
142 P( A, B, C, D, 1, 5, 0xF61E2562 );
143 P( D, A, B, C, 6, 9, 0xC040B340 );
144 P( C, D, A, B, 11, 14, 0x265E5A51 );
145 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
146 P( A, B, C, D, 5, 5, 0xD62F105D );
147 P( D, A, B, C, 10, 9, 0x02441453 );
148 P( C, D, A, B, 15, 14, 0xD8A1E681 );
149 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
150 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
151 P( D, A, B, C, 14, 9, 0xC33707D6 );
152 P( C, D, A, B, 3, 14, 0xF4D50D87 );
153 P( B, C, D, A, 8, 20, 0x455A14ED );
154 P( A, B, C, D, 13, 5, 0xA9E3E905 );
155 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
156 P( C, D, A, B, 7, 14, 0x676F02D9 );
157 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
158
159#undef F
160
161#define F(x,y,z) (x ^ y ^ z)
162
163 P( A, B, C, D, 5, 4, 0xFFFA3942 );
164 P( D, A, B, C, 8, 11, 0x8771F681 );
165 P( C, D, A, B, 11, 16, 0x6D9D6122 );
166 P( B, C, D, A, 14, 23, 0xFDE5380C );
167 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
168 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
169 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
170 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
171 P( A, B, C, D, 13, 4, 0x289B7EC6 );
172 P( D, A, B, C, 0, 11, 0xEAA127FA );
173 P( C, D, A, B, 3, 16, 0xD4EF3085 );
174 P( B, C, D, A, 6, 23, 0x04881D05 );
175 P( A, B, C, D, 9, 4, 0xD9D4D039 );
176 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
177 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
178 P( B, C, D, A, 2, 23, 0xC4AC5665 );
179
180#undef F
181
182#define F(x,y,z) (y ^ (x | ~z))
183
184 P( A, B, C, D, 0, 6, 0xF4292244 );
185 P( D, A, B, C, 7, 10, 0x432AFF97 );
186 P( C, D, A, B, 14, 15, 0xAB9423A7 );
187 P( B, C, D, A, 5, 21, 0xFC93A039 );
188 P( A, B, C, D, 12, 6, 0x655B59C3 );
189 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
190 P( C, D, A, B, 10, 15, 0xFFEFF47D );
191 P( B, C, D, A, 1, 21, 0x85845DD1 );
192 P( A, B, C, D, 8, 6, 0x6FA87E4F );
193 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
194 P( C, D, A, B, 6, 15, 0xA3014314 );
195 P( B, C, D, A, 13, 21, 0x4E0811A1 );
196 P( A, B, C, D, 4, 6, 0xF7537E82 );
197 P( D, A, B, C, 11, 10, 0xBD3AF235 );
198 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
199 P( B, C, D, A, 9, 21, 0xEB86D391 );
200
201#undef F
202
203 ctx->state[0] += A;
204 ctx->state[1] += B;
205 ctx->state[2] += C;
206 ctx->state[3] += D;
207}
208
209/*
210 * MD5 process buffer
211 */
Paul Bakker23986e52011-04-24 08:57:21 +0000212void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000213{
Paul Bakker23986e52011-04-24 08:57:21 +0000214 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000215 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000216
217 if( ilen <= 0 )
218 return;
219
220 left = ctx->total[0] & 0x3F;
221 fill = 64 - left;
222
Paul Bakker5c2364c2012-10-01 14:41:15 +0000223 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000224 ctx->total[0] &= 0xFFFFFFFF;
225
Paul Bakker5c2364c2012-10-01 14:41:15 +0000226 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 ctx->total[1]++;
228
229 if( left && ilen >= fill )
230 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200231 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000232 md5_process( ctx, ctx->buffer );
233 input += fill;
234 ilen -= fill;
235 left = 0;
236 }
237
238 while( ilen >= 64 )
239 {
240 md5_process( ctx, input );
241 input += 64;
242 ilen -= 64;
243 }
244
245 if( ilen > 0 )
246 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200247 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000248 }
249}
250
251static const unsigned char md5_padding[64] =
252{
253 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
257};
258
259/*
260 * MD5 final digest
261 */
262void md5_finish( md5_context *ctx, unsigned char output[16] )
263{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000264 uint32_t last, padn;
265 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000266 unsigned char msglen[8];
267
268 high = ( ctx->total[0] >> 29 )
269 | ( ctx->total[1] << 3 );
270 low = ( ctx->total[0] << 3 );
271
Paul Bakker5c2364c2012-10-01 14:41:15 +0000272 PUT_UINT32_LE( low, msglen, 0 );
273 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000274
275 last = ctx->total[0] & 0x3F;
276 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
277
Paul Bakker3c2122f2013-06-24 19:03:14 +0200278 md5_update( ctx, md5_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 md5_update( ctx, msglen, 8 );
280
Paul Bakker5c2364c2012-10-01 14:41:15 +0000281 PUT_UINT32_LE( ctx->state[0], output, 0 );
282 PUT_UINT32_LE( ctx->state[1], output, 4 );
283 PUT_UINT32_LE( ctx->state[2], output, 8 );
284 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000285}
286
Paul Bakker90995b52013-06-24 19:20:35 +0200287#endif /* !POLARSSL_MD5_ALT */
288
Paul Bakker5121ce52009-01-03 21:22:43 +0000289/*
290 * output = MD5( input buffer )
291 */
Paul Bakker23986e52011-04-24 08:57:21 +0000292void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000293{
294 md5_context ctx;
295
296 md5_starts( &ctx );
297 md5_update( &ctx, input, ilen );
298 md5_finish( &ctx, output );
299
300 memset( &ctx, 0, sizeof( md5_context ) );
301}
302
Paul Bakker335db3f2011-04-25 15:28:35 +0000303#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000304/*
305 * output = MD5( file contents )
306 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000307int md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000308{
309 FILE *f;
310 size_t n;
311 md5_context ctx;
312 unsigned char buf[1024];
313
314 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000315 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000316
317 md5_starts( &ctx );
318
319 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000320 md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
322 md5_finish( &ctx, output );
323
324 memset( &ctx, 0, sizeof( md5_context ) );
325
326 if( ferror( f ) != 0 )
327 {
328 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000329 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 }
331
332 fclose( f );
333 return( 0 );
334}
Paul Bakker335db3f2011-04-25 15:28:35 +0000335#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000336
337/*
338 * MD5 HMAC context setup
339 */
Paul Bakker23986e52011-04-24 08:57:21 +0000340void md5_hmac_starts( md5_context *ctx, const unsigned char *key, size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000341{
Paul Bakker23986e52011-04-24 08:57:21 +0000342 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000343 unsigned char sum[16];
344
345 if( keylen > 64 )
346 {
347 md5( key, keylen, sum );
348 keylen = 16;
349 key = sum;
350 }
351
352 memset( ctx->ipad, 0x36, 64 );
353 memset( ctx->opad, 0x5C, 64 );
354
355 for( i = 0; i < keylen; i++ )
356 {
357 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
358 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
359 }
360
361 md5_starts( ctx );
362 md5_update( ctx, ctx->ipad, 64 );
363
364 memset( sum, 0, sizeof( sum ) );
365}
366
367/*
368 * MD5 HMAC process buffer
369 */
Paul Bakker23986e52011-04-24 08:57:21 +0000370void md5_hmac_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000371{
372 md5_update( ctx, input, ilen );
373}
374
375/*
376 * MD5 HMAC final digest
377 */
378void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
379{
380 unsigned char tmpbuf[16];
381
382 md5_finish( ctx, tmpbuf );
383 md5_starts( ctx );
384 md5_update( ctx, ctx->opad, 64 );
385 md5_update( ctx, tmpbuf, 16 );
386 md5_finish( ctx, output );
387
388 memset( tmpbuf, 0, sizeof( tmpbuf ) );
389}
390
391/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000392 * MD5 HMAC context reset
393 */
394void md5_hmac_reset( md5_context *ctx )
395{
396 md5_starts( ctx );
397 md5_update( ctx, ctx->ipad, 64 );
398}
399
400/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 * output = HMAC-MD5( hmac key, input buffer )
402 */
Paul Bakker23986e52011-04-24 08:57:21 +0000403void md5_hmac( const unsigned char *key, size_t keylen,
404 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 unsigned char output[16] )
406{
407 md5_context ctx;
408
409 md5_hmac_starts( &ctx, key, keylen );
410 md5_hmac_update( &ctx, input, ilen );
411 md5_hmac_finish( &ctx, output );
412
413 memset( &ctx, 0, sizeof( md5_context ) );
414}
415
Paul Bakker40e46942009-01-03 21:51:57 +0000416#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000417/*
418 * RFC 1321 test vectors
419 */
420static unsigned char md5_test_buf[7][81] =
421{
422 { "" },
423 { "a" },
424 { "abc" },
425 { "message digest" },
426 { "abcdefghijklmnopqrstuvwxyz" },
427 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
428 { "12345678901234567890123456789012345678901234567890123456789012" \
429 "345678901234567890" }
430};
431
432static const int md5_test_buflen[7] =
433{
434 0, 1, 3, 14, 26, 62, 80
435};
436
437static const unsigned char md5_test_sum[7][16] =
438{
439 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
440 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
441 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
442 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
443 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
444 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
445 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
446 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
447 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
448 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
449 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
450 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
451 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
452 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
453};
454
455/*
456 * RFC 2202 test vectors
457 */
458static unsigned char md5_hmac_test_key[7][26] =
459{
460 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
461 { "Jefe" },
462 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
463 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
464 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
465 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
466 { "" }, /* 0xAA 80 times */
467 { "" }
468};
469
470static const int md5_hmac_test_keylen[7] =
471{
472 16, 4, 16, 25, 16, 80, 80
473};
474
475static unsigned char md5_hmac_test_buf[7][74] =
476{
477 { "Hi There" },
478 { "what do ya want for nothing?" },
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 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
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 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
489 { "Test With Truncation" },
490 { "Test Using Larger Than Block-Size Key - Hash Key First" },
491 { "Test Using Larger Than Block-Size Key and Larger"
492 " Than One Block-Size Data" }
493};
494
495static const int md5_hmac_test_buflen[7] =
496{
497 8, 28, 50, 50, 20, 54, 73
498};
499
500static const unsigned char md5_hmac_test_sum[7][16] =
501{
502 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
503 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
504 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
505 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
506 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
507 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
508 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
509 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
510 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
511 0xF9, 0xBA, 0xB9, 0x95 },
512 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
513 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
514 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
515 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
516};
517
518/*
519 * Checkup routine
520 */
521int md5_self_test( int verbose )
522{
523 int i, buflen;
524 unsigned char buf[1024];
525 unsigned char md5sum[16];
526 md5_context ctx;
527
528 for( i = 0; i < 7; i++ )
529 {
530 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100531 polarssl_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
533 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
534
535 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
536 {
537 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100538 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000539
540 return( 1 );
541 }
542
543 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100544 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000545 }
546
547 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100548 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
550 for( i = 0; i < 7; i++ )
551 {
552 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100553 polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000554
555 if( i == 5 || i == 6 )
556 {
557 memset( buf, '\xAA', buflen = 80 );
558 md5_hmac_starts( &ctx, buf, buflen );
559 }
560 else
561 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
562 md5_hmac_test_keylen[i] );
563
564 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
565 md5_hmac_test_buflen[i] );
566
567 md5_hmac_finish( &ctx, md5sum );
568
569 buflen = ( i == 4 ) ? 12 : 16;
570
571 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
572 {
573 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100574 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 return( 1 );
577 }
578
579 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100580 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000581 }
582
583 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100584 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000585
586 return( 0 );
587}
588
589#endif
590
591#endif