blob: eb22fcd02bc14e1254592c1e436b8fe0359cf6b3 [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/platform.h"
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010039
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020040#if !defined(MBEDTLS_MD4_ALT)
41
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020043{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020044 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020045}
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020048{
49 if( ctx == NULL )
50 return;
51
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050052 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020053}
54
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020055void mbedtls_md4_clone( mbedtls_md4_context *dst,
56 const mbedtls_md4_context *src )
57{
58 *dst = *src;
59}
60
Paul Bakker5121ce52009-01-03 21:22:43 +000061/*
62 * MD4 context setup
63 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010064int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +000065{
66 ctx->total[0] = 0;
67 ctx->total[1] = 0;
68
69 ctx->state[0] = 0x67452301;
70 ctx->state[1] = 0xEFCDAB89;
71 ctx->state[2] = 0x98BADCFE;
72 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +010073
74 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +000075}
76
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020077#if !defined(MBEDTLS_DEPRECATED_REMOVED)
78void mbedtls_md4_starts( mbedtls_md4_context *ctx )
79{
80 mbedtls_md4_starts_ret( ctx );
81}
82#endif
83
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +010085int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
86 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000087{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020088 struct
89 {
90 uint32_t X[16], A, B, C, D;
91 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +000092
Joe Subbianica8a7cf2021-08-03 16:42:42 +010093 local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
94 local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
95 local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
96 local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
97 local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
98 local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
99 local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
100 local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
101 local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
102 local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
103 local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
104 local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
105 local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
106 local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
107 local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
108 local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000109
Hanno Becker1eeca412018-10-15 12:01:35 +0100110#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000111
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200112 local.A = ctx->state[0];
113 local.B = ctx->state[1];
114 local.C = ctx->state[2];
115 local.D = ctx->state[3];
Paul Bakker5121ce52009-01-03 21:22:43 +0000116
Hanno Becker1eeca412018-10-15 12:01:35 +0100117#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
Hanno Becker26d02e12018-10-30 09:29:25 +0000118#define P(a,b,c,d,x,s) \
119 do \
120 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100121 (a) += F((b),(c),(d)) + (x); \
122 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100123 } while( 0 )
124
Paul Bakker5121ce52009-01-03 21:22:43 +0000125
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200126 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
127 P( local.D, local.A, local.B, local.C, local.X[ 1], 7 );
128 P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
129 P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
130 P( local.A, local.B, local.C, local.D, local.X[ 4], 3 );
131 P( local.D, local.A, local.B, local.C, local.X[ 5], 7 );
132 P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
133 P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
134 P( local.A, local.B, local.C, local.D, local.X[ 8], 3 );
135 P( local.D, local.A, local.B, local.C, local.X[ 9], 7 );
136 P( local.C, local.D, local.A, local.B, local.X[10], 11 );
137 P( local.B, local.C, local.D, local.A, local.X[11], 19 );
138 P( local.A, local.B, local.C, local.D, local.X[12], 3 );
139 P( local.D, local.A, local.B, local.C, local.X[13], 7 );
140 P( local.C, local.D, local.A, local.B, local.X[14], 11 );
141 P( local.B, local.C, local.D, local.A, local.X[15], 19 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000142
143#undef P
144#undef F
145
Hanno Becker1eeca412018-10-15 12:01:35 +0100146#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
147#define P(a,b,c,d,x,s) \
148 do \
149 { \
Hanno Becker26d02e12018-10-30 09:29:25 +0000150 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
151 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100152 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000153
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200154 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
155 P( local.D, local.A, local.B, local.C, local.X[ 4], 5 );
156 P( local.C, local.D, local.A, local.B, local.X[ 8], 9 );
157 P( local.B, local.C, local.D, local.A, local.X[12], 13 );
158 P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
159 P( local.D, local.A, local.B, local.C, local.X[ 5], 5 );
160 P( local.C, local.D, local.A, local.B, local.X[ 9], 9 );
161 P( local.B, local.C, local.D, local.A, local.X[13], 13 );
162 P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
163 P( local.D, local.A, local.B, local.C, local.X[ 6], 5 );
164 P( local.C, local.D, local.A, local.B, local.X[10], 9 );
165 P( local.B, local.C, local.D, local.A, local.X[14], 13 );
166 P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
167 P( local.D, local.A, local.B, local.C, local.X[ 7], 5 );
168 P( local.C, local.D, local.A, local.B, local.X[11], 9 );
169 P( local.B, local.C, local.D, local.A, local.X[15], 13 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
171#undef P
172#undef F
173
Hanno Becker1eeca412018-10-15 12:01:35 +0100174#define F(x,y,z) ((x) ^ (y) ^ (z))
Hanno Becker26d02e12018-10-30 09:29:25 +0000175#define P(a,b,c,d,x,s) \
176 do \
177 { \
178 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
179 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100180 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000181
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200182 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
183 P( local.D, local.A, local.B, local.C, local.X[ 8], 9 );
184 P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
185 P( local.B, local.C, local.D, local.A, local.X[12], 15 );
186 P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
187 P( local.D, local.A, local.B, local.C, local.X[10], 9 );
188 P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
189 P( local.B, local.C, local.D, local.A, local.X[14], 15 );
190 P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
191 P( local.D, local.A, local.B, local.C, local.X[ 9], 9 );
192 P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
193 P( local.B, local.C, local.D, local.A, local.X[13], 15 );
194 P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
195 P( local.D, local.A, local.B, local.C, local.X[11], 9 );
196 P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
197 P( local.B, local.C, local.D, local.A, local.X[15], 15 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000198
199#undef F
200#undef P
201
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200202 ctx->state[0] += local.A;
203 ctx->state[1] += local.B;
204 ctx->state[2] += local.C;
205 ctx->state[3] += local.D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100206
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200207 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200208 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100209
210 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000211}
Jaeden Amero041039f2018-02-19 15:28:08 +0000212
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200213#if !defined(MBEDTLS_DEPRECATED_REMOVED)
214void mbedtls_md4_process( mbedtls_md4_context *ctx,
215 const unsigned char data[64] )
216{
217 mbedtls_internal_md4_process( ctx, data );
218}
219#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000221
222/*
223 * MD4 process buffer
224 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100225int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100226 const unsigned char *input,
227 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000228{
Janos Follath24eed8d2019-11-22 13:21:35 +0000229 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000230 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000231 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000232
Brian White12895d12014-04-11 11:29:42 -0400233 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100234 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000235
236 left = ctx->total[0] & 0x3F;
237 fill = 64 - left;
238
Paul Bakker5c2364c2012-10-01 14:41:15 +0000239 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 ctx->total[0] &= 0xFFFFFFFF;
241
Paul Bakker5c2364c2012-10-01 14:41:15 +0000242 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000243 ctx->total[1]++;
244
245 if( left && ilen >= fill )
246 {
247 memcpy( (void *) (ctx->buffer + left),
248 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100249
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100250 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100251 return( ret );
252
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 input += fill;
254 ilen -= fill;
255 left = 0;
256 }
257
258 while( ilen >= 64 )
259 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100260 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100261 return( ret );
262
Paul Bakker5121ce52009-01-03 21:22:43 +0000263 input += 64;
264 ilen -= 64;
265 }
266
267 if( ilen > 0 )
268 {
269 memcpy( (void *) (ctx->buffer + left),
270 (void *) input, ilen );
271 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100272
273 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000274}
275
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200276#if !defined(MBEDTLS_DEPRECATED_REMOVED)
277void mbedtls_md4_update( mbedtls_md4_context *ctx,
278 const unsigned char *input,
279 size_t ilen )
280{
281 mbedtls_md4_update_ret( ctx, input, ilen );
282}
283#endif
284
Paul Bakker5121ce52009-01-03 21:22:43 +0000285static const unsigned char md4_padding[64] =
286{
287 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
288 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
290 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
291};
292
293/*
294 * MD4 final digest
295 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100296int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100297 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000298{
Janos Follath24eed8d2019-11-22 13:21:35 +0000299 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000300 uint32_t last, padn;
301 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000302 unsigned char msglen[8];
303
304 high = ( ctx->total[0] >> 29 )
305 | ( ctx->total[1] << 3 );
306 low = ( ctx->total[0] << 3 );
307
Joe Subbianica8a7cf2021-08-03 16:42:42 +0100308 MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
309 MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
311 last = ctx->total[0] & 0x3F;
312 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
313
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100314 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100315 if( ret != 0 )
316 return( ret );
317
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100318 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100319 return( ret );
320
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
Joe Subbianica8a7cf2021-08-03 16:42:42 +0100322 MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
323 MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
324 MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
325 MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100326
327 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000328}
329
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200330#if !defined(MBEDTLS_DEPRECATED_REMOVED)
331void mbedtls_md4_finish( mbedtls_md4_context *ctx,
332 unsigned char output[16] )
333{
334 mbedtls_md4_finish_ret( ctx, output );
335}
336#endif
337
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200338#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200339
Paul Bakker5121ce52009-01-03 21:22:43 +0000340/*
341 * output = MD4( input buffer )
342 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100343int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100344 size_t ilen,
345 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000346{
Janos Follath24eed8d2019-11-22 13:21:35 +0000347 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000349
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100351
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100352 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 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_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100356 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100357
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100358 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100359 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100360
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100361exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100363
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100364 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000365}
366
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200367#if !defined(MBEDTLS_DEPRECATED_REMOVED)
368void mbedtls_md4( const unsigned char *input,
369 size_t ilen,
370 unsigned char output[16] )
371{
372 mbedtls_md4_ret( input, ilen, output );
373}
374#endif
375
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200376#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000377
378/*
379 * RFC 1320 test vectors
380 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100381static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000382{
Paul Bakker9af723c2014-05-01 13:03:14 +0200383 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 { "a" },
385 { "abc" },
386 { "message digest" },
387 { "abcdefghijklmnopqrstuvwxyz" },
388 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200389 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
Paul Bakker5121ce52009-01-03 21:22:43 +0000390};
391
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100392static const size_t md4_test_strlen[7] =
393{
394 0, 1, 3, 14, 26, 62, 80
395};
396
Paul Bakker5121ce52009-01-03 21:22:43 +0000397static const unsigned char md4_test_sum[7][16] =
398{
399 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
400 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
401 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
402 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
403 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
404 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
405 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
406 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
407 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
408 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
409 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
410 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
411 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
412 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
413};
414
415/*
416 * Checkup routine
417 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000419{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100420 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000421 unsigned char md4sum[16];
422
423 for( i = 0; i < 7; i++ )
424 {
425 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200426 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100428 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100429 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100430 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
432 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100433 {
434 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100435 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100436 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
438 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200439 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440 }
441
442 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
445 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100446
447fail:
448 if( verbose != 0 )
449 mbedtls_printf( "failed\n" );
450
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100451 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452}
453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000455
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200456#endif /* MBEDTLS_MD4_C */