blob: eaa679a0a6eee95d436ef2f979fd30d8cfd5ec81 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Jerome Forissier79013242021-07-28 10:24:04 +02004 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
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.
Jens Wiklander817466c2018-05-22 13:49:31 +020018 */
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
Jerome Forissier79013242021-07-28 10:24:04 +020026#include "common.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020027
28#if defined(MBEDTLS_MD4_C)
29
30#include "mbedtls/md4.h"
Jens Wiklander3d3b0592019-03-20 15:30:29 +010031#include "mbedtls/platform_util.h"
Jerome Forissier11fa71b2020-04-20 17:17:56 +020032#include "mbedtls/error.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020033
34#include <string.h>
35
36#if defined(MBEDTLS_SELF_TEST)
37#if defined(MBEDTLS_PLATFORM_C)
38#include "mbedtls/platform.h"
39#else
40#include <stdio.h>
41#define mbedtls_printf printf
42#endif /* MBEDTLS_PLATFORM_C */
43#endif /* MBEDTLS_SELF_TEST */
44
45#if !defined(MBEDTLS_MD4_ALT)
46
Jens Wiklander817466c2018-05-22 13:49:31 +020047void mbedtls_md4_init( mbedtls_md4_context *ctx )
48{
49 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
50}
51
52void mbedtls_md4_free( mbedtls_md4_context *ctx )
53{
54 if( ctx == NULL )
55 return;
56
Jens Wiklander3d3b0592019-03-20 15:30:29 +010057 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Jens Wiklander817466c2018-05-22 13:49:31 +020058}
59
60void mbedtls_md4_clone( mbedtls_md4_context *dst,
61 const mbedtls_md4_context *src )
62{
63 *dst = *src;
64}
65
66/*
67 * MD4 context setup
68 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +010069int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Jens Wiklander817466c2018-05-22 13:49:31 +020070{
71 ctx->total[0] = 0;
72 ctx->total[1] = 0;
73
74 ctx->state[0] = 0x67452301;
75 ctx->state[1] = 0xEFCDAB89;
76 ctx->state[2] = 0x98BADCFE;
77 ctx->state[3] = 0x10325476;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010078
79 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +020080}
81
Jens Wiklander3d3b0592019-03-20 15:30:29 +010082#if !defined(MBEDTLS_DEPRECATED_REMOVED)
83void mbedtls_md4_starts( mbedtls_md4_context *ctx )
84{
85 mbedtls_md4_starts_ret( ctx );
86}
87#endif
88
Jens Wiklander817466c2018-05-22 13:49:31 +020089#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Jens Wiklander3d3b0592019-03-20 15:30:29 +010090int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
91 const unsigned char data[64] )
Jens Wiklander817466c2018-05-22 13:49:31 +020092{
Jerome Forissier79013242021-07-28 10:24:04 +020093 struct
94 {
95 uint32_t X[16], A, B, C, D;
96 } local;
Jens Wiklander817466c2018-05-22 13:49:31 +020097
Jerome Forissier039e02d2022-08-09 17:10:15 +020098 local.X[ 0] = MBEDTLS_GET_UINT32_LE( data, 0 );
99 local.X[ 1] = MBEDTLS_GET_UINT32_LE( data, 4 );
100 local.X[ 2] = MBEDTLS_GET_UINT32_LE( data, 8 );
101 local.X[ 3] = MBEDTLS_GET_UINT32_LE( data, 12 );
102 local.X[ 4] = MBEDTLS_GET_UINT32_LE( data, 16 );
103 local.X[ 5] = MBEDTLS_GET_UINT32_LE( data, 20 );
104 local.X[ 6] = MBEDTLS_GET_UINT32_LE( data, 24 );
105 local.X[ 7] = MBEDTLS_GET_UINT32_LE( data, 28 );
106 local.X[ 8] = MBEDTLS_GET_UINT32_LE( data, 32 );
107 local.X[ 9] = MBEDTLS_GET_UINT32_LE( data, 36 );
108 local.X[10] = MBEDTLS_GET_UINT32_LE( data, 40 );
109 local.X[11] = MBEDTLS_GET_UINT32_LE( data, 44 );
110 local.X[12] = MBEDTLS_GET_UINT32_LE( data, 48 );
111 local.X[13] = MBEDTLS_GET_UINT32_LE( data, 52 );
112 local.X[14] = MBEDTLS_GET_UINT32_LE( data, 56 );
113 local.X[15] = MBEDTLS_GET_UINT32_LE( data, 60 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200114
Jerome Forissier5b25c762020-04-07 11:18:49 +0200115#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Jens Wiklander817466c2018-05-22 13:49:31 +0200116
Jerome Forissier79013242021-07-28 10:24:04 +0200117 local.A = ctx->state[0];
118 local.B = ctx->state[1];
119 local.C = ctx->state[2];
120 local.D = ctx->state[3];
Jens Wiklander817466c2018-05-22 13:49:31 +0200121
Jerome Forissier5b25c762020-04-07 11:18:49 +0200122#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
123#define P(a,b,c,d,x,s) \
124 do \
125 { \
126 (a) += F((b),(c),(d)) + (x); \
127 (a) = S((a),(s)); \
128 } while( 0 )
129
Jens Wiklander817466c2018-05-22 13:49:31 +0200130
Jerome Forissier79013242021-07-28 10:24:04 +0200131 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
132 P( local.D, local.A, local.B, local.C, local.X[ 1], 7 );
133 P( local.C, local.D, local.A, local.B, local.X[ 2], 11 );
134 P( local.B, local.C, local.D, local.A, local.X[ 3], 19 );
135 P( local.A, local.B, local.C, local.D, local.X[ 4], 3 );
136 P( local.D, local.A, local.B, local.C, local.X[ 5], 7 );
137 P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
138 P( local.B, local.C, local.D, local.A, local.X[ 7], 19 );
139 P( local.A, local.B, local.C, local.D, local.X[ 8], 3 );
140 P( local.D, local.A, local.B, local.C, local.X[ 9], 7 );
141 P( local.C, local.D, local.A, local.B, local.X[10], 11 );
142 P( local.B, local.C, local.D, local.A, local.X[11], 19 );
143 P( local.A, local.B, local.C, local.D, local.X[12], 3 );
144 P( local.D, local.A, local.B, local.C, local.X[13], 7 );
145 P( local.C, local.D, local.A, local.B, local.X[14], 11 );
146 P( local.B, local.C, local.D, local.A, local.X[15], 19 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200147
148#undef P
149#undef F
150
Jerome Forissier5b25c762020-04-07 11:18:49 +0200151#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
152#define P(a,b,c,d,x,s) \
153 do \
154 { \
155 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
156 (a) = S((a),(s)); \
157 } while( 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200158
Jerome Forissier79013242021-07-28 10:24:04 +0200159 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
160 P( local.D, local.A, local.B, local.C, local.X[ 4], 5 );
161 P( local.C, local.D, local.A, local.B, local.X[ 8], 9 );
162 P( local.B, local.C, local.D, local.A, local.X[12], 13 );
163 P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
164 P( local.D, local.A, local.B, local.C, local.X[ 5], 5 );
165 P( local.C, local.D, local.A, local.B, local.X[ 9], 9 );
166 P( local.B, local.C, local.D, local.A, local.X[13], 13 );
167 P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
168 P( local.D, local.A, local.B, local.C, local.X[ 6], 5 );
169 P( local.C, local.D, local.A, local.B, local.X[10], 9 );
170 P( local.B, local.C, local.D, local.A, local.X[14], 13 );
171 P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
172 P( local.D, local.A, local.B, local.C, local.X[ 7], 5 );
173 P( local.C, local.D, local.A, local.B, local.X[11], 9 );
174 P( local.B, local.C, local.D, local.A, local.X[15], 13 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200175
176#undef P
177#undef F
178
Jerome Forissier5b25c762020-04-07 11:18:49 +0200179#define F(x,y,z) ((x) ^ (y) ^ (z))
180#define P(a,b,c,d,x,s) \
181 do \
182 { \
183 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
184 (a) = S((a),(s)); \
185 } while( 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200186
Jerome Forissier79013242021-07-28 10:24:04 +0200187 P( local.A, local.B, local.C, local.D, local.X[ 0], 3 );
188 P( local.D, local.A, local.B, local.C, local.X[ 8], 9 );
189 P( local.C, local.D, local.A, local.B, local.X[ 4], 11 );
190 P( local.B, local.C, local.D, local.A, local.X[12], 15 );
191 P( local.A, local.B, local.C, local.D, local.X[ 2], 3 );
192 P( local.D, local.A, local.B, local.C, local.X[10], 9 );
193 P( local.C, local.D, local.A, local.B, local.X[ 6], 11 );
194 P( local.B, local.C, local.D, local.A, local.X[14], 15 );
195 P( local.A, local.B, local.C, local.D, local.X[ 1], 3 );
196 P( local.D, local.A, local.B, local.C, local.X[ 9], 9 );
197 P( local.C, local.D, local.A, local.B, local.X[ 5], 11 );
198 P( local.B, local.C, local.D, local.A, local.X[13], 15 );
199 P( local.A, local.B, local.C, local.D, local.X[ 3], 3 );
200 P( local.D, local.A, local.B, local.C, local.X[11], 9 );
201 P( local.C, local.D, local.A, local.B, local.X[ 7], 11 );
202 P( local.B, local.C, local.D, local.A, local.X[15], 15 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200203
204#undef F
205#undef P
206
Jerome Forissier79013242021-07-28 10:24:04 +0200207 ctx->state[0] += local.A;
208 ctx->state[1] += local.B;
209 ctx->state[2] += local.C;
210 ctx->state[3] += local.D;
211
212 /* Zeroise variables to clear sensitive data from memory. */
213 mbedtls_platform_zeroize( &local, sizeof( local ) );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100214
215 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200216}
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100217
218#if !defined(MBEDTLS_DEPRECATED_REMOVED)
219void mbedtls_md4_process( mbedtls_md4_context *ctx,
220 const unsigned char data[64] )
221{
222 mbedtls_internal_md4_process( ctx, data );
223}
224#endif
Jens Wiklander817466c2018-05-22 13:49:31 +0200225#endif /* !MBEDTLS_MD4_PROCESS_ALT */
226
227/*
228 * MD4 process buffer
229 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100230int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
231 const unsigned char *input,
232 size_t ilen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200233{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200234 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200235 size_t fill;
236 uint32_t left;
237
238 if( ilen == 0 )
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100239 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200240
241 left = ctx->total[0] & 0x3F;
242 fill = 64 - left;
243
244 ctx->total[0] += (uint32_t) ilen;
245 ctx->total[0] &= 0xFFFFFFFF;
246
247 if( ctx->total[0] < (uint32_t) ilen )
248 ctx->total[1]++;
249
250 if( left && ilen >= fill )
251 {
252 memcpy( (void *) (ctx->buffer + left),
253 (void *) input, fill );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100254
255 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
256 return( ret );
257
Jens Wiklander817466c2018-05-22 13:49:31 +0200258 input += fill;
259 ilen -= fill;
260 left = 0;
261 }
262
263 while( ilen >= 64 )
264 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100265 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
266 return( ret );
267
Jens Wiklander817466c2018-05-22 13:49:31 +0200268 input += 64;
269 ilen -= 64;
270 }
271
272 if( ilen > 0 )
273 {
274 memcpy( (void *) (ctx->buffer + left),
275 (void *) input, ilen );
276 }
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100277
278 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200279}
280
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100281#if !defined(MBEDTLS_DEPRECATED_REMOVED)
282void mbedtls_md4_update( mbedtls_md4_context *ctx,
283 const unsigned char *input,
284 size_t ilen )
285{
286 mbedtls_md4_update_ret( ctx, input, ilen );
287}
288#endif
289
Jens Wiklander817466c2018-05-22 13:49:31 +0200290static 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 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100301int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
302 unsigned char output[16] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200303{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200304 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200305 uint32_t last, padn;
306 uint32_t high, low;
307 unsigned char msglen[8];
308
309 high = ( ctx->total[0] >> 29 )
310 | ( ctx->total[1] << 3 );
311 low = ( ctx->total[0] << 3 );
312
Jerome Forissier039e02d2022-08-09 17:10:15 +0200313 MBEDTLS_PUT_UINT32_LE( low, msglen, 0 );
314 MBEDTLS_PUT_UINT32_LE( high, msglen, 4 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200315
316 last = ctx->total[0] & 0x3F;
317 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
318
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100319 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
320 if( ret != 0 )
321 return( ret );
322
323 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
324 return( ret );
325
Jens Wiklander817466c2018-05-22 13:49:31 +0200326
Jerome Forissier039e02d2022-08-09 17:10:15 +0200327 MBEDTLS_PUT_UINT32_LE( ctx->state[0], output, 0 );
328 MBEDTLS_PUT_UINT32_LE( ctx->state[1], output, 4 );
329 MBEDTLS_PUT_UINT32_LE( ctx->state[2], output, 8 );
330 MBEDTLS_PUT_UINT32_LE( ctx->state[3], output, 12 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100331
332 return( 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200333}
334
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100335#if !defined(MBEDTLS_DEPRECATED_REMOVED)
336void mbedtls_md4_finish( mbedtls_md4_context *ctx,
337 unsigned char output[16] )
338{
339 mbedtls_md4_finish_ret( ctx, output );
340}
341#endif
342
Jens Wiklander817466c2018-05-22 13:49:31 +0200343#endif /* !MBEDTLS_MD4_ALT */
344
345/*
346 * output = MD4( input buffer )
347 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100348int mbedtls_md4_ret( const unsigned char *input,
349 size_t ilen,
350 unsigned char output[16] )
Jens Wiklander817466c2018-05-22 13:49:31 +0200351{
Jerome Forissier11fa71b2020-04-20 17:17:56 +0200352 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Jens Wiklander817466c2018-05-22 13:49:31 +0200353 mbedtls_md4_context ctx;
354
355 mbedtls_md4_init( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100356
357 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
358 goto exit;
359
360 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
361 goto exit;
362
363 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
364 goto exit;
365
366exit:
Jens Wiklander817466c2018-05-22 13:49:31 +0200367 mbedtls_md4_free( &ctx );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100368
369 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200370}
371
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100372#if !defined(MBEDTLS_DEPRECATED_REMOVED)
373void mbedtls_md4( const unsigned char *input,
374 size_t ilen,
375 unsigned char output[16] )
376{
377 mbedtls_md4_ret( input, ilen, output );
378}
379#endif
380
Jens Wiklander817466c2018-05-22 13:49:31 +0200381#if defined(MBEDTLS_SELF_TEST)
382
383/*
384 * RFC 1320 test vectors
385 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100386static const unsigned char md4_test_str[7][81] =
Jens Wiklander817466c2018-05-22 13:49:31 +0200387{
388 { "" },
389 { "a" },
390 { "abc" },
391 { "message digest" },
392 { "abcdefghijklmnopqrstuvwxyz" },
393 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Guido Vranken36905f92021-04-22 14:47:51 +0200394 { "12345678901234567890123456789012345678901234567890123456789012345678901234567890" }
Jens Wiklander817466c2018-05-22 13:49:31 +0200395};
396
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100397static const size_t md4_test_strlen[7] =
398{
399 0, 1, 3, 14, 26, 62, 80
400};
401
Jens Wiklander817466c2018-05-22 13:49:31 +0200402static const unsigned char md4_test_sum[7][16] =
403{
404 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
405 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
406 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
407 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
408 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
409 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
410 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
411 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
412 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
413 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
414 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
415 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
416 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
417 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
418};
419
420/*
421 * Checkup routine
422 */
423int mbedtls_md4_self_test( int verbose )
424{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100425 int i, ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200426 unsigned char md4sum[16];
427
428 for( i = 0; i < 7; i++ )
429 {
430 if( verbose != 0 )
431 mbedtls_printf( " MD4 test #%d: ", i + 1 );
432
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100433 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
434 if( ret != 0 )
435 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200436
437 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
438 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100439 ret = 1;
440 goto fail;
Jens Wiklander817466c2018-05-22 13:49:31 +0200441 }
442
443 if( verbose != 0 )
444 mbedtls_printf( "passed\n" );
445 }
446
447 if( verbose != 0 )
448 mbedtls_printf( "\n" );
449
450 return( 0 );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100451
452fail:
453 if( verbose != 0 )
454 mbedtls_printf( "failed\n" );
455
456 return( ret );
Jens Wiklander817466c2018-05-22 13:49:31 +0200457}
458
459#endif /* MBEDTLS_SELF_TEST */
460
461#endif /* MBEDTLS_MD4_C */