blob: ac9507454b066ab6f6d2a2d2e6051ac817aa55b5 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
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 Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The MD4 algorithm was designed by Ron Rivest in 1990.
21 *
22 * http://www.ietf.org/rfc/rfc1186.txt
23 * http://www.ietf.org/rfc/rfc1320.txt
24 */
25
Gilles Peskinedb09ef62020-06-03 01:43:33 +020026#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000027
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if defined(MBEDTLS_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/md4.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050031#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000032#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Rich Evans00ab4702015-02-06 13:43:58 +000034#include <string.h>
35
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if defined(MBEDTLS_SELF_TEST)
37#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000038#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010039#else
Rich Evans00ab4702015-02-06 13:43:58 +000040#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020041#define mbedtls_printf printf
42#endif /* MBEDTLS_PLATFORM_C */
43#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010044
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020045#if !defined(MBEDTLS_MD4_ALT)
46
Paul Bakker5121ce52009-01-03 21:22:43 +000047/*
48 * 32-bit integer manipulation macros (little endian)
49 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000050#ifndef GET_UINT32_LE
51#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000052{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000053 (n) = ( (uint32_t) (b)[(i) ] ) \
54 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
55 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
56 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000057}
58#endif
59
Paul Bakker5c2364c2012-10-01 14:41:15 +000060#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000061#define PUT_UINT32_LE(n,b,i) \
62{ \
63 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
64 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
65 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
66 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000067}
68#endif
69
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020070void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020071{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020073}
74
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020075void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020076{
77 if( ctx == NULL )
78 return;
79
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050080 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020081}
82
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020083void mbedtls_md4_clone( mbedtls_md4_context *dst,
84 const mbedtls_md4_context *src )
85{
86 *dst = *src;
87}
88
Paul Bakker5121ce52009-01-03 21:22:43 +000089/*
90 * MD4 context setup
91 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010092int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +000093{
94 ctx->total[0] = 0;
95 ctx->total[1] = 0;
96
97 ctx->state[0] = 0x67452301;
98 ctx->state[1] = 0xEFCDAB89;
99 ctx->state[2] = 0x98BADCFE;
100 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100101
102 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000103}
104
Jaeden Amero041039f2018-02-19 15:28:08 +0000105#if !defined(MBEDTLS_DEPRECATED_REMOVED)
106void mbedtls_md4_starts( mbedtls_md4_context *ctx )
107{
108 mbedtls_md4_starts_ret( ctx );
109}
110#endif
111
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200112#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100113int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
114 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000115{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000116 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000117
Paul Bakker5c2364c2012-10-01 14:41:15 +0000118 GET_UINT32_LE( X[ 0], data, 0 );
119 GET_UINT32_LE( X[ 1], data, 4 );
120 GET_UINT32_LE( X[ 2], data, 8 );
121 GET_UINT32_LE( X[ 3], data, 12 );
122 GET_UINT32_LE( X[ 4], data, 16 );
123 GET_UINT32_LE( X[ 5], data, 20 );
124 GET_UINT32_LE( X[ 6], data, 24 );
125 GET_UINT32_LE( X[ 7], data, 28 );
126 GET_UINT32_LE( X[ 8], data, 32 );
127 GET_UINT32_LE( X[ 9], data, 36 );
128 GET_UINT32_LE( X[10], data, 40 );
129 GET_UINT32_LE( X[11], data, 44 );
130 GET_UINT32_LE( X[12], data, 48 );
131 GET_UINT32_LE( X[13], data, 52 );
132 GET_UINT32_LE( X[14], data, 56 );
133 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000134
Hanno Becker1eeca412018-10-15 12:01:35 +0100135#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000136
137 A = ctx->state[0];
138 B = ctx->state[1];
139 C = ctx->state[2];
140 D = ctx->state[3];
141
Hanno Becker1eeca412018-10-15 12:01:35 +0100142#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
Hanno Becker26d02e12018-10-30 09:29:25 +0000143#define P(a,b,c,d,x,s) \
144 do \
145 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100146 (a) += F((b),(c),(d)) + (x); \
147 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100148 } while( 0 )
149
Paul Bakker5121ce52009-01-03 21:22:43 +0000150
151 P( A, B, C, D, X[ 0], 3 );
152 P( D, A, B, C, X[ 1], 7 );
153 P( C, D, A, B, X[ 2], 11 );
154 P( B, C, D, A, X[ 3], 19 );
155 P( A, B, C, D, X[ 4], 3 );
156 P( D, A, B, C, X[ 5], 7 );
157 P( C, D, A, B, X[ 6], 11 );
158 P( B, C, D, A, X[ 7], 19 );
159 P( A, B, C, D, X[ 8], 3 );
160 P( D, A, B, C, X[ 9], 7 );
161 P( C, D, A, B, X[10], 11 );
162 P( B, C, D, A, X[11], 19 );
163 P( A, B, C, D, X[12], 3 );
164 P( D, A, B, C, X[13], 7 );
165 P( C, D, A, B, X[14], 11 );
166 P( B, C, D, A, X[15], 19 );
167
168#undef P
169#undef F
170
Hanno Becker1eeca412018-10-15 12:01:35 +0100171#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
172#define P(a,b,c,d,x,s) \
173 do \
174 { \
Hanno Becker26d02e12018-10-30 09:29:25 +0000175 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
176 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100177 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000178
179 P( A, B, C, D, X[ 0], 3 );
180 P( D, A, B, C, X[ 4], 5 );
181 P( C, D, A, B, X[ 8], 9 );
182 P( B, C, D, A, X[12], 13 );
183 P( A, B, C, D, X[ 1], 3 );
184 P( D, A, B, C, X[ 5], 5 );
185 P( C, D, A, B, X[ 9], 9 );
186 P( B, C, D, A, X[13], 13 );
187 P( A, B, C, D, X[ 2], 3 );
188 P( D, A, B, C, X[ 6], 5 );
189 P( C, D, A, B, X[10], 9 );
190 P( B, C, D, A, X[14], 13 );
191 P( A, B, C, D, X[ 3], 3 );
192 P( D, A, B, C, X[ 7], 5 );
193 P( C, D, A, B, X[11], 9 );
194 P( B, C, D, A, X[15], 13 );
195
196#undef P
197#undef F
198
Hanno Becker1eeca412018-10-15 12:01:35 +0100199#define F(x,y,z) ((x) ^ (y) ^ (z))
Hanno Becker26d02e12018-10-30 09:29:25 +0000200#define P(a,b,c,d,x,s) \
201 do \
202 { \
203 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
204 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100205 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000206
207 P( A, B, C, D, X[ 0], 3 );
208 P( D, A, B, C, X[ 8], 9 );
209 P( C, D, A, B, X[ 4], 11 );
210 P( B, C, D, A, X[12], 15 );
211 P( A, B, C, D, X[ 2], 3 );
212 P( D, A, B, C, X[10], 9 );
213 P( C, D, A, B, X[ 6], 11 );
214 P( B, C, D, A, X[14], 15 );
215 P( A, B, C, D, X[ 1], 3 );
216 P( D, A, B, C, X[ 9], 9 );
217 P( C, D, A, B, X[ 5], 11 );
218 P( B, C, D, A, X[13], 15 );
219 P( A, B, C, D, X[ 3], 3 );
220 P( D, A, B, C, X[11], 9 );
221 P( C, D, A, B, X[ 7], 11 );
222 P( B, C, D, A, X[15], 15 );
223
224#undef F
225#undef P
226
227 ctx->state[0] += A;
228 ctx->state[1] += B;
229 ctx->state[2] += C;
230 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100231
232 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000233}
Jaeden Amero041039f2018-02-19 15:28:08 +0000234
235#if !defined(MBEDTLS_DEPRECATED_REMOVED)
236void mbedtls_md4_process( mbedtls_md4_context *ctx,
237 const unsigned char data[64] )
238{
239 mbedtls_internal_md4_process( ctx, data );
240}
241#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200242#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
244/*
245 * MD4 process buffer
246 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100247int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100248 const unsigned char *input,
249 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000250{
Janos Follath24eed8d2019-11-22 13:21:35 +0000251 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000252 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000253 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000254
Brian White12895d12014-04-11 11:29:42 -0400255 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100256 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258 left = ctx->total[0] & 0x3F;
259 fill = 64 - left;
260
Paul Bakker5c2364c2012-10-01 14:41:15 +0000261 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000262 ctx->total[0] &= 0xFFFFFFFF;
263
Paul Bakker5c2364c2012-10-01 14:41:15 +0000264 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000265 ctx->total[1]++;
266
267 if( left && ilen >= fill )
268 {
269 memcpy( (void *) (ctx->buffer + left),
270 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100271
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100272 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100273 return( ret );
274
Paul Bakker5121ce52009-01-03 21:22:43 +0000275 input += fill;
276 ilen -= fill;
277 left = 0;
278 }
279
280 while( ilen >= 64 )
281 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100282 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100283 return( ret );
284
Paul Bakker5121ce52009-01-03 21:22:43 +0000285 input += 64;
286 ilen -= 64;
287 }
288
289 if( ilen > 0 )
290 {
291 memcpy( (void *) (ctx->buffer + left),
292 (void *) input, ilen );
293 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100294
295 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000296}
297
Jaeden Amero041039f2018-02-19 15:28:08 +0000298#if !defined(MBEDTLS_DEPRECATED_REMOVED)
299void mbedtls_md4_update( mbedtls_md4_context *ctx,
300 const unsigned char *input,
301 size_t ilen )
302{
303 mbedtls_md4_update_ret( ctx, input, ilen );
304}
305#endif
306
Paul Bakker5121ce52009-01-03 21:22:43 +0000307static const unsigned char md4_padding[64] =
308{
309 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
313};
314
315/*
316 * MD4 final digest
317 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100318int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100319 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000320{
Janos Follath24eed8d2019-11-22 13:21:35 +0000321 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000322 uint32_t last, padn;
323 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000324 unsigned char msglen[8];
325
326 high = ( ctx->total[0] >> 29 )
327 | ( ctx->total[1] << 3 );
328 low = ( ctx->total[0] << 3 );
329
Paul Bakker5c2364c2012-10-01 14:41:15 +0000330 PUT_UINT32_LE( low, msglen, 0 );
331 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
333 last = ctx->total[0] & 0x3F;
334 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
335
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100336 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100337 if( ret != 0 )
338 return( ret );
339
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100340 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100341 return( ret );
342
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
Paul Bakker5c2364c2012-10-01 14:41:15 +0000344 PUT_UINT32_LE( ctx->state[0], output, 0 );
345 PUT_UINT32_LE( ctx->state[1], output, 4 );
346 PUT_UINT32_LE( ctx->state[2], output, 8 );
347 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100348
349 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000350}
351
Jaeden Amero041039f2018-02-19 15:28:08 +0000352#if !defined(MBEDTLS_DEPRECATED_REMOVED)
353void mbedtls_md4_finish( mbedtls_md4_context *ctx,
354 unsigned char output[16] )
355{
356 mbedtls_md4_finish_ret( ctx, output );
357}
358#endif
359
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200361
Paul Bakker5121ce52009-01-03 21:22:43 +0000362/*
363 * output = MD4( input buffer )
364 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100365int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100366 size_t ilen,
367 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000368{
Janos Follath24eed8d2019-11-22 13:21:35 +0000369 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200370 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000371
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100373
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100374 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100375 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100376
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100377 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100378 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100379
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100380 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100381 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100382
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100383exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200384 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100385
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100386 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000387}
388
Jaeden Amero041039f2018-02-19 15:28:08 +0000389#if !defined(MBEDTLS_DEPRECATED_REMOVED)
390void mbedtls_md4( const unsigned char *input,
391 size_t ilen,
392 unsigned char output[16] )
393{
394 mbedtls_md4_ret( input, ilen, output );
395}
396#endif
397
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200398#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
400/*
401 * RFC 1320 test vectors
402 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100403static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000404{
Paul Bakker9af723c2014-05-01 13:03:14 +0200405 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 { "a" },
407 { "abc" },
408 { "message digest" },
409 { "abcdefghijklmnopqrstuvwxyz" },
410 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100411 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 "345678901234567890" }
413};
414
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100415static const size_t md4_test_strlen[7] =
416{
417 0, 1, 3, 14, 26, 62, 80
418};
419
Paul Bakker5121ce52009-01-03 21:22:43 +0000420static const unsigned char md4_test_sum[7][16] =
421{
422 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
423 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
424 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
425 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
426 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
427 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
428 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
429 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
430 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
431 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
432 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
433 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
434 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
435 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
436};
437
438/*
439 * Checkup routine
440 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000442{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100443 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 unsigned char md4sum[16];
445
446 for( i = 0; i < 7; i++ )
447 {
448 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200449 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100451 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100452 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100453 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
455 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100456 {
457 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100458 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100459 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200462 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 }
464
465 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200466 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
468 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100469
470fail:
471 if( verbose != 0 )
472 mbedtls_printf( "failed\n" );
473
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100474 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475}
476
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200477#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000478
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479#endif /* MBEDTLS_MD4_C */