blob: a4122134801db1abe63e93c485e12c282b5520b3 [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é-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010037
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020038#if !defined(MBEDTLS_MD4_ALT)
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020041{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020042 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020043}
44
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020046{
47 if( ctx == NULL )
48 return;
49
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050050 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020051}
52
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020053void mbedtls_md4_clone( mbedtls_md4_context *dst,
54 const mbedtls_md4_context *src )
55{
56 *dst = *src;
57}
58
Paul Bakker5121ce52009-01-03 21:22:43 +000059/*
60 * MD4 context setup
61 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010062int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +000063{
64 ctx->total[0] = 0;
65 ctx->total[1] = 0;
66
67 ctx->state[0] = 0x67452301;
68 ctx->state[1] = 0xEFCDAB89;
69 ctx->state[2] = 0x98BADCFE;
70 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +010071
72 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +000073}
74
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +020075#if !defined(MBEDTLS_DEPRECATED_REMOVED)
76void mbedtls_md4_starts( mbedtls_md4_context *ctx )
77{
78 mbedtls_md4_starts_ret( ctx );
79}
80#endif
81
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020082#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +010083int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
84 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000085{
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +020086 struct
87 {
88 uint32_t X[16], A, B, C, D;
89 } local;
Paul Bakker5121ce52009-01-03 21:22:43 +000090
Joe Subbianica8a7cf2021-08-03 16:42:42 +010091 local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
92 local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
93 local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
94 local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
95 local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
96 local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
97 local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
98 local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
99 local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
100 local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
101 local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
102 local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
103 local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
104 local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
105 local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
106 local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
Hanno Becker1eeca412018-10-15 12:01:35 +0100108#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000109
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200110 local.A = ctx->state[0];
111 local.B = ctx->state[1];
112 local.C = ctx->state[2];
113 local.D = ctx->state[3];
Paul Bakker5121ce52009-01-03 21:22:43 +0000114
Hanno Becker1eeca412018-10-15 12:01:35 +0100115#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
Hanno Becker26d02e12018-10-30 09:29:25 +0000116#define P(a,b,c,d,x,s) \
117 do \
118 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100119 (a) += F((b),(c),(d)) + (x); \
120 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100121 } while( 0 )
122
Paul Bakker5121ce52009-01-03 21:22:43 +0000123
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200124 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
125 P( local.D, local.A, local.B, local.C, local.X[ 1], 7 );
126 P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
127 P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
128 P( local.A, local.B, local.C, local.D, local.X[ 4], 3 );
129 P( local.D, local.A, local.B, local.C, local.X[ 5], 7 );
130 P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
131 P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
132 P( local.A, local.B, local.C, local.D, local.X[ 8], 3 );
133 P( local.D, local.A, local.B, local.C, local.X[ 9], 7 );
134 P( local.C, local.D, local.A, local.B, local.X[10], 11 );
135 P( local.B, local.C, local.D, local.A, local.X[11], 19 );
136 P( local.A, local.B, local.C, local.D, local.X[12], 3 );
137 P( local.D, local.A, local.B, local.C, local.X[13], 7 );
138 P( local.C, local.D, local.A, local.B, local.X[14], 11 );
139 P( local.B, local.C, local.D, local.A, local.X[15], 19 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000140
141#undef P
142#undef F
143
Hanno Becker1eeca412018-10-15 12:01:35 +0100144#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
145#define P(a,b,c,d,x,s) \
146 do \
147 { \
Hanno Becker26d02e12018-10-30 09:29:25 +0000148 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
149 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100150 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000151
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200152 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
153 P( local.D, local.A, local.B, local.C, local.X[ 4], 5 );
154 P( local.C, local.D, local.A, local.B, local.X[ 8], 9 );
155 P( local.B, local.C, local.D, local.A, local.X[12], 13 );
156 P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
157 P( local.D, local.A, local.B, local.C, local.X[ 5], 5 );
158 P( local.C, local.D, local.A, local.B, local.X[ 9], 9 );
159 P( local.B, local.C, local.D, local.A, local.X[13], 13 );
160 P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
161 P( local.D, local.A, local.B, local.C, local.X[ 6], 5 );
162 P( local.C, local.D, local.A, local.B, local.X[10], 9 );
163 P( local.B, local.C, local.D, local.A, local.X[14], 13 );
164 P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
165 P( local.D, local.A, local.B, local.C, local.X[ 7], 5 );
166 P( local.C, local.D, local.A, local.B, local.X[11], 9 );
167 P( local.B, local.C, local.D, local.A, local.X[15], 13 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
169#undef P
170#undef F
171
Hanno Becker1eeca412018-10-15 12:01:35 +0100172#define F(x,y,z) ((x) ^ (y) ^ (z))
Hanno Becker26d02e12018-10-30 09:29:25 +0000173#define P(a,b,c,d,x,s) \
174 do \
175 { \
176 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
177 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100178 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000179
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200180 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
181 P( local.D, local.A, local.B, local.C, local.X[ 8], 9 );
182 P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
183 P( local.B, local.C, local.D, local.A, local.X[12], 15 );
184 P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
185 P( local.D, local.A, local.B, local.C, local.X[10], 9 );
186 P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
187 P( local.B, local.C, local.D, local.A, local.X[14], 15 );
188 P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
189 P( local.D, local.A, local.B, local.C, local.X[ 9], 9 );
190 P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
191 P( local.B, local.C, local.D, local.A, local.X[13], 15 );
192 P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
193 P( local.D, local.A, local.B, local.C, local.X[11], 9 );
194 P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
195 P( local.B, local.C, local.D, local.A, local.X[15], 15 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000196
197#undef F
198#undef P
199
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200200 ctx->state[0] += local.A;
201 ctx->state[1] += local.B;
202 ctx->state[2] += local.C;
203 ctx->state[3] += local.D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100204
gabor-mezei-armd1c98fc2020-08-19 14:03:06 +0200205 /* Zeroise variables to clear sensitive data from memory. */
gabor-mezei-arm4cb56f82020-08-25 19:12:01 +0200206 mbedtls_platform_zeroize( &local, sizeof( local ) );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100207
208 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000209}
Jaeden Amero041039f2018-02-19 15:28:08 +0000210
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200211#if !defined(MBEDTLS_DEPRECATED_REMOVED)
212void mbedtls_md4_process( mbedtls_md4_context *ctx,
213 const unsigned char data[64] )
214{
215 mbedtls_internal_md4_process( ctx, data );
216}
217#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200218#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000219
220/*
221 * MD4 process buffer
222 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100223int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100224 const unsigned char *input,
225 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000226{
Janos Follath24eed8d2019-11-22 13:21:35 +0000227 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000228 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000229 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000230
Brian White12895d12014-04-11 11:29:42 -0400231 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100232 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000233
234 left = ctx->total[0] & 0x3F;
235 fill = 64 - left;
236
Paul Bakker5c2364c2012-10-01 14:41:15 +0000237 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000238 ctx->total[0] &= 0xFFFFFFFF;
239
Paul Bakker5c2364c2012-10-01 14:41:15 +0000240 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000241 ctx->total[1]++;
242
243 if( left && ilen >= fill )
244 {
245 memcpy( (void *) (ctx->buffer + left),
246 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100247
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100248 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100249 return( ret );
250
Paul Bakker5121ce52009-01-03 21:22:43 +0000251 input += fill;
252 ilen -= fill;
253 left = 0;
254 }
255
256 while( ilen >= 64 )
257 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100258 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100259 return( ret );
260
Paul Bakker5121ce52009-01-03 21:22:43 +0000261 input += 64;
262 ilen -= 64;
263 }
264
265 if( ilen > 0 )
266 {
267 memcpy( (void *) (ctx->buffer + left),
268 (void *) input, ilen );
269 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100270
271 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000272}
273
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200274#if !defined(MBEDTLS_DEPRECATED_REMOVED)
275void mbedtls_md4_update( mbedtls_md4_context *ctx,
276 const unsigned char *input,
277 size_t ilen )
278{
279 mbedtls_md4_update_ret( ctx, input, ilen );
280}
281#endif
282
Paul Bakker5121ce52009-01-03 21:22:43 +0000283static const unsigned char md4_padding[64] =
284{
285 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
286 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
287 0, 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};
290
291/*
292 * MD4 final digest
293 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100294int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100295 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000296{
Janos Follath24eed8d2019-11-22 13:21:35 +0000297 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000298 uint32_t last, padn;
299 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000300 unsigned char msglen[8];
301
302 high = ( ctx->total[0] >> 29 )
303 | ( ctx->total[1] << 3 );
304 low = ( ctx->total[0] << 3 );
305
Joe Subbianica8a7cf2021-08-03 16:42:42 +0100306 MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
307 MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
309 last = ctx->total[0] & 0x3F;
310 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
311
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100312 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100313 if( ret != 0 )
314 return( ret );
315
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100316 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100317 return( ret );
318
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
Joe Subbianica8a7cf2021-08-03 16:42:42 +0100320 MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
321 MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
322 MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
323 MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100324
325 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000326}
327
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200328#if !defined(MBEDTLS_DEPRECATED_REMOVED)
329void mbedtls_md4_finish( mbedtls_md4_context *ctx,
330 unsigned char output[16] )
331{
332 mbedtls_md4_finish_ret( ctx, output );
333}
334#endif
335
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200336#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200337
Paul Bakker5121ce52009-01-03 21:22:43 +0000338/*
339 * output = MD4( input buffer )
340 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100341int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100342 size_t ilen,
343 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000344{
Janos Follath24eed8d2019-11-22 13:21:35 +0000345 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000347
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200348 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100349
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100350 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100351 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100352
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100353 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100354 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100355
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100356 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100357 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100358
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100359exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200360 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100361
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100362 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000363}
364
Manuel Pégourié-Gonnard93c08472021-04-15 12:23:55 +0200365#if !defined(MBEDTLS_DEPRECATED_REMOVED)
366void mbedtls_md4( const unsigned char *input,
367 size_t ilen,
368 unsigned char output[16] )
369{
370 mbedtls_md4_ret( input, ilen, output );
371}
372#endif
373
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200374#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
376/*
377 * RFC 1320 test vectors
378 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100379static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000380{
Paul Bakker9af723c2014-05-01 13:03:14 +0200381 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000382 { "a" },
383 { "abc" },
384 { "message digest" },
385 { "abcdefghijklmnopqrstuvwxyz" },
386 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken962e4ee2020-08-21 21:08:56 +0200387 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
Paul Bakker5121ce52009-01-03 21:22:43 +0000388};
389
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100390static const size_t md4_test_strlen[7] =
391{
392 0, 1, 3, 14, 26, 62, 80
393};
394
Paul Bakker5121ce52009-01-03 21:22:43 +0000395static const unsigned char md4_test_sum[7][16] =
396{
397 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
398 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
399 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
400 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
401 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
402 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
403 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
404 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
405 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
406 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
407 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
408 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
409 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
410 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
411};
412
413/*
414 * Checkup routine
415 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200416int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000417{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100418 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 unsigned char md4sum[16];
420
421 for( i = 0; i < 7; i++ )
422 {
423 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200424 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000425
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100426 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100427 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100428 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000429
430 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100431 {
432 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100433 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100434 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000435
436 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200437 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 }
439
440 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200441 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000442
443 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100444
445fail:
446 if( verbose != 0 )
447 mbedtls_printf( "failed\n" );
448
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100449 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450}
451
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200452#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200454#endif /* MBEDTLS_MD4_C */