blob: 56b359ce3491d0a84253e5a2072ae390f3bea696 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Bence Szépkútif744bd72020-06-05 13:02:18 +02005 * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6 *
7 * This file is provided under the Apache License 2.0, or the
8 * GNU General Public License v2.0 or later.
9 *
10 * **********
11 * Apache License 2.0:
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +020012 *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may
14 * not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
Paul Bakkerb96f1542010-07-18 20:36:00 +000024 *
Bence Szépkútif744bd72020-06-05 13:02:18 +020025 * **********
26 *
27 * **********
28 * GNU General Public License v2.0 or later:
29 *
30 * This program is free software; you can redistribute it and/or modify
31 * it under the terms of the GNU General Public License as published by
32 * the Free Software Foundation; either version 2 of the License, or
33 * (at your option) any later version.
34 *
35 * This program is distributed in the hope that it will be useful,
36 * but WITHOUT ANY WARRANTY; without even the implied warranty of
37 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38 * GNU General Public License for more details.
39 *
40 * You should have received a copy of the GNU General Public License along
41 * with this program; if not, write to the Free Software Foundation, Inc.,
42 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43 *
44 * **********
45 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000046 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000047 */
48/*
49 * The MD4 algorithm was designed by Ron Rivest in 1990.
50 *
51 * http://www.ietf.org/rfc/rfc1186.txt
52 * http://www.ietf.org/rfc/rfc1320.txt
53 */
54
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020055#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000056#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020058#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020059#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000060
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020061#if defined(MBEDTLS_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000062
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000063#include "mbedtls/md4.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050064#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000065
Rich Evans00ab4702015-02-06 13:43:58 +000066#include <string.h>
67
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020068#if defined(MBEDTLS_SELF_TEST)
69#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000070#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010071#else
Rich Evans00ab4702015-02-06 13:43:58 +000072#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020073#define mbedtls_printf printf
74#endif /* MBEDTLS_PLATFORM_C */
75#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010076
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020077#if !defined(MBEDTLS_MD4_ALT)
78
Paul Bakker5121ce52009-01-03 21:22:43 +000079/*
80 * 32-bit integer manipulation macros (little endian)
81 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000082#ifndef GET_UINT32_LE
83#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000084{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000085 (n) = ( (uint32_t) (b)[(i) ] ) \
86 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
87 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
88 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000089}
90#endif
91
Paul Bakker5c2364c2012-10-01 14:41:15 +000092#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000093#define PUT_UINT32_LE(n,b,i) \
94{ \
95 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
96 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
97 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
98 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000099}
100#endif
101
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200103{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200105}
106
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200107void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200108{
109 if( ctx == NULL )
110 return;
111
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500112 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200113}
114
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200115void mbedtls_md4_clone( mbedtls_md4_context *dst,
116 const mbedtls_md4_context *src )
117{
118 *dst = *src;
119}
120
Paul Bakker5121ce52009-01-03 21:22:43 +0000121/*
122 * MD4 context setup
123 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100124int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000125{
126 ctx->total[0] = 0;
127 ctx->total[1] = 0;
128
129 ctx->state[0] = 0x67452301;
130 ctx->state[1] = 0xEFCDAB89;
131 ctx->state[2] = 0x98BADCFE;
132 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100133
134 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000135}
136
Jaeden Amero041039f2018-02-19 15:28:08 +0000137#if !defined(MBEDTLS_DEPRECATED_REMOVED)
138void mbedtls_md4_starts( mbedtls_md4_context *ctx )
139{
140 mbedtls_md4_starts_ret( ctx );
141}
142#endif
143
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200144#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100145int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
146 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000147{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000148 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000149
Paul Bakker5c2364c2012-10-01 14:41:15 +0000150 GET_UINT32_LE( X[ 0], data, 0 );
151 GET_UINT32_LE( X[ 1], data, 4 );
152 GET_UINT32_LE( X[ 2], data, 8 );
153 GET_UINT32_LE( X[ 3], data, 12 );
154 GET_UINT32_LE( X[ 4], data, 16 );
155 GET_UINT32_LE( X[ 5], data, 20 );
156 GET_UINT32_LE( X[ 6], data, 24 );
157 GET_UINT32_LE( X[ 7], data, 28 );
158 GET_UINT32_LE( X[ 8], data, 32 );
159 GET_UINT32_LE( X[ 9], data, 36 );
160 GET_UINT32_LE( X[10], data, 40 );
161 GET_UINT32_LE( X[11], data, 44 );
162 GET_UINT32_LE( X[12], data, 48 );
163 GET_UINT32_LE( X[13], data, 52 );
164 GET_UINT32_LE( X[14], data, 56 );
165 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000166
Hanno Beckerd6028a12018-10-15 12:01:35 +0100167#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
169 A = ctx->state[0];
170 B = ctx->state[1];
171 C = ctx->state[2];
172 D = ctx->state[3];
173
Hanno Beckerd6028a12018-10-15 12:01:35 +0100174#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
Hanno Becker9306f1c2018-10-30 09:29:25 +0000175#define P(a,b,c,d,x,s) \
176 do \
177 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100178 (a) += F((b),(c),(d)) + (x); \
179 (a) = S((a),(s)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100180 } while( 0 )
181
Paul Bakker5121ce52009-01-03 21:22:43 +0000182
183 P( A, B, C, D, X[ 0], 3 );
184 P( D, A, B, C, X[ 1], 7 );
185 P( C, D, A, B, X[ 2], 11 );
186 P( B, C, D, A, X[ 3], 19 );
187 P( A, B, C, D, X[ 4], 3 );
188 P( D, A, B, C, X[ 5], 7 );
189 P( C, D, A, B, X[ 6], 11 );
190 P( B, C, D, A, X[ 7], 19 );
191 P( A, B, C, D, X[ 8], 3 );
192 P( D, A, B, C, X[ 9], 7 );
193 P( C, D, A, B, X[10], 11 );
194 P( B, C, D, A, X[11], 19 );
195 P( A, B, C, D, X[12], 3 );
196 P( D, A, B, C, X[13], 7 );
197 P( C, D, A, B, X[14], 11 );
198 P( B, C, D, A, X[15], 19 );
199
200#undef P
201#undef F
202
Hanno Beckerd6028a12018-10-15 12:01:35 +0100203#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
204#define P(a,b,c,d,x,s) \
205 do \
206 { \
Hanno Becker9306f1c2018-10-30 09:29:25 +0000207 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
208 (a) = S((a),(s)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100209 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000210
211 P( A, B, C, D, X[ 0], 3 );
212 P( D, A, B, C, X[ 4], 5 );
213 P( C, D, A, B, X[ 8], 9 );
214 P( B, C, D, A, X[12], 13 );
215 P( A, B, C, D, X[ 1], 3 );
216 P( D, A, B, C, X[ 5], 5 );
217 P( C, D, A, B, X[ 9], 9 );
218 P( B, C, D, A, X[13], 13 );
219 P( A, B, C, D, X[ 2], 3 );
220 P( D, A, B, C, X[ 6], 5 );
221 P( C, D, A, B, X[10], 9 );
222 P( B, C, D, A, X[14], 13 );
223 P( A, B, C, D, X[ 3], 3 );
224 P( D, A, B, C, X[ 7], 5 );
225 P( C, D, A, B, X[11], 9 );
226 P( B, C, D, A, X[15], 13 );
227
228#undef P
229#undef F
230
Hanno Beckerd6028a12018-10-15 12:01:35 +0100231#define F(x,y,z) ((x) ^ (y) ^ (z))
Hanno Becker9306f1c2018-10-30 09:29:25 +0000232#define P(a,b,c,d,x,s) \
233 do \
234 { \
235 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
236 (a) = S((a),(s)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100237 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239 P( A, B, C, D, X[ 0], 3 );
240 P( D, A, B, C, X[ 8], 9 );
241 P( C, D, A, B, X[ 4], 11 );
242 P( B, C, D, A, X[12], 15 );
243 P( A, B, C, D, X[ 2], 3 );
244 P( D, A, B, C, X[10], 9 );
245 P( C, D, A, B, X[ 6], 11 );
246 P( B, C, D, A, X[14], 15 );
247 P( A, B, C, D, X[ 1], 3 );
248 P( D, A, B, C, X[ 9], 9 );
249 P( C, D, A, B, X[ 5], 11 );
250 P( B, C, D, A, X[13], 15 );
251 P( A, B, C, D, X[ 3], 3 );
252 P( D, A, B, C, X[11], 9 );
253 P( C, D, A, B, X[ 7], 11 );
254 P( B, C, D, A, X[15], 15 );
255
256#undef F
257#undef P
258
259 ctx->state[0] += A;
260 ctx->state[1] += B;
261 ctx->state[2] += C;
262 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100263
264 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000265}
Jaeden Amero041039f2018-02-19 15:28:08 +0000266
267#if !defined(MBEDTLS_DEPRECATED_REMOVED)
268void mbedtls_md4_process( mbedtls_md4_context *ctx,
269 const unsigned char data[64] )
270{
271 mbedtls_internal_md4_process( ctx, data );
272}
273#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200274#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000275
276/*
277 * MD4 process buffer
278 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100279int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100280 const unsigned char *input,
281 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000282{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100283 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000284 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000285 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000286
Brian White12895d12014-04-11 11:29:42 -0400287 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100288 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000289
290 left = ctx->total[0] & 0x3F;
291 fill = 64 - left;
292
Paul Bakker5c2364c2012-10-01 14:41:15 +0000293 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 ctx->total[0] &= 0xFFFFFFFF;
295
Paul Bakker5c2364c2012-10-01 14:41:15 +0000296 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000297 ctx->total[1]++;
298
299 if( left && ilen >= fill )
300 {
301 memcpy( (void *) (ctx->buffer + left),
302 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100303
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100304 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100305 return( ret );
306
Paul Bakker5121ce52009-01-03 21:22:43 +0000307 input += fill;
308 ilen -= fill;
309 left = 0;
310 }
311
312 while( ilen >= 64 )
313 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100314 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100315 return( ret );
316
Paul Bakker5121ce52009-01-03 21:22:43 +0000317 input += 64;
318 ilen -= 64;
319 }
320
321 if( ilen > 0 )
322 {
323 memcpy( (void *) (ctx->buffer + left),
324 (void *) input, ilen );
325 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100326
327 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000328}
329
Jaeden Amero041039f2018-02-19 15:28:08 +0000330#if !defined(MBEDTLS_DEPRECATED_REMOVED)
331void mbedtls_md4_update( mbedtls_md4_context *ctx,
332 const unsigned char *input,
333 size_t ilen )
334{
335 mbedtls_md4_update_ret( ctx, input, ilen );
336}
337#endif
338
Paul Bakker5121ce52009-01-03 21:22:43 +0000339static const unsigned char md4_padding[64] =
340{
341 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
342 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
343 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
344 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
345};
346
347/*
348 * MD4 final digest
349 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100350int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100351 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000352{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100353 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000354 uint32_t last, padn;
355 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 unsigned char msglen[8];
357
358 high = ( ctx->total[0] >> 29 )
359 | ( ctx->total[1] << 3 );
360 low = ( ctx->total[0] << 3 );
361
Paul Bakker5c2364c2012-10-01 14:41:15 +0000362 PUT_UINT32_LE( low, msglen, 0 );
363 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
365 last = ctx->total[0] & 0x3F;
366 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
367
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100368 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100369 if( ret != 0 )
370 return( ret );
371
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100372 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100373 return( ret );
374
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Paul Bakker5c2364c2012-10-01 14:41:15 +0000376 PUT_UINT32_LE( ctx->state[0], output, 0 );
377 PUT_UINT32_LE( ctx->state[1], output, 4 );
378 PUT_UINT32_LE( ctx->state[2], output, 8 );
379 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100380
381 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000382}
383
Jaeden Amero041039f2018-02-19 15:28:08 +0000384#if !defined(MBEDTLS_DEPRECATED_REMOVED)
385void mbedtls_md4_finish( mbedtls_md4_context *ctx,
386 unsigned char output[16] )
387{
388 mbedtls_md4_finish_ret( ctx, output );
389}
390#endif
391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200393
Paul Bakker5121ce52009-01-03 21:22:43 +0000394/*
395 * output = MD4( input buffer )
396 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100397int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100398 size_t ilen,
399 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000400{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100401 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100405
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100406 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100407 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100408
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100409 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100410 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100411
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100412 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100413 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100414
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100415exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100417
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100418 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419}
420
Jaeden Amero041039f2018-02-19 15:28:08 +0000421#if !defined(MBEDTLS_DEPRECATED_REMOVED)
422void mbedtls_md4( const unsigned char *input,
423 size_t ilen,
424 unsigned char output[16] )
425{
426 mbedtls_md4_ret( input, ilen, output );
427}
428#endif
429
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200430#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
432/*
433 * RFC 1320 test vectors
434 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100435static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000436{
Paul Bakker9af723c2014-05-01 13:03:14 +0200437 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 { "a" },
439 { "abc" },
440 { "message digest" },
441 { "abcdefghijklmnopqrstuvwxyz" },
442 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100443 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 "345678901234567890" }
445};
446
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100447static const size_t md4_test_strlen[7] =
448{
449 0, 1, 3, 14, 26, 62, 80
450};
451
Paul Bakker5121ce52009-01-03 21:22:43 +0000452static const unsigned char md4_test_sum[7][16] =
453{
454 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
455 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
456 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
457 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
458 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
459 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
460 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
461 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
462 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
463 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
464 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
465 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
466 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
467 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
468};
469
470/*
471 * Checkup routine
472 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200473int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000474{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100475 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000476 unsigned char md4sum[16];
477
478 for( i = 0; i < 7; i++ )
479 {
480 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100483 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100484 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100485 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
487 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100488 {
489 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100490 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100491 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
493 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200494 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495 }
496
497 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200498 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
500 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100501
502fail:
503 if( verbose != 0 )
504 mbedtls_printf( "failed\n" );
505
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100506 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000507}
508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000510
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200511#endif /* MBEDTLS_MD4_C */