blob: 1121fd1906eb625f1d33b7a4b60a660034358210 [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 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100336 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100337
338 if( ( ret = mbedtls_md4_update_ext( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100339 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100340
341 if( ( ret = mbedtls_md4_finish_ext( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100342 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100343
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100344exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200345 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100346
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100347 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000348}
349
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200350#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000351
352/*
353 * RFC 1320 test vectors
354 */
355static const char md4_test_str[7][81] =
356{
Paul Bakker9af723c2014-05-01 13:03:14 +0200357 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000358 { "a" },
359 { "abc" },
360 { "message digest" },
361 { "abcdefghijklmnopqrstuvwxyz" },
362 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
363 { "12345678901234567890123456789012345678901234567890123456789012" \
364 "345678901234567890" }
365};
366
367static const unsigned char md4_test_sum[7][16] =
368{
369 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
370 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
371 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
372 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
373 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
374 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
375 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
376 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
377 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
378 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
379 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
380 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
381 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
382 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
383};
384
385/*
386 * Checkup routine
387 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200388int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000389{
390 int i;
391 unsigned char md4sum[16];
392
393 for( i = 0; i < 7; i++ )
394 {
395 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200396 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100398 if( mbedtls_md4_ext( (unsigned char *) md4_test_str[i],
399 strlen( md4_test_str[i] ), md4sum ) != 0 )
400 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
402 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100403 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000404
405 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200406 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407 }
408
409 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200410 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100413
414fail:
415 if( verbose != 0 )
416 mbedtls_printf( "failed\n" );
417
418 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419}
420
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200421#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200423#endif /* MBEDTLS_MD4_C */