blob: 592304eb24d0de96a79b87e9ad761662d2cc3292 [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é-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#if defined(MBEDTLS_SELF_TEST)
45#if defined(MBEDTLS_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>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020049#define mbedtls_printf printf
50#endif /* MBEDTLS_PLATFORM_C */
51#endif /* MBEDTLS_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 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020055 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
56}
57
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#if !defined(MBEDTLS_MD5_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020059
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083void mbedtls_md5_init( mbedtls_md5_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020084{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020085 memset( ctx, 0, sizeof( mbedtls_md5_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020086}
87
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088void mbedtls_md5_free( mbedtls_md5_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020089{
90 if( ctx == NULL )
91 return;
92
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020093 mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020094}
95
Paul Bakker5121ce52009-01-03 21:22:43 +000096/*
97 * MD5 context setup
98 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020099void mbedtls_md5_starts( mbedtls_md5_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000100{
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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200110#if !defined(MBEDTLS_MD5_PROCESS_ALT)
111void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000112{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000113 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000114
Paul Bakker5c2364c2012-10-01 14:41:15 +0000115 GET_UINT32_LE( X[ 0], data, 0 );
116 GET_UINT32_LE( X[ 1], data, 4 );
117 GET_UINT32_LE( X[ 2], data, 8 );
118 GET_UINT32_LE( X[ 3], data, 12 );
119 GET_UINT32_LE( X[ 4], data, 16 );
120 GET_UINT32_LE( X[ 5], data, 20 );
121 GET_UINT32_LE( X[ 6], data, 24 );
122 GET_UINT32_LE( X[ 7], data, 28 );
123 GET_UINT32_LE( X[ 8], data, 32 );
124 GET_UINT32_LE( X[ 9], data, 36 );
125 GET_UINT32_LE( X[10], data, 40 );
126 GET_UINT32_LE( X[11], data, 44 );
127 GET_UINT32_LE( X[12], data, 48 );
128 GET_UINT32_LE( X[13], data, 52 );
129 GET_UINT32_LE( X[14], data, 56 );
130 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000131
132#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
133
134#define P(a,b,c,d,k,s,t) \
135{ \
136 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
137}
138
139 A = ctx->state[0];
140 B = ctx->state[1];
141 C = ctx->state[2];
142 D = ctx->state[3];
143
144#define F(x,y,z) (z ^ (x & (y ^ z)))
145
146 P( A, B, C, D, 0, 7, 0xD76AA478 );
147 P( D, A, B, C, 1, 12, 0xE8C7B756 );
148 P( C, D, A, B, 2, 17, 0x242070DB );
149 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
150 P( A, B, C, D, 4, 7, 0xF57C0FAF );
151 P( D, A, B, C, 5, 12, 0x4787C62A );
152 P( C, D, A, B, 6, 17, 0xA8304613 );
153 P( B, C, D, A, 7, 22, 0xFD469501 );
154 P( A, B, C, D, 8, 7, 0x698098D8 );
155 P( D, A, B, C, 9, 12, 0x8B44F7AF );
156 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
157 P( B, C, D, A, 11, 22, 0x895CD7BE );
158 P( A, B, C, D, 12, 7, 0x6B901122 );
159 P( D, A, B, C, 13, 12, 0xFD987193 );
160 P( C, D, A, B, 14, 17, 0xA679438E );
161 P( B, C, D, A, 15, 22, 0x49B40821 );
162
163#undef F
164
165#define F(x,y,z) (y ^ (z & (x ^ y)))
166
167 P( A, B, C, D, 1, 5, 0xF61E2562 );
168 P( D, A, B, C, 6, 9, 0xC040B340 );
169 P( C, D, A, B, 11, 14, 0x265E5A51 );
170 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
171 P( A, B, C, D, 5, 5, 0xD62F105D );
172 P( D, A, B, C, 10, 9, 0x02441453 );
173 P( C, D, A, B, 15, 14, 0xD8A1E681 );
174 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
175 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
176 P( D, A, B, C, 14, 9, 0xC33707D6 );
177 P( C, D, A, B, 3, 14, 0xF4D50D87 );
178 P( B, C, D, A, 8, 20, 0x455A14ED );
179 P( A, B, C, D, 13, 5, 0xA9E3E905 );
180 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
181 P( C, D, A, B, 7, 14, 0x676F02D9 );
182 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
183
184#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200185
Paul Bakker5121ce52009-01-03 21:22:43 +0000186#define F(x,y,z) (x ^ y ^ z)
187
188 P( A, B, C, D, 5, 4, 0xFFFA3942 );
189 P( D, A, B, C, 8, 11, 0x8771F681 );
190 P( C, D, A, B, 11, 16, 0x6D9D6122 );
191 P( B, C, D, A, 14, 23, 0xFDE5380C );
192 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
193 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
194 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
195 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
196 P( A, B, C, D, 13, 4, 0x289B7EC6 );
197 P( D, A, B, C, 0, 11, 0xEAA127FA );
198 P( C, D, A, B, 3, 16, 0xD4EF3085 );
199 P( B, C, D, A, 6, 23, 0x04881D05 );
200 P( A, B, C, D, 9, 4, 0xD9D4D039 );
201 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
202 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
203 P( B, C, D, A, 2, 23, 0xC4AC5665 );
204
205#undef F
206
207#define F(x,y,z) (y ^ (x | ~z))
208
209 P( A, B, C, D, 0, 6, 0xF4292244 );
210 P( D, A, B, C, 7, 10, 0x432AFF97 );
211 P( C, D, A, B, 14, 15, 0xAB9423A7 );
212 P( B, C, D, A, 5, 21, 0xFC93A039 );
213 P( A, B, C, D, 12, 6, 0x655B59C3 );
214 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
215 P( C, D, A, B, 10, 15, 0xFFEFF47D );
216 P( B, C, D, A, 1, 21, 0x85845DD1 );
217 P( A, B, C, D, 8, 6, 0x6FA87E4F );
218 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
219 P( C, D, A, B, 6, 15, 0xA3014314 );
220 P( B, C, D, A, 13, 21, 0x4E0811A1 );
221 P( A, B, C, D, 4, 6, 0xF7537E82 );
222 P( D, A, B, C, 11, 10, 0xBD3AF235 );
223 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
224 P( B, C, D, A, 9, 21, 0xEB86D391 );
225
226#undef F
227
228 ctx->state[0] += A;
229 ctx->state[1] += B;
230 ctx->state[2] += C;
231 ctx->state[3] += D;
232}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200233#endif /* !MBEDTLS_MD5_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000234
235/*
236 * MD5 process buffer
237 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200238void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000239{
Paul Bakker23986e52011-04-24 08:57:21 +0000240 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000241 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000242
Brian White12895d12014-04-11 11:29:42 -0400243 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000244 return;
245
246 left = ctx->total[0] & 0x3F;
247 fill = 64 - left;
248
Paul Bakker5c2364c2012-10-01 14:41:15 +0000249 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000250 ctx->total[0] &= 0xFFFFFFFF;
251
Paul Bakker5c2364c2012-10-01 14:41:15 +0000252 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 ctx->total[1]++;
254
255 if( left && ilen >= fill )
256 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200257 memcpy( (void *) (ctx->buffer + left), input, fill );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200258 mbedtls_md5_process( ctx, ctx->buffer );
Paul Bakker5121ce52009-01-03 21:22:43 +0000259 input += fill;
260 ilen -= fill;
261 left = 0;
262 }
263
264 while( ilen >= 64 )
265 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200266 mbedtls_md5_process( ctx, input );
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 input += 64;
268 ilen -= 64;
269 }
270
271 if( ilen > 0 )
272 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200273 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000274 }
275}
276
277static const unsigned char md5_padding[64] =
278{
279 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
283};
284
285/*
286 * MD5 final digest
287 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200288void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000289{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000290 uint32_t last, padn;
291 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 unsigned char msglen[8];
293
294 high = ( ctx->total[0] >> 29 )
295 | ( ctx->total[1] << 3 );
296 low = ( ctx->total[0] << 3 );
297
Paul Bakker5c2364c2012-10-01 14:41:15 +0000298 PUT_UINT32_LE( low, msglen, 0 );
299 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
301 last = ctx->total[0] & 0x3F;
302 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
303
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200304 mbedtls_md5_update( ctx, md5_padding, padn );
305 mbedtls_md5_update( ctx, msglen, 8 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000306
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307 PUT_UINT32_LE( ctx->state[0], output, 0 );
308 PUT_UINT32_LE( ctx->state[1], output, 4 );
309 PUT_UINT32_LE( ctx->state[2], output, 8 );
310 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000311}
312
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200313#endif /* !MBEDTLS_MD5_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200314
Paul Bakker5121ce52009-01-03 21:22:43 +0000315/*
316 * output = MD5( input buffer )
317 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200318void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000319{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200320 mbedtls_md5_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200322 mbedtls_md5_init( &ctx );
323 mbedtls_md5_starts( &ctx );
324 mbedtls_md5_update( &ctx, input, ilen );
325 mbedtls_md5_finish( &ctx, output );
326 mbedtls_md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000327}
328
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200329#if defined(MBEDTLS_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000330/*
331 * output = MD5( file contents )
332 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333int mbedtls_md5_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000334{
335 FILE *f;
336 size_t n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200337 mbedtls_md5_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000338 unsigned char buf[1024];
339
340 if( ( f = fopen( path, "rb" ) ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200341 return( MBEDTLS_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000342
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200343 mbedtls_md5_init( &ctx );
344 mbedtls_md5_starts( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347 mbedtls_md5_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349 mbedtls_md5_finish( &ctx, output );
350 mbedtls_md5_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352 if( ferror( f ) != 0 )
353 {
354 fclose( f );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200355 return( MBEDTLS_ERR_MD5_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 }
357
358 fclose( f );
359 return( 0 );
360}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200361#endif /* MBEDTLS_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000364/*
365 * RFC 1321 test vectors
366 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000367static const unsigned char md5_test_buf[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000368{
Paul Bakker9af723c2014-05-01 13:03:14 +0200369 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000370 { "a" },
371 { "abc" },
372 { "message digest" },
373 { "abcdefghijklmnopqrstuvwxyz" },
374 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
375 { "12345678901234567890123456789012345678901234567890123456789012" \
376 "345678901234567890" }
377};
378
379static const int md5_test_buflen[7] =
380{
381 0, 1, 3, 14, 26, 62, 80
382};
383
384static const unsigned char md5_test_sum[7][16] =
385{
386 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
387 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
388 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
389 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
390 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
391 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
392 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
393 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
394 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
395 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
396 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
397 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
398 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
399 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
400};
401
402/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 * Checkup routine
404 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405int mbedtls_md5_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000406{
Manuel Pégourié-Gonnard4da88c52015-03-24 18:23:20 +0100407 int i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 unsigned char md5sum[16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410 for( i = 0; i < 7; i++ )
411 {
412 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200413 mbedtls_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200415 mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum );
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
417 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
418 {
419 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
422 return( 1 );
423 }
424
425 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 }
428
429 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 return( 0 );
433}
434
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200435#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000436
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437#endif /* MBEDTLS_MD5_C */