blob: 8238c2b81a4a11d842a44d6e9c5c3dce0f1e6f07 [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"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050036#include "mbedtls/platform_util.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_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#define mbedtls_printf printf
46#endif /* MBEDTLS_PLATFORM_C */
47#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020049#if !defined(MBEDTLS_MD5_ALT)
50
Paul Bakker5121ce52009-01-03 21:22:43 +000051/*
52 * 32-bit integer manipulation macros (little endian)
53 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000054#ifndef GET_UINT32_LE
55#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000056{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000057 (n) = ( (uint32_t) (b)[(i) ] ) \
58 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
59 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
60 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000061}
62#endif
63
Paul Bakker5c2364c2012-10-01 14:41:15 +000064#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000065#define PUT_UINT32_LE(n,b,i) \
66{ \
67 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
68 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
69 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
70 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000071}
72#endif
73
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074void mbedtls_md5_init( mbedtls_md5_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020075{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076 memset( ctx, 0, sizeof( mbedtls_md5_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020077}
78
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079void mbedtls_md5_free( mbedtls_md5_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020080{
81 if( ctx == NULL )
82 return;
83
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050084 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md5_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020085}
86
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020087void mbedtls_md5_clone( mbedtls_md5_context *dst,
88 const mbedtls_md5_context *src )
89{
90 *dst = *src;
91}
92
Paul Bakker5121ce52009-01-03 21:22:43 +000093/*
94 * MD5 context setup
95 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010096int mbedtls_md5_starts_ret( mbedtls_md5_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +000097{
98 ctx->total[0] = 0;
99 ctx->total[1] = 0;
100
101 ctx->state[0] = 0x67452301;
102 ctx->state[1] = 0xEFCDAB89;
103 ctx->state[2] = 0x98BADCFE;
104 ctx->state[3] = 0x10325476;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100105
106 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107}
108
Jaeden Amero041039f2018-02-19 15:28:08 +0000109#if !defined(MBEDTLS_DEPRECATED_REMOVED)
110void mbedtls_md5_starts( mbedtls_md5_context *ctx )
111{
112 mbedtls_md5_starts_ret( ctx );
113}
114#endif
115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116#if !defined(MBEDTLS_MD5_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100117int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
118 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000119{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000120 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000121
Paul Bakker5c2364c2012-10-01 14:41:15 +0000122 GET_UINT32_LE( X[ 0], data, 0 );
123 GET_UINT32_LE( X[ 1], data, 4 );
124 GET_UINT32_LE( X[ 2], data, 8 );
125 GET_UINT32_LE( X[ 3], data, 12 );
126 GET_UINT32_LE( X[ 4], data, 16 );
127 GET_UINT32_LE( X[ 5], data, 20 );
128 GET_UINT32_LE( X[ 6], data, 24 );
129 GET_UINT32_LE( X[ 7], data, 28 );
130 GET_UINT32_LE( X[ 8], data, 32 );
131 GET_UINT32_LE( X[ 9], data, 36 );
132 GET_UINT32_LE( X[10], data, 40 );
133 GET_UINT32_LE( X[11], data, 44 );
134 GET_UINT32_LE( X[12], data, 48 );
135 GET_UINT32_LE( X[13], data, 52 );
136 GET_UINT32_LE( X[14], data, 56 );
137 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000138
139#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
140
141#define P(a,b,c,d,k,s,t) \
142{ \
143 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
144}
145
146 A = ctx->state[0];
147 B = ctx->state[1];
148 C = ctx->state[2];
149 D = ctx->state[3];
150
151#define F(x,y,z) (z ^ (x & (y ^ z)))
152
153 P( A, B, C, D, 0, 7, 0xD76AA478 );
154 P( D, A, B, C, 1, 12, 0xE8C7B756 );
155 P( C, D, A, B, 2, 17, 0x242070DB );
156 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
157 P( A, B, C, D, 4, 7, 0xF57C0FAF );
158 P( D, A, B, C, 5, 12, 0x4787C62A );
159 P( C, D, A, B, 6, 17, 0xA8304613 );
160 P( B, C, D, A, 7, 22, 0xFD469501 );
161 P( A, B, C, D, 8, 7, 0x698098D8 );
162 P( D, A, B, C, 9, 12, 0x8B44F7AF );
163 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
164 P( B, C, D, A, 11, 22, 0x895CD7BE );
165 P( A, B, C, D, 12, 7, 0x6B901122 );
166 P( D, A, B, C, 13, 12, 0xFD987193 );
167 P( C, D, A, B, 14, 17, 0xA679438E );
168 P( B, C, D, A, 15, 22, 0x49B40821 );
169
170#undef F
171
172#define F(x,y,z) (y ^ (z & (x ^ y)))
173
174 P( A, B, C, D, 1, 5, 0xF61E2562 );
175 P( D, A, B, C, 6, 9, 0xC040B340 );
176 P( C, D, A, B, 11, 14, 0x265E5A51 );
177 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
178 P( A, B, C, D, 5, 5, 0xD62F105D );
179 P( D, A, B, C, 10, 9, 0x02441453 );
180 P( C, D, A, B, 15, 14, 0xD8A1E681 );
181 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
182 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
183 P( D, A, B, C, 14, 9, 0xC33707D6 );
184 P( C, D, A, B, 3, 14, 0xF4D50D87 );
185 P( B, C, D, A, 8, 20, 0x455A14ED );
186 P( A, B, C, D, 13, 5, 0xA9E3E905 );
187 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
188 P( C, D, A, B, 7, 14, 0x676F02D9 );
189 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
190
191#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200192
Paul Bakker5121ce52009-01-03 21:22:43 +0000193#define F(x,y,z) (x ^ y ^ z)
194
195 P( A, B, C, D, 5, 4, 0xFFFA3942 );
196 P( D, A, B, C, 8, 11, 0x8771F681 );
197 P( C, D, A, B, 11, 16, 0x6D9D6122 );
198 P( B, C, D, A, 14, 23, 0xFDE5380C );
199 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
200 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
201 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
202 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
203 P( A, B, C, D, 13, 4, 0x289B7EC6 );
204 P( D, A, B, C, 0, 11, 0xEAA127FA );
205 P( C, D, A, B, 3, 16, 0xD4EF3085 );
206 P( B, C, D, A, 6, 23, 0x04881D05 );
207 P( A, B, C, D, 9, 4, 0xD9D4D039 );
208 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
209 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
210 P( B, C, D, A, 2, 23, 0xC4AC5665 );
211
212#undef F
213
214#define F(x,y,z) (y ^ (x | ~z))
215
216 P( A, B, C, D, 0, 6, 0xF4292244 );
217 P( D, A, B, C, 7, 10, 0x432AFF97 );
218 P( C, D, A, B, 14, 15, 0xAB9423A7 );
219 P( B, C, D, A, 5, 21, 0xFC93A039 );
220 P( A, B, C, D, 12, 6, 0x655B59C3 );
221 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
222 P( C, D, A, B, 10, 15, 0xFFEFF47D );
223 P( B, C, D, A, 1, 21, 0x85845DD1 );
224 P( A, B, C, D, 8, 6, 0x6FA87E4F );
225 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
226 P( C, D, A, B, 6, 15, 0xA3014314 );
227 P( B, C, D, A, 13, 21, 0x4E0811A1 );
228 P( A, B, C, D, 4, 6, 0xF7537E82 );
229 P( D, A, B, C, 11, 10, 0xBD3AF235 );
230 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
231 P( B, C, D, A, 9, 21, 0xEB86D391 );
232
233#undef F
234
235 ctx->state[0] += A;
236 ctx->state[1] += B;
237 ctx->state[2] += C;
238 ctx->state[3] += D;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100239
240 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000241}
Jaeden Amero041039f2018-02-19 15:28:08 +0000242
243#if !defined(MBEDTLS_DEPRECATED_REMOVED)
244void mbedtls_md5_process( mbedtls_md5_context *ctx,
245 const unsigned char data[64] )
246{
247 mbedtls_internal_md5_process( ctx, data );
248}
249#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250#endif /* !MBEDTLS_MD5_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
252/*
253 * MD5 process buffer
254 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100255int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100256 const unsigned char *input,
257 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000258{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100259 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000260 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000261 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
Brian White12895d12014-04-11 11:29:42 -0400263 if( ilen == 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100264 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000265
266 left = ctx->total[0] & 0x3F;
267 fill = 64 - left;
268
Paul Bakker5c2364c2012-10-01 14:41:15 +0000269 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 ctx->total[0] &= 0xFFFFFFFF;
271
Paul Bakker5c2364c2012-10-01 14:41:15 +0000272 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 ctx->total[1]++;
274
275 if( left && ilen >= fill )
276 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200277 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100278 if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100279 return( ret );
280
Paul Bakker5121ce52009-01-03 21:22:43 +0000281 input += fill;
282 ilen -= fill;
283 left = 0;
284 }
285
286 while( ilen >= 64 )
287 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100288 if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100289 return( ret );
290
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 input += 64;
292 ilen -= 64;
293 }
294
295 if( ilen > 0 )
296 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200297 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 }
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100299
300 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000301}
302
Jaeden Amero041039f2018-02-19 15:28:08 +0000303#if !defined(MBEDTLS_DEPRECATED_REMOVED)
304void mbedtls_md5_update( mbedtls_md5_context *ctx,
305 const unsigned char *input,
306 size_t ilen )
307{
308 mbedtls_md5_update_ret( ctx, input, ilen );
309}
310#endif
311
Paul Bakker5121ce52009-01-03 21:22:43 +0000312static const unsigned char md5_padding[64] =
313{
314 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
315 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
318};
319
320/*
321 * MD5 final digest
322 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100323int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100324 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000325{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100326 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000327 uint32_t last, padn;
328 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 unsigned char msglen[8];
330
331 high = ( ctx->total[0] >> 29 )
332 | ( ctx->total[1] << 3 );
333 low = ( ctx->total[0] << 3 );
334
Paul Bakker5c2364c2012-10-01 14:41:15 +0000335 PUT_UINT32_LE( low, msglen, 0 );
336 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
338 last = ctx->total[0] & 0x3F;
339 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
340
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100341 if( ( ret = mbedtls_md5_update_ret( ctx, md5_padding, padn ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100342 return( ret );
343
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100344 if( ( ret = mbedtls_md5_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100345 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347 PUT_UINT32_LE( ctx->state[0], output, 0 );
348 PUT_UINT32_LE( ctx->state[1], output, 4 );
349 PUT_UINT32_LE( ctx->state[2], output, 8 );
350 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100351
352 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000353}
354
Jaeden Amero041039f2018-02-19 15:28:08 +0000355#if !defined(MBEDTLS_DEPRECATED_REMOVED)
356void mbedtls_md5_finish( mbedtls_md5_context *ctx,
357 unsigned char output[16] )
358{
359 mbedtls_md5_finish_ret( ctx, output );
360}
361#endif
362
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363#endif /* !MBEDTLS_MD5_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200364
Paul Bakker5121ce52009-01-03 21:22:43 +0000365/*
366 * output = MD5( input buffer )
367 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100368int mbedtls_md5_ret( const unsigned char *input,
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100369 size_t ilen,
370 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000371{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100372 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200373 mbedtls_md5_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000374
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 mbedtls_md5_init( &ctx );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100376
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100377 if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100378 goto exit;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100379
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100380 if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100381 goto exit;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100382
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100383 if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100384 goto exit;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100385
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100386exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387 mbedtls_md5_free( &ctx );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100388
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100389 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000390}
391
Jaeden Amero041039f2018-02-19 15:28:08 +0000392#if !defined(MBEDTLS_DEPRECATED_REMOVED)
393void mbedtls_md5( const unsigned char *input,
394 size_t ilen,
395 unsigned char output[16] )
396{
397 mbedtls_md5_ret( input, ilen, output );
398}
399#endif
400
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000402/*
403 * RFC 1321 test vectors
404 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000405static const unsigned char md5_test_buf[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000406{
Paul Bakker9af723c2014-05-01 13:03:14 +0200407 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 { "a" },
409 { "abc" },
410 { "message digest" },
411 { "abcdefghijklmnopqrstuvwxyz" },
412 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100413 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 "345678901234567890" }
415};
416
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100417static const size_t md5_test_buflen[7] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000418{
419 0, 1, 3, 14, 26, 62, 80
420};
421
422static const unsigned char md5_test_sum[7][16] =
423{
424 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
425 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
426 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
427 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
428 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
429 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
430 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
431 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
432 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
433 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
434 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
435 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
436 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
437 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
438};
439
440/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000441 * Checkup routine
442 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443int mbedtls_md5_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000444{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100445 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 unsigned char md5sum[16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
448 for( i = 0; i < 7; i++ )
449 {
450 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 mbedtls_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100453 ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100454 if( ret != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100455 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100458 {
459 ret = 1;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100460 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100461 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000465 }
466
467 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
Paul Bakker5121ce52009-01-03 21:22:43 +0000470 return( 0 );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100471
472fail:
473 if( verbose != 0 )
474 mbedtls_printf( "failed\n" );
475
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100476 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477}
478
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481#endif /* MBEDTLS_MD5_C */