blob: 28e81c81d548cc62fbef296e8c8129118c35f063 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Bence Szépkúti44bfbe32020-08-19 16:54:51 +02004 * Copyright The Mbed TLS Contributors
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 * **********
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"
Paul Bakker5121ce52009-01-03 21:22:43 +000062
Rich Evans00ab4702015-02-06 13:43:58 +000063#include <string.h>
64
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020065#if defined(MBEDTLS_SELF_TEST)
66#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000067#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010068#else
Rich Evans00ab4702015-02-06 13:43:58 +000069#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070#define mbedtls_printf printf
71#endif /* MBEDTLS_PLATFORM_C */
72#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010073
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020074#if !defined(MBEDTLS_MD4_ALT)
75
Paul Bakker34617722014-06-13 17:20:13 +020076/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020078 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
79}
80
Paul Bakker5121ce52009-01-03 21:22:43 +000081/*
82 * 32-bit integer manipulation macros (little endian)
83 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000084#ifndef GET_UINT32_LE
85#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000086{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000087 (n) = ( (uint32_t) (b)[(i) ] ) \
88 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
89 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
90 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000091}
92#endif
93
Paul Bakker5c2364c2012-10-01 14:41:15 +000094#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000095#define PUT_UINT32_LE(n,b,i) \
96{ \
97 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
98 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
99 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
100 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +0000101}
102#endif
103
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200105{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200106 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200107}
108
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200109void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +0200110{
111 if( ctx == NULL )
112 return;
113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114 mbedtls_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +0200115}
116
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +0200117void mbedtls_md4_clone( mbedtls_md4_context *dst,
118 const mbedtls_md4_context *src )
119{
120 *dst = *src;
121}
122
Paul Bakker5121ce52009-01-03 21:22:43 +0000123/*
124 * MD4 context setup
125 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100126int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000127{
128 ctx->total[0] = 0;
129 ctx->total[1] = 0;
130
131 ctx->state[0] = 0x67452301;
132 ctx->state[1] = 0xEFCDAB89;
133 ctx->state[2] = 0x98BADCFE;
134 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100135
136 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000137}
138
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000139#if !defined(MBEDTLS_DEPRECATED_REMOVED)
140void mbedtls_md4_starts( mbedtls_md4_context *ctx )
141{
142 mbedtls_md4_starts_ret( ctx );
143}
144#endif
145
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100147int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
148 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000149{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000150 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
Paul Bakker5c2364c2012-10-01 14:41:15 +0000152 GET_UINT32_LE( X[ 0], data, 0 );
153 GET_UINT32_LE( X[ 1], data, 4 );
154 GET_UINT32_LE( X[ 2], data, 8 );
155 GET_UINT32_LE( X[ 3], data, 12 );
156 GET_UINT32_LE( X[ 4], data, 16 );
157 GET_UINT32_LE( X[ 5], data, 20 );
158 GET_UINT32_LE( X[ 6], data, 24 );
159 GET_UINT32_LE( X[ 7], data, 28 );
160 GET_UINT32_LE( X[ 8], data, 32 );
161 GET_UINT32_LE( X[ 9], data, 36 );
162 GET_UINT32_LE( X[10], data, 40 );
163 GET_UINT32_LE( X[11], data, 44 );
164 GET_UINT32_LE( X[12], data, 48 );
165 GET_UINT32_LE( X[13], data, 52 );
166 GET_UINT32_LE( X[14], data, 56 );
167 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
169#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
170
171 A = ctx->state[0];
172 B = ctx->state[1];
173 C = ctx->state[2];
174 D = ctx->state[3];
175
176#define F(x, y, z) ((x & y) | ((~x) & z))
177#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
178
179 P( A, B, C, D, X[ 0], 3 );
180 P( D, A, B, C, X[ 1], 7 );
181 P( C, D, A, B, X[ 2], 11 );
182 P( B, C, D, A, X[ 3], 19 );
183 P( A, B, C, D, X[ 4], 3 );
184 P( D, A, B, C, X[ 5], 7 );
185 P( C, D, A, B, X[ 6], 11 );
186 P( B, C, D, A, X[ 7], 19 );
187 P( A, B, C, D, X[ 8], 3 );
188 P( D, A, B, C, X[ 9], 7 );
189 P( C, D, A, B, X[10], 11 );
190 P( B, C, D, A, X[11], 19 );
191 P( A, B, C, D, X[12], 3 );
192 P( D, A, B, C, X[13], 7 );
193 P( C, D, A, B, X[14], 11 );
194 P( B, C, D, A, X[15], 19 );
195
196#undef P
197#undef F
198
199#define F(x,y,z) ((x & y) | (x & z) | (y & z))
200#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
201
202 P( A, B, C, D, X[ 0], 3 );
203 P( D, A, B, C, X[ 4], 5 );
204 P( C, D, A, B, X[ 8], 9 );
205 P( B, C, D, A, X[12], 13 );
206 P( A, B, C, D, X[ 1], 3 );
207 P( D, A, B, C, X[ 5], 5 );
208 P( C, D, A, B, X[ 9], 9 );
209 P( B, C, D, A, X[13], 13 );
210 P( A, B, C, D, X[ 2], 3 );
211 P( D, A, B, C, X[ 6], 5 );
212 P( C, D, A, B, X[10], 9 );
213 P( B, C, D, A, X[14], 13 );
214 P( A, B, C, D, X[ 3], 3 );
215 P( D, A, B, C, X[ 7], 5 );
216 P( C, D, A, B, X[11], 9 );
217 P( B, C, D, A, X[15], 13 );
218
219#undef P
220#undef F
221
222#define F(x,y,z) (x ^ y ^ z)
223#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
224
225 P( A, B, C, D, X[ 0], 3 );
226 P( D, A, B, C, X[ 8], 9 );
227 P( C, D, A, B, X[ 4], 11 );
228 P( B, C, D, A, X[12], 15 );
229 P( A, B, C, D, X[ 2], 3 );
230 P( D, A, B, C, X[10], 9 );
231 P( C, D, A, B, X[ 6], 11 );
232 P( B, C, D, A, X[14], 15 );
233 P( A, B, C, D, X[ 1], 3 );
234 P( D, A, B, C, X[ 9], 9 );
235 P( C, D, A, B, X[ 5], 11 );
236 P( B, C, D, A, X[13], 15 );
237 P( A, B, C, D, X[ 3], 3 );
238 P( D, A, B, C, X[11], 9 );
239 P( C, D, A, B, X[ 7], 11 );
240 P( B, C, D, A, X[15], 15 );
241
242#undef F
243#undef P
244
245 ctx->state[0] += A;
246 ctx->state[1] += B;
247 ctx->state[2] += C;
248 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100249
gabor-mezei-armcb3a7422020-08-19 14:03:06 +0200250 /* Zeroise variables to clear sensitive data from memory. */
251 mbedtls_zeroize( &X, sizeof( X ) );
252 mbedtls_zeroize( &A, sizeof( A ) );
253 mbedtls_zeroize( &B, sizeof( B ) );
254 mbedtls_zeroize( &C, sizeof( C ) );
255 mbedtls_zeroize( &D, sizeof( D ) );
256
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100257 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000258}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000259
260#if !defined(MBEDTLS_DEPRECATED_REMOVED)
261void mbedtls_md4_process( mbedtls_md4_context *ctx,
262 const unsigned char data[64] )
263{
264 mbedtls_internal_md4_process( ctx, data );
265}
266#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200267#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000268
269/*
270 * MD4 process buffer
271 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100272int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100273 const unsigned char *input,
274 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000275{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100276 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000277 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000278 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000279
Brian White12895d12014-04-11 11:29:42 -0400280 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100281 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000282
283 left = ctx->total[0] & 0x3F;
284 fill = 64 - left;
285
Paul Bakker5c2364c2012-10-01 14:41:15 +0000286 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 ctx->total[0] &= 0xFFFFFFFF;
288
Paul Bakker5c2364c2012-10-01 14:41:15 +0000289 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 ctx->total[1]++;
291
292 if( left && ilen >= fill )
293 {
294 memcpy( (void *) (ctx->buffer + left),
295 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100296
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100297 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100298 return( ret );
299
Paul Bakker5121ce52009-01-03 21:22:43 +0000300 input += fill;
301 ilen -= fill;
302 left = 0;
303 }
304
305 while( ilen >= 64 )
306 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100307 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100308 return( ret );
309
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 input += 64;
311 ilen -= 64;
312 }
313
314 if( ilen > 0 )
315 {
316 memcpy( (void *) (ctx->buffer + left),
317 (void *) input, ilen );
318 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100319
320 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000321}
322
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000323#if !defined(MBEDTLS_DEPRECATED_REMOVED)
324void mbedtls_md4_update( mbedtls_md4_context *ctx,
325 const unsigned char *input,
326 size_t ilen )
327{
328 mbedtls_md4_update_ret( ctx, input, ilen );
329}
330#endif
331
Paul Bakker5121ce52009-01-03 21:22:43 +0000332static const unsigned char md4_padding[64] =
333{
334 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
335 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
336 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
337 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
338};
339
340/*
341 * MD4 final digest
342 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100343int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100344 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000345{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100346 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000347 uint32_t last, padn;
348 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000349 unsigned char msglen[8];
350
351 high = ( ctx->total[0] >> 29 )
352 | ( ctx->total[1] << 3 );
353 low = ( ctx->total[0] << 3 );
354
Paul Bakker5c2364c2012-10-01 14:41:15 +0000355 PUT_UINT32_LE( low, msglen, 0 );
356 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000357
358 last = ctx->total[0] & 0x3F;
359 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
360
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100361 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100362 if( ret != 0 )
363 return( ret );
364
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100365 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100366 return( ret );
367
Paul Bakker5121ce52009-01-03 21:22:43 +0000368
Paul Bakker5c2364c2012-10-01 14:41:15 +0000369 PUT_UINT32_LE( ctx->state[0], output, 0 );
370 PUT_UINT32_LE( ctx->state[1], output, 4 );
371 PUT_UINT32_LE( ctx->state[2], output, 8 );
372 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100373
374 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000375}
376
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000377#if !defined(MBEDTLS_DEPRECATED_REMOVED)
378void mbedtls_md4_finish( mbedtls_md4_context *ctx,
379 unsigned char output[16] )
380{
381 mbedtls_md4_finish_ret( ctx, output );
382}
383#endif
384
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200385#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200386
Paul Bakker5121ce52009-01-03 21:22:43 +0000387/*
388 * output = MD4( input buffer )
389 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100390int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100391 size_t ilen,
392 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000393{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100394 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100398
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100399 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100400 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100401
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100402 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100403 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100404
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100405 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100406 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100407
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100408exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100410
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100411 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412}
413
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000414#if !defined(MBEDTLS_DEPRECATED_REMOVED)
415void mbedtls_md4( const unsigned char *input,
416 size_t ilen,
417 unsigned char output[16] )
418{
419 mbedtls_md4_ret( input, ilen, output );
420}
421#endif
422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
425/*
426 * RFC 1320 test vectors
427 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100428static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000429{
Paul Bakker9af723c2014-05-01 13:03:14 +0200430 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 { "a" },
432 { "abc" },
433 { "message digest" },
434 { "abcdefghijklmnopqrstuvwxyz" },
435 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100436 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 "345678901234567890" }
438};
439
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100440static const size_t md4_test_strlen[7] =
441{
442 0, 1, 3, 14, 26, 62, 80
443};
444
Paul Bakker5121ce52009-01-03 21:22:43 +0000445static const unsigned char md4_test_sum[7][16] =
446{
447 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
448 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
449 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
450 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
451 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
452 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
453 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
454 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
455 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
456 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
457 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
458 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
459 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
460 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
461};
462
463/*
464 * Checkup routine
465 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000467{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100468 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000469 unsigned char md4sum[16];
470
471 for( i = 0; i < 7; i++ )
472 {
473 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200474 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100476 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100477 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100478 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
480 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100481 {
482 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100483 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100484 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
486 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200487 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488 }
489
490 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200491 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000492
493 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100494
495fail:
496 if( verbose != 0 )
497 mbedtls_printf( "failed\n" );
498
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100499 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000500}
501
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200502#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000503
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504#endif /* MBEDTLS_MD4_C */