blob: c366c0de800c1ca874e6731824dba046e6c9550d [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
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200105#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100106int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
107 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000108{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200109 struct
110 {
111 uint32_t X[16], A, B, C, D;
112 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +0000113
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200114 GET_UINT32_LE( local.X[ 0], data, 0 );
115 GET_UINT32_LE( local.X[ 1], data, 4 );
116 GET_UINT32_LE( local.X[ 2], data, 8 );
117 GET_UINT32_LE( local.X[ 3], data, 12 );
118 GET_UINT32_LE( local.X[ 4], data, 16 );
119 GET_UINT32_LE( local.X[ 5], data, 20 );
120 GET_UINT32_LE( local.X[ 6], data, 24 );
121 GET_UINT32_LE( local.X[ 7], data, 28 );
122 GET_UINT32_LE( local.X[ 8], data, 32 );
123 GET_UINT32_LE( local.X[ 9], data, 36 );
124 GET_UINT32_LE( local.X[10], data, 40 );
125 GET_UINT32_LE( local.X[11], data, 44 );
126 GET_UINT32_LE( local.X[12], data, 48 );
127 GET_UINT32_LE( local.X[13], data, 52 );
128 GET_UINT32_LE( local.X[14], data, 56 );
129 GET_UINT32_LE( local.X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000130
Hanno Becker1eeca412018-10-15 12:01:35 +0100131#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000132
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200133 local.A = ctx->state[0];
134 local.B = ctx->state[1];
135 local.C = ctx->state[2];
136 local.D = ctx->state[3];
Paul Bakker5121ce52009-01-03 21:22:43 +0000137
Hanno Becker1eeca412018-10-15 12:01:35 +0100138#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
Hanno Becker26d02e12018-10-30 09:29:25 +0000139#define P(a,b,c,d,x,s) \
140 do \
141 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100142 (a) += F((b),(c),(d)) + (x); \
143 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100144 } while( 0 )
145
Paul Bakker5121ce52009-01-03 21:22:43 +0000146
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200147 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
148 P( local.D, local.A, local.B, local.C, local.X[ 1], 7 );
149 P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
150 P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
151 P( local.A, local.B, local.C, local.D, local.X[ 4], 3 );
152 P( local.D, local.A, local.B, local.C, local.X[ 5], 7 );
153 P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
154 P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
155 P( local.A, local.B, local.C, local.D, local.X[ 8], 3 );
156 P( local.D, local.A, local.B, local.C, local.X[ 9], 7 );
157 P( local.C, local.D, local.A, local.B, local.X[10], 11 );
158 P( local.B, local.C, local.D, local.A, local.X[11], 19 );
159 P( local.A, local.B, local.C, local.D, local.X[12], 3 );
160 P( local.D, local.A, local.B, local.C, local.X[13], 7 );
161 P( local.C, local.D, local.A, local.B, local.X[14], 11 );
162 P( local.B, local.C, local.D, local.A, local.X[15], 19 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000163
164#undef P
165#undef F
166
Hanno Becker1eeca412018-10-15 12:01:35 +0100167#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
168#define P(a,b,c,d,x,s) \
169 do \
170 { \
Hanno Becker26d02e12018-10-30 09:29:25 +0000171 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
172 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100173 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000174
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200175 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
176 P( local.D, local.A, local.B, local.C, local.X[ 4], 5 );
177 P( local.C, local.D, local.A, local.B, local.X[ 8], 9 );
178 P( local.B, local.C, local.D, local.A, local.X[12], 13 );
179 P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
180 P( local.D, local.A, local.B, local.C, local.X[ 5], 5 );
181 P( local.C, local.D, local.A, local.B, local.X[ 9], 9 );
182 P( local.B, local.C, local.D, local.A, local.X[13], 13 );
183 P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
184 P( local.D, local.A, local.B, local.C, local.X[ 6], 5 );
185 P( local.C, local.D, local.A, local.B, local.X[10], 9 );
186 P( local.B, local.C, local.D, local.A, local.X[14], 13 );
187 P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
188 P( local.D, local.A, local.B, local.C, local.X[ 7], 5 );
189 P( local.C, local.D, local.A, local.B, local.X[11], 9 );
190 P( local.B, local.C, local.D, local.A, local.X[15], 13 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000191
192#undef P
193#undef F
194
Hanno Becker1eeca412018-10-15 12:01:35 +0100195#define F(x,y,z) ((x) ^ (y) ^ (z))
Hanno Becker26d02e12018-10-30 09:29:25 +0000196#define P(a,b,c,d,x,s) \
197 do \
198 { \
199 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
200 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100201 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000202
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200203 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
204 P( local.D, local.A, local.B, local.C, local.X[ 8], 9 );
205 P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
206 P( local.B, local.C, local.D, local.A, local.X[12], 15 );
207 P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
208 P( local.D, local.A, local.B, local.C, local.X[10], 9 );
209 P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
210 P( local.B, local.C, local.D, local.A, local.X[14], 15 );
211 P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
212 P( local.D, local.A, local.B, local.C, local.X[ 9], 9 );
213 P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
214 P( local.B, local.C, local.D, local.A, local.X[13], 15 );
215 P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
216 P( local.D, local.A, local.B, local.C, local.X[11], 9 );
217 P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
218 P( local.B, local.C, local.D, local.A, local.X[15], 15 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
220#undef F
221#undef P
222
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200223 ctx->state[0] += local.A;
224 ctx->state[1] += local.B;
225 ctx->state[2] += local.C;
226 ctx->state[3] += local.D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100227
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200228 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200229 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100230
231 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000232}
Jaeden Amero041039f2018-02-19 15:28:08 +0000233
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200234#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000235
236/*
237 * MD4 process buffer
238 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100239int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100240 const unsigned char *input,
241 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000242{
Janos Follath24eed8d2019-11-22 13:21:35 +0000243 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000244 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000245 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000246
Brian White12895d12014-04-11 11:29:42 -0400247 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100248 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000249
250 left = ctx->total[0] & 0x3F;
251 fill = 64 - left;
252
Paul Bakker5c2364c2012-10-01 14:41:15 +0000253 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000254 ctx->total[0] &= 0xFFFFFFFF;
255
Paul Bakker5c2364c2012-10-01 14:41:15 +0000256 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000257 ctx->total[1]++;
258
259 if( left && ilen >= fill )
260 {
261 memcpy( (void *) (ctx->buffer + left),
262 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100263
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100264 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100265 return( ret );
266
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 input += fill;
268 ilen -= fill;
269 left = 0;
270 }
271
272 while( ilen >= 64 )
273 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100274 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100275 return( ret );
276
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 input += 64;
278 ilen -= 64;
279 }
280
281 if( ilen > 0 )
282 {
283 memcpy( (void *) (ctx->buffer + left),
284 (void *) input, ilen );
285 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100286
287 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000288}
289
290static const unsigned char md4_padding[64] =
291{
292 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
293 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
294 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
295 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
296};
297
298/*
299 * MD4 final digest
300 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100301int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100302 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000303{
Janos Follath24eed8d2019-11-22 13:21:35 +0000304 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000305 uint32_t last, padn;
306 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000307 unsigned char msglen[8];
308
309 high = ( ctx->total[0] >> 29 )
310 | ( ctx->total[1] << 3 );
311 low = ( ctx->total[0] << 3 );
312
Paul Bakker5c2364c2012-10-01 14:41:15 +0000313 PUT_UINT32_LE( low, msglen, 0 );
314 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000315
316 last = ctx->total[0] & 0x3F;
317 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
318
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100319 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100320 if( ret != 0 )
321 return( ret );
322
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100323 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100324 return( ret );
325
Paul Bakker5121ce52009-01-03 21:22:43 +0000326
Paul Bakker5c2364c2012-10-01 14:41:15 +0000327 PUT_UINT32_LE( ctx->state[0], output, 0 );
328 PUT_UINT32_LE( ctx->state[1], output, 4 );
329 PUT_UINT32_LE( ctx->state[2], output, 8 );
330 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100331
332 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000333}
334
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200335#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200336
Paul Bakker5121ce52009-01-03 21:22:43 +0000337/*
338 * output = MD4( input buffer )
339 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100340int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100341 size_t ilen,
342 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000343{
Janos Follath24eed8d2019-11-22 13:21:35 +0000344 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200347 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100348
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100349 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100350 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100351
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100352 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100353 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100354
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100355 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100356 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100357
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100358exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200359 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100360
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100361 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000362}
363
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200364#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000365
366/*
367 * RFC 1320 test vectors
368 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100369static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000370{
Paul Bakker9af723c2014-05-01 13:03:14 +0200371 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000372 { "a" },
373 { "abc" },
374 { "message digest" },
375 { "abcdefghijklmnopqrstuvwxyz" },
376 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200377 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
Paul Bakker5121ce52009-01-03 21:22:43 +0000378};
379
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100380static const size_t md4_test_strlen[7] =
381{
382 0, 1, 3, 14, 26, 62, 80
383};
384
Paul Bakker5121ce52009-01-03 21:22:43 +0000385static const unsigned char md4_test_sum[7][16] =
386{
387 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
388 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
389 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
390 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
391 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
392 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
393 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
394 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
395 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
396 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
397 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
398 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
399 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
400 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
401};
402
403/*
404 * Checkup routine
405 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000407{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100408 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000409 unsigned char md4sum[16];
410
411 for( i = 0; i < 7; i++ )
412 {
413 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100416 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100417 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100418 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100421 {
422 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100423 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100424 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
426 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200427 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000428 }
429
430 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432
433 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100434
435fail:
436 if( verbose != 0 )
437 mbedtls_printf( "failed\n" );
438
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100439 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440}
441
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000443
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200444#endif /* MBEDTLS_MD4_C */