blob: ba704f58e8b9bbc2cbaabc5cf8b9cedade023855 [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
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000114#if !defined(MBEDTLS_DEPRECATED_REMOVED)
115void mbedtls_md4_starts( mbedtls_md4_context *ctx )
116{
117 mbedtls_md4_starts_ret( ctx );
118}
119#endif
120
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200121#if !defined(MBEDTLS_MD4_PROCESS_ALT)
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100122int mbedtls_internal_md4_process( mbedtls_md4_context *ctx,
123 const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000124{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000125 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +0000126
Paul Bakker5c2364c2012-10-01 14:41:15 +0000127 GET_UINT32_LE( X[ 0], data, 0 );
128 GET_UINT32_LE( X[ 1], data, 4 );
129 GET_UINT32_LE( X[ 2], data, 8 );
130 GET_UINT32_LE( X[ 3], data, 12 );
131 GET_UINT32_LE( X[ 4], data, 16 );
132 GET_UINT32_LE( X[ 5], data, 20 );
133 GET_UINT32_LE( X[ 6], data, 24 );
134 GET_UINT32_LE( X[ 7], data, 28 );
135 GET_UINT32_LE( X[ 8], data, 32 );
136 GET_UINT32_LE( X[ 9], data, 36 );
137 GET_UINT32_LE( X[10], data, 40 );
138 GET_UINT32_LE( X[11], data, 44 );
139 GET_UINT32_LE( X[12], data, 48 );
140 GET_UINT32_LE( X[13], data, 52 );
141 GET_UINT32_LE( X[14], data, 56 );
142 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000143
144#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
145
146 A = ctx->state[0];
147 B = ctx->state[1];
148 C = ctx->state[2];
149 D = ctx->state[3];
150
151#define F(x, y, z) ((x & y) | ((~x) & z))
152#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
153
154 P( A, B, C, D, X[ 0], 3 );
155 P( D, A, B, C, X[ 1], 7 );
156 P( C, D, A, B, X[ 2], 11 );
157 P( B, C, D, A, X[ 3], 19 );
158 P( A, B, C, D, X[ 4], 3 );
159 P( D, A, B, C, X[ 5], 7 );
160 P( C, D, A, B, X[ 6], 11 );
161 P( B, C, D, A, X[ 7], 19 );
162 P( A, B, C, D, X[ 8], 3 );
163 P( D, A, B, C, X[ 9], 7 );
164 P( C, D, A, B, X[10], 11 );
165 P( B, C, D, A, X[11], 19 );
166 P( A, B, C, D, X[12], 3 );
167 P( D, A, B, C, X[13], 7 );
168 P( C, D, A, B, X[14], 11 );
169 P( B, C, D, A, X[15], 19 );
170
171#undef P
172#undef F
173
174#define F(x,y,z) ((x & y) | (x & z) | (y & z))
175#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
176
177 P( A, B, C, D, X[ 0], 3 );
178 P( D, A, B, C, X[ 4], 5 );
179 P( C, D, A, B, X[ 8], 9 );
180 P( B, C, D, A, X[12], 13 );
181 P( A, B, C, D, X[ 1], 3 );
182 P( D, A, B, C, X[ 5], 5 );
183 P( C, D, A, B, X[ 9], 9 );
184 P( B, C, D, A, X[13], 13 );
185 P( A, B, C, D, X[ 2], 3 );
186 P( D, A, B, C, X[ 6], 5 );
187 P( C, D, A, B, X[10], 9 );
188 P( B, C, D, A, X[14], 13 );
189 P( A, B, C, D, X[ 3], 3 );
190 P( D, A, B, C, X[ 7], 5 );
191 P( C, D, A, B, X[11], 9 );
192 P( B, C, D, A, X[15], 13 );
193
194#undef P
195#undef F
196
197#define F(x,y,z) (x ^ y ^ z)
198#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
199
200 P( A, B, C, D, X[ 0], 3 );
201 P( D, A, B, C, X[ 8], 9 );
202 P( C, D, A, B, X[ 4], 11 );
203 P( B, C, D, A, X[12], 15 );
204 P( A, B, C, D, X[ 2], 3 );
205 P( D, A, B, C, X[10], 9 );
206 P( C, D, A, B, X[ 6], 11 );
207 P( B, C, D, A, X[14], 15 );
208 P( A, B, C, D, X[ 1], 3 );
209 P( D, A, B, C, X[ 9], 9 );
210 P( C, D, A, B, X[ 5], 11 );
211 P( B, C, D, A, X[13], 15 );
212 P( A, B, C, D, X[ 3], 3 );
213 P( D, A, B, C, X[11], 9 );
214 P( C, D, A, B, X[ 7], 11 );
215 P( B, C, D, A, X[15], 15 );
216
217#undef F
218#undef P
219
220 ctx->state[0] += A;
221 ctx->state[1] += B;
222 ctx->state[2] += C;
223 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100224
225 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000226}
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000227
228#if !defined(MBEDTLS_DEPRECATED_REMOVED)
229void mbedtls_md4_process( mbedtls_md4_context *ctx,
230 const unsigned char data[64] )
231{
232 mbedtls_internal_md4_process( ctx, data );
233}
234#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200235#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000236
237/*
238 * MD4 process buffer
239 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100240int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100241 const unsigned char *input,
242 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000243{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100244 int ret;
Paul Bakker23986e52011-04-24 08:57:21 +0000245 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000246 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000247
Brian White12895d12014-04-11 11:29:42 -0400248 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100249 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000250
251 left = ctx->total[0] & 0x3F;
252 fill = 64 - left;
253
Paul Bakker5c2364c2012-10-01 14:41:15 +0000254 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000255 ctx->total[0] &= 0xFFFFFFFF;
256
Paul Bakker5c2364c2012-10-01 14:41:15 +0000257 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 ctx->total[1]++;
259
260 if( left && ilen >= fill )
261 {
262 memcpy( (void *) (ctx->buffer + left),
263 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100264
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100265 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100266 return( ret );
267
Paul Bakker5121ce52009-01-03 21:22:43 +0000268 input += fill;
269 ilen -= fill;
270 left = 0;
271 }
272
273 while( ilen >= 64 )
274 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100275 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100276 return( ret );
277
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 input += 64;
279 ilen -= 64;
280 }
281
282 if( ilen > 0 )
283 {
284 memcpy( (void *) (ctx->buffer + left),
285 (void *) input, ilen );
286 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100287
288 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000289}
290
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000291#if !defined(MBEDTLS_DEPRECATED_REMOVED)
292void mbedtls_md4_update( mbedtls_md4_context *ctx,
293 const unsigned char *input,
294 size_t ilen )
295{
296 mbedtls_md4_update_ret( ctx, input, ilen );
297}
298#endif
299
Paul Bakker5121ce52009-01-03 21:22:43 +0000300static const unsigned char md4_padding[64] =
301{
302 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
303 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
304 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
306};
307
308/*
309 * MD4 final digest
310 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100311int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100312 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000313{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100314 int ret;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000315 uint32_t last, padn;
316 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000317 unsigned char msglen[8];
318
319 high = ( ctx->total[0] >> 29 )
320 | ( ctx->total[1] << 3 );
321 low = ( ctx->total[0] << 3 );
322
Paul Bakker5c2364c2012-10-01 14:41:15 +0000323 PUT_UINT32_LE( low, msglen, 0 );
324 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000325
326 last = ctx->total[0] & 0x3F;
327 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
328
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100329 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100330 if( ret != 0 )
331 return( ret );
332
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100333 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100334 return( ret );
335
Paul Bakker5121ce52009-01-03 21:22:43 +0000336
Paul Bakker5c2364c2012-10-01 14:41:15 +0000337 PUT_UINT32_LE( ctx->state[0], output, 0 );
338 PUT_UINT32_LE( ctx->state[1], output, 4 );
339 PUT_UINT32_LE( ctx->state[2], output, 8 );
340 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100341
342 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000343}
344
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000345#if !defined(MBEDTLS_DEPRECATED_REMOVED)
346void mbedtls_md4_finish( mbedtls_md4_context *ctx,
347 unsigned char output[16] )
348{
349 mbedtls_md4_finish_ret( ctx, output );
350}
351#endif
352
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200353#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200354
Paul Bakker5121ce52009-01-03 21:22:43 +0000355/*
356 * output = MD4( input buffer )
357 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100358int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100359 size_t ilen,
360 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000361{
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100362 int ret;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200363 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000364
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200365 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100366
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100367 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100368 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100369
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100370 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100371 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100372
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100373 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100374 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100375
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100376exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200377 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100378
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100379 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000380}
381
Jaeden Ameroa53ff8d2018-02-19 15:28:08 +0000382#if !defined(MBEDTLS_DEPRECATED_REMOVED)
383void mbedtls_md4( const unsigned char *input,
384 size_t ilen,
385 unsigned char output[16] )
386{
387 mbedtls_md4_ret( input, ilen, output );
388}
389#endif
390
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200391#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000392
393/*
394 * RFC 1320 test vectors
395 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100396static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000397{
Paul Bakker9af723c2014-05-01 13:03:14 +0200398 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 { "a" },
400 { "abc" },
401 { "message digest" },
402 { "abcdefghijklmnopqrstuvwxyz" },
403 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100404 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 "345678901234567890" }
406};
407
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100408static const size_t md4_test_strlen[7] =
409{
410 0, 1, 3, 14, 26, 62, 80
411};
412
Paul Bakker5121ce52009-01-03 21:22:43 +0000413static const unsigned char md4_test_sum[7][16] =
414{
415 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
416 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
417 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
418 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
419 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
420 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
421 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
422 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
423 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
424 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
425 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
426 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
427 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
428 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
429};
430
431/*
432 * Checkup routine
433 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200434int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000435{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100436 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 unsigned char md4sum[16];
438
439 for( i = 0; i < 7; i++ )
440 {
441 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200442 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000443
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100444 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100445 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100446 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
448 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100449 {
450 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100451 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100452 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000453
454 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200455 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 }
457
458 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200459 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100462
463fail:
464 if( verbose != 0 )
465 mbedtls_printf( "failed\n" );
466
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100467 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468}
469
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200470#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000471
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200472#endif /* MBEDTLS_MD4_C */