blob: ca163175204062d9ab4f791f9fbfa37aa745a05a [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 Bakker34617722014-06-13 17:20:13 +020051/* Implementation that should never be optimized out by the compiler */
52static void polarssl_zeroize( void *v, size_t n ) {
53 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
54}
55
Paul Bakker90995b52013-06-24 19:20:35 +020056#if !defined(POLARSSL_MD5_ALT)
57
Paul Bakker5121ce52009-01-03 21:22:43 +000058/*
59 * 32-bit integer manipulation macros (little endian)
60 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000061#ifndef GET_UINT32_LE
62#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000063{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000064 (n) = ( (uint32_t) (b)[(i) ] ) \
65 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
66 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
67 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000068}
69#endif
70
Paul Bakker5c2364c2012-10-01 14:41:15 +000071#ifndef PUT_UINT32_LE
72#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000073{ \
74 (b)[(i) ] = (unsigned char) ( (n) ); \
75 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
76 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
77 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
78}
79#endif
80
81/*
82 * MD5 context setup
83 */
84void md5_starts( md5_context *ctx )
85{
86 ctx->total[0] = 0;
87 ctx->total[1] = 0;
88
89 ctx->state[0] = 0x67452301;
90 ctx->state[1] = 0xEFCDAB89;
91 ctx->state[2] = 0x98BADCFE;
92 ctx->state[3] = 0x10325476;
93}
94
Paul Bakkere47b34b2013-02-27 14:48:00 +010095void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000096{
Paul Bakker5c2364c2012-10-01 14:41:15 +000097 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000098
Paul Bakker5c2364c2012-10-01 14:41:15 +000099 GET_UINT32_LE( X[ 0], data, 0 );
100 GET_UINT32_LE( X[ 1], data, 4 );
101 GET_UINT32_LE( X[ 2], data, 8 );
102 GET_UINT32_LE( X[ 3], data, 12 );
103 GET_UINT32_LE( X[ 4], data, 16 );
104 GET_UINT32_LE( X[ 5], data, 20 );
105 GET_UINT32_LE( X[ 6], data, 24 );
106 GET_UINT32_LE( X[ 7], data, 28 );
107 GET_UINT32_LE( X[ 8], data, 32 );
108 GET_UINT32_LE( X[ 9], data, 36 );
109 GET_UINT32_LE( X[10], data, 40 );
110 GET_UINT32_LE( X[11], data, 44 );
111 GET_UINT32_LE( X[12], data, 48 );
112 GET_UINT32_LE( X[13], data, 52 );
113 GET_UINT32_LE( X[14], data, 56 );
114 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000115
116#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
117
118#define P(a,b,c,d,k,s,t) \
119{ \
120 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
121}
122
123 A = ctx->state[0];
124 B = ctx->state[1];
125 C = ctx->state[2];
126 D = ctx->state[3];
127
128#define F(x,y,z) (z ^ (x & (y ^ z)))
129
130 P( A, B, C, D, 0, 7, 0xD76AA478 );
131 P( D, A, B, C, 1, 12, 0xE8C7B756 );
132 P( C, D, A, B, 2, 17, 0x242070DB );
133 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
134 P( A, B, C, D, 4, 7, 0xF57C0FAF );
135 P( D, A, B, C, 5, 12, 0x4787C62A );
136 P( C, D, A, B, 6, 17, 0xA8304613 );
137 P( B, C, D, A, 7, 22, 0xFD469501 );
138 P( A, B, C, D, 8, 7, 0x698098D8 );
139 P( D, A, B, C, 9, 12, 0x8B44F7AF );
140 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
141 P( B, C, D, A, 11, 22, 0x895CD7BE );
142 P( A, B, C, D, 12, 7, 0x6B901122 );
143 P( D, A, B, C, 13, 12, 0xFD987193 );
144 P( C, D, A, B, 14, 17, 0xA679438E );
145 P( B, C, D, A, 15, 22, 0x49B40821 );
146
147#undef F
148
149#define F(x,y,z) (y ^ (z & (x ^ y)))
150
151 P( A, B, C, D, 1, 5, 0xF61E2562 );
152 P( D, A, B, C, 6, 9, 0xC040B340 );
153 P( C, D, A, B, 11, 14, 0x265E5A51 );
154 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
155 P( A, B, C, D, 5, 5, 0xD62F105D );
156 P( D, A, B, C, 10, 9, 0x02441453 );
157 P( C, D, A, B, 15, 14, 0xD8A1E681 );
158 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
159 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
160 P( D, A, B, C, 14, 9, 0xC33707D6 );
161 P( C, D, A, B, 3, 14, 0xF4D50D87 );
162 P( B, C, D, A, 8, 20, 0x455A14ED );
163 P( A, B, C, D, 13, 5, 0xA9E3E905 );
164 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
165 P( C, D, A, B, 7, 14, 0x676F02D9 );
166 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
167
168#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200169
Paul Bakker5121ce52009-01-03 21:22:43 +0000170#define F(x,y,z) (x ^ y ^ z)
171
172 P( A, B, C, D, 5, 4, 0xFFFA3942 );
173 P( D, A, B, C, 8, 11, 0x8771F681 );
174 P( C, D, A, B, 11, 16, 0x6D9D6122 );
175 P( B, C, D, A, 14, 23, 0xFDE5380C );
176 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
177 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
178 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
179 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
180 P( A, B, C, D, 13, 4, 0x289B7EC6 );
181 P( D, A, B, C, 0, 11, 0xEAA127FA );
182 P( C, D, A, B, 3, 16, 0xD4EF3085 );
183 P( B, C, D, A, 6, 23, 0x04881D05 );
184 P( A, B, C, D, 9, 4, 0xD9D4D039 );
185 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
186 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
187 P( B, C, D, A, 2, 23, 0xC4AC5665 );
188
189#undef F
190
191#define F(x,y,z) (y ^ (x | ~z))
192
193 P( A, B, C, D, 0, 6, 0xF4292244 );
194 P( D, A, B, C, 7, 10, 0x432AFF97 );
195 P( C, D, A, B, 14, 15, 0xAB9423A7 );
196 P( B, C, D, A, 5, 21, 0xFC93A039 );
197 P( A, B, C, D, 12, 6, 0x655B59C3 );
198 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
199 P( C, D, A, B, 10, 15, 0xFFEFF47D );
200 P( B, C, D, A, 1, 21, 0x85845DD1 );
201 P( A, B, C, D, 8, 6, 0x6FA87E4F );
202 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
203 P( C, D, A, B, 6, 15, 0xA3014314 );
204 P( B, C, D, A, 13, 21, 0x4E0811A1 );
205 P( A, B, C, D, 4, 6, 0xF7537E82 );
206 P( D, A, B, C, 11, 10, 0xBD3AF235 );
207 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
208 P( B, C, D, A, 9, 21, 0xEB86D391 );
209
210#undef F
211
212 ctx->state[0] += A;
213 ctx->state[1] += B;
214 ctx->state[2] += C;
215 ctx->state[3] += D;
216}
217
218/*
219 * MD5 process buffer
220 */
Paul Bakker23986e52011-04-24 08:57:21 +0000221void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000222{
Paul Bakker23986e52011-04-24 08:57:21 +0000223 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000224 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000225
Brian White12895d12014-04-11 11:29:42 -0400226 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000227 return;
228
229 left = ctx->total[0] & 0x3F;
230 fill = 64 - left;
231
Paul Bakker5c2364c2012-10-01 14:41:15 +0000232 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000233 ctx->total[0] &= 0xFFFFFFFF;
234
Paul Bakker5c2364c2012-10-01 14:41:15 +0000235 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000236 ctx->total[1]++;
237
238 if( left && ilen >= fill )
239 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200240 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000241 md5_process( ctx, ctx->buffer );
242 input += fill;
243 ilen -= fill;
244 left = 0;
245 }
246
247 while( ilen >= 64 )
248 {
249 md5_process( ctx, input );
250 input += 64;
251 ilen -= 64;
252 }
253
254 if( ilen > 0 )
255 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200256 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257 }
258}
259
260static const unsigned char md5_padding[64] =
261{
262 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
264 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
266};
267
268/*
269 * MD5 final digest
270 */
271void md5_finish( md5_context *ctx, unsigned char output[16] )
272{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000273 uint32_t last, padn;
274 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000275 unsigned char msglen[8];
276
277 high = ( ctx->total[0] >> 29 )
278 | ( ctx->total[1] << 3 );
279 low = ( ctx->total[0] << 3 );
280
Paul Bakker5c2364c2012-10-01 14:41:15 +0000281 PUT_UINT32_LE( low, msglen, 0 );
282 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000283
284 last = ctx->total[0] & 0x3F;
285 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
286
Paul Bakker3c2122f2013-06-24 19:03:14 +0200287 md5_update( ctx, md5_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 md5_update( ctx, msglen, 8 );
289
Paul Bakker5c2364c2012-10-01 14:41:15 +0000290 PUT_UINT32_LE( ctx->state[0], output, 0 );
291 PUT_UINT32_LE( ctx->state[1], output, 4 );
292 PUT_UINT32_LE( ctx->state[2], output, 8 );
293 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000294}
295
Paul Bakker90995b52013-06-24 19:20:35 +0200296#endif /* !POLARSSL_MD5_ALT */
297
Paul Bakker5121ce52009-01-03 21:22:43 +0000298/*
299 * output = MD5( input buffer )
300 */
Paul Bakker23986e52011-04-24 08:57:21 +0000301void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000302{
303 md5_context ctx;
304
305 md5_starts( &ctx );
306 md5_update( &ctx, input, ilen );
307 md5_finish( &ctx, output );
308
Paul Bakker34617722014-06-13 17:20:13 +0200309 polarssl_zeroize( &ctx, sizeof( md5_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310}
311
Paul Bakker335db3f2011-04-25 15:28:35 +0000312#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000313/*
314 * output = MD5( file contents )
315 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000316int md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000317{
318 FILE *f;
319 size_t n;
320 md5_context ctx;
321 unsigned char buf[1024];
322
323 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000324 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000325
326 md5_starts( &ctx );
327
328 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000329 md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000330
331 md5_finish( &ctx, output );
332
Paul Bakker34617722014-06-13 17:20:13 +0200333 polarssl_zeroize( &ctx, sizeof( md5_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000334
335 if( ferror( f ) != 0 )
336 {
337 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000338 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000339 }
340
341 fclose( f );
342 return( 0 );
343}
Paul Bakker335db3f2011-04-25 15:28:35 +0000344#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346/*
347 * MD5 HMAC context setup
348 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200349void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
350 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000351{
Paul Bakker23986e52011-04-24 08:57:21 +0000352 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000353 unsigned char sum[16];
354
355 if( keylen > 64 )
356 {
357 md5( key, keylen, sum );
358 keylen = 16;
359 key = sum;
360 }
361
362 memset( ctx->ipad, 0x36, 64 );
363 memset( ctx->opad, 0x5C, 64 );
364
365 for( i = 0; i < keylen; i++ )
366 {
367 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
368 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
369 }
370
371 md5_starts( ctx );
372 md5_update( ctx, ctx->ipad, 64 );
373
Paul Bakker34617722014-06-13 17:20:13 +0200374 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000375}
376
377/*
378 * MD5 HMAC process buffer
379 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200380void md5_hmac_update( md5_context *ctx, const unsigned char *input,
381 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000382{
383 md5_update( ctx, input, ilen );
384}
385
386/*
387 * MD5 HMAC final digest
388 */
389void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
390{
391 unsigned char tmpbuf[16];
392
393 md5_finish( ctx, tmpbuf );
394 md5_starts( ctx );
395 md5_update( ctx, ctx->opad, 64 );
396 md5_update( ctx, tmpbuf, 16 );
397 md5_finish( ctx, output );
398
Paul Bakker34617722014-06-13 17:20:13 +0200399 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000400}
401
402/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000403 * MD5 HMAC context reset
404 */
405void md5_hmac_reset( md5_context *ctx )
406{
407 md5_starts( ctx );
408 md5_update( ctx, ctx->ipad, 64 );
409}
410
411/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 * output = HMAC-MD5( hmac key, input buffer )
413 */
Paul Bakker23986e52011-04-24 08:57:21 +0000414void md5_hmac( const unsigned char *key, size_t keylen,
415 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000416 unsigned char output[16] )
417{
418 md5_context ctx;
419
420 md5_hmac_starts( &ctx, key, keylen );
421 md5_hmac_update( &ctx, input, ilen );
422 md5_hmac_finish( &ctx, output );
423
Paul Bakker34617722014-06-13 17:20:13 +0200424 polarssl_zeroize( &ctx, sizeof( md5_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000425}
426
Paul Bakker40e46942009-01-03 21:51:57 +0000427#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000428/*
429 * RFC 1321 test vectors
430 */
431static unsigned char md5_test_buf[7][81] =
432{
Paul Bakker9af723c2014-05-01 13:03:14 +0200433 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 { "a" },
435 { "abc" },
436 { "message digest" },
437 { "abcdefghijklmnopqrstuvwxyz" },
438 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
439 { "12345678901234567890123456789012345678901234567890123456789012" \
440 "345678901234567890" }
441};
442
443static const int md5_test_buflen[7] =
444{
445 0, 1, 3, 14, 26, 62, 80
446};
447
448static const unsigned char md5_test_sum[7][16] =
449{
450 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
451 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
452 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
453 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
454 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
455 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
456 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
457 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
458 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
459 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
460 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
461 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
462 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
463 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
464};
465
466/*
467 * RFC 2202 test vectors
468 */
469static unsigned char md5_hmac_test_key[7][26] =
470{
471 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
472 { "Jefe" },
473 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
474 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
475 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
476 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
477 { "" }, /* 0xAA 80 times */
478 { "" }
479};
480
481static const int md5_hmac_test_keylen[7] =
482{
483 16, 4, 16, 25, 16, 80, 80
484};
485
486static unsigned char md5_hmac_test_buf[7][74] =
487{
488 { "Hi There" },
489 { "what do ya want for nothing?" },
490 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
491 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
492 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
493 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
494 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
495 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
496 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
497 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
498 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
499 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
500 { "Test With Truncation" },
501 { "Test Using Larger Than Block-Size Key - Hash Key First" },
502 { "Test Using Larger Than Block-Size Key and Larger"
503 " Than One Block-Size Data" }
504};
505
506static const int md5_hmac_test_buflen[7] =
507{
508 8, 28, 50, 50, 20, 54, 73
509};
510
511static const unsigned char md5_hmac_test_sum[7][16] =
512{
513 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
514 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
515 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
516 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
517 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
518 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
519 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
520 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
521 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
522 0xF9, 0xBA, 0xB9, 0x95 },
523 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
524 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
525 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
526 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
527};
528
529/*
530 * Checkup routine
531 */
532int md5_self_test( int verbose )
533{
534 int i, buflen;
535 unsigned char buf[1024];
536 unsigned char md5sum[16];
537 md5_context ctx;
538
539 for( i = 0; i < 7; i++ )
540 {
541 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100542 polarssl_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
544 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
545
546 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
547 {
548 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100549 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
551 return( 1 );
552 }
553
554 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100555 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000556 }
557
558 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100559 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 for( i = 0; i < 7; i++ )
562 {
563 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100564 polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
566 if( i == 5 || i == 6 )
567 {
568 memset( buf, '\xAA', buflen = 80 );
569 md5_hmac_starts( &ctx, buf, buflen );
570 }
571 else
572 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
573 md5_hmac_test_keylen[i] );
574
575 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
576 md5_hmac_test_buflen[i] );
577
578 md5_hmac_finish( &ctx, md5sum );
579
580 buflen = ( i == 4 ) ? 12 : 16;
581
582 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
583 {
584 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100585 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000586
587 return( 1 );
588 }
589
590 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100591 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000592 }
593
594 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100595 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596
597 return( 0 );
598}
599
Paul Bakker9af723c2014-05-01 13:03:14 +0200600#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000601
Paul Bakker9af723c2014-05-01 13:03:14 +0200602#endif /* POLARSSL_MD5_C */