blob: 6a658e31d4ccb3dcedf1ffc82d1ac65daa031343 [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
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 MD4 algorithm was designed by Ron Rivest in 1990.
23 *
24 * http://www.ietf.org/rfc/rfc1186.txt
25 * http://www.ietf.org/rfc/rfc1320.txt
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/md4.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050037#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000038#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <string.h>
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042#if defined(MBEDTLS_SELF_TEST)
43#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000044#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010045#else
Rich Evans00ab4702015-02-06 13:43:58 +000046#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#define mbedtls_printf printf
48#endif /* MBEDTLS_PLATFORM_C */
49#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010050
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020051#if !defined(MBEDTLS_MD4_ALT)
52
Paul Bakker5121ce52009-01-03 21:22:43 +000053/*
54 * 32-bit integer manipulation macros (little endian)
55 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000056#ifndef GET_UINT32_LE
57#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000058{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000059 (n) = ( (uint32_t) (b)[(i) ] ) \
60 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
61 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
62 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000063}
64#endif
65
Paul Bakker5c2364c2012-10-01 14:41:15 +000066#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000067#define PUT_UINT32_LE(n,b,i) \
68{ \
69 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
70 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
71 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
72 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000073}
74#endif
75
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020076void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020077{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020078 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020079}
80
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020082{
83 if( ctx == NULL )
84 return;
85
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050086 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020087}
88
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020089void mbedtls_md4_clone( mbedtls_md4_context *dst,
90 const mbedtls_md4_context *src )
91{
92 *dst = *src;
93}
94
Paul Bakker5121ce52009-01-03 21:22:43 +000095/*
96 * MD4 context setup
97 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010098int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +000099{
100 ctx->total[0] = 0;
101 ctx->total[1] = 0;
102
103 ctx->state[0] = 0x67452301;
104 ctx->state[1] = 0xEFCDAB89;
105 ctx->state[2] = 0x98BADCFE;
106 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100107
108 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000109}
110
Jaeden Amero041039f2018-02-19 15:28:08 +0000111#if !defined(MBEDTLS_DEPRECATED_REMOVED)
112void mbedtls_md4_starts( mbedtls_md4_context *ctx )
113{
114 mbedtls_md4_starts_ret( ctx );
115}
116#endif
117
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200118#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100119int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
120 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000121{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000122 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000123
Paul Bakker5c2364c2012-10-01 14:41:15 +0000124 GET_UINT32_LE( X[ 0], data, 0 );
125 GET_UINT32_LE( X[ 1], data, 4 );
126 GET_UINT32_LE( X[ 2], data, 8 );
127 GET_UINT32_LE( X[ 3], data, 12 );
128 GET_UINT32_LE( X[ 4], data, 16 );
129 GET_UINT32_LE( X[ 5], data, 20 );
130 GET_UINT32_LE( X[ 6], data, 24 );
131 GET_UINT32_LE( X[ 7], data, 28 );
132 GET_UINT32_LE( X[ 8], data, 32 );
133 GET_UINT32_LE( X[ 9], data, 36 );
134 GET_UINT32_LE( X[10], data, 40 );
135 GET_UINT32_LE( X[11], data, 44 );
136 GET_UINT32_LE( X[12], data, 48 );
137 GET_UINT32_LE( X[13], data, 52 );
138 GET_UINT32_LE( X[14], data, 56 );
139 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000140
Hanno Becker1eeca412018-10-15 12:01:35 +0100141#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000142
143 A = ctx->state[0];
144 B = ctx->state[1];
145 C = ctx->state[2];
146 D = ctx->state[3];
147
Hanno Becker1eeca412018-10-15 12:01:35 +0100148#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
Hanno Becker26d02e12018-10-30 09:29:25 +0000149#define P(a,b,c,d,x,s) \
150 do \
151 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100152 (a) += F((b),(c),(d)) + (x); \
153 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100154 } while( 0 )
155
Paul Bakker5121ce52009-01-03 21:22:43 +0000156
157 P( A, B, C, D, X[ 0], 3 );
158 P( D, A, B, C, X[ 1], 7 );
159 P( C, D, A, B, X[ 2], 11 );
160 P( B, C, D, A, X[ 3], 19 );
161 P( A, B, C, D, X[ 4], 3 );
162 P( D, A, B, C, X[ 5], 7 );
163 P( C, D, A, B, X[ 6], 11 );
164 P( B, C, D, A, X[ 7], 19 );
165 P( A, B, C, D, X[ 8], 3 );
166 P( D, A, B, C, X[ 9], 7 );
167 P( C, D, A, B, X[10], 11 );
168 P( B, C, D, A, X[11], 19 );
169 P( A, B, C, D, X[12], 3 );
170 P( D, A, B, C, X[13], 7 );
171 P( C, D, A, B, X[14], 11 );
172 P( B, C, D, A, X[15], 19 );
173
174#undef P
175#undef F
176
Hanno Becker1eeca412018-10-15 12:01:35 +0100177#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
178#define P(a,b,c,d,x,s) \
179 do \
180 { \
Hanno Becker26d02e12018-10-30 09:29:25 +0000181 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
182 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100183 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000184
185 P( A, B, C, D, X[ 0], 3 );
186 P( D, A, B, C, X[ 4], 5 );
187 P( C, D, A, B, X[ 8], 9 );
188 P( B, C, D, A, X[12], 13 );
189 P( A, B, C, D, X[ 1], 3 );
190 P( D, A, B, C, X[ 5], 5 );
191 P( C, D, A, B, X[ 9], 9 );
192 P( B, C, D, A, X[13], 13 );
193 P( A, B, C, D, X[ 2], 3 );
194 P( D, A, B, C, X[ 6], 5 );
195 P( C, D, A, B, X[10], 9 );
196 P( B, C, D, A, X[14], 13 );
197 P( A, B, C, D, X[ 3], 3 );
198 P( D, A, B, C, X[ 7], 5 );
199 P( C, D, A, B, X[11], 9 );
200 P( B, C, D, A, X[15], 13 );
201
202#undef P
203#undef F
204
Hanno Becker1eeca412018-10-15 12:01:35 +0100205#define F(x,y,z) ((x) ^ (y) ^ (z))
Hanno Becker26d02e12018-10-30 09:29:25 +0000206#define P(a,b,c,d,x,s) \
207 do \
208 { \
209 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
210 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100211 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000212
213 P( A, B, C, D, X[ 0], 3 );
214 P( D, A, B, C, X[ 8], 9 );
215 P( C, D, A, B, X[ 4], 11 );
216 P( B, C, D, A, X[12], 15 );
217 P( A, B, C, D, X[ 2], 3 );
218 P( D, A, B, C, X[10], 9 );
219 P( C, D, A, B, X[ 6], 11 );
220 P( B, C, D, A, X[14], 15 );
221 P( A, B, C, D, X[ 1], 3 );
222 P( D, A, B, C, X[ 9], 9 );
223 P( C, D, A, B, X[ 5], 11 );
224 P( B, C, D, A, X[13], 15 );
225 P( A, B, C, D, X[ 3], 3 );
226 P( D, A, B, C, X[11], 9 );
227 P( C, D, A, B, X[ 7], 11 );
228 P( B, C, D, A, X[15], 15 );
229
230#undef F
231#undef P
232
233 ctx->state[0] += A;
234 ctx->state[1] += B;
235 ctx->state[2] += C;
236 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100237
238 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000239}
Jaeden Amero041039f2018-02-19 15:28:08 +0000240
241#if !defined(MBEDTLS_DEPRECATED_REMOVED)
242void mbedtls_md4_process( mbedtls_md4_context *ctx,
243 const unsigned char data[64] )
244{
245 mbedtls_internal_md4_process( ctx, data );
246}
247#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200248#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000249
250/*
251 * MD4 process buffer
252 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100253int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100254 const unsigned char *input,
255 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000256{
Janos Follath24eed8d2019-11-22 13:21:35 +0000257 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000258 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000259 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000260
Brian White12895d12014-04-11 11:29:42 -0400261 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100262 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000263
264 left = ctx->total[0] & 0x3F;
265 fill = 64 - left;
266
Paul Bakker5c2364c2012-10-01 14:41:15 +0000267 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000268 ctx->total[0] &= 0xFFFFFFFF;
269
Paul Bakker5c2364c2012-10-01 14:41:15 +0000270 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000271 ctx->total[1]++;
272
273 if( left && ilen >= fill )
274 {
275 memcpy( (void *) (ctx->buffer + left),
276 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100277
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100278 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +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_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100289 return( ret );
290
Paul Bakker5121ce52009-01-03 21:22:43 +0000291 input += 64;
292 ilen -= 64;
293 }
294
295 if( ilen > 0 )
296 {
297 memcpy( (void *) (ctx->buffer + left),
298 (void *) input, ilen );
299 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100300
301 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302}
303
Jaeden Amero041039f2018-02-19 15:28:08 +0000304#if !defined(MBEDTLS_DEPRECATED_REMOVED)
305void mbedtls_md4_update( mbedtls_md4_context *ctx,
306 const unsigned char *input,
307 size_t ilen )
308{
309 mbedtls_md4_update_ret( ctx, input, ilen );
310}
311#endif
312
Paul Bakker5121ce52009-01-03 21:22:43 +0000313static const unsigned char md4_padding[64] =
314{
315 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
319};
320
321/*
322 * MD4 final digest
323 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100324int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100325 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000326{
Janos Follath24eed8d2019-11-22 13:21:35 +0000327 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000328 uint32_t last, padn;
329 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 unsigned char msglen[8];
331
332 high = ( ctx->total[0] >> 29 )
333 | ( ctx->total[1] << 3 );
334 low = ( ctx->total[0] << 3 );
335
Paul Bakker5c2364c2012-10-01 14:41:15 +0000336 PUT_UINT32_LE( low, msglen, 0 );
337 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
339 last = ctx->total[0] & 0x3F;
340 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
341
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100342 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100343 if( ret != 0 )
344 return( ret );
345
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100346 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100347 return( ret );
348
Paul Bakker5121ce52009-01-03 21:22:43 +0000349
Paul Bakker5c2364c2012-10-01 14:41:15 +0000350 PUT_UINT32_LE( ctx->state[0], output, 0 );
351 PUT_UINT32_LE( ctx->state[1], output, 4 );
352 PUT_UINT32_LE( ctx->state[2], output, 8 );
353 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100354
355 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356}
357
Jaeden Amero041039f2018-02-19 15:28:08 +0000358#if !defined(MBEDTLS_DEPRECATED_REMOVED)
359void mbedtls_md4_finish( mbedtls_md4_context *ctx,
360 unsigned char output[16] )
361{
362 mbedtls_md4_finish_ret( ctx, output );
363}
364#endif
365
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200366#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200367
Paul Bakker5121ce52009-01-03 21:22:43 +0000368/*
369 * output = MD4( input buffer )
370 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100371int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100372 size_t ilen,
373 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000374{
Janos Follath24eed8d2019-11-22 13:21:35 +0000375 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000377
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100379
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100380 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100381 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100382
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100383 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100384 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100385
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100386 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100387 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100388
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100389exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100391
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100392 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000393}
394
Jaeden Amero041039f2018-02-19 15:28:08 +0000395#if !defined(MBEDTLS_DEPRECATED_REMOVED)
396void mbedtls_md4( const unsigned char *input,
397 size_t ilen,
398 unsigned char output[16] )
399{
400 mbedtls_md4_ret( input, ilen, output );
401}
402#endif
403
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200404#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
406/*
407 * RFC 1320 test vectors
408 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100409static const unsigned char md4_test_str[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 md4_test_strlen[7] =
422{
423 0, 1, 3, 14, 26, 62, 80
424};
425
Paul Bakker5121ce52009-01-03 21:22:43 +0000426static const unsigned char md4_test_sum[7][16] =
427{
428 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
429 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
430 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
431 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
432 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
433 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
434 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
435 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
436 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
437 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
438 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
439 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
440 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
441 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
442};
443
444/*
445 * Checkup routine
446 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200447int mbedtls_md4_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 md4sum[16];
451
452 for( i = 0; i < 7; i++ )
453 {
454 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100457 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100458 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100459 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100462 {
463 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +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
474 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +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_MD4_C */