blob: 7a60bbafc47c7c0d48d280fa21214ec40bd0f990 [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úti4e9f7122020-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úti4e9f7122020-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"
Paul Bakker5121ce52009-01-03 21:22:43 +000064
Rich Evans00ab4702015-02-06 13:43:58 +000065#include <string.h>
66
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020067#if defined(MBEDTLS_SELF_TEST)
68#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000069#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010070#else
Rich Evans00ab4702015-02-06 13:43:58 +000071#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072#define mbedtls_printf printf
73#endif /* MBEDTLS_PLATFORM_C */
74#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010075
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020076#if !defined(MBEDTLS_MD4_ALT)
77
Paul Bakker34617722014-06-13 17:20:13 +020078/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020080 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
81}
82
Paul Bakker5121ce52009-01-03 21:22:43 +000083/*
84 * 32-bit integer manipulation macros (little endian)
85 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000086#ifndef GET_UINT32_LE
87#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000088{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000089 (n) = ( (uint32_t) (b)[(i) ] ) \
90 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
91 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
92 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000093}
94#endif
95
Paul Bakker5c2364c2012-10-01 14:41:15 +000096#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000097#define PUT_UINT32_LE(n,b,i) \
98{ \
99 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
100 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
101 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
102 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +0000103}
104#endif
105
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200107{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200108 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200109}
110
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200111void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200112{
113 if( ctx == NULL )
114 return;
115
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200116 mbedtls_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200117}
118
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200119void mbedtls_md4_clone( mbedtls_md4_context *dst,
120 const mbedtls_md4_context *src )
121{
122 *dst = *src;
123}
124
Paul Bakker5121ce52009-01-03 21:22:43 +0000125/*
126 * MD4 context setup
127 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100128int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000129{
130 ctx->total[0] = 0;
131 ctx->total[1] = 0;
132
133 ctx->state[0] = 0x67452301;
134 ctx->state[1] = 0xEFCDAB89;
135 ctx->state[2] = 0x98BADCFE;
136 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100137
138 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000139}
140
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000141#if !defined(MBEDTLS_DEPRECATED_REMOVED)
142void mbedtls_md4_starts( mbedtls_md4_context *ctx )
143{
144 mbedtls_md4_starts_ret( ctx );
145}
146#endif
147
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100149int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
150 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000151{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000152 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000153
Paul Bakker5c2364c2012-10-01 14:41:15 +0000154 GET_UINT32_LE( X[ 0], data, 0 );
155 GET_UINT32_LE( X[ 1], data, 4 );
156 GET_UINT32_LE( X[ 2], data, 8 );
157 GET_UINT32_LE( X[ 3], data, 12 );
158 GET_UINT32_LE( X[ 4], data, 16 );
159 GET_UINT32_LE( X[ 5], data, 20 );
160 GET_UINT32_LE( X[ 6], data, 24 );
161 GET_UINT32_LE( X[ 7], data, 28 );
162 GET_UINT32_LE( X[ 8], data, 32 );
163 GET_UINT32_LE( X[ 9], data, 36 );
164 GET_UINT32_LE( X[10], data, 40 );
165 GET_UINT32_LE( X[11], data, 44 );
166 GET_UINT32_LE( X[12], data, 48 );
167 GET_UINT32_LE( X[13], data, 52 );
168 GET_UINT32_LE( X[14], data, 56 );
169 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
171#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
172
173 A = ctx->state[0];
174 B = ctx->state[1];
175 C = ctx->state[2];
176 D = ctx->state[3];
177
178#define F(x, y, z) ((x & y) | ((~x) & z))
179#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
180
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
201#define F(x,y,z) ((x & y) | (x & z) | (y & z))
202#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
203
204 P( A, B, C, D, X[ 0], 3 );
205 P( D, A, B, C, X[ 4], 5 );
206 P( C, D, A, B, X[ 8], 9 );
207 P( B, C, D, A, X[12], 13 );
208 P( A, B, C, D, X[ 1], 3 );
209 P( D, A, B, C, X[ 5], 5 );
210 P( C, D, A, B, X[ 9], 9 );
211 P( B, C, D, A, X[13], 13 );
212 P( A, B, C, D, X[ 2], 3 );
213 P( D, A, B, C, X[ 6], 5 );
214 P( C, D, A, B, X[10], 9 );
215 P( B, C, D, A, X[14], 13 );
216 P( A, B, C, D, X[ 3], 3 );
217 P( D, A, B, C, X[ 7], 5 );
218 P( C, D, A, B, X[11], 9 );
219 P( B, C, D, A, X[15], 13 );
220
221#undef P
222#undef F
223
224#define F(x,y,z) (x ^ y ^ z)
225#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
226
227 P( A, B, C, D, X[ 0], 3 );
228 P( D, A, B, C, X[ 8], 9 );
229 P( C, D, A, B, X[ 4], 11 );
230 P( B, C, D, A, X[12], 15 );
231 P( A, B, C, D, X[ 2], 3 );
232 P( D, A, B, C, X[10], 9 );
233 P( C, D, A, B, X[ 6], 11 );
234 P( B, C, D, A, X[14], 15 );
235 P( A, B, C, D, X[ 1], 3 );
236 P( D, A, B, C, X[ 9], 9 );
237 P( C, D, A, B, X[ 5], 11 );
238 P( B, C, D, A, X[13], 15 );
239 P( A, B, C, D, X[ 3], 3 );
240 P( D, A, B, C, X[11], 9 );
241 P( C, D, A, B, X[ 7], 11 );
242 P( B, C, D, A, X[15], 15 );
243
244#undef F
245#undef P
246
247 ctx->state[0] += A;
248 ctx->state[1] += B;
249 ctx->state[2] += C;
250 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100251
252 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000254
255#if !defined(MBEDTLS_DEPRECATED_REMOVED)
256void mbedtls_md4_process( mbedtls_md4_context *ctx,
257 const unsigned char data[64] )
258{
259 mbedtls_internal_md4_process( ctx, data );
260}
261#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200262#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264/*
265 * MD4 process buffer
266 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100267int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100268 const unsigned char *input,
269 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000270{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100271 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000272 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000273 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000274
Brian White12895d12014-04-11 11:29:42 -0400275 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100276 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000277
278 left = ctx->total[0] & 0x3F;
279 fill = 64 - left;
280
Paul Bakker5c2364c2012-10-01 14:41:15 +0000281 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000282 ctx->total[0] &= 0xFFFFFFFF;
283
Paul Bakker5c2364c2012-10-01 14:41:15 +0000284 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 ctx->total[1]++;
286
287 if( left && ilen >= fill )
288 {
289 memcpy( (void *) (ctx->buffer + left),
290 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100291
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100292 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100293 return( ret );
294
Paul Bakker5121ce52009-01-03 21:22:43 +0000295 input += fill;
296 ilen -= fill;
297 left = 0;
298 }
299
300 while( ilen >= 64 )
301 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100302 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100303 return( ret );
304
Paul Bakker5121ce52009-01-03 21:22:43 +0000305 input += 64;
306 ilen -= 64;
307 }
308
309 if( ilen > 0 )
310 {
311 memcpy( (void *) (ctx->buffer + left),
312 (void *) input, ilen );
313 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100314
315 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000316}
317
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000318#if !defined(MBEDTLS_DEPRECATED_REMOVED)
319void mbedtls_md4_update( mbedtls_md4_context *ctx,
320 const unsigned char *input,
321 size_t ilen )
322{
323 mbedtls_md4_update_ret( ctx, input, ilen );
324}
325#endif
326
Paul Bakker5121ce52009-01-03 21:22:43 +0000327static const unsigned char md4_padding[64] =
328{
329 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
330 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
331 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
332 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
333};
334
335/*
336 * MD4 final digest
337 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100338int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100339 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000340{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100341 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000342 uint32_t last, padn;
343 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000344 unsigned char msglen[8];
345
346 high = ( ctx->total[0] >> 29 )
347 | ( ctx->total[1] << 3 );
348 low = ( ctx->total[0] << 3 );
349
Paul Bakker5c2364c2012-10-01 14:41:15 +0000350 PUT_UINT32_LE( low, msglen, 0 );
351 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000352
353 last = ctx->total[0] & 0x3F;
354 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
355
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100356 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100357 if( ret != 0 )
358 return( ret );
359
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100360 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100361 return( ret );
362
Paul Bakker5121ce52009-01-03 21:22:43 +0000363
Paul Bakker5c2364c2012-10-01 14:41:15 +0000364 PUT_UINT32_LE( ctx->state[0], output, 0 );
365 PUT_UINT32_LE( ctx->state[1], output, 4 );
366 PUT_UINT32_LE( ctx->state[2], output, 8 );
367 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100368
369 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000370}
371
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000372#if !defined(MBEDTLS_DEPRECATED_REMOVED)
373void mbedtls_md4_finish( mbedtls_md4_context *ctx,
374 unsigned char output[16] )
375{
376 mbedtls_md4_finish_ret( ctx, output );
377}
378#endif
379
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200380#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200381
Paul Bakker5121ce52009-01-03 21:22:43 +0000382/*
383 * output = MD4( input buffer )
384 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100385int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100386 size_t ilen,
387 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000388{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100389 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200392 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100393
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100394 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100395 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100396
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100397 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100398 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100399
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100400 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100401 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100402
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100403exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100405
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100406 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407}
408
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000409#if !defined(MBEDTLS_DEPRECATED_REMOVED)
410void mbedtls_md4( const unsigned char *input,
411 size_t ilen,
412 unsigned char output[16] )
413{
414 mbedtls_md4_ret( input, ilen, output );
415}
416#endif
417
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420/*
421 * RFC 1320 test vectors
422 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100423static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000424{
Paul Bakker9af723c2014-05-01 13:03:14 +0200425 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000426 { "a" },
427 { "abc" },
428 { "message digest" },
429 { "abcdefghijklmnopqrstuvwxyz" },
430 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100431 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 "345678901234567890" }
433};
434
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100435static const size_t md4_test_strlen[7] =
436{
437 0, 1, 3, 14, 26, 62, 80
438};
439
Paul Bakker5121ce52009-01-03 21:22:43 +0000440static const unsigned char md4_test_sum[7][16] =
441{
442 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
443 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
444 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
445 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
446 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
447 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
448 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
449 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
450 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
451 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
452 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
453 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
454 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
455 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
456};
457
458/*
459 * Checkup routine
460 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200461int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000462{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100463 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000464 unsigned char md4sum[16];
465
466 for( i = 0; i < 7; i++ )
467 {
468 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200469 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100471 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100472 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100473 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
475 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100476 {
477 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100478 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100479 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000483 }
484
485 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200486 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000487
488 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100489
490fail:
491 if( verbose != 0 )
492 mbedtls_printf( "failed\n" );
493
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100494 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495}
496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000498
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200499#endif /* MBEDTLS_MD4_C */