blob: d33cc520a8b540f9b73408f6c42d973e4cb72d1a [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * The MD4 algorithm was designed by Ron Rivest in 1990.
24 *
25 * http://www.ietf.org/rfc/rfc1186.txt
26 * http://www.ietf.org/rfc/rfc1320.txt
27 */
28
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020029#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000030#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020031#else
32#include POLARSSL_CONFIG_FILE
33#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker40e46942009-01-03 21:51:57 +000035#if defined(POLARSSL_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/md4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Rich Evans00ab4702015-02-06 13:43:58 +000039#include <string.h>
40
41#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +000042#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000043#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000044
Rich Evans00ab4702015-02-06 13:43:58 +000045#if defined(POLARSSL_SELF_TEST)
Paul Bakker7dc4c442014-02-01 22:50:26 +010046#if defined(POLARSSL_PLATFORM_C)
47#include "polarssl/platform.h"
48#else
Rich Evans00ab4702015-02-06 13:43:58 +000049#include <stdio.h>
Paul Bakker7dc4c442014-02-01 22:50:26 +010050#define polarssl_printf printf
Rich Evans00ab4702015-02-06 13:43:58 +000051#endif /* POLARSSL_PLATFORM_C */
52#endif /* POLARSSL_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010053
Paul Bakker34617722014-06-13 17:20:13 +020054/* Implementation that should never be optimized out by the compiler */
55static void polarssl_zeroize( void *v, size_t n ) {
56 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
57}
58
Paul Bakker90995b52013-06-24 19:20:35 +020059#if !defined(POLARSSL_MD4_ALT)
60
Paul Bakker5121ce52009-01-03 21:22:43 +000061/*
62 * 32-bit integer manipulation macros (little endian)
63 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000064#ifndef GET_UINT32_LE
65#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000066{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000067 (n) = ( (uint32_t) (b)[(i) ] ) \
68 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
69 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
70 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000071}
72#endif
73
Paul Bakker5c2364c2012-10-01 14:41:15 +000074#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000075#define PUT_UINT32_LE(n,b,i) \
76{ \
77 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
78 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
79 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
80 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000081}
82#endif
83
Paul Bakker5b4af392014-06-26 12:09:34 +020084void md4_init( md4_context *ctx )
85{
86 memset( ctx, 0, sizeof( md4_context ) );
87}
88
89void md4_free( md4_context *ctx )
90{
91 if( ctx == NULL )
92 return;
93
94 polarssl_zeroize( ctx, sizeof( md4_context ) );
95}
96
Paul Bakker5121ce52009-01-03 21:22:43 +000097/*
98 * MD4 context setup
99 */
100void md4_starts( md4_context *ctx )
101{
102 ctx->total[0] = 0;
103 ctx->total[1] = 0;
104
105 ctx->state[0] = 0x67452301;
106 ctx->state[1] = 0xEFCDAB89;
107 ctx->state[2] = 0x98BADCFE;
108 ctx->state[3] = 0x10325476;
109}
110
Paul Bakker1bd3ae82013-03-13 10:26:44 +0100111void md4_process( md4_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000112{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000113 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000114
Paul Bakker5c2364c2012-10-01 14:41:15 +0000115 GET_UINT32_LE( X[ 0], data, 0 );
116 GET_UINT32_LE( X[ 1], data, 4 );
117 GET_UINT32_LE( X[ 2], data, 8 );
118 GET_UINT32_LE( X[ 3], data, 12 );
119 GET_UINT32_LE( X[ 4], data, 16 );
120 GET_UINT32_LE( X[ 5], data, 20 );
121 GET_UINT32_LE( X[ 6], data, 24 );
122 GET_UINT32_LE( X[ 7], data, 28 );
123 GET_UINT32_LE( X[ 8], data, 32 );
124 GET_UINT32_LE( X[ 9], data, 36 );
125 GET_UINT32_LE( X[10], data, 40 );
126 GET_UINT32_LE( X[11], data, 44 );
127 GET_UINT32_LE( X[12], data, 48 );
128 GET_UINT32_LE( X[13], data, 52 );
129 GET_UINT32_LE( X[14], data, 56 );
130 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000131
132#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
133
134 A = ctx->state[0];
135 B = ctx->state[1];
136 C = ctx->state[2];
137 D = ctx->state[3];
138
139#define F(x, y, z) ((x & y) | ((~x) & z))
140#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
141
142 P( A, B, C, D, X[ 0], 3 );
143 P( D, A, B, C, X[ 1], 7 );
144 P( C, D, A, B, X[ 2], 11 );
145 P( B, C, D, A, X[ 3], 19 );
146 P( A, B, C, D, X[ 4], 3 );
147 P( D, A, B, C, X[ 5], 7 );
148 P( C, D, A, B, X[ 6], 11 );
149 P( B, C, D, A, X[ 7], 19 );
150 P( A, B, C, D, X[ 8], 3 );
151 P( D, A, B, C, X[ 9], 7 );
152 P( C, D, A, B, X[10], 11 );
153 P( B, C, D, A, X[11], 19 );
154 P( A, B, C, D, X[12], 3 );
155 P( D, A, B, C, X[13], 7 );
156 P( C, D, A, B, X[14], 11 );
157 P( B, C, D, A, X[15], 19 );
158
159#undef P
160#undef F
161
162#define F(x,y,z) ((x & y) | (x & z) | (y & z))
163#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
164
165 P( A, B, C, D, X[ 0], 3 );
166 P( D, A, B, C, X[ 4], 5 );
167 P( C, D, A, B, X[ 8], 9 );
168 P( B, C, D, A, X[12], 13 );
169 P( A, B, C, D, X[ 1], 3 );
170 P( D, A, B, C, X[ 5], 5 );
171 P( C, D, A, B, X[ 9], 9 );
172 P( B, C, D, A, X[13], 13 );
173 P( A, B, C, D, X[ 2], 3 );
174 P( D, A, B, C, X[ 6], 5 );
175 P( C, D, A, B, X[10], 9 );
176 P( B, C, D, A, X[14], 13 );
177 P( A, B, C, D, X[ 3], 3 );
178 P( D, A, B, C, X[ 7], 5 );
179 P( C, D, A, B, X[11], 9 );
180 P( B, C, D, A, X[15], 13 );
181
182#undef P
183#undef F
184
185#define F(x,y,z) (x ^ y ^ z)
186#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
187
188 P( A, B, C, D, X[ 0], 3 );
189 P( D, A, B, C, X[ 8], 9 );
190 P( C, D, A, B, X[ 4], 11 );
191 P( B, C, D, A, X[12], 15 );
192 P( A, B, C, D, X[ 2], 3 );
193 P( D, A, B, C, X[10], 9 );
194 P( C, D, A, B, X[ 6], 11 );
195 P( B, C, D, A, X[14], 15 );
196 P( A, B, C, D, X[ 1], 3 );
197 P( D, A, B, C, X[ 9], 9 );
198 P( C, D, A, B, X[ 5], 11 );
199 P( B, C, D, A, X[13], 15 );
200 P( A, B, C, D, X[ 3], 3 );
201 P( D, A, B, C, X[11], 9 );
202 P( C, D, A, B, X[ 7], 11 );
203 P( B, C, D, A, X[15], 15 );
204
205#undef F
206#undef P
207
208 ctx->state[0] += A;
209 ctx->state[1] += B;
210 ctx->state[2] += C;
211 ctx->state[3] += D;
212}
213
214/*
215 * MD4 process buffer
216 */
Paul Bakker23986e52011-04-24 08:57:21 +0000217void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000218{
Paul Bakker23986e52011-04-24 08:57:21 +0000219 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000220 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000221
Brian White12895d12014-04-11 11:29:42 -0400222 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000223 return;
224
225 left = ctx->total[0] & 0x3F;
226 fill = 64 - left;
227
Paul Bakker5c2364c2012-10-01 14:41:15 +0000228 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000229 ctx->total[0] &= 0xFFFFFFFF;
230
Paul Bakker5c2364c2012-10-01 14:41:15 +0000231 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000232 ctx->total[1]++;
233
234 if( left && ilen >= fill )
235 {
236 memcpy( (void *) (ctx->buffer + left),
237 (void *) input, fill );
238 md4_process( ctx, ctx->buffer );
239 input += fill;
240 ilen -= fill;
241 left = 0;
242 }
243
244 while( ilen >= 64 )
245 {
246 md4_process( ctx, input );
247 input += 64;
248 ilen -= 64;
249 }
250
251 if( ilen > 0 )
252 {
253 memcpy( (void *) (ctx->buffer + left),
254 (void *) input, ilen );
255 }
256}
257
258static const unsigned char md4_padding[64] =
259{
260 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
263 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
264};
265
266/*
267 * MD4 final digest
268 */
269void md4_finish( md4_context *ctx, unsigned char output[16] )
270{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000271 uint32_t last, padn;
272 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 unsigned char msglen[8];
274
275 high = ( ctx->total[0] >> 29 )
276 | ( ctx->total[1] << 3 );
277 low = ( ctx->total[0] << 3 );
278
Paul Bakker5c2364c2012-10-01 14:41:15 +0000279 PUT_UINT32_LE( low, msglen, 0 );
280 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000281
282 last = ctx->total[0] & 0x3F;
283 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
284
285 md4_update( ctx, (unsigned char *) md4_padding, padn );
286 md4_update( ctx, msglen, 8 );
287
Paul Bakker5c2364c2012-10-01 14:41:15 +0000288 PUT_UINT32_LE( ctx->state[0], output, 0 );
289 PUT_UINT32_LE( ctx->state[1], output, 4 );
290 PUT_UINT32_LE( ctx->state[2], output, 8 );
291 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000292}
293
Paul Bakker90995b52013-06-24 19:20:35 +0200294#endif /* !POLARSSL_MD4_ALT */
295
Paul Bakker5121ce52009-01-03 21:22:43 +0000296/*
297 * output = MD4( input buffer )
298 */
Paul Bakker23986e52011-04-24 08:57:21 +0000299void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000300{
301 md4_context ctx;
302
Paul Bakker5b4af392014-06-26 12:09:34 +0200303 md4_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304 md4_starts( &ctx );
305 md4_update( &ctx, input, ilen );
306 md4_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200307 md4_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308}
309
Paul Bakker335db3f2011-04-25 15:28:35 +0000310#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000311/*
312 * output = MD4( file contents )
313 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000314int md4_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000315{
316 FILE *f;
317 size_t n;
318 md4_context ctx;
319 unsigned char buf[1024];
320
321 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000322 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
Paul Bakker5b4af392014-06-26 12:09:34 +0200324 md4_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000325 md4_starts( &ctx );
326
327 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000328 md4_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000329
330 md4_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200331 md4_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000332
333 if( ferror( f ) != 0 )
334 {
335 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000336 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000337 }
338
339 fclose( f );
340 return( 0 );
341}
Paul Bakker335db3f2011-04-25 15:28:35 +0000342#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344/*
345 * MD4 HMAC context setup
346 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200347void md4_hmac_starts( md4_context *ctx, const unsigned char *key,
348 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000349{
Paul Bakker23986e52011-04-24 08:57:21 +0000350 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000351 unsigned char sum[16];
352
353 if( keylen > 64 )
354 {
355 md4( key, keylen, sum );
356 keylen = 16;
357 key = sum;
358 }
359
360 memset( ctx->ipad, 0x36, 64 );
361 memset( ctx->opad, 0x5C, 64 );
362
363 for( i = 0; i < keylen; i++ )
364 {
365 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
366 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
367 }
368
369 md4_starts( ctx );
370 md4_update( ctx, ctx->ipad, 64 );
371
Paul Bakker34617722014-06-13 17:20:13 +0200372 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000373}
374
375/*
376 * MD4 HMAC process buffer
377 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200378void md4_hmac_update( md4_context *ctx, const unsigned char *input,
379 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000380{
381 md4_update( ctx, input, ilen );
382}
383
384/*
385 * MD4 HMAC final digest
386 */
387void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
388{
389 unsigned char tmpbuf[16];
390
391 md4_finish( ctx, tmpbuf );
392 md4_starts( ctx );
393 md4_update( ctx, ctx->opad, 64 );
394 md4_update( ctx, tmpbuf, 16 );
395 md4_finish( ctx, output );
396
Paul Bakker34617722014-06-13 17:20:13 +0200397 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000398}
399
400/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000401 * MD4 HMAC context reset
402 */
403void md4_hmac_reset( md4_context *ctx )
404{
405 md4_starts( ctx );
406 md4_update( ctx, ctx->ipad, 64 );
407}
408
409/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000410 * output = HMAC-MD4( hmac key, input buffer )
411 */
Paul Bakker23986e52011-04-24 08:57:21 +0000412void md4_hmac( const unsigned char *key, size_t keylen,
413 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 unsigned char output[16] )
415{
416 md4_context ctx;
417
Paul Bakker5b4af392014-06-26 12:09:34 +0200418 md4_init( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 md4_hmac_starts( &ctx, key, keylen );
420 md4_hmac_update( &ctx, input, ilen );
421 md4_hmac_finish( &ctx, output );
Paul Bakker5b4af392014-06-26 12:09:34 +0200422 md4_free( &ctx );
Paul Bakker5121ce52009-01-03 21:22:43 +0000423}
424
Paul Bakker40e46942009-01-03 21:51:57 +0000425#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000426
427/*
428 * RFC 1320 test vectors
429 */
430static const char md4_test_str[7][81] =
431{
Paul Bakker9af723c2014-05-01 13:03:14 +0200432 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000433 { "a" },
434 { "abc" },
435 { "message digest" },
436 { "abcdefghijklmnopqrstuvwxyz" },
437 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
438 { "12345678901234567890123456789012345678901234567890123456789012" \
439 "345678901234567890" }
440};
441
442static const unsigned char md4_test_sum[7][16] =
443{
444 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
445 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
446 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
447 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
448 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
449 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
450 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
451 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
452 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
453 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
454 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
455 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
456 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
457 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
458};
459
460/*
461 * Checkup routine
462 */
463int md4_self_test( int verbose )
464{
465 int i;
466 unsigned char md4sum[16];
467
468 for( i = 0; i < 7; i++ )
469 {
470 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100471 polarssl_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 md4( (unsigned char *) md4_test_str[i],
474 strlen( md4_test_str[i] ), md4sum );
475
476 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
477 {
478 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100479 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 return( 1 );
482 }
483
484 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100485 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000486 }
487
488 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100489 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000490
491 return( 0 );
492}
493
Paul Bakker9af723c2014-05-01 13:03:14 +0200494#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
Paul Bakker9af723c2014-05-01 13:03:14 +0200496#endif /* POLARSSL_MD4_C */