blob: cb16dce54a96c070600e13a0d5d6d8faf615915f [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Bence Szépkútia2947ac2020-08-19 16:37:36 +02004 * Copyright The Mbed TLS Contributors
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 * **********
Paul Bakker5121ce52009-01-03 21:22:43 +000045 */
46/*
47 * The MD4 algorithm was designed by Ron Rivest in 1990.
48 *
49 * http://www.ietf.org/rfc/rfc1186.txt
50 * http://www.ietf.org/rfc/rfc1320.txt
51 */
52
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020053#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000054#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020055#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020056#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020057#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000058
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020059#if defined(MBEDTLS_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000060
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000061#include "mbedtls/md4.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050062#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000063
Rich Evans00ab4702015-02-06 13:43:58 +000064#include <string.h>
65
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020066#if defined(MBEDTLS_SELF_TEST)
67#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000068#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010069#else
Rich Evans00ab4702015-02-06 13:43:58 +000070#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020071#define mbedtls_printf printf
72#endif /* MBEDTLS_PLATFORM_C */
73#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010074
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020075#if !defined(MBEDTLS_MD4_ALT)
76
Paul Bakker5121ce52009-01-03 21:22:43 +000077/*
78 * 32-bit integer manipulation macros (little endian)
79 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000080#ifndef GET_UINT32_LE
81#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000082{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000083 (n) = ( (uint32_t) (b)[(i) ] ) \
84 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
85 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
86 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000087}
88#endif
89
Paul Bakker5c2364c2012-10-01 14:41:15 +000090#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000091#define PUT_UINT32_LE(n,b,i) \
92{ \
93 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
94 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
95 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
96 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000097}
98#endif
99
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200100void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200101{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200102 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200103}
104
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200106{
107 if( ctx == NULL )
108 return;
109
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -0500110 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200111}
112
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200113void mbedtls_md4_clone( mbedtls_md4_context *dst,
114 const mbedtls_md4_context *src )
115{
116 *dst = *src;
117}
118
Paul Bakker5121ce52009-01-03 21:22:43 +0000119/*
120 * MD4 context setup
121 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100122int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000123{
124 ctx->total[0] = 0;
125 ctx->total[1] = 0;
126
127 ctx->state[0] = 0x67452301;
128 ctx->state[1] = 0xEFCDAB89;
129 ctx->state[2] = 0x98BADCFE;
130 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100131
132 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000133}
134
Jaeden Amero041039f2018-02-19 15:28:08 +0000135#if !defined(MBEDTLS_DEPRECATED_REMOVED)
136void mbedtls_md4_starts( mbedtls_md4_context *ctx )
137{
138 mbedtls_md4_starts_ret( ctx );
139}
140#endif
141
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200142#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100143int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
144 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000145{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000146 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000147
Paul Bakker5c2364c2012-10-01 14:41:15 +0000148 GET_UINT32_LE( X[ 0], data, 0 );
149 GET_UINT32_LE( X[ 1], data, 4 );
150 GET_UINT32_LE( X[ 2], data, 8 );
151 GET_UINT32_LE( X[ 3], data, 12 );
152 GET_UINT32_LE( X[ 4], data, 16 );
153 GET_UINT32_LE( X[ 5], data, 20 );
154 GET_UINT32_LE( X[ 6], data, 24 );
155 GET_UINT32_LE( X[ 7], data, 28 );
156 GET_UINT32_LE( X[ 8], data, 32 );
157 GET_UINT32_LE( X[ 9], data, 36 );
158 GET_UINT32_LE( X[10], data, 40 );
159 GET_UINT32_LE( X[11], data, 44 );
160 GET_UINT32_LE( X[12], data, 48 );
161 GET_UINT32_LE( X[13], data, 52 );
162 GET_UINT32_LE( X[14], data, 56 );
163 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000164
Hanno Beckerd6028a12018-10-15 12:01:35 +0100165#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000166
167 A = ctx->state[0];
168 B = ctx->state[1];
169 C = ctx->state[2];
170 D = ctx->state[3];
171
Hanno Beckerd6028a12018-10-15 12:01:35 +0100172#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
Hanno Becker9306f1c2018-10-30 09:29:25 +0000173#define P(a,b,c,d,x,s) \
174 do \
175 { \
Hanno Becker3ac21ac2018-10-26 09:13:26 +0100176 (a) += F((b),(c),(d)) + (x); \
177 (a) = S((a),(s)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100178 } while( 0 )
179
Paul Bakker5121ce52009-01-03 21:22:43 +0000180
181 P( A, B, C, D, X[ 0], 3 );
182 P( D, A, B, C, X[ 1], 7 );
183 P( C, D, A, B, X[ 2], 11 );
184 P( B, C, D, A, X[ 3], 19 );
185 P( A, B, C, D, X[ 4], 3 );
186 P( D, A, B, C, X[ 5], 7 );
187 P( C, D, A, B, X[ 6], 11 );
188 P( B, C, D, A, X[ 7], 19 );
189 P( A, B, C, D, X[ 8], 3 );
190 P( D, A, B, C, X[ 9], 7 );
191 P( C, D, A, B, X[10], 11 );
192 P( B, C, D, A, X[11], 19 );
193 P( A, B, C, D, X[12], 3 );
194 P( D, A, B, C, X[13], 7 );
195 P( C, D, A, B, X[14], 11 );
196 P( B, C, D, A, X[15], 19 );
197
198#undef P
199#undef F
200
Hanno Beckerd6028a12018-10-15 12:01:35 +0100201#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
202#define P(a,b,c,d,x,s) \
203 do \
204 { \
Hanno Becker9306f1c2018-10-30 09:29:25 +0000205 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
206 (a) = S((a),(s)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100207 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000208
209 P( A, B, C, D, X[ 0], 3 );
210 P( D, A, B, C, X[ 4], 5 );
211 P( C, D, A, B, X[ 8], 9 );
212 P( B, C, D, A, X[12], 13 );
213 P( A, B, C, D, X[ 1], 3 );
214 P( D, A, B, C, X[ 5], 5 );
215 P( C, D, A, B, X[ 9], 9 );
216 P( B, C, D, A, X[13], 13 );
217 P( A, B, C, D, X[ 2], 3 );
218 P( D, A, B, C, X[ 6], 5 );
219 P( C, D, A, B, X[10], 9 );
220 P( B, C, D, A, X[14], 13 );
221 P( A, B, C, D, X[ 3], 3 );
222 P( D, A, B, C, X[ 7], 5 );
223 P( C, D, A, B, X[11], 9 );
224 P( B, C, D, A, X[15], 13 );
225
226#undef P
227#undef F
228
Hanno Beckerd6028a12018-10-15 12:01:35 +0100229#define F(x,y,z) ((x) ^ (y) ^ (z))
Hanno Becker9306f1c2018-10-30 09:29:25 +0000230#define P(a,b,c,d,x,s) \
231 do \
232 { \
233 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
234 (a) = S((a),(s)); \
Hanno Beckerd6028a12018-10-15 12:01:35 +0100235 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000236
237 P( A, B, C, D, X[ 0], 3 );
238 P( D, A, B, C, X[ 8], 9 );
239 P( C, D, A, B, X[ 4], 11 );
240 P( B, C, D, A, X[12], 15 );
241 P( A, B, C, D, X[ 2], 3 );
242 P( D, A, B, C, X[10], 9 );
243 P( C, D, A, B, X[ 6], 11 );
244 P( B, C, D, A, X[14], 15 );
245 P( A, B, C, D, X[ 1], 3 );
246 P( D, A, B, C, X[ 9], 9 );
247 P( C, D, A, B, X[ 5], 11 );
248 P( B, C, D, A, X[13], 15 );
249 P( A, B, C, D, X[ 3], 3 );
250 P( D, A, B, C, X[11], 9 );
251 P( C, D, A, B, X[ 7], 11 );
252 P( B, C, D, A, X[15], 15 );
253
254#undef F
255#undef P
256
257 ctx->state[0] += A;
258 ctx->state[1] += B;
259 ctx->state[2] += C;
260 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100261
262 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000263}
Jaeden Amero041039f2018-02-19 15:28:08 +0000264
265#if !defined(MBEDTLS_DEPRECATED_REMOVED)
266void mbedtls_md4_process( mbedtls_md4_context *ctx,
267 const unsigned char data[64] )
268{
269 mbedtls_internal_md4_process( ctx, data );
270}
271#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200272#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000273
274/*
275 * MD4 process buffer
276 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100277int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100278 const unsigned char *input,
279 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000280{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100281 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000282 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000283 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000284
Brian White12895d12014-04-11 11:29:42 -0400285 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100286 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000287
288 left = ctx->total[0] & 0x3F;
289 fill = 64 - left;
290
Paul Bakker5c2364c2012-10-01 14:41:15 +0000291 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000292 ctx->total[0] &= 0xFFFFFFFF;
293
Paul Bakker5c2364c2012-10-01 14:41:15 +0000294 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 ctx->total[1]++;
296
297 if( left && ilen >= fill )
298 {
299 memcpy( (void *) (ctx->buffer + left),
300 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100301
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100302 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100303 return( ret );
304
Paul Bakker5121ce52009-01-03 21:22:43 +0000305 input += fill;
306 ilen -= fill;
307 left = 0;
308 }
309
310 while( ilen >= 64 )
311 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100312 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100313 return( ret );
314
Paul Bakker5121ce52009-01-03 21:22:43 +0000315 input += 64;
316 ilen -= 64;
317 }
318
319 if( ilen > 0 )
320 {
321 memcpy( (void *) (ctx->buffer + left),
322 (void *) input, ilen );
323 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100324
325 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000326}
327
Jaeden Amero041039f2018-02-19 15:28:08 +0000328#if !defined(MBEDTLS_DEPRECATED_REMOVED)
329void mbedtls_md4_update( mbedtls_md4_context *ctx,
330 const unsigned char *input,
331 size_t ilen )
332{
333 mbedtls_md4_update_ret( ctx, input, ilen );
334}
335#endif
336
Paul Bakker5121ce52009-01-03 21:22:43 +0000337static const unsigned char md4_padding[64] =
338{
339 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
340 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
341 0, 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};
344
345/*
346 * MD4 final digest
347 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100348int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100349 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000350{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100351 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000352 uint32_t last, padn;
353 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000354 unsigned char msglen[8];
355
356 high = ( ctx->total[0] >> 29 )
357 | ( ctx->total[1] << 3 );
358 low = ( ctx->total[0] << 3 );
359
Paul Bakker5c2364c2012-10-01 14:41:15 +0000360 PUT_UINT32_LE( low, msglen, 0 );
361 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000362
363 last = ctx->total[0] & 0x3F;
364 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
365
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100366 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100367 if( ret != 0 )
368 return( ret );
369
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100370 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100371 return( ret );
372
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
Paul Bakker5c2364c2012-10-01 14:41:15 +0000374 PUT_UINT32_LE( ctx->state[0], output, 0 );
375 PUT_UINT32_LE( ctx->state[1], output, 4 );
376 PUT_UINT32_LE( ctx->state[2], output, 8 );
377 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100378
379 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000380}
381
Jaeden Amero041039f2018-02-19 15:28:08 +0000382#if !defined(MBEDTLS_DEPRECATED_REMOVED)
383void mbedtls_md4_finish( mbedtls_md4_context *ctx,
384 unsigned char output[16] )
385{
386 mbedtls_md4_finish_ret( ctx, output );
387}
388#endif
389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200391
Paul Bakker5121ce52009-01-03 21:22:43 +0000392/*
393 * output = MD4( input buffer )
394 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100395int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100396 size_t ilen,
397 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000398{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100399 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100403
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100404 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100405 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100406
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100407 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100408 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100409
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100410 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100411 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100412
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100413exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100415
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100416 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000417}
418
Jaeden Amero041039f2018-02-19 15:28:08 +0000419#if !defined(MBEDTLS_DEPRECATED_REMOVED)
420void mbedtls_md4( const unsigned char *input,
421 size_t ilen,
422 unsigned char output[16] )
423{
424 mbedtls_md4_ret( input, ilen, output );
425}
426#endif
427
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200428#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430/*
431 * RFC 1320 test vectors
432 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100433static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000434{
Paul Bakker9af723c2014-05-01 13:03:14 +0200435 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000436 { "a" },
437 { "abc" },
438 { "message digest" },
439 { "abcdefghijklmnopqrstuvwxyz" },
440 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100441 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 "345678901234567890" }
443};
444
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100445static const size_t md4_test_strlen[7] =
446{
447 0, 1, 3, 14, 26, 62, 80
448};
449
Paul Bakker5121ce52009-01-03 21:22:43 +0000450static const unsigned char md4_test_sum[7][16] =
451{
452 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
453 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
454 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
455 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
456 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
457 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
458 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
459 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
460 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
461 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
462 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
463 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
464 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
465 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
466};
467
468/*
469 * Checkup routine
470 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000472{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100473 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000474 unsigned char md4sum[16];
475
476 for( i = 0; i < 7; i++ )
477 {
478 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100481 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100482 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100483 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000484
485 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100486 {
487 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100488 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100489 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
491 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200492 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000493 }
494
495 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000497
498 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100499
500fail:
501 if( verbose != 0 )
502 mbedtls_printf( "failed\n" );
503
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100504 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000505}
506
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200507#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200509#endif /* MBEDTLS_MD4_C */