blob: beb42c9541d63fc9db4fef9a883c58005b15ba4f [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
Gilles Peskinedb09ef62020-06-03 01:43:33 +020028#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000029
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020030#if defined(MBEDTLS_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000032#include "mbedtls/md4.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050033#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000034#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Rich Evans00ab4702015-02-06 13:43:58 +000036#include <string.h>
37
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_SELF_TEST)
39#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010041#else
Rich Evans00ab4702015-02-06 13:43:58 +000042#include <stdio.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020043#define mbedtls_printf printf
44#endif /* MBEDTLS_PLATFORM_C */
45#endif /* MBEDTLS_SELF_TEST */
Paul Bakker7dc4c442014-02-01 22:50:26 +010046
Manuel Pégourié-Gonnard8b2641d2015-08-27 20:03:46 +020047#if !defined(MBEDTLS_MD4_ALT)
48
Paul Bakker5121ce52009-01-03 21:22:43 +000049/*
50 * 32-bit integer manipulation macros (little endian)
51 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000052#ifndef GET_UINT32_LE
53#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000054{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000055 (n) = ( (uint32_t) (b)[(i) ] ) \
56 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
57 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
58 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000059}
60#endif
61
Paul Bakker5c2364c2012-10-01 14:41:15 +000062#ifndef PUT_UINT32_LE
Manuel Pégourié-Gonnardceedb822015-01-23 15:02:43 +000063#define PUT_UINT32_LE(n,b,i) \
64{ \
65 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \
66 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \
67 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \
68 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000069}
70#endif
71
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020072void mbedtls_md4_init( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020073{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020074 memset( ctx, 0, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020075}
76
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020077void mbedtls_md4_free( mbedtls_md4_context *ctx )
Paul Bakker5b4af392014-06-26 12:09:34 +020078{
79 if( ctx == NULL )
80 return;
81
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050082 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) );
Paul Bakker5b4af392014-06-26 12:09:34 +020083}
84
Manuel Pégourié-Gonnard16d412f2015-07-06 15:26:26 +020085void mbedtls_md4_clone( mbedtls_md4_context *dst,
86 const mbedtls_md4_context *src )
87{
88 *dst = *src;
89}
90
Paul Bakker5121ce52009-01-03 21:22:43 +000091/*
92 * MD4 context setup
93 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +010094int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx )
Paul Bakker5121ce52009-01-03 21:22:43 +000095{
96 ctx->total[0] = 0;
97 ctx->total[1] = 0;
98
99 ctx->state[0] = 0x67452301;
100 ctx->state[1] = 0xEFCDAB89;
101 ctx->state[2] = 0x98BADCFE;
102 ctx->state[3] = 0x10325476;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100103
104 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000105}
106
Jaeden Amero041039f2018-02-19 15:28:08 +0000107#if !defined(MBEDTLS_DEPRECATED_REMOVED)
108void mbedtls_md4_starts( mbedtls_md4_context *ctx )
109{
110 mbedtls_md4_starts_ret( ctx );
111}
112#endif
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
Hanno Becker1eeca412018-10-15 12:01:35 +0100137#define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n))))
Paul Bakker5121ce52009-01-03 21:22:43 +0000138
139 A = ctx->state[0];
140 B = ctx->state[1];
141 C = ctx->state[2];
142 D = ctx->state[3];
143
Hanno Becker1eeca412018-10-15 12:01:35 +0100144#define F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
Hanno Becker26d02e12018-10-30 09:29:25 +0000145#define P(a,b,c,d,x,s) \
146 do \
147 { \
Hanno Becker818bac52018-10-26 09:13:26 +0100148 (a) += F((b),(c),(d)) + (x); \
149 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100150 } while( 0 )
151
Paul Bakker5121ce52009-01-03 21:22:43 +0000152
153 P( A, B, C, D, X[ 0], 3 );
154 P( D, A, B, C, X[ 1], 7 );
155 P( C, D, A, B, X[ 2], 11 );
156 P( B, C, D, A, X[ 3], 19 );
157 P( A, B, C, D, X[ 4], 3 );
158 P( D, A, B, C, X[ 5], 7 );
159 P( C, D, A, B, X[ 6], 11 );
160 P( B, C, D, A, X[ 7], 19 );
161 P( A, B, C, D, X[ 8], 3 );
162 P( D, A, B, C, X[ 9], 7 );
163 P( C, D, A, B, X[10], 11 );
164 P( B, C, D, A, X[11], 19 );
165 P( A, B, C, D, X[12], 3 );
166 P( D, A, B, C, X[13], 7 );
167 P( C, D, A, B, X[14], 11 );
168 P( B, C, D, A, X[15], 19 );
169
170#undef P
171#undef F
172
Hanno Becker1eeca412018-10-15 12:01:35 +0100173#define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
174#define P(a,b,c,d,x,s) \
175 do \
176 { \
Hanno Becker26d02e12018-10-30 09:29:25 +0000177 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \
178 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100179 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000180
181 P( A, B, C, D, X[ 0], 3 );
182 P( D, A, B, C, X[ 4], 5 );
183 P( C, D, A, B, X[ 8], 9 );
184 P( B, C, D, A, X[12], 13 );
185 P( A, B, C, D, X[ 1], 3 );
186 P( D, A, B, C, X[ 5], 5 );
187 P( C, D, A, B, X[ 9], 9 );
188 P( B, C, D, A, X[13], 13 );
189 P( A, B, C, D, X[ 2], 3 );
190 P( D, A, B, C, X[ 6], 5 );
191 P( C, D, A, B, X[10], 9 );
192 P( B, C, D, A, X[14], 13 );
193 P( A, B, C, D, X[ 3], 3 );
194 P( D, A, B, C, X[ 7], 5 );
195 P( C, D, A, B, X[11], 9 );
196 P( B, C, D, A, X[15], 13 );
197
198#undef P
199#undef F
200
Hanno Becker1eeca412018-10-15 12:01:35 +0100201#define F(x,y,z) ((x) ^ (y) ^ (z))
Hanno Becker26d02e12018-10-30 09:29:25 +0000202#define P(a,b,c,d,x,s) \
203 do \
204 { \
205 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \
206 (a) = S((a),(s)); \
Hanno Becker1eeca412018-10-15 12:01:35 +0100207 } while( 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000208
209 P( A, B, C, D, X[ 0], 3 );
210 P( D, A, B, C, X[ 8], 9 );
211 P( C, D, A, B, X[ 4], 11 );
212 P( B, C, D, A, X[12], 15 );
213 P( A, B, C, D, X[ 2], 3 );
214 P( D, A, B, C, X[10], 9 );
215 P( C, D, A, B, X[ 6], 11 );
216 P( B, C, D, A, X[14], 15 );
217 P( A, B, C, D, X[ 1], 3 );
218 P( D, A, B, C, X[ 9], 9 );
219 P( C, D, A, B, X[ 5], 11 );
220 P( B, C, D, A, X[13], 15 );
221 P( A, B, C, D, X[ 3], 3 );
222 P( D, A, B, C, X[11], 9 );
223 P( C, D, A, B, X[ 7], 11 );
224 P( B, C, D, A, X[15], 15 );
225
226#undef F
227#undef P
228
229 ctx->state[0] += A;
230 ctx->state[1] += B;
231 ctx->state[2] += C;
232 ctx->state[3] += D;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100233
234 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000235}
Jaeden Amero041039f2018-02-19 15:28:08 +0000236
237#if !defined(MBEDTLS_DEPRECATED_REMOVED)
238void mbedtls_md4_process( mbedtls_md4_context *ctx,
239 const unsigned char data[64] )
240{
241 mbedtls_internal_md4_process( ctx, data );
242}
243#endif
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200244#endif /* !MBEDTLS_MD4_PROCESS_ALT */
Paul Bakker5121ce52009-01-03 21:22:43 +0000245
246/*
247 * MD4 process buffer
248 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100249int mbedtls_md4_update_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100250 const unsigned char *input,
251 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000252{
Janos Follath24eed8d2019-11-22 13:21:35 +0000253 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000254 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000255 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
Brian White12895d12014-04-11 11:29:42 -0400257 if( ilen == 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100258 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000259
260 left = ctx->total[0] & 0x3F;
261 fill = 64 - left;
262
Paul Bakker5c2364c2012-10-01 14:41:15 +0000263 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000264 ctx->total[0] &= 0xFFFFFFFF;
265
Paul Bakker5c2364c2012-10-01 14:41:15 +0000266 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000267 ctx->total[1]++;
268
269 if( left && ilen >= fill )
270 {
271 memcpy( (void *) (ctx->buffer + left),
272 (void *) input, fill );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100273
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100274 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100275 return( ret );
276
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 input += fill;
278 ilen -= fill;
279 left = 0;
280 }
281
282 while( ilen >= 64 )
283 {
Andres Amaya Garciacccfe082017-06-28 10:36:39 +0100284 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100285 return( ret );
286
Paul Bakker5121ce52009-01-03 21:22:43 +0000287 input += 64;
288 ilen -= 64;
289 }
290
291 if( ilen > 0 )
292 {
293 memcpy( (void *) (ctx->buffer + left),
294 (void *) input, ilen );
295 }
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100296
297 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298}
299
Jaeden Amero041039f2018-02-19 15:28:08 +0000300#if !defined(MBEDTLS_DEPRECATED_REMOVED)
301void mbedtls_md4_update( mbedtls_md4_context *ctx,
302 const unsigned char *input,
303 size_t ilen )
304{
305 mbedtls_md4_update_ret( ctx, input, ilen );
306}
307#endif
308
Paul Bakker5121ce52009-01-03 21:22:43 +0000309static const unsigned char md4_padding[64] =
310{
311 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
312 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
313 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
314 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
315};
316
317/*
318 * MD4 final digest
319 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100320int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100321 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000322{
Janos Follath24eed8d2019-11-22 13:21:35 +0000323 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000324 uint32_t last, padn;
325 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 unsigned char msglen[8];
327
328 high = ( ctx->total[0] >> 29 )
329 | ( ctx->total[1] << 3 );
330 low = ( ctx->total[0] << 3 );
331
Paul Bakker5c2364c2012-10-01 14:41:15 +0000332 PUT_UINT32_LE( low, msglen, 0 );
333 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000334
335 last = ctx->total[0] & 0x3F;
336 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
337
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100338 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100339 if( ret != 0 )
340 return( ret );
341
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100342 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100343 return( ret );
344
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
Paul Bakker5c2364c2012-10-01 14:41:15 +0000346 PUT_UINT32_LE( ctx->state[0], output, 0 );
347 PUT_UINT32_LE( ctx->state[1], output, 4 );
348 PUT_UINT32_LE( ctx->state[2], output, 8 );
349 PUT_UINT32_LE( ctx->state[3], output, 12 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100350
351 return( 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000352}
353
Jaeden Amero041039f2018-02-19 15:28:08 +0000354#if !defined(MBEDTLS_DEPRECATED_REMOVED)
355void mbedtls_md4_finish( mbedtls_md4_context *ctx,
356 unsigned char output[16] )
357{
358 mbedtls_md4_finish_ret( ctx, output );
359}
360#endif
361
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200362#endif /* !MBEDTLS_MD4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200363
Paul Bakker5121ce52009-01-03 21:22:43 +0000364/*
365 * output = MD4( input buffer )
366 */
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100367int mbedtls_md4_ret( const unsigned char *input,
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100368 size_t ilen,
369 unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000370{
Janos Follath24eed8d2019-11-22 13:21:35 +0000371 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200372 mbedtls_md4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000373
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200374 mbedtls_md4_init( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100375
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100376 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100377 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100378
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100379 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100380 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100381
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100382 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 )
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100383 goto exit;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100384
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100385exit:
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200386 mbedtls_md4_free( &ctx );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100387
Andres Amaya Garcia0963e6c2017-07-20 14:34:08 +0100388 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000389}
390
Jaeden Amero041039f2018-02-19 15:28:08 +0000391#if !defined(MBEDTLS_DEPRECATED_REMOVED)
392void mbedtls_md4( const unsigned char *input,
393 size_t ilen,
394 unsigned char output[16] )
395{
396 mbedtls_md4_ret( input, ilen, output );
397}
398#endif
399
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200400#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
402/*
403 * RFC 1320 test vectors
404 */
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100405static const unsigned char md4_test_str[7][81] =
Paul Bakker5121ce52009-01-03 21:22:43 +0000406{
Paul Bakker9af723c2014-05-01 13:03:14 +0200407 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 { "a" },
409 { "abc" },
410 { "message digest" },
411 { "abcdefghijklmnopqrstuvwxyz" },
412 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100413 { "12345678901234567890123456789012345678901234567890123456789012"
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 "345678901234567890" }
415};
416
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100417static const size_t md4_test_strlen[7] =
418{
419 0, 1, 3, 14, 26, 62, 80
420};
421
Paul Bakker5121ce52009-01-03 21:22:43 +0000422static const unsigned char md4_test_sum[7][16] =
423{
424 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
425 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
426 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
427 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
428 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
429 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
430 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
431 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
432 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
433 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
434 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
435 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
436 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
437 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
438};
439
440/*
441 * Checkup routine
442 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443int mbedtls_md4_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +0000444{
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100445 int i, ret = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 unsigned char md4sum[16];
447
448 for( i = 0; i < 7; i++ )
449 {
450 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200451 mbedtls_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
Gilles Peskine9e4f77c2018-01-22 11:48:08 +0100453 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum );
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100454 if( ret != 0 )
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100455 goto fail;
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100458 {
459 ret = 1;
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100460 goto fail;
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100461 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200464 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000465 }
466
467 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200468 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470 return( 0 );
Andres Amaya Garciabee06352017-04-28 17:00:30 +0100471
472fail:
473 if( verbose != 0 )
474 mbedtls_printf( "failed\n" );
475
Andres Amaya Garcia2d0aa8b2017-07-21 14:57:26 +0100476 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477}
478
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200479#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200481#endif /* MBEDTLS_MD4_C */