blob: 34a4b0e24e0df1d62d20134087e8e998776bd5ae [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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100101int mbedtls_md4_starts_ret( 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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100225int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100226 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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100287int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100288 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
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100305 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100306 if( ret != 0 )
307 return( ret );
308
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100309 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100310 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 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100326int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100327 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
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100335 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100336 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100337
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100338 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100339 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100340
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100341 if( ( ret = mbedtls_md4_finish_ret( &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 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100355static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000356{
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" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100363 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000364 "345678901234567890" }
365};
366
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100367static const size_t md4_test_strlen[7] =
368{
369 0, 1, 3, 14, 26, 62, 80
370};
371
Paul Bakker5121ce52009-01-03 21:22:43 +0000372static const unsigned char md4_test_sum[7][16] =
373{
374 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
375 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
376 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
377 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
378 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
379 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
380 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
381 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
382 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
383 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
384 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
385 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
386 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
387 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
388};
389
390/*
391 * Checkup routine
392 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200393int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000394{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100395 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000396 unsigned char md4sum[16];
397
398 for( i = 0; i < 7; i++ )
399 {
400 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200401 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000402
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100403 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100404 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100405 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
407 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100408 {
409 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100410 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100411 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
413 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 }
416
417 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200418 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419
420 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100421
422fail:
423 if( verbose != 0 )
424 mbedtls_printf( "failed\n" );
425
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100426 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427}
428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200431#endif /* MBEDTLS_MD4_C */