blob: f6873526b001615a72ac57aafe535ee1aaccb0be [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 *
Manuel Pégourié-Gonnard967a2a52015-01-22 14:28:16 +00006 * This file is part of mbed TLS (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
Paul Bakker5b4af392014-06-26 12:09:34 +020081void md5_init( md5_context *ctx )
82{
83 memset( ctx, 0, sizeof( md5_context ) );
84}
85
86void md5_free( md5_context *ctx )
87{
88 if( ctx == NULL )
89 return;
90
91 polarssl_zeroize( ctx, sizeof( md5_context ) );
92}
93
Paul Bakker5121ce52009-01-03 21:22:43 +000094/*
95 * MD5 context setup
96 */
97void md5_starts( md5_context *ctx )
98{
99 ctx->total[0] = 0;
100 ctx->total[1] = 0;
101
102 ctx->state[0] = 0x67452301;
103 ctx->state[1] = 0xEFCDAB89;
104 ctx->state[2] = 0x98BADCFE;
105 ctx->state[3] = 0x10325476;
106}
107
Paul Bakkere47b34b2013-02-27 14:48:00 +0100108void md5_process( md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000109{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000110 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000111
Paul Bakker5c2364c2012-10-01 14:41:15 +0000112 GET_UINT32_LE( X[ 0], data, 0 );
113 GET_UINT32_LE( X[ 1], data, 4 );
114 GET_UINT32_LE( X[ 2], data, 8 );
115 GET_UINT32_LE( X[ 3], data, 12 );
116 GET_UINT32_LE( X[ 4], data, 16 );
117 GET_UINT32_LE( X[ 5], data, 20 );
118 GET_UINT32_LE( X[ 6], data, 24 );
119 GET_UINT32_LE( X[ 7], data, 28 );
120 GET_UINT32_LE( X[ 8], data, 32 );
121 GET_UINT32_LE( X[ 9], data, 36 );
122 GET_UINT32_LE( X[10], data, 40 );
123 GET_UINT32_LE( X[11], data, 44 );
124 GET_UINT32_LE( X[12], data, 48 );
125 GET_UINT32_LE( X[13], data, 52 );
126 GET_UINT32_LE( X[14], data, 56 );
127 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000128
129#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
130
131#define P(a,b,c,d,k,s,t) \
132{ \
133 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
134}
135
136 A = ctx->state[0];
137 B = ctx->state[1];
138 C = ctx->state[2];
139 D = ctx->state[3];
140
141#define F(x,y,z) (z ^ (x & (y ^ z)))
142
143 P( A, B, C, D, 0, 7, 0xD76AA478 );
144 P( D, A, B, C, 1, 12, 0xE8C7B756 );
145 P( C, D, A, B, 2, 17, 0x242070DB );
146 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
147 P( A, B, C, D, 4, 7, 0xF57C0FAF );
148 P( D, A, B, C, 5, 12, 0x4787C62A );
149 P( C, D, A, B, 6, 17, 0xA8304613 );
150 P( B, C, D, A, 7, 22, 0xFD469501 );
151 P( A, B, C, D, 8, 7, 0x698098D8 );
152 P( D, A, B, C, 9, 12, 0x8B44F7AF );
153 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
154 P( B, C, D, A, 11, 22, 0x895CD7BE );
155 P( A, B, C, D, 12, 7, 0x6B901122 );
156 P( D, A, B, C, 13, 12, 0xFD987193 );
157 P( C, D, A, B, 14, 17, 0xA679438E );
158 P( B, C, D, A, 15, 22, 0x49B40821 );
159
160#undef F
161
162#define F(x,y,z) (y ^ (z & (x ^ y)))
163
164 P( A, B, C, D, 1, 5, 0xF61E2562 );
165 P( D, A, B, C, 6, 9, 0xC040B340 );
166 P( C, D, A, B, 11, 14, 0x265E5A51 );
167 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
168 P( A, B, C, D, 5, 5, 0xD62F105D );
169 P( D, A, B, C, 10, 9, 0x02441453 );
170 P( C, D, A, B, 15, 14, 0xD8A1E681 );
171 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
172 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
173 P( D, A, B, C, 14, 9, 0xC33707D6 );
174 P( C, D, A, B, 3, 14, 0xF4D50D87 );
175 P( B, C, D, A, 8, 20, 0x455A14ED );
176 P( A, B, C, D, 13, 5, 0xA9E3E905 );
177 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
178 P( C, D, A, B, 7, 14, 0x676F02D9 );
179 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
180
181#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200182
Paul Bakker5121ce52009-01-03 21:22:43 +0000183#define F(x,y,z) (x ^ y ^ z)
184
185 P( A, B, C, D, 5, 4, 0xFFFA3942 );
186 P( D, A, B, C, 8, 11, 0x8771F681 );
187 P( C, D, A, B, 11, 16, 0x6D9D6122 );
188 P( B, C, D, A, 14, 23, 0xFDE5380C );
189 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
190 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
191 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
192 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
193 P( A, B, C, D, 13, 4, 0x289B7EC6 );
194 P( D, A, B, C, 0, 11, 0xEAA127FA );
195 P( C, D, A, B, 3, 16, 0xD4EF3085 );
196 P( B, C, D, A, 6, 23, 0x04881D05 );
197 P( A, B, C, D, 9, 4, 0xD9D4D039 );
198 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
199 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
200 P( B, C, D, A, 2, 23, 0xC4AC5665 );
201
202#undef F
203
204#define F(x,y,z) (y ^ (x | ~z))
205
206 P( A, B, C, D, 0, 6, 0xF4292244 );
207 P( D, A, B, C, 7, 10, 0x432AFF97 );
208 P( C, D, A, B, 14, 15, 0xAB9423A7 );
209 P( B, C, D, A, 5, 21, 0xFC93A039 );
210 P( A, B, C, D, 12, 6, 0x655B59C3 );
211 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
212 P( C, D, A, B, 10, 15, 0xFFEFF47D );
213 P( B, C, D, A, 1, 21, 0x85845DD1 );
214 P( A, B, C, D, 8, 6, 0x6FA87E4F );
215 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
216 P( C, D, A, B, 6, 15, 0xA3014314 );
217 P( B, C, D, A, 13, 21, 0x4E0811A1 );
218 P( A, B, C, D, 4, 6, 0xF7537E82 );
219 P( D, A, B, C, 11, 10, 0xBD3AF235 );
220 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
221 P( B, C, D, A, 9, 21, 0xEB86D391 );
222
223#undef F
224
225 ctx->state[0] += A;
226 ctx->state[1] += B;
227 ctx->state[2] += C;
228 ctx->state[3] += D;
229}
230
231/*
232 * MD5 process buffer
233 */
Paul Bakker23986e52011-04-24 08:57:21 +0000234void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000235{
Paul Bakker23986e52011-04-24 08:57:21 +0000236 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000237 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
Brian White12895d12014-04-11 11:29:42 -0400239 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 return;
241
242 left = ctx->total[0] & 0x3F;
243 fill = 64 - left;
244
Paul Bakker5c2364c2012-10-01 14:41:15 +0000245 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000246 ctx->total[0] &= 0xFFFFFFFF;
247
Paul Bakker5c2364c2012-10-01 14:41:15 +0000248 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 ctx->total[1]++;
250
251 if( left && ilen >= fill )
252 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200253 memcpy( (void *) (ctx->buffer + left), input, fill );
Paul Bakker5121ce52009-01-03 21:22:43 +0000254 md5_process( ctx, ctx->buffer );
255 input += fill;
256 ilen -= fill;
257 left = 0;
258 }
259
260 while( ilen >= 64 )
261 {
262 md5_process( ctx, input );
263 input += 64;
264 ilen -= 64;
265 }
266
267 if( ilen > 0 )
268 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200269 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 }
271}
272
273static const unsigned char md5_padding[64] =
274{
275 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
276 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
277 0, 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};
280
281/*
282 * MD5 final digest
283 */
284void md5_finish( md5_context *ctx, unsigned char output[16] )
285{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000286 uint32_t last, padn;
287 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000288 unsigned char msglen[8];
289
290 high = ( ctx->total[0] >> 29 )
291 | ( ctx->total[1] << 3 );
292 low = ( ctx->total[0] << 3 );
293
Paul Bakker5c2364c2012-10-01 14:41:15 +0000294 PUT_UINT32_LE( low, msglen, 0 );
295 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
297 last = ctx->total[0] & 0x3F;
298 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
299
Paul Bakker3c2122f2013-06-24 19:03:14 +0200300 md5_update( ctx, md5_padding, padn );
Paul Bakker5121ce52009-01-03 21:22:43 +0000301 md5_update( ctx, msglen, 8 );
302
Paul Bakker5c2364c2012-10-01 14:41:15 +0000303 PUT_UINT32_LE( ctx->state[0], output, 0 );
304 PUT_UINT32_LE( ctx->state[1], output, 4 );
305 PUT_UINT32_LE( ctx->state[2], output, 8 );
306 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307}
308
Paul Bakker90995b52013-06-24 19:20:35 +0200309#endif /* !POLARSSL_MD5_ALT */
310
Paul Bakker5121ce52009-01-03 21:22:43 +0000311/*
312 * output = MD5( input buffer )
313 */
Paul Bakker23986e52011-04-24 08:57:21 +0000314void md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000315{
316 md5_context ctx;
317
Paul Bakker5b4af392014-06-26 12:09:34 +0200318 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000319 md5_starts( &ctx );
320 md5_update( &ctx, input, ilen );
321 md5_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200322 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323}
324
Paul Bakker335db3f2011-04-25 15:28:35 +0000325#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000326/*
327 * output = MD5( file contents )
328 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000329int md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000330{
331 FILE *f;
332 size_t n;
333 md5_context ctx;
334 unsigned char buf[1024];
335
336 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000337 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
Paul Bakker5b4af392014-06-26 12:09:34 +0200339 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 md5_starts( &ctx );
341
342 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000343 md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000344
345 md5_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200346 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
348 if( ferror( f ) != 0 )
349 {
350 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000351 return( POLARSSL_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000352 }
353
354 fclose( f );
355 return( 0 );
356}
Paul Bakker335db3f2011-04-25 15:28:35 +0000357#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000358
359/*
360 * MD5 HMAC context setup
361 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200362void md5_hmac_starts( md5_context *ctx, const unsigned char *key,
363 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000364{
Paul Bakker23986e52011-04-24 08:57:21 +0000365 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000366 unsigned char sum[16];
367
368 if( keylen > 64 )
369 {
370 md5( key, keylen, sum );
371 keylen = 16;
372 key = sum;
373 }
374
375 memset( ctx->ipad, 0x36, 64 );
376 memset( ctx->opad, 0x5C, 64 );
377
378 for( i = 0; i < keylen; i++ )
379 {
380 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
381 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
382 }
383
384 md5_starts( ctx );
385 md5_update( ctx, ctx->ipad, 64 );
386
Paul Bakker34617722014-06-13 17:20:13 +0200387 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000388}
389
390/*
391 * MD5 HMAC process buffer
392 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200393void md5_hmac_update( md5_context *ctx, const unsigned char *input,
394 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000395{
396 md5_update( ctx, input, ilen );
397}
398
399/*
400 * MD5 HMAC final digest
401 */
402void md5_hmac_finish( md5_context *ctx, unsigned char output[16] )
403{
404 unsigned char tmpbuf[16];
405
406 md5_finish( ctx, tmpbuf );
407 md5_starts( ctx );
408 md5_update( ctx, ctx->opad, 64 );
409 md5_update( ctx, tmpbuf, 16 );
410 md5_finish( ctx, output );
411
Paul Bakker34617722014-06-13 17:20:13 +0200412 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000413}
414
415/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000416 * MD5 HMAC context reset
417 */
418void md5_hmac_reset( md5_context *ctx )
419{
420 md5_starts( ctx );
421 md5_update( ctx, ctx->ipad, 64 );
422}
423
424/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 * output = HMAC-MD5( hmac key, input buffer )
426 */
Paul Bakker23986e52011-04-24 08:57:21 +0000427void md5_hmac( const unsigned char *key, size_t keylen,
428 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 unsigned char output[16] )
430{
431 md5_context ctx;
432
Paul Bakker5b4af392014-06-26 12:09:34 +0200433 md5_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 md5_hmac_starts( &ctx, key, keylen );
435 md5_hmac_update( &ctx, input, ilen );
436 md5_hmac_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200437 md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438}
439
Paul Bakker40e46942009-01-03 21:51:57 +0000440#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000441/*
442 * RFC 1321 test vectors
443 */
444static unsigned char md5_test_buf[7][81] =
445{
Paul Bakker9af723c2014-05-01 13:03:14 +0200446 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000447 { "a" },
448 { "abc" },
449 { "message digest" },
450 { "abcdefghijklmnopqrstuvwxyz" },
451 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
452 { "12345678901234567890123456789012345678901234567890123456789012" \
453 "345678901234567890" }
454};
455
456static const int md5_test_buflen[7] =
457{
458 0, 1, 3, 14, 26, 62, 80
459};
460
461static const unsigned char md5_test_sum[7][16] =
462{
463 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
464 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
465 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
466 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
467 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
468 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
469 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
470 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
471 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
472 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
473 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
474 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
475 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
476 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
477};
478
479/*
480 * RFC 2202 test vectors
481 */
482static unsigned char md5_hmac_test_key[7][26] =
483{
484 { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B" },
485 { "Jefe" },
486 { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" },
487 { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
488 "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
489 { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C" },
490 { "" }, /* 0xAA 80 times */
491 { "" }
492};
493
494static const int md5_hmac_test_keylen[7] =
495{
496 16, 4, 16, 25, 16, 80, 80
497};
498
499static unsigned char md5_hmac_test_buf[7][74] =
500{
501 { "Hi There" },
502 { "what do ya want for nothing?" },
503 { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
504 "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
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 { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
509 "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
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 { "Test With Truncation" },
514 { "Test Using Larger Than Block-Size Key - Hash Key First" },
515 { "Test Using Larger Than Block-Size Key and Larger"
516 " Than One Block-Size Data" }
517};
518
519static const int md5_hmac_test_buflen[7] =
520{
521 8, 28, 50, 50, 20, 54, 73
522};
523
524static const unsigned char md5_hmac_test_sum[7][16] =
525{
526 { 0x92, 0x94, 0x72, 0x7A, 0x36, 0x38, 0xBB, 0x1C,
527 0x13, 0xF4, 0x8E, 0xF8, 0x15, 0x8B, 0xFC, 0x9D },
528 { 0x75, 0x0C, 0x78, 0x3E, 0x6A, 0xB0, 0xB5, 0x03,
529 0xEA, 0xA8, 0x6E, 0x31, 0x0A, 0x5D, 0xB7, 0x38 },
530 { 0x56, 0xBE, 0x34, 0x52, 0x1D, 0x14, 0x4C, 0x88,
531 0xDB, 0xB8, 0xC7, 0x33, 0xF0, 0xE8, 0xB3, 0xF6 },
532 { 0x69, 0x7E, 0xAF, 0x0A, 0xCA, 0x3A, 0x3A, 0xEA,
533 0x3A, 0x75, 0x16, 0x47, 0x46, 0xFF, 0xAA, 0x79 },
534 { 0x56, 0x46, 0x1E, 0xF2, 0x34, 0x2E, 0xDC, 0x00,
535 0xF9, 0xBA, 0xB9, 0x95 },
536 { 0x6B, 0x1A, 0xB7, 0xFE, 0x4B, 0xD7, 0xBF, 0x8F,
537 0x0B, 0x62, 0xE6, 0xCE, 0x61, 0xB9, 0xD0, 0xCD },
538 { 0x6F, 0x63, 0x0F, 0xAD, 0x67, 0xCD, 0xA0, 0xEE,
539 0x1F, 0xB1, 0xF5, 0x62, 0xDB, 0x3A, 0xA5, 0x3E }
540};
541
542/*
543 * Checkup routine
544 */
545int md5_self_test( int verbose )
546{
547 int i, buflen;
548 unsigned char buf[1024];
549 unsigned char md5sum[16];
550 md5_context ctx;
551
552 for( i = 0; i < 7; i++ )
553 {
554 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100555 polarssl_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000556
557 md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
558
559 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
560 {
561 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100562 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
564 return( 1 );
565 }
566
567 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100568 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000569 }
570
571 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100572 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
574 for( i = 0; i < 7; i++ )
575 {
576 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100577 polarssl_printf( " HMAC-MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000578
579 if( i == 5 || i == 6 )
580 {
581 memset( buf, '\xAA', buflen = 80 );
582 md5_hmac_starts( &ctx, buf, buflen );
583 }
584 else
585 md5_hmac_starts( &ctx, md5_hmac_test_key[i],
586 md5_hmac_test_keylen[i] );
587
588 md5_hmac_update( &ctx, md5_hmac_test_buf[i],
589 md5_hmac_test_buflen[i] );
590
591 md5_hmac_finish( &ctx, md5sum );
592
593 buflen = ( i == 4 ) ? 12 : 16;
594
595 if( memcmp( md5sum, md5_hmac_test_sum[i], buflen ) != 0 )
596 {
597 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100598 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
600 return( 1 );
601 }
602
603 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100604 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000605 }
606
607 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100608 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
610 return( 0 );
611}
612
Paul Bakker9af723c2014-05-01 13:03:14 +0200613#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
Paul Bakker9af723c2014-05-01 13:03:14 +0200615#endif /* POLARSSL_MD5_C */