blob: 8440ebffcfadc080e0219252427ffb6c959c08ec [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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100100int mbedtls_md5_starts_ret( 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
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000113#if !defined(MBEDTLS_DEPRECATED_REMOVED)
114void mbedtls_md5_starts( mbedtls_md5_context *ctx )
115{
116 mbedtls_md5_starts_ret( ctx );
117}
118#endif
119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120#if !defined(MBEDTLS_MD5_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100121int mbedtls_internal_md5_process( mbedtls_md5_context *ctx,
122 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000123{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000124 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000125
Paul Bakker5c2364c2012-10-01 14:41:15 +0000126 GET_UINT32_LE( X[ 0], data, 0 );
127 GET_UINT32_LE( X[ 1], data, 4 );
128 GET_UINT32_LE( X[ 2], data, 8 );
129 GET_UINT32_LE( X[ 3], data, 12 );
130 GET_UINT32_LE( X[ 4], data, 16 );
131 GET_UINT32_LE( X[ 5], data, 20 );
132 GET_UINT32_LE( X[ 6], data, 24 );
133 GET_UINT32_LE( X[ 7], data, 28 );
134 GET_UINT32_LE( X[ 8], data, 32 );
135 GET_UINT32_LE( X[ 9], data, 36 );
136 GET_UINT32_LE( X[10], data, 40 );
137 GET_UINT32_LE( X[11], data, 44 );
138 GET_UINT32_LE( X[12], data, 48 );
139 GET_UINT32_LE( X[13], data, 52 );
140 GET_UINT32_LE( X[14], data, 56 );
141 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000142
143#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
144
145#define P(a,b,c,d,k,s,t) \
146{ \
147 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \
148}
149
150 A = ctx->state[0];
151 B = ctx->state[1];
152 C = ctx->state[2];
153 D = ctx->state[3];
154
155#define F(x,y,z) (z ^ (x & (y ^ z)))
156
157 P( A, B, C, D, 0, 7, 0xD76AA478 );
158 P( D, A, B, C, 1, 12, 0xE8C7B756 );
159 P( C, D, A, B, 2, 17, 0x242070DB );
160 P( B, C, D, A, 3, 22, 0xC1BDCEEE );
161 P( A, B, C, D, 4, 7, 0xF57C0FAF );
162 P( D, A, B, C, 5, 12, 0x4787C62A );
163 P( C, D, A, B, 6, 17, 0xA8304613 );
164 P( B, C, D, A, 7, 22, 0xFD469501 );
165 P( A, B, C, D, 8, 7, 0x698098D8 );
166 P( D, A, B, C, 9, 12, 0x8B44F7AF );
167 P( C, D, A, B, 10, 17, 0xFFFF5BB1 );
168 P( B, C, D, A, 11, 22, 0x895CD7BE );
169 P( A, B, C, D, 12, 7, 0x6B901122 );
170 P( D, A, B, C, 13, 12, 0xFD987193 );
171 P( C, D, A, B, 14, 17, 0xA679438E );
172 P( B, C, D, A, 15, 22, 0x49B40821 );
173
174#undef F
175
176#define F(x,y,z) (y ^ (z & (x ^ y)))
177
178 P( A, B, C, D, 1, 5, 0xF61E2562 );
179 P( D, A, B, C, 6, 9, 0xC040B340 );
180 P( C, D, A, B, 11, 14, 0x265E5A51 );
181 P( B, C, D, A, 0, 20, 0xE9B6C7AA );
182 P( A, B, C, D, 5, 5, 0xD62F105D );
183 P( D, A, B, C, 10, 9, 0x02441453 );
184 P( C, D, A, B, 15, 14, 0xD8A1E681 );
185 P( B, C, D, A, 4, 20, 0xE7D3FBC8 );
186 P( A, B, C, D, 9, 5, 0x21E1CDE6 );
187 P( D, A, B, C, 14, 9, 0xC33707D6 );
188 P( C, D, A, B, 3, 14, 0xF4D50D87 );
189 P( B, C, D, A, 8, 20, 0x455A14ED );
190 P( A, B, C, D, 13, 5, 0xA9E3E905 );
191 P( D, A, B, C, 2, 9, 0xFCEFA3F8 );
192 P( C, D, A, B, 7, 14, 0x676F02D9 );
193 P( B, C, D, A, 12, 20, 0x8D2A4C8A );
194
195#undef F
Paul Bakker9af723c2014-05-01 13:03:14 +0200196
Paul Bakker5121ce52009-01-03 21:22:43 +0000197#define F(x,y,z) (x ^ y ^ z)
198
199 P( A, B, C, D, 5, 4, 0xFFFA3942 );
200 P( D, A, B, C, 8, 11, 0x8771F681 );
201 P( C, D, A, B, 11, 16, 0x6D9D6122 );
202 P( B, C, D, A, 14, 23, 0xFDE5380C );
203 P( A, B, C, D, 1, 4, 0xA4BEEA44 );
204 P( D, A, B, C, 4, 11, 0x4BDECFA9 );
205 P( C, D, A, B, 7, 16, 0xF6BB4B60 );
206 P( B, C, D, A, 10, 23, 0xBEBFBC70 );
207 P( A, B, C, D, 13, 4, 0x289B7EC6 );
208 P( D, A, B, C, 0, 11, 0xEAA127FA );
209 P( C, D, A, B, 3, 16, 0xD4EF3085 );
210 P( B, C, D, A, 6, 23, 0x04881D05 );
211 P( A, B, C, D, 9, 4, 0xD9D4D039 );
212 P( D, A, B, C, 12, 11, 0xE6DB99E5 );
213 P( C, D, A, B, 15, 16, 0x1FA27CF8 );
214 P( B, C, D, A, 2, 23, 0xC4AC5665 );
215
216#undef F
217
218#define F(x,y,z) (y ^ (x | ~z))
219
220 P( A, B, C, D, 0, 6, 0xF4292244 );
221 P( D, A, B, C, 7, 10, 0x432AFF97 );
222 P( C, D, A, B, 14, 15, 0xAB9423A7 );
223 P( B, C, D, A, 5, 21, 0xFC93A039 );
224 P( A, B, C, D, 12, 6, 0x655B59C3 );
225 P( D, A, B, C, 3, 10, 0x8F0CCC92 );
226 P( C, D, A, B, 10, 15, 0xFFEFF47D );
227 P( B, C, D, A, 1, 21, 0x85845DD1 );
228 P( A, B, C, D, 8, 6, 0x6FA87E4F );
229 P( D, A, B, C, 15, 10, 0xFE2CE6E0 );
230 P( C, D, A, B, 6, 15, 0xA3014314 );
231 P( B, C, D, A, 13, 21, 0x4E0811A1 );
232 P( A, B, C, D, 4, 6, 0xF7537E82 );
233 P( D, A, B, C, 11, 10, 0xBD3AF235 );
234 P( C, D, A, B, 2, 15, 0x2AD7D2BB );
235 P( B, C, D, A, 9, 21, 0xEB86D391 );
236
237#undef F
238
239 ctx->state[0] += A;
240 ctx->state[1] += B;
241 ctx->state[2] += C;
242 ctx->state[3] += D;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100243
244 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000245}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000246
247#if !defined(MBEDTLS_DEPRECATED_REMOVED)
248void mbedtls_md5_process( mbedtls_md5_context *ctx,
249 const unsigned char data[64] )
250{
251 mbedtls_internal_md5_process( ctx, data );
252}
253#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200254#endif /* !MBEDTLS_MD5_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000255
256/*
257 * MD5 process buffer
258 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100259int mbedtls_md5_update_ret( mbedtls_md5_context *ctx,
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100260 const unsigned char *input,
261 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000262{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100263 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000264 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000265 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
Brian White12895d12014-04-11 11:29:42 -0400267 if( ilen == 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100268 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000269
270 left = ctx->total[0] & 0x3F;
271 fill = 64 - left;
272
Paul Bakker5c2364c2012-10-01 14:41:15 +0000273 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000274 ctx->total[0] &= 0xFFFFFFFF;
275
Paul Bakker5c2364c2012-10-01 14:41:15 +0000276 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 ctx->total[1]++;
278
279 if( left && ilen >= fill )
280 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200281 memcpy( (void *) (ctx->buffer + left), input, fill );
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100282 if( ( ret = mbedtls_internal_md5_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100283 return( ret );
284
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 input += fill;
286 ilen -= fill;
287 left = 0;
288 }
289
290 while( ilen >= 64 )
291 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100292 if( ( ret = mbedtls_internal_md5_process( ctx, input ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100293 return( ret );
294
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 input += 64;
296 ilen -= 64;
297 }
298
299 if( ilen > 0 )
300 {
Paul Bakker3c2122f2013-06-24 19:03:14 +0200301 memcpy( (void *) (ctx->buffer + left), input, ilen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302 }
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100303
304 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000305}
306
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000307#if !defined(MBEDTLS_DEPRECATED_REMOVED)
308void mbedtls_md5_update( mbedtls_md5_context *ctx,
309 const unsigned char *input,
310 size_t ilen )
311{
312 mbedtls_md5_update_ret( ctx, input, ilen );
313}
314#endif
315
Paul Bakker5121ce52009-01-03 21:22:43 +0000316static const unsigned char md5_padding[64] =
317{
318 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
319 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
320 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
321 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
322};
323
324/*
325 * MD5 final digest
326 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100327int mbedtls_md5_finish_ret( mbedtls_md5_context *ctx,
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100328 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000329{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100330 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000331 uint32_t last, padn;
332 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000333 unsigned char msglen[8];
334
335 high = ( ctx->total[0] >> 29 )
336 | ( ctx->total[1] << 3 );
337 low = ( ctx->total[0] << 3 );
338
Paul Bakker5c2364c2012-10-01 14:41:15 +0000339 PUT_UINT32_LE( low, msglen, 0 );
340 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342 last = ctx->total[0] & 0x3F;
343 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
344
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100345 if( ( ret = mbedtls_md5_update_ret( ctx, md5_padding, padn ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100346 return( ret );
347
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100348 if( ( ret = mbedtls_md5_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100349 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
Paul Bakker5c2364c2012-10-01 14:41:15 +0000351 PUT_UINT32_LE( ctx->state[0], output, 0 );
352 PUT_UINT32_LE( ctx->state[1], output, 4 );
353 PUT_UINT32_LE( ctx->state[2], output, 8 );
354 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100355
356 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000357}
358
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000359#if !defined(MBEDTLS_DEPRECATED_REMOVED)
360void mbedtls_md5_finish( mbedtls_md5_context *ctx,
361 unsigned char output[16] )
362{
363 mbedtls_md5_finish_ret( ctx, output );
364}
365#endif
366
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200367#endif /* !MBEDTLS_MD5_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200368
Paul Bakker5121ce52009-01-03 21:22:43 +0000369/*
370 * output = MD5( input buffer )
371 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100372int mbedtls_md5_ret( const unsigned char *input,
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100373 size_t ilen,
374 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000375{
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100376 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_md5_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000378
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200379 mbedtls_md5_init( &ctx );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100380
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100381 if( ( ret = mbedtls_md5_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100382 goto exit;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100383
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100384 if( ( ret = mbedtls_md5_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100385 goto exit;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100386
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100387 if( ( ret = mbedtls_md5_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100388 goto exit;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100389
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100390exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391 mbedtls_md5_free( &ctx );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100392
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100393 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000394}
395
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000396#if !defined(MBEDTLS_DEPRECATED_REMOVED)
397void mbedtls_md5( const unsigned char *input,
398 size_t ilen,
399 unsigned char output[16] )
400{
401 mbedtls_md5_ret( input, ilen, output );
402}
403#endif
404
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000406/*
407 * RFC 1321 test vectors
408 */
Manuel Pégourié-Gonnard28122e42015-03-11 09:13:42 +0000409static const unsigned char md5_test_buf[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000410{
Paul Bakker9af723c2014-05-01 13:03:14 +0200411 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 { "a" },
413 { "abc" },
414 { "message digest" },
415 { "abcdefghijklmnopqrstuvwxyz" },
416 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100417 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 "345678901234567890" }
419};
420
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100421static const size_t md5_test_buflen[7] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000422{
423 0, 1, 3, 14, 26, 62, 80
424};
425
426static const unsigned char md5_test_sum[7][16] =
427{
428 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04,
429 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E },
430 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8,
431 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 },
432 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0,
433 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 },
434 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D,
435 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 },
436 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00,
437 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B },
438 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5,
439 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F },
440 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55,
441 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A }
442};
443
444/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000445 * Checkup routine
446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447int mbedtls_md5_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000448{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100449 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 unsigned char md5sum[16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
452 for( i = 0; i < 7; i++ )
453 {
454 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 mbedtls_printf( " MD5 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100457 ret = mbedtls_md5_ret( md5_test_buf[i], md5_test_buflen[i], md5sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100458 if( ret != 0 )
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100459 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100462 {
463 ret = 1;
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100464 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100465 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000466
467 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469 }
470
471 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
Paul Bakker5121ce52009-01-03 21:22:43 +0000474 return( 0 );
Andres Amaya Garcia2cfd7a92017-05-02 10:19:27 +0100475
476fail:
477 if( verbose != 0 )
478 mbedtls_printf( "failed\n" );
479
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100480 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000481}
482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200483#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200485#endif /* MBEDTLS_MD5_C */