blob: 69825595f660eb7c0fa130a80633a1e2147a620c [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
250 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000251}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000252
253#if !defined(MBEDTLS_DEPRECATED_REMOVED)
254void mbedtls_md4_process( mbedtls_md4_context *ctx,
255 const unsigned char data[64] )
256{
257 mbedtls_internal_md4_process( ctx, data );
258}
259#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200260#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000261
262/*
263 * MD4 process buffer
264 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100265int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100266 const unsigned char *input,
267 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000268{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100269 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000270 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000271 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000272
Brian White12895d12014-04-11 11:29:42 -0400273 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100274 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000275
276 left = ctx->total[0] & 0x3F;
277 fill = 64 - left;
278
Paul Bakker5c2364c2012-10-01 14:41:15 +0000279 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 ctx->total[0] &= 0xFFFFFFFF;
281
Paul Bakker5c2364c2012-10-01 14:41:15 +0000282 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 ctx->total[1]++;
284
285 if( left && ilen >= fill )
286 {
287 memcpy( (void *) (ctx->buffer + left),
288 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100289
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100290 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100291 return( ret );
292
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 input += fill;
294 ilen -= fill;
295 left = 0;
296 }
297
298 while( ilen >= 64 )
299 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100300 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100301 return( ret );
302
Paul Bakker5121ce52009-01-03 21:22:43 +0000303 input += 64;
304 ilen -= 64;
305 }
306
307 if( ilen > 0 )
308 {
309 memcpy( (void *) (ctx->buffer + left),
310 (void *) input, ilen );
311 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100312
313 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000314}
315
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000316#if !defined(MBEDTLS_DEPRECATED_REMOVED)
317void mbedtls_md4_update( mbedtls_md4_context *ctx,
318 const unsigned char *input,
319 size_t ilen )
320{
321 mbedtls_md4_update_ret( ctx, input, ilen );
322}
323#endif
324
Paul Bakker5121ce52009-01-03 21:22:43 +0000325static const unsigned char md4_padding[64] =
326{
327 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
328 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
329 0, 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};
332
333/*
334 * MD4 final digest
335 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100336int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100337 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000338{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100339 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000340 uint32_t last, padn;
341 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000342 unsigned char msglen[8];
343
344 high = ( ctx->total[0] >> 29 )
345 | ( ctx->total[1] << 3 );
346 low = ( ctx->total[0] << 3 );
347
Paul Bakker5c2364c2012-10-01 14:41:15 +0000348 PUT_UINT32_LE( low, msglen, 0 );
349 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351 last = ctx->total[0] & 0x3F;
352 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
353
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100354 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100355 if( ret != 0 )
356 return( ret );
357
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100358 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100359 return( ret );
360
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
Paul Bakker5c2364c2012-10-01 14:41:15 +0000362 PUT_UINT32_LE( ctx->state[0], output, 0 );
363 PUT_UINT32_LE( ctx->state[1], output, 4 );
364 PUT_UINT32_LE( ctx->state[2], output, 8 );
365 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100366
367 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000368}
369
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000370#if !defined(MBEDTLS_DEPRECATED_REMOVED)
371void mbedtls_md4_finish( mbedtls_md4_context *ctx,
372 unsigned char output[16] )
373{
374 mbedtls_md4_finish_ret( ctx, output );
375}
376#endif
377
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200379
Paul Bakker5121ce52009-01-03 21:22:43 +0000380/*
381 * output = MD4( input buffer )
382 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100383int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100384 size_t ilen,
385 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000386{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100387 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200390 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100391
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100392 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100393 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100394
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100395 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100396 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100397
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100398 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100399 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100400
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100401exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200402 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100403
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100404 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405}
406
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000407#if !defined(MBEDTLS_DEPRECATED_REMOVED)
408void mbedtls_md4( const unsigned char *input,
409 size_t ilen,
410 unsigned char output[16] )
411{
412 mbedtls_md4_ret( input, ilen, output );
413}
414#endif
415
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000417
418/*
419 * RFC 1320 test vectors
420 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100421static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000422{
Paul Bakker9af723c2014-05-01 13:03:14 +0200423 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 { "a" },
425 { "abc" },
426 { "message digest" },
427 { "abcdefghijklmnopqrstuvwxyz" },
428 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100429 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 "345678901234567890" }
431};
432
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100433static const size_t md4_test_strlen[7] =
434{
435 0, 1, 3, 14, 26, 62, 80
436};
437
Paul Bakker5121ce52009-01-03 21:22:43 +0000438static const unsigned char md4_test_sum[7][16] =
439{
440 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
441 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
442 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
443 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
444 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
445 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
446 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
447 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
448 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
449 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
450 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
451 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
452 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
453 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
454};
455
456/*
457 * Checkup routine
458 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000460{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100461 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000462 unsigned char md4sum[16];
463
464 for( i = 0; i < 7; i++ )
465 {
466 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100469 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100470 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100471 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100474 {
475 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100476 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100477 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
479 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200480 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000481 }
482
483 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000485
486 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100487
488fail:
489 if( verbose != 0 )
490 mbedtls_printf( "failed\n" );
491
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100492 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000493}
494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200495#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000496
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200497#endif /* MBEDTLS_MD4_C */