blob: da4df7b141aab19c46ee0525d29853fc1bd7ded7 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Manuel Pégourié-Gonnard6fb81872015-07-27 11:11:48 +02004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
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 Bakkerb96f1542010-07-18 20:36:00 +000018 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +000019 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakker5121ce52009-01-03 21:22:43 +000020 */
21/*
22 * The MD4 algorithm was designed by Ron Rivest in 1990.
23 *
24 * http://www.ietf.org/rfc/rfc1186.txt
25 * http://www.ietf.org/rfc/rfc1320.txt
26 */
27
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020028#if !defined(MBEDTLS_CONFIG_FILE)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020031#include MBEDTLS_CONFIG_FILE
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020034#if defined(MBEDTLS_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000036#include "mbedtls/md4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Rich Evans00ab4702015-02-06 13:43:58 +000038#include <string.h>
39
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020040#if defined(MBEDTLS_SELF_TEST)
41#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000042#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#else
Rich Evans00ab4702015-02-06 13:43:58 +000044#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020045#define mbedtls_printf printf
46#endif /* MBEDTLS_PLATFORM_C */
47#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010048
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020049#if !defined(MBEDTLS_MD4_ALT)
50
Paul Bakker34617722014-06-13 17:20:13 +020051/* Implementation that should never be optimized out by the compiler */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052static void mbedtls_zeroize( void *v, size_t n ) {
Paul Bakker34617722014-06-13 17:20:13 +020053 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
54}
55
Paul Bakker5121ce52009-01-03 21:22:43 +000056/*
57 * 32-bit integer manipulation macros (little endian)
58 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000059#ifndef GET_UINT32_LE
60#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000061{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000062 (n) = ( (uint32_t) (b)[(i) ] ) \
63 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
64 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
65 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000066}
67#endif
68
Paul Bakker5c2364c2012-10-01 14:41:15 +000069#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000070#define PUT_UINT32_LE(n,b,i) \
71{ \
72 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
73 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
74 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
75 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000076}
77#endif
78
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020079void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020080{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020081 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020082}
83
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020085{
86 if( ctx == NULL )
87 return;
88
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020089 mbedtls_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020090}
91
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020092void mbedtls_md4_clone( mbedtls_md4_context *dst,
93 const mbedtls_md4_context *src )
94{
95 *dst = *src;
96}
97
Paul Bakker5121ce52009-01-03 21:22:43 +000098/*
99 * MD4 context setup
100 */
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100101int mbedtls_md4_starts_ext( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +0000102{
103 ctx->total[0] = 0;
104 ctx->total[1] = 0;
105
106 ctx->state[0] = 0x67452301;
107 ctx->state[1] = 0xEFCDAB89;
108 ctx->state[2] = 0x98BADCFE;
109 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100110
111 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000112}
113
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200114#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100115int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
116 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000117{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000118 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000119
Paul Bakker5c2364c2012-10-01 14:41:15 +0000120 GET_UINT32_LE( X[ 0], data, 0 );
121 GET_UINT32_LE( X[ 1], data, 4 );
122 GET_UINT32_LE( X[ 2], data, 8 );
123 GET_UINT32_LE( X[ 3], data, 12 );
124 GET_UINT32_LE( X[ 4], data, 16 );
125 GET_UINT32_LE( X[ 5], data, 20 );
126 GET_UINT32_LE( X[ 6], data, 24 );
127 GET_UINT32_LE( X[ 7], data, 28 );
128 GET_UINT32_LE( X[ 8], data, 32 );
129 GET_UINT32_LE( X[ 9], data, 36 );
130 GET_UINT32_LE( X[10], data, 40 );
131 GET_UINT32_LE( X[11], data, 44 );
132 GET_UINT32_LE( X[12], data, 48 );
133 GET_UINT32_LE( X[13], data, 52 );
134 GET_UINT32_LE( X[14], data, 56 );
135 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000136
137#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
138
139 A = ctx->state[0];
140 B = ctx->state[1];
141 C = ctx->state[2];
142 D = ctx->state[3];
143
144#define F(x, y, z) ((x & y) | ((~x) & z))
145#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
146
147 P( A, B, C, D, X[ 0], 3 );
148 P( D, A, B, C, X[ 1], 7 );
149 P( C, D, A, B, X[ 2], 11 );
150 P( B, C, D, A, X[ 3], 19 );
151 P( A, B, C, D, X[ 4], 3 );
152 P( D, A, B, C, X[ 5], 7 );
153 P( C, D, A, B, X[ 6], 11 );
154 P( B, C, D, A, X[ 7], 19 );
155 P( A, B, C, D, X[ 8], 3 );
156 P( D, A, B, C, X[ 9], 7 );
157 P( C, D, A, B, X[10], 11 );
158 P( B, C, D, A, X[11], 19 );
159 P( A, B, C, D, X[12], 3 );
160 P( D, A, B, C, X[13], 7 );
161 P( C, D, A, B, X[14], 11 );
162 P( B, C, D, A, X[15], 19 );
163
164#undef P
165#undef F
166
167#define F(x,y,z) ((x & y) | (x & z) | (y & z))
168#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
169
170 P( A, B, C, D, X[ 0], 3 );
171 P( D, A, B, C, X[ 4], 5 );
172 P( C, D, A, B, X[ 8], 9 );
173 P( B, C, D, A, X[12], 13 );
174 P( A, B, C, D, X[ 1], 3 );
175 P( D, A, B, C, X[ 5], 5 );
176 P( C, D, A, B, X[ 9], 9 );
177 P( B, C, D, A, X[13], 13 );
178 P( A, B, C, D, X[ 2], 3 );
179 P( D, A, B, C, X[ 6], 5 );
180 P( C, D, A, B, X[10], 9 );
181 P( B, C, D, A, X[14], 13 );
182 P( A, B, C, D, X[ 3], 3 );
183 P( D, A, B, C, X[ 7], 5 );
184 P( C, D, A, B, X[11], 9 );
185 P( B, C, D, A, X[15], 13 );
186
187#undef P
188#undef F
189
190#define F(x,y,z) (x ^ y ^ z)
191#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
192
193 P( A, B, C, D, X[ 0], 3 );
194 P( D, A, B, C, X[ 8], 9 );
195 P( C, D, A, B, X[ 4], 11 );
196 P( B, C, D, A, X[12], 15 );
197 P( A, B, C, D, X[ 2], 3 );
198 P( D, A, B, C, X[10], 9 );
199 P( C, D, A, B, X[ 6], 11 );
200 P( B, C, D, A, X[14], 15 );
201 P( A, B, C, D, X[ 1], 3 );
202 P( D, A, B, C, X[ 9], 9 );
203 P( C, D, A, B, X[ 5], 11 );
204 P( B, C, D, A, X[13], 15 );
205 P( A, B, C, D, X[ 3], 3 );
206 P( D, A, B, C, X[11], 9 );
207 P( C, D, A, B, X[ 7], 11 );
208 P( B, C, D, A, X[15], 15 );
209
210#undef F
211#undef P
212
213 ctx->state[0] += A;
214 ctx->state[1] += B;
215 ctx->state[2] += C;
216 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100217
218 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000219}
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 */
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100225int mbedtls_md4_update_ext( mbedtls_md4_context *ctx,
226 const unsigned char *input,
227 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000228{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100229 int ret;
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
276static const unsigned char md4_padding[64] =
277{
278 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
282};
283
284/*
285 * MD4 final digest
286 */
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100287int mbedtls_md4_finish_ext( mbedtls_md4_context *ctx,
288 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000289{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100290 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000291 uint32_t last, padn;
292 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 unsigned char msglen[8];
294
295 high = ( ctx->total[0] >> 29 )
296 | ( ctx->total[1] << 3 );
297 low = ( ctx->total[0] << 3 );
298
Paul Bakker5c2364c2012-10-01 14:41:15 +0000299 PUT_UINT32_LE( low, msglen, 0 );
300 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000301
302 last = ctx->total[0] & 0x3F;
303 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
304
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100305 ret = mbedtls_md4_update_ext( ctx, (unsigned char *)md4_padding, padn );
306 if( ret != 0 )
307 return( ret );
308
309 if( ( ret = mbedtls_md4_update_ext( ctx, msglen, 8 ) ) != 0 )
310 return( ret );
311
Paul Bakker5121ce52009-01-03 21:22:43 +0000312
Paul Bakker5c2364c2012-10-01 14:41:15 +0000313 PUT_UINT32_LE( ctx->state[0], output, 0 );
314 PUT_UINT32_LE( ctx->state[1], output, 4 );
315 PUT_UINT32_LE( ctx->state[2], output, 8 );
316 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100317
318 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000319}
320
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200321#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200322
Paul Bakker5121ce52009-01-03 21:22:43 +0000323/*
324 * output = MD4( input buffer )
325 */
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100326int mbedtls_md4_ext( const unsigned char *input,
327 size_t ilen,
328 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000329{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100330 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200331 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200333 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100334
335 if( ( ret = mbedtls_md4_starts_ext( &ctx ) ) != 0 )
336 return( ret );
337
338 if( ( ret = mbedtls_md4_update_ext( &ctx, input, ilen ) ) != 0 )
339 return( ret );
340
341 if( ( ret = mbedtls_md4_finish_ext( &ctx, output ) ) != 0 )
342 return( ret );
343
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200344 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100345
346 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000347}
348
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200349#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351/*
352 * RFC 1320 test vectors
353 */
354static const char md4_test_str[7][81] =
355{
Paul Bakker9af723c2014-05-01 13:03:14 +0200356 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000357 { "a" },
358 { "abc" },
359 { "message digest" },
360 { "abcdefghijklmnopqrstuvwxyz" },
361 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
362 { "12345678901234567890123456789012345678901234567890123456789012" \
363 "345678901234567890" }
364};
365
366static const unsigned char md4_test_sum[7][16] =
367{
368 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
369 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
370 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
371 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
372 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
373 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
374 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
375 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
376 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
377 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
378 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
379 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
380 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
381 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
382};
383
384/*
385 * Checkup routine
386 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200387int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000388{
389 int i;
390 unsigned char md4sum[16];
391
392 for( i = 0; i < 7; i++ )
393 {
394 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200395 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100397 if( mbedtls_md4_ext( (unsigned char *) md4_test_str[i],
398 strlen( md4_test_str[i] ), md4sum ) != 0 )
399 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
401 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100402 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
404 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200405 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 }
407
408 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200409 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
411 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100412
413fail:
414 if( verbose != 0 )
415 mbedtls_printf( "failed\n" );
416
417 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000418}
419
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200420#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000421
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422#endif /* MBEDTLS_MD4_C */