blob: 062154d4905d0ba34a291055e2cc8064e2c5537d [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é-Gonnard967a2a52015-01-22 14:28:16 +00006 * This file is part of mbed TLS (http://www.polarssl.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)
Paul Bakker40e46942009-01-03 21:51:57 +000029#include "polarssl/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
Paul Bakker40e46942009-01-03 21:51:57 +000036#include "polarssl/md5.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Paul Bakker335db3f2011-04-25 15:28:35 +000038#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000039#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000040#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000041
Paul Bakker7dc4c442014-02-01 22:50:26 +010042#if defined(POLARSSL_PLATFORM_C)
43#include "polarssl/platform.h"
44#else
45#define polarssl_printf printf
46#endif
47
Paul Bakker34617722014-06-13 17:20:13 +020048/* Implementation that should never be optimized out by the compiler */
49static void polarssl_zeroize( void *v, size_t n ) {
50 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
51}
52
Paul Bakker90995b52013-06-24 19:20:35 +020053#if !defined(POLARSSL_MD5_ALT)
54
Paul Bakker5121ce52009-01-03 21:22:43 +000055/*
56 * 32-bit integer manipulation macros (little endian)
57 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000058#ifndef GET_UINT32_LE
59#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000060{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000061 (n) = ( (uint32_t) (b)[(i) ] ) \
62 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
63 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
64 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000065}
66#endif
67
Paul Bakker5c2364c2012-10-01 14:41:15 +000068#ifndef PUT_UINT32_LE
69#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000070{ \
71 (b)[(i) ] = (unsigned char) ( (n) ); \
72 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
73 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
74 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
75}
76#endif
77
Paul Bakker5b4af392014-06-26 12:09:34 +020078void md5_init( md5_context *ctx )
79{
80 memset( ctx, 0, sizeof( md5_context ) );
81}
82
83void md5_free( md5_context *ctx )
84{
85 if( ctx == NULL )
86 return;
87
88 polarssl_zeroize( ctx, sizeof( md5_context ) );
89}
90
Paul Bakker5121ce52009-01-03 21:22:43 +000091/*
92 * MD5 context setup
93 */
94void md5_starts( md5_context *ctx )
95{
96 ctx->total[0] = 0;
97 ctx->total[1] = 0;
98
99 ctx->state[0] = 0x67452301;
100 ctx->state[1] = 0xEFCDAB89;
101 ctx->state[2] = 0x98BADCFE;
102 ctx->state[3] = 0x10325476;
103}
104
Paul Bakkere47b34b2013-02-27 14:48:00 +0100105void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000106{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000107 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000108
Paul Bakker5c2364c2012-10-01 14:41:15 +0000109 GET_UINT32_LE( X[ 0], data, 0 );
110 GET_UINT32_LE( X[ 1], data, 4 );
111 GET_UINT32_LE( X[ 2], data, 8 );
112 GET_UINT32_LE( X[ 3], data, 12 );
113 GET_UINT32_LE( X[ 4], data, 16 );
114 GET_UINT32_LE( X[ 5], data, 20 );
115 GET_UINT32_LE( X[ 6], data, 24 );
116 GET_UINT32_LE( X[ 7], data, 28 );
117 GET_UINT32_LE( X[ 8], data, 32 );
118 GET_UINT32_LE( X[ 9], data, 36 );
119 GET_UINT32_LE( X[10], data, 40 );
120 GET_UINT32_LE( X[11], data, 44 );
121 GET_UINT32_LE( X[12], data, 48 );
122 GET_UINT32_LE( X[13], data, 52 );
123 GET_UINT32_LE( X[14], data, 56 );
124 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000125
126#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
127
128#define P(a,b,c,d,k,s,t) \
129{ \
130 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
131}
132
133 A = ctx->state[0];
134 B = ctx->state[1];
135 C = ctx->state[2];
136 D = ctx->state[3];
137
138#define F(x,y,z) (z ^ (x & (y ^ z)))
139
140 P( A, B, C, D, 0, 7, 0xD76AA478 );
141 P( D, A, B, C, 1, 12, 0xE8C7B756 );
142 P( C, D, A, B, 2, 17, 0x242070DB );
143 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
144 P( A, B, C, D, 4, 7, 0xF57C0FAF );
145 P( D, A, B, C, 5, 12, 0x4787C62A );
146 P( C, D, A, B, 6, 17, 0xA8304613 );
147 P( B, C, D, A, 7, 22, 0xFD469501 );
148 P( A, B, C, D, 8, 7, 0x698098D8 );
149 P( D, A, B, C, 9, 12, 0x8B44F7AF );
150 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
151 P( B, C, D, A, 11, 22, 0x895CD7BE );
152 P( A, B, C, D, 12, 7, 0x6B901122 );
153 P( D, A, B, C, 13, 12, 0xFD987193 );
154 P( C, D, A, B, 14, 17, 0xA679438E );
155 P( B, C, D, A, 15, 22, 0x49B40821 );
156
157#undef F
158
159#define F(x,y,z) (y ^ (z & (x ^ y)))
160
161 P( A, B, C, D, 1, 5, 0xF61E2562 );
162 P( D, A, B, C, 6, 9, 0xC040B340 );
163 P( C, D, A, B, 11, 14, 0x265E5A51 );
164 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
165 P( A, B, C, D, 5, 5, 0xD62F105D );
166 P( D, A, B, C, 10, 9, 0x02441453 );
167 P( C, D, A, B, 15, 14, 0xD8A1E681 );
168 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
169 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
170 P( D, A, B, C, 14, 9, 0xC33707D6 );
171 P( C, D, A, B, 3, 14, 0xF4D50D87 );
172 P( B, C, D, A, 8, 20, 0x455A14ED );
173 P( A, B, C, D, 13, 5, 0xA9E3E905 );
174 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
175 P( C, D, A, B, 7, 14, 0x676F02D9 );
176 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
177
178#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200179
Paul Bakker5121ce52009-01-03 21:22:43 +0000180#define F(x,y,z) (x ^ y ^ z)
181
182 P( A, B, C, D, 5, 4, 0xFFFA3942 );
183 P( D, A, B, C, 8, 11, 0x8771F681 );
184 P( C, D, A, B, 11, 16, 0x6D9D6122 );
185 P( B, C, D, A, 14, 23, 0xFDE5380C );
186 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
187 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
188 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
189 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
190 P( A, B, C, D, 13, 4, 0x289B7EC6 );
191 P( D, A, B, C, 0, 11, 0xEAA127FA );
192 P( C, D, A, B, 3, 16, 0xD4EF3085 );
193 P( B, C, D, A, 6, 23, 0x04881D05 );
194 P( A, B, C, D, 9, 4, 0xD9D4D039 );
195 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
196 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
197 P( B, C, D, A, 2, 23, 0xC4AC5665 );
198
199#undef F
200
201#define F(x,y,z) (y ^ (x | ~z))
202
203 P( A, B, C, D, 0, 6, 0xF4292244 );
204 P( D, A, B, C, 7, 10, 0x432AFF97 );
205 P( C, D, A, B, 14, 15, 0xAB9423A7 );
206 P( B, C, D, A, 5, 21, 0xFC93A039 );
207 P( A, B, C, D, 12, 6, 0x655B59C3 );
208 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
209 P( C, D, A, B, 10, 15, 0xFFEFF47D );
210 P( B, C, D, A, 1, 21, 0x85845DD1 );
211 P( A, B, C, D, 8, 6, 0x6FA87E4F );
212 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
213 P( C, D, A, B, 6, 15, 0xA3014314 );
214 P( B, C, D, A, 13, 21, 0x4E0811A1 );
215 P( A, B, C, D, 4, 6, 0xF7537E82 );
216 P( D, A, B, C, 11, 10, 0xBD3AF235 );
217 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
218 P( B, C, D, A, 9, 21, 0xEB86D391 );
219
220#undef F
221
222 ctx->state[0] += A;
223 ctx->state[1] += B;
224 ctx->state[2] += C;
225 ctx->state[3] += D;
226}
227
228/*
229 * MD5 process buffer
230 */
Paul Bakker23986e52011-04-24 08:57:21 +0000231void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000232{
Paul Bakker23986e52011-04-24 08:57:21 +0000233 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000234 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000235
Brian White12895d12014-04-11 11:29:42 -0400236 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000237 return;
238
239 left = ctx->total[0] & 0x3F;
240 fill = 64 - left;
241
Paul Bakker5c2364c2012-10-01 14:41:15 +0000242 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000243 ctx->total[0] &= 0xFFFFFFFF;
244
Paul Bakker5c2364c2012-10-01 14:41:15 +0000245 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000246 ctx->total[1]++;
247
248 if( left && ilen >= fill )
249 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200250 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 md5_process( ctx, ctx->buffer );
252 input += fill;
253 ilen -= fill;
254 left = 0;
255 }
256
257 while( ilen >= 64 )
258 {
259 md5_process( ctx, input );
260 input += 64;
261 ilen -= 64;
262 }
263
264 if( ilen > 0 )
265 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200266 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 }
268}
269
270static const unsigned char md5_padding[64] =
271{
272 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
273 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
274 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
275 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
276};
277
278/*
279 * MD5 final digest
280 */
281void md5_finish( md5_context *ctx, unsigned char output[16] )
282{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000283 uint32_t last, padn;
284 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 unsigned char msglen[8];
286
287 high = ( ctx->total[0] >> 29 )
288 | ( ctx->total[1] << 3 );
289 low = ( ctx->total[0] << 3 );
290
Paul Bakker5c2364c2012-10-01 14:41:15 +0000291 PUT_UINT32_LE( low, msglen, 0 );
292 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000293
294 last = ctx->total[0] & 0x3F;
295 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
296
Paul Bakker3c2122f2013-06-24 19:03:14 +0200297 md5_update( ctx, md5_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 md5_update( ctx, msglen, 8 );
299
Paul Bakker5c2364c2012-10-01 14:41:15 +0000300 PUT_UINT32_LE( ctx->state[0], output, 0 );
301 PUT_UINT32_LE( ctx->state[1], output, 4 );
302 PUT_UINT32_LE( ctx->state[2], output, 8 );
303 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304}
305
Paul Bakker90995b52013-06-24 19:20:35 +0200306#endif /* !POLARSSL_MD5_ALT */
307
Paul Bakker5121ce52009-01-03 21:22:43 +0000308/*
309 * output = MD5( input buffer )
310 */
Paul Bakker23986e52011-04-24 08:57:21 +0000311void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000312{
313 md5_context ctx;
314
Paul Bakker5b4af392014-06-26 12:09:34 +0200315 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000316 md5_starts( &ctx );
317 md5_update( &ctx, input, ilen );
318 md5_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200319 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000320}
321
Paul Bakker335db3f2011-04-25 15:28:35 +0000322#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000323/*
324 * output = MD5( file contents )
325 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000326int md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000327{
328 FILE *f;
329 size_t n;
330 md5_context ctx;
331 unsigned char buf[1024];
332
333 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000334 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
Paul Bakker5b4af392014-06-26 12:09:34 +0200336 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337 md5_starts( &ctx );
338
339 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000340 md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342 md5_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200343 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000344
345 if( ferror( f ) != 0 )
346 {
347 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000348 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000349 }
350
351 fclose( f );
352 return( 0 );
353}
Paul Bakker335db3f2011-04-25 15:28:35 +0000354#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000355
356/*
357 * MD5 HMAC context setup
358 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200359void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
360 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000361{
Paul Bakker23986e52011-04-24 08:57:21 +0000362 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000363 unsigned char sum[16];
364
365 if( keylen > 64 )
366 {
367 md5( key, keylen, sum );
368 keylen = 16;
369 key = sum;
370 }
371
372 memset( ctx->ipad, 0x36, 64 );
373 memset( ctx->opad, 0x5C, 64 );
374
375 for( i = 0; i < keylen; i++ )
376 {
377 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
378 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
379 }
380
381 md5_starts( ctx );
382 md5_update( ctx, ctx->ipad, 64 );
383
Paul Bakker34617722014-06-13 17:20:13 +0200384 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000385}
386
387/*
388 * MD5 HMAC process buffer
389 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200390void md5_hmac_update( md5_context *ctx, const unsigned char *input,
391 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000392{
393 md5_update( ctx, input, ilen );
394}
395
396/*
397 * MD5 HMAC final digest
398 */
399void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
400{
401 unsigned char tmpbuf[16];
402
403 md5_finish( ctx, tmpbuf );
404 md5_starts( ctx );
405 md5_update( ctx, ctx->opad, 64 );
406 md5_update( ctx, tmpbuf, 16 );
407 md5_finish( ctx, output );
408
Paul Bakker34617722014-06-13 17:20:13 +0200409 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410}
411
412/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000413 * MD5 HMAC context reset
414 */
415void md5_hmac_reset( md5_context *ctx )
416{
417 md5_starts( ctx );
418 md5_update( ctx, ctx->ipad, 64 );
419}
420
421/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000422 * output = HMAC-MD5( hmac key, input buffer )
423 */
Paul Bakker23986e52011-04-24 08:57:21 +0000424void md5_hmac( const unsigned char *key, size_t keylen,
425 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 unsigned char output[16] )
427{
428 md5_context ctx;
429
Paul Bakker5b4af392014-06-26 12:09:34 +0200430 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 md5_hmac_starts( &ctx, key, keylen );
432 md5_hmac_update( &ctx, input, ilen );
433 md5_hmac_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200434 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000435}
436
Paul Bakker40e46942009-01-03 21:51:57 +0000437#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000438/*
439 * RFC 1321 test vectors
440 */
441static unsigned char md5_test_buf[7][81] =
442{
Paul Bakker9af723c2014-05-01 13:03:14 +0200443 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 { "a" },
445 { "abc" },
446 { "message digest" },
447 { "abcdefghijklmnopqrstuvwxyz" },
448 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
449 { "12345678901234567890123456789012345678901234567890123456789012" \
450 "345678901234567890" }
451};
452
453static const int md5_test_buflen[7] =
454{
455 0, 1, 3, 14, 26, 62, 80
456};
457
458static const unsigned char md5_test_sum[7][16] =
459{
460 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
461 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
462 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
463 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
464 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
465 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
466 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
467 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
468 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
469 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
470 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
471 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
472 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
473 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
474};
475
476/*
477 * RFC 2202 test vectors
478 */
479static unsigned char md5_hmac_test_key[7][26] =
480{
481 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
482 { "Jefe" },
483 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
484 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
485 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
486 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
487 { "" }, /* 0xAA 80 times */
488 { "" }
489};
490
491static const int md5_hmac_test_keylen[7] =
492{
493 16, 4, 16, 25, 16, 80, 80
494};
495
496static unsigned char md5_hmac_test_buf[7][74] =
497{
498 { "Hi There" },
499 { "what do ya want for nothing?" },
500 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
501 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
502 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
503 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
504 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
505 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
506 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
507 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
508 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
509 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
510 { "Test With Truncation" },
511 { "Test Using Larger Than Block-Size Key - Hash Key First" },
512 { "Test Using Larger Than Block-Size Key and Larger"
513 " Than One Block-Size Data" }
514};
515
516static const int md5_hmac_test_buflen[7] =
517{
518 8, 28, 50, 50, 20, 54, 73
519};
520
521static const unsigned char md5_hmac_test_sum[7][16] =
522{
523 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
524 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
525 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
526 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
527 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
528 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
529 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
530 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
531 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
532 0xF9, 0xBA, 0xB9, 0x95 },
533 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
534 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
535 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
536 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
537};
538
539/*
540 * Checkup routine
541 */
542int md5_self_test( int verbose )
543{
544 int i, buflen;
545 unsigned char buf[1024];
546 unsigned char md5sum[16];
547 md5_context ctx;
548
549 for( i = 0; i < 7; i++ )
550 {
551 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100552 polarssl_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000553
554 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
555
556 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
557 {
558 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100559 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 return( 1 );
562 }
563
564 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100565 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000566 }
567
568 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100569 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
571 for( i = 0; i < 7; i++ )
572 {
573 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100574 polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 if( i == 5 || i == 6 )
577 {
578 memset( buf, '\xAA', buflen = 80 );
579 md5_hmac_starts( &ctx, buf, buflen );
580 }
581 else
582 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
583 md5_hmac_test_keylen[i] );
584
585 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
586 md5_hmac_test_buflen[i] );
587
588 md5_hmac_finish( &ctx, md5sum );
589
590 buflen = ( i == 4 ) ? 12 : 16;
591
592 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
593 {
594 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100595 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596
597 return( 1 );
598 }
599
600 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100601 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 }
603
604 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100605 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000606
607 return( 0 );
608}
609
Paul Bakker9af723c2014-05-01 13:03:14 +0200610#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
Paul Bakker9af723c2014-05-01 13:03:14 +0200612#endif /* POLARSSL_MD5_C */