blob: 8150f941db3c5700deb1c5c9674fa1dc6798a456 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1321 compliant MD5 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * The MD5 algorithm was designed by Ron Rivest in 1991.
23 *
24 * http://www.ietf.org/rfc/rfc1321.txt
25 */
26
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000028#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020029#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020033#if defined(MBEDTLS_MD5_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000035#include "mbedtls/md5.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Rich Evans00ab4702015-02-06 13:43:58 +000037#include <string.h>
38
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020039#if defined(MBEDTLS_SELF_TEST)
40#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000041#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010042#else
Rich Evans00ab4702015-02-06 13:43:58 +000043#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044#define mbedtls_printf printf
45#endif /* MBEDTLS_PLATFORM_C */
46#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010047
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020048#if !defined(MBEDTLS_MD5_ALT)
49
Paul Bakker34617722014-06-13 17:20:13 +020050/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020051static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020052 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
53}
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
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000069#define PUT_UINT32_LE(n,b,i) \
70{ \
71 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
72 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
73 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
74 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000075}
76#endif
77
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078void mbedtls_md5_init( mbedtls_md5_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020079{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080 memset( ctx, 0, sizeof( mbedtls_md5_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020081}
82
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020083void mbedtls_md5_free( mbedtls_md5_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020084{
85 if( ctx == NULL )
86 return;
87
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020088 mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020089}
90
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020091void mbedtls_md5_clone( mbedtls_md5_context *dst,
92 const mbedtls_md5_context *src )
93{
94 *dst = *src;
95}
96
Paul Bakker5121ce52009-01-03 21:22:43 +000097/*
98 * MD5 context setup
99 */
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100100int mbedtls_md5_starts_ext( mbedtls_md5_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000101{
102 ctx->total[0] = 0;
103 ctx->total[1] = 0;
104
105 ctx->state[0] = 0x67452301;
106 ctx->state[1] = 0xEFCDAB89;
107 ctx->state[2] = 0x98BADCFE;
108 ctx->state[3] = 0x10325476;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100109
110 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000111}
112
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200113#if !defined(MBEDTLS_MD5_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100114int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
115 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000116{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000117 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000118
Paul Bakker5c2364c2012-10-01 14:41:15 +0000119 GET_UINT32_LE( X[ 0], data, 0 );
120 GET_UINT32_LE( X[ 1], data, 4 );
121 GET_UINT32_LE( X[ 2], data, 8 );
122 GET_UINT32_LE( X[ 3], data, 12 );
123 GET_UINT32_LE( X[ 4], data, 16 );
124 GET_UINT32_LE( X[ 5], data, 20 );
125 GET_UINT32_LE( X[ 6], data, 24 );
126 GET_UINT32_LE( X[ 7], data, 28 );
127 GET_UINT32_LE( X[ 8], data, 32 );
128 GET_UINT32_LE( X[ 9], data, 36 );
129 GET_UINT32_LE( X[10], data, 40 );
130 GET_UINT32_LE( X[11], data, 44 );
131 GET_UINT32_LE( X[12], data, 48 );
132 GET_UINT32_LE( X[13], data, 52 );
133 GET_UINT32_LE( X[14], data, 56 );
134 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000135
136#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
137
138#define P(a,b,c,d,k,s,t) \
139{ \
140 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
141}
142
143 A = ctx->state[0];
144 B = ctx->state[1];
145 C = ctx->state[2];
146 D = ctx->state[3];
147
148#define F(x,y,z) (z ^ (x & (y ^ z)))
149
150 P( A, B, C, D, 0, 7, 0xD76AA478 );
151 P( D, A, B, C, 1, 12, 0xE8C7B756 );
152 P( C, D, A, B, 2, 17, 0x242070DB );
153 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
154 P( A, B, C, D, 4, 7, 0xF57C0FAF );
155 P( D, A, B, C, 5, 12, 0x4787C62A );
156 P( C, D, A, B, 6, 17, 0xA8304613 );
157 P( B, C, D, A, 7, 22, 0xFD469501 );
158 P( A, B, C, D, 8, 7, 0x698098D8 );
159 P( D, A, B, C, 9, 12, 0x8B44F7AF );
160 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
161 P( B, C, D, A, 11, 22, 0x895CD7BE );
162 P( A, B, C, D, 12, 7, 0x6B901122 );
163 P( D, A, B, C, 13, 12, 0xFD987193 );
164 P( C, D, A, B, 14, 17, 0xA679438E );
165 P( B, C, D, A, 15, 22, 0x49B40821 );
166
167#undef F
168
169#define F(x,y,z) (y ^ (z & (x ^ y)))
170
171 P( A, B, C, D, 1, 5, 0xF61E2562 );
172 P( D, A, B, C, 6, 9, 0xC040B340 );
173 P( C, D, A, B, 11, 14, 0x265E5A51 );
174 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
175 P( A, B, C, D, 5, 5, 0xD62F105D );
176 P( D, A, B, C, 10, 9, 0x02441453 );
177 P( C, D, A, B, 15, 14, 0xD8A1E681 );
178 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
179 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
180 P( D, A, B, C, 14, 9, 0xC33707D6 );
181 P( C, D, A, B, 3, 14, 0xF4D50D87 );
182 P( B, C, D, A, 8, 20, 0x455A14ED );
183 P( A, B, C, D, 13, 5, 0xA9E3E905 );
184 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
185 P( C, D, A, B, 7, 14, 0x676F02D9 );
186 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
187
188#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200189
Paul Bakker5121ce52009-01-03 21:22:43 +0000190#define F(x,y,z) (x ^ y ^ z)
191
192 P( A, B, C, D, 5, 4, 0xFFFA3942 );
193 P( D, A, B, C, 8, 11, 0x8771F681 );
194 P( C, D, A, B, 11, 16, 0x6D9D6122 );
195 P( B, C, D, A, 14, 23, 0xFDE5380C );
196 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
197 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
198 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
199 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
200 P( A, B, C, D, 13, 4, 0x289B7EC6 );
201 P( D, A, B, C, 0, 11, 0xEAA127FA );
202 P( C, D, A, B, 3, 16, 0xD4EF3085 );
203 P( B, C, D, A, 6, 23, 0x04881D05 );
204 P( A, B, C, D, 9, 4, 0xD9D4D039 );
205 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
206 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
207 P( B, C, D, A, 2, 23, 0xC4AC5665 );
208
209#undef F
210
211#define F(x,y,z) (y ^ (x | ~z))
212
213 P( A, B, C, D, 0, 6, 0xF4292244 );
214 P( D, A, B, C, 7, 10, 0x432AFF97 );
215 P( C, D, A, B, 14, 15, 0xAB9423A7 );
216 P( B, C, D, A, 5, 21, 0xFC93A039 );
217 P( A, B, C, D, 12, 6, 0x655B59C3 );
218 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
219 P( C, D, A, B, 10, 15, 0xFFEFF47D );
220 P( B, C, D, A, 1, 21, 0x85845DD1 );
221 P( A, B, C, D, 8, 6, 0x6FA87E4F );
222 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
223 P( C, D, A, B, 6, 15, 0xA3014314 );
224 P( B, C, D, A, 13, 21, 0x4E0811A1 );
225 P( A, B, C, D, 4, 6, 0xF7537E82 );
226 P( D, A, B, C, 11, 10, 0xBD3AF235 );
227 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
228 P( B, C, D, A, 9, 21, 0xEB86D391 );
229
230#undef F
231
232 ctx->state[0] += A;
233 ctx->state[1] += B;
234 ctx->state[2] += C;
235 ctx->state[3] += D;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100236
237 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000238}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200239#endif /* !MBEDTLS_MD5_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000240
241/*
242 * MD5 process buffer
243 */
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100244int mbedtls_md5_update_ext( mbedtls_md5_context *ctx,
245 const unsigned char *input,
246 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000247{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100248 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000249 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000250 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
Brian White12895d12014-04-11 11:29:42 -0400252 if( ilen == 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100253 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
255 left = ctx->total[0] & 0x3F;
256 fill = 64 - left;
257
Paul Bakker5c2364c2012-10-01 14:41:15 +0000258 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000259 ctx->total[0] &= 0xFFFFFFFF;
260
Paul Bakker5c2364c2012-10-01 14:41:15 +0000261 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000262 ctx->total[1]++;
263
264 if( left && ilen >= fill )
265 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200266 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100267 if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100268 return( ret );
269
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 input += fill;
271 ilen -= fill;
272 left = 0;
273 }
274
275 while( ilen >= 64 )
276 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100277 if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100278 return( ret );
279
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 input += 64;
281 ilen -= 64;
282 }
283
284 if( ilen > 0 )
285 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200286 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 }
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100288
289 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000290}
291
292static const unsigned char md5_padding[64] =
293{
294 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
295 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
296 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
297 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
298};
299
300/*
301 * MD5 final digest
302 */
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100303int mbedtls_md5_finish_ext( mbedtls_md5_context *ctx,
304 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000305{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100306 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000307 uint32_t last, padn;
308 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000309 unsigned char msglen[8];
310
311 high = ( ctx->total[0] >> 29 )
312 | ( ctx->total[1] << 3 );
313 low = ( ctx->total[0] << 3 );
314
Paul Bakker5c2364c2012-10-01 14:41:15 +0000315 PUT_UINT32_LE( low, msglen, 0 );
316 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
318 last = ctx->total[0] & 0x3F;
319 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
320
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100321 if( ( ret = mbedtls_md5_update_ext( ctx, md5_padding, padn ) ) != 0 )
322 return( ret );
323
324 if( ( ret = mbedtls_md5_update_ext( ctx, msglen, 8 ) ) != 0 )
325 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
Paul Bakker5c2364c2012-10-01 14:41:15 +0000327 PUT_UINT32_LE( ctx->state[0], output, 0 );
328 PUT_UINT32_LE( ctx->state[1], output, 4 );
329 PUT_UINT32_LE( ctx->state[2], output, 8 );
330 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100331
332 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333}
334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335#endif /* !MBEDTLS_MD5_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200336
Paul Bakker5121ce52009-01-03 21:22:43 +0000337/*
338 * output = MD5( input buffer )
339 */
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100340int mbedtls_md5_ext( const unsigned char *input,
341 size_t ilen,
342 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000343{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100344 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345 mbedtls_md5_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347 mbedtls_md5_init( &ctx );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100348
349 if( ( ret = mbedtls_md5_starts_ext( &ctx ) ) != 0 )
350 return( ret );
351
352 if( ( ret = mbedtls_md5_update_ext( &ctx, input, ilen ) ) != 0 )
353 return( ret );
354
355 if( ( ret = mbedtls_md5_finish_ext( &ctx, output ) ) != 0 )
356 return( ret );
357
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200358 mbedtls_md5_free( &ctx );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100359
360 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000361}
362
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
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100415 if( mbedtls_md5_ext( md5_test_buf[i],
416 md5_test_buflen[i], md5sum ) != 0 )
417 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
419 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100420 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
422 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 }
425
426 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000428
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 return( 0 );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100430
431fail:
432 if( verbose != 0 )
433 mbedtls_printf( "failed\n" );
434
435 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000436}
437
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200438#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200440#endif /* MBEDTLS_MD5_C */