blob: 156e715340e80eca2079a5fceb7c21b8446a978a [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"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#if defined(MBEDTLS_SELF_TEST)
42#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000043#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#else
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020046#define mbedtls_printf printf
47#endif /* MBEDTLS_PLATFORM_C */
48#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010049
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020050#if !defined(MBEDTLS_MD4_ALT)
51
Paul Bakker5121ce52009-01-03 21:22:43 +000052/*
53 * 32-bit integer manipulation macros (little endian)
54 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000055#ifndef GET_UINT32_LE
56#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000057{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000058 (n) = ( (uint32_t) (b)[(i) ] ) \
59 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
60 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
61 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000062}
63#endif
64
Paul Bakker5c2364c2012-10-01 14:41:15 +000065#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000066#define PUT_UINT32_LE(n,b,i) \
67{ \
68 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
69 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
70 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
71 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000072}
73#endif
74
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020076{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020078}
79
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020080void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020081{
82 if( ctx == NULL )
83 return;
84
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050085 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020086}
87
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020088void mbedtls_md4_clone( mbedtls_md4_context *dst,
89 const mbedtls_md4_context *src )
90{
91 *dst = *src;
92}
93
Paul Bakker5121ce52009-01-03 21:22:43 +000094/*
95 * MD4 context setup
96 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010097int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +000098{
99 ctx->total[0] = 0;
100 ctx->total[1] = 0;
101
102 ctx->state[0] = 0x67452301;
103 ctx->state[1] = 0xEFCDAB89;
104 ctx->state[2] = 0x98BADCFE;
105 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100106
107 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000108}
109
Jaeden Amero041039f2018-02-19 15:28:08 +0000110#if !defined(MBEDTLS_DEPRECATED_REMOVED)
111void mbedtls_md4_starts( mbedtls_md4_context *ctx )
112{
113 mbedtls_md4_starts_ret( ctx );
114}
115#endif
116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100118int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
119 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000120{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000121 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000122
Paul Bakker5c2364c2012-10-01 14:41:15 +0000123 GET_UINT32_LE( X[ 0], data, 0 );
124 GET_UINT32_LE( X[ 1], data, 4 );
125 GET_UINT32_LE( X[ 2], data, 8 );
126 GET_UINT32_LE( X[ 3], data, 12 );
127 GET_UINT32_LE( X[ 4], data, 16 );
128 GET_UINT32_LE( X[ 5], data, 20 );
129 GET_UINT32_LE( X[ 6], data, 24 );
130 GET_UINT32_LE( X[ 7], data, 28 );
131 GET_UINT32_LE( X[ 8], data, 32 );
132 GET_UINT32_LE( X[ 9], data, 36 );
133 GET_UINT32_LE( X[10], data, 40 );
134 GET_UINT32_LE( X[11], data, 44 );
135 GET_UINT32_LE( X[12], data, 48 );
136 GET_UINT32_LE( X[13], data, 52 );
137 GET_UINT32_LE( X[14], data, 56 );
138 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000139
Hanno Beckerd6028a12018-10-15 12:01:35 +0100140#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000141
142 A = ctx->state[0];
143 B = ctx->state[1];
144 C = ctx->state[2];
145 D = ctx->state[3];
146
Hanno Beckerd6028a12018-10-15 12:01:35 +0100147#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
148#define P(a,b,c,d,x,s) \
149 do \
150 { \
151 (a) += F(b,c,d) + (x); \
152 (a) = S(a,s); \
153 } while( 0 )
154
Paul Bakker5121ce52009-01-03 21:22:43 +0000155
156 P( A, B, C, D, X[ 0], 3 );
157 P( D, A, B, C, X[ 1], 7 );
158 P( C, D, A, B, X[ 2], 11 );
159 P( B, C, D, A, X[ 3], 19 );
160 P( A, B, C, D, X[ 4], 3 );
161 P( D, A, B, C, X[ 5], 7 );
162 P( C, D, A, B, X[ 6], 11 );
163 P( B, C, D, A, X[ 7], 19 );
164 P( A, B, C, D, X[ 8], 3 );
165 P( D, A, B, C, X[ 9], 7 );
166 P( C, D, A, B, X[10], 11 );
167 P( B, C, D, A, X[11], 19 );
168 P( A, B, C, D, X[12], 3 );
169 P( D, A, B, C, X[13], 7 );
170 P( C, D, A, B, X[14], 11 );
171 P( B, C, D, A, X[15], 19 );
172
173#undef P
174#undef F
175
Hanno Beckerd6028a12018-10-15 12:01:35 +0100176#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
177#define P(a,b,c,d,x,s) \
178 do \
179 { \
180 (a) += F(b,c,d) + (x) + 0x5A827999; \
181 (a) = S(a,s); \
182 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000183
184 P( A, B, C, D, X[ 0], 3 );
185 P( D, A, B, C, X[ 4], 5 );
186 P( C, D, A, B, X[ 8], 9 );
187 P( B, C, D, A, X[12], 13 );
188 P( A, B, C, D, X[ 1], 3 );
189 P( D, A, B, C, X[ 5], 5 );
190 P( C, D, A, B, X[ 9], 9 );
191 P( B, C, D, A, X[13], 13 );
192 P( A, B, C, D, X[ 2], 3 );
193 P( D, A, B, C, X[ 6], 5 );
194 P( C, D, A, B, X[10], 9 );
195 P( B, C, D, A, X[14], 13 );
196 P( A, B, C, D, X[ 3], 3 );
197 P( D, A, B, C, X[ 7], 5 );
198 P( C, D, A, B, X[11], 9 );
199 P( B, C, D, A, X[15], 13 );
200
201#undef P
202#undef F
203
Hanno Beckerd6028a12018-10-15 12:01:35 +0100204#define F(x,y,z) ((x) ^ (y) ^ (z))
205#define P(a,b,c,d,x,s) \
206 do \
207 { \
208 (a) += F(b,c,d) + (x) + 0x6ED9EBA1; \
209 (a) = S(a,s); \
210 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000211
212 P( A, B, C, D, X[ 0], 3 );
213 P( D, A, B, C, X[ 8], 9 );
214 P( C, D, A, B, X[ 4], 11 );
215 P( B, C, D, A, X[12], 15 );
216 P( A, B, C, D, X[ 2], 3 );
217 P( D, A, B, C, X[10], 9 );
218 P( C, D, A, B, X[ 6], 11 );
219 P( B, C, D, A, X[14], 15 );
220 P( A, B, C, D, X[ 1], 3 );
221 P( D, A, B, C, X[ 9], 9 );
222 P( C, D, A, B, X[ 5], 11 );
223 P( B, C, D, A, X[13], 15 );
224 P( A, B, C, D, X[ 3], 3 );
225 P( D, A, B, C, X[11], 9 );
226 P( C, D, A, B, X[ 7], 11 );
227 P( B, C, D, A, X[15], 15 );
228
229#undef F
230#undef P
231
232 ctx->state[0] += A;
233 ctx->state[1] += B;
234 ctx->state[2] += C;
235 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100236
237 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000238}
Jaeden Amero041039f2018-02-19 15:28:08 +0000239
240#if !defined(MBEDTLS_DEPRECATED_REMOVED)
241void mbedtls_md4_process( mbedtls_md4_context *ctx,
242 const unsigned char data[64] )
243{
244 mbedtls_internal_md4_process( ctx, data );
245}
246#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200247#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000248
249/*
250 * MD4 process buffer
251 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100252int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100253 const unsigned char *input,
254 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000255{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100256 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000257 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000258 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000259
Brian White12895d12014-04-11 11:29:42 -0400260 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100261 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000262
263 left = ctx->total[0] & 0x3F;
264 fill = 64 - left;
265
Paul Bakker5c2364c2012-10-01 14:41:15 +0000266 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 ctx->total[0] &= 0xFFFFFFFF;
268
Paul Bakker5c2364c2012-10-01 14:41:15 +0000269 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 ctx->total[1]++;
271
272 if( left && ilen >= fill )
273 {
274 memcpy( (void *) (ctx->buffer + left),
275 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100276
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100277 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100278 return( ret );
279
Paul Bakker5121ce52009-01-03 21:22:43 +0000280 input += fill;
281 ilen -= fill;
282 left = 0;
283 }
284
285 while( ilen >= 64 )
286 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100287 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100288 return( ret );
289
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 input += 64;
291 ilen -= 64;
292 }
293
294 if( ilen > 0 )
295 {
296 memcpy( (void *) (ctx->buffer + left),
297 (void *) input, ilen );
298 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100299
300 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000301}
302
Jaeden Amero041039f2018-02-19 15:28:08 +0000303#if !defined(MBEDTLS_DEPRECATED_REMOVED)
304void mbedtls_md4_update( mbedtls_md4_context *ctx,
305 const unsigned char *input,
306 size_t ilen )
307{
308 mbedtls_md4_update_ret( ctx, input, ilen );
309}
310#endif
311
Paul Bakker5121ce52009-01-03 21:22:43 +0000312static const unsigned char md4_padding[64] =
313{
314 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
315 0, 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};
319
320/*
321 * MD4 final digest
322 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100323int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100324 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000325{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100326 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000327 uint32_t last, padn;
328 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 unsigned char msglen[8];
330
331 high = ( ctx->total[0] >> 29 )
332 | ( ctx->total[1] << 3 );
333 low = ( ctx->total[0] << 3 );
334
Paul Bakker5c2364c2012-10-01 14:41:15 +0000335 PUT_UINT32_LE( low, msglen, 0 );
336 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337
338 last = ctx->total[0] & 0x3F;
339 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
340
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100341 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100342 if( ret != 0 )
343 return( ret );
344
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100345 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100346 return( ret );
347
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
Paul Bakker5c2364c2012-10-01 14:41:15 +0000349 PUT_UINT32_LE( ctx->state[0], output, 0 );
350 PUT_UINT32_LE( ctx->state[1], output, 4 );
351 PUT_UINT32_LE( ctx->state[2], output, 8 );
352 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100353
354 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000355}
356
Jaeden Amero041039f2018-02-19 15:28:08 +0000357#if !defined(MBEDTLS_DEPRECATED_REMOVED)
358void mbedtls_md4_finish( mbedtls_md4_context *ctx,
359 unsigned char output[16] )
360{
361 mbedtls_md4_finish_ret( ctx, output );
362}
363#endif
364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200366
Paul Bakker5121ce52009-01-03 21:22:43 +0000367/*
368 * output = MD4( input buffer )
369 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100370int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100371 size_t ilen,
372 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000373{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100374 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200375 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000376
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100378
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100379 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100380 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100381
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100382 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100383 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100384
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100385 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100386 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100387
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100388exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200389 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100390
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100391 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000392}
393
Jaeden Amero041039f2018-02-19 15:28:08 +0000394#if !defined(MBEDTLS_DEPRECATED_REMOVED)
395void mbedtls_md4( const unsigned char *input,
396 size_t ilen,
397 unsigned char output[16] )
398{
399 mbedtls_md4_ret( input, ilen, output );
400}
401#endif
402
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200403#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
405/*
406 * RFC 1320 test vectors
407 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100408static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000409{
Paul Bakker9af723c2014-05-01 13:03:14 +0200410 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 { "a" },
412 { "abc" },
413 { "message digest" },
414 { "abcdefghijklmnopqrstuvwxyz" },
415 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100416 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000417 "345678901234567890" }
418};
419
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100420static const size_t md4_test_strlen[7] =
421{
422 0, 1, 3, 14, 26, 62, 80
423};
424
Paul Bakker5121ce52009-01-03 21:22:43 +0000425static const unsigned char md4_test_sum[7][16] =
426{
427 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
428 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
429 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
430 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
431 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
432 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
433 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
434 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
435 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
436 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
437 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
438 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
439 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
440 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
441};
442
443/*
444 * Checkup routine
445 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200446int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000447{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100448 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000449 unsigned char md4sum[16];
450
451 for( i = 0; i < 7; i++ )
452 {
453 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100456 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100457 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100458 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
460 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100461 {
462 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100463 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100464 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
466 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200467 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468 }
469
470 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200471 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100474
475fail:
476 if( verbose != 0 )
477 mbedtls_printf( "failed\n" );
478
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100479 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000480}
481
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200482#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200484#endif /* MBEDTLS_MD4_C */