blob: 4f0c5c1efed762776ea99f7e3942af506e3829c9 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1321 compliant MD5 implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The MD5 algorithm was designed by Ron Rivest in 1991.
24 *
25 * http://www.ietf.org/rfc/rfc1321.txt
26 */
27
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020028#if !defined(POLARSSL_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
31#include POLARSSL_CONFIG_FILE
32#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Paul Bakker40e46942009-01-03 21:51:57 +000034#if defined(POLARSSL_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/md5.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
40#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +000041#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000042#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000043
Rich Evans00ab4702015-02-06 13:43:58 +000044#if defined(POLARSSL_SELF_TEST)
Paul Bakker7dc4c442014-02-01 22:50:26 +010045#if defined(POLARSSL_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000046#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010047#else
Rich Evans00ab4702015-02-06 13:43:58 +000048#include <stdio.h>
Paul Bakker7dc4c442014-02-01 22:50:26 +010049#define polarssl_printf printf
Rich Evans00ab4702015-02-06 13:43:58 +000050#endif /* POLARSSL_PLATFORM_C */
51#endif /* POLARSSL_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010052
Paul Bakker34617722014-06-13 17:20:13 +020053/* Implementation that should never be optimized out by the compiler */
54static void polarssl_zeroize( void *v, size_t n ) {
55 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
56}
57
Paul Bakker90995b52013-06-24 19:20:35 +020058#if !defined(POLARSSL_MD5_ALT)
59
Paul Bakker5121ce52009-01-03 21:22:43 +000060/*
61 * 32-bit integer manipulation macros (little endian)
62 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000063#ifndef GET_UINT32_LE
64#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000065{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000066 (n) = ( (uint32_t) (b)[(i) ] ) \
67 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
68 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
69 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000070}
71#endif
72
Paul Bakker5c2364c2012-10-01 14:41:15 +000073#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000074#define PUT_UINT32_LE(n,b,i) \
75{ \
76 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
77 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
78 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
79 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000080}
81#endif
82
Paul Bakker5b4af392014-06-26 12:09:34 +020083void md5_init( md5_context *ctx )
84{
85 memset( ctx, 0, sizeof( md5_context ) );
86}
87
88void md5_free( md5_context *ctx )
89{
90 if( ctx == NULL )
91 return;
92
93 polarssl_zeroize( ctx, sizeof( md5_context ) );
94}
95
Paul Bakker5121ce52009-01-03 21:22:43 +000096/*
97 * MD5 context setup
98 */
99void md5_starts( md5_context *ctx )
100{
101 ctx->total[0] = 0;
102 ctx->total[1] = 0;
103
104 ctx->state[0] = 0x67452301;
105 ctx->state[1] = 0xEFCDAB89;
106 ctx->state[2] = 0x98BADCFE;
107 ctx->state[3] = 0x10325476;
108}
109
Paul Bakkere47b34b2013-02-27 14:48:00 +0100110void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000111{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000112 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000113
Paul Bakker5c2364c2012-10-01 14:41:15 +0000114 GET_UINT32_LE( X[ 0], data, 0 );
115 GET_UINT32_LE( X[ 1], data, 4 );
116 GET_UINT32_LE( X[ 2], data, 8 );
117 GET_UINT32_LE( X[ 3], data, 12 );
118 GET_UINT32_LE( X[ 4], data, 16 );
119 GET_UINT32_LE( X[ 5], data, 20 );
120 GET_UINT32_LE( X[ 6], data, 24 );
121 GET_UINT32_LE( X[ 7], data, 28 );
122 GET_UINT32_LE( X[ 8], data, 32 );
123 GET_UINT32_LE( X[ 9], data, 36 );
124 GET_UINT32_LE( X[10], data, 40 );
125 GET_UINT32_LE( X[11], data, 44 );
126 GET_UINT32_LE( X[12], data, 48 );
127 GET_UINT32_LE( X[13], data, 52 );
128 GET_UINT32_LE( X[14], data, 56 );
129 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000130
131#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
132
133#define P(a,b,c,d,k,s,t) \
134{ \
135 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
136}
137
138 A = ctx->state[0];
139 B = ctx->state[1];
140 C = ctx->state[2];
141 D = ctx->state[3];
142
143#define F(x,y,z) (z ^ (x & (y ^ z)))
144
145 P( A, B, C, D, 0, 7, 0xD76AA478 );
146 P( D, A, B, C, 1, 12, 0xE8C7B756 );
147 P( C, D, A, B, 2, 17, 0x242070DB );
148 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
149 P( A, B, C, D, 4, 7, 0xF57C0FAF );
150 P( D, A, B, C, 5, 12, 0x4787C62A );
151 P( C, D, A, B, 6, 17, 0xA8304613 );
152 P( B, C, D, A, 7, 22, 0xFD469501 );
153 P( A, B, C, D, 8, 7, 0x698098D8 );
154 P( D, A, B, C, 9, 12, 0x8B44F7AF );
155 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
156 P( B, C, D, A, 11, 22, 0x895CD7BE );
157 P( A, B, C, D, 12, 7, 0x6B901122 );
158 P( D, A, B, C, 13, 12, 0xFD987193 );
159 P( C, D, A, B, 14, 17, 0xA679438E );
160 P( B, C, D, A, 15, 22, 0x49B40821 );
161
162#undef F
163
164#define F(x,y,z) (y ^ (z & (x ^ y)))
165
166 P( A, B, C, D, 1, 5, 0xF61E2562 );
167 P( D, A, B, C, 6, 9, 0xC040B340 );
168 P( C, D, A, B, 11, 14, 0x265E5A51 );
169 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
170 P( A, B, C, D, 5, 5, 0xD62F105D );
171 P( D, A, B, C, 10, 9, 0x02441453 );
172 P( C, D, A, B, 15, 14, 0xD8A1E681 );
173 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
174 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
175 P( D, A, B, C, 14, 9, 0xC33707D6 );
176 P( C, D, A, B, 3, 14, 0xF4D50D87 );
177 P( B, C, D, A, 8, 20, 0x455A14ED );
178 P( A, B, C, D, 13, 5, 0xA9E3E905 );
179 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
180 P( C, D, A, B, 7, 14, 0x676F02D9 );
181 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
182
183#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200184
Paul Bakker5121ce52009-01-03 21:22:43 +0000185#define F(x,y,z) (x ^ y ^ z)
186
187 P( A, B, C, D, 5, 4, 0xFFFA3942 );
188 P( D, A, B, C, 8, 11, 0x8771F681 );
189 P( C, D, A, B, 11, 16, 0x6D9D6122 );
190 P( B, C, D, A, 14, 23, 0xFDE5380C );
191 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
192 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
193 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
194 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
195 P( A, B, C, D, 13, 4, 0x289B7EC6 );
196 P( D, A, B, C, 0, 11, 0xEAA127FA );
197 P( C, D, A, B, 3, 16, 0xD4EF3085 );
198 P( B, C, D, A, 6, 23, 0x04881D05 );
199 P( A, B, C, D, 9, 4, 0xD9D4D039 );
200 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
201 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
202 P( B, C, D, A, 2, 23, 0xC4AC5665 );
203
204#undef F
205
206#define F(x,y,z) (y ^ (x | ~z))
207
208 P( A, B, C, D, 0, 6, 0xF4292244 );
209 P( D, A, B, C, 7, 10, 0x432AFF97 );
210 P( C, D, A, B, 14, 15, 0xAB9423A7 );
211 P( B, C, D, A, 5, 21, 0xFC93A039 );
212 P( A, B, C, D, 12, 6, 0x655B59C3 );
213 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
214 P( C, D, A, B, 10, 15, 0xFFEFF47D );
215 P( B, C, D, A, 1, 21, 0x85845DD1 );
216 P( A, B, C, D, 8, 6, 0x6FA87E4F );
217 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
218 P( C, D, A, B, 6, 15, 0xA3014314 );
219 P( B, C, D, A, 13, 21, 0x4E0811A1 );
220 P( A, B, C, D, 4, 6, 0xF7537E82 );
221 P( D, A, B, C, 11, 10, 0xBD3AF235 );
222 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
223 P( B, C, D, A, 9, 21, 0xEB86D391 );
224
225#undef F
226
227 ctx->state[0] += A;
228 ctx->state[1] += B;
229 ctx->state[2] += C;
230 ctx->state[3] += D;
231}
232
233/*
234 * MD5 process buffer
235 */
Paul Bakker23986e52011-04-24 08:57:21 +0000236void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000237{
Paul Bakker23986e52011-04-24 08:57:21 +0000238 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000239 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000240
Brian White12895d12014-04-11 11:29:42 -0400241 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000242 return;
243
244 left = ctx->total[0] & 0x3F;
245 fill = 64 - left;
246
Paul Bakker5c2364c2012-10-01 14:41:15 +0000247 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000248 ctx->total[0] &= 0xFFFFFFFF;
249
Paul Bakker5c2364c2012-10-01 14:41:15 +0000250 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 ctx->total[1]++;
252
253 if( left && ilen >= fill )
254 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200255 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000256 md5_process( ctx, ctx->buffer );
257 input += fill;
258 ilen -= fill;
259 left = 0;
260 }
261
262 while( ilen >= 64 )
263 {
264 md5_process( ctx, input );
265 input += 64;
266 ilen -= 64;
267 }
268
269 if( ilen > 0 )
270 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200271 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000272 }
273}
274
275static const unsigned char md5_padding[64] =
276{
277 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
278 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
281};
282
283/*
284 * MD5 final digest
285 */
286void md5_finish( md5_context *ctx, unsigned char output[16] )
287{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000288 uint32_t last, padn;
289 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 unsigned char msglen[8];
291
292 high = ( ctx->total[0] >> 29 )
293 | ( ctx->total[1] << 3 );
294 low = ( ctx->total[0] << 3 );
295
Paul Bakker5c2364c2012-10-01 14:41:15 +0000296 PUT_UINT32_LE( low, msglen, 0 );
297 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
299 last = ctx->total[0] & 0x3F;
300 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
301
Paul Bakker3c2122f2013-06-24 19:03:14 +0200302 md5_update( ctx, md5_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303 md5_update( ctx, msglen, 8 );
304
Paul Bakker5c2364c2012-10-01 14:41:15 +0000305 PUT_UINT32_LE( ctx->state[0], output, 0 );
306 PUT_UINT32_LE( ctx->state[1], output, 4 );
307 PUT_UINT32_LE( ctx->state[2], output, 8 );
308 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000309}
310
Paul Bakker90995b52013-06-24 19:20:35 +0200311#endif /* !POLARSSL_MD5_ALT */
312
Paul Bakker5121ce52009-01-03 21:22:43 +0000313/*
314 * output = MD5( input buffer )
315 */
Paul Bakker23986e52011-04-24 08:57:21 +0000316void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000317{
318 md5_context ctx;
319
Paul Bakker5b4af392014-06-26 12:09:34 +0200320 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321 md5_starts( &ctx );
322 md5_update( &ctx, input, ilen );
323 md5_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200324 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000325}
326
Paul Bakker335db3f2011-04-25 15:28:35 +0000327#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000328/*
329 * output = MD5( file contents )
330 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000331int md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000332{
333 FILE *f;
334 size_t n;
335 md5_context ctx;
336 unsigned char buf[1024];
337
338 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000339 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000340
Paul Bakker5b4af392014-06-26 12:09:34 +0200341 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000342 md5_starts( &ctx );
343
344 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000345 md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347 md5_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200348 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000349
350 if( ferror( f ) != 0 )
351 {
352 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000353 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000354 }
355
356 fclose( f );
357 return( 0 );
358}
Paul Bakker335db3f2011-04-25 15:28:35 +0000359#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
361/*
362 * MD5 HMAC context setup
363 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200364void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
365 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000366{
Paul Bakker23986e52011-04-24 08:57:21 +0000367 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000368 unsigned char sum[16];
369
370 if( keylen > 64 )
371 {
372 md5( key, keylen, sum );
373 keylen = 16;
374 key = sum;
375 }
376
377 memset( ctx->ipad, 0x36, 64 );
378 memset( ctx->opad, 0x5C, 64 );
379
380 for( i = 0; i < keylen; i++ )
381 {
382 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
383 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
384 }
385
386 md5_starts( ctx );
387 md5_update( ctx, ctx->ipad, 64 );
388
Paul Bakker34617722014-06-13 17:20:13 +0200389 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390}
391
392/*
393 * MD5 HMAC process buffer
394 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200395void md5_hmac_update( md5_context *ctx, const unsigned char *input,
396 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000397{
398 md5_update( ctx, input, ilen );
399}
400
401/*
402 * MD5 HMAC final digest
403 */
404void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
405{
406 unsigned char tmpbuf[16];
407
408 md5_finish( ctx, tmpbuf );
409 md5_starts( ctx );
410 md5_update( ctx, ctx->opad, 64 );
411 md5_update( ctx, tmpbuf, 16 );
412 md5_finish( ctx, output );
413
Paul Bakker34617722014-06-13 17:20:13 +0200414 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415}
416
417/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000418 * MD5 HMAC context reset
419 */
420void md5_hmac_reset( md5_context *ctx )
421{
422 md5_starts( ctx );
423 md5_update( ctx, ctx->ipad, 64 );
424}
425
426/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 * output = HMAC-MD5( hmac key, input buffer )
428 */
Paul Bakker23986e52011-04-24 08:57:21 +0000429void md5_hmac( const unsigned char *key, size_t keylen,
430 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 unsigned char output[16] )
432{
433 md5_context ctx;
434
Paul Bakker5b4af392014-06-26 12:09:34 +0200435 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 md5_hmac_starts( &ctx, key, keylen );
437 md5_hmac_update( &ctx, input, ilen );
438 md5_hmac_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200439 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440}
441
Paul Bakker40e46942009-01-03 21:51:57 +0000442#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000443/*
444 * RFC 1321 test vectors
445 */
446static unsigned char md5_test_buf[7][81] =
447{
Paul Bakker9af723c2014-05-01 13:03:14 +0200448 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 { "a" },
450 { "abc" },
451 { "message digest" },
452 { "abcdefghijklmnopqrstuvwxyz" },
453 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
454 { "12345678901234567890123456789012345678901234567890123456789012" \
455 "345678901234567890" }
456};
457
458static const int md5_test_buflen[7] =
459{
460 0, 1, 3, 14, 26, 62, 80
461};
462
463static const unsigned char md5_test_sum[7][16] =
464{
465 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
466 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
467 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
468 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
469 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
470 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
471 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
472 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
473 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
474 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
475 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
476 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
477 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
478 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
479};
480
481/*
482 * RFC 2202 test vectors
483 */
484static unsigned char md5_hmac_test_key[7][26] =
485{
486 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
487 { "Jefe" },
488 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
489 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
490 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
491 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
492 { "" }, /* 0xAA 80 times */
493 { "" }
494};
495
496static const int md5_hmac_test_keylen[7] =
497{
498 16, 4, 16, 25, 16, 80, 80
499};
500
501static unsigned char md5_hmac_test_buf[7][74] =
502{
503 { "Hi There" },
504 { "what do ya want for nothing?" },
505 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
506 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
507 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
508 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
509 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
510 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
511 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
512 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
513 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
514 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
515 { "Test With Truncation" },
516 { "Test Using Larger Than Block-Size Key - Hash Key First" },
517 { "Test Using Larger Than Block-Size Key and Larger"
518 " Than One Block-Size Data" }
519};
520
521static const int md5_hmac_test_buflen[7] =
522{
523 8, 28, 50, 50, 20, 54, 73
524};
525
526static const unsigned char md5_hmac_test_sum[7][16] =
527{
528 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
529 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
530 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
531 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
532 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
533 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
534 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
535 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
536 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
537 0xF9, 0xBA, 0xB9, 0x95 },
538 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
539 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
540 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
541 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
542};
543
544/*
545 * Checkup routine
546 */
547int md5_self_test( int verbose )
548{
549 int i, buflen;
550 unsigned char buf[1024];
551 unsigned char md5sum[16];
552 md5_context ctx;
553
554 for( i = 0; i < 7; i++ )
555 {
556 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100557 polarssl_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
559 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
560
561 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
562 {
563 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100564 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
566 return( 1 );
567 }
568
569 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100570 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571 }
572
573 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100574 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 for( i = 0; i < 7; i++ )
577 {
578 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100579 polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
581 if( i == 5 || i == 6 )
582 {
Manuel Pégourié-Gonnardd48bf682015-02-14 15:05:32 +0000583 memset( buf, 0xAA, buflen = 80 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 md5_hmac_starts( &ctx, buf, buflen );
585 }
586 else
587 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
588 md5_hmac_test_keylen[i] );
589
590 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
591 md5_hmac_test_buflen[i] );
592
593 md5_hmac_finish( &ctx, md5sum );
594
595 buflen = ( i == 4 ) ? 12 : 16;
596
597 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
598 {
599 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100600 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
602 return( 1 );
603 }
604
605 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100606 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000607 }
608
609 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100610 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 return( 0 );
613}
614
Paul Bakker9af723c2014-05-01 13:03:14 +0200615#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
Paul Bakker9af723c2014-05-01 13:03:14 +0200617#endif /* POLARSSL_MD5_C */