blob: 47f762d85d93bd9878566951ab256da6ed169f8b [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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000030#include "mbedtls/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
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000037#include "mbedtls/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)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000047#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#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
Paul Bakker40e46942009-01-03 21:51:57 +0000344#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346/*
347 * RFC 1320 test vectors
348 */
349static const char md4_test_str[7][81] =
350{
Paul Bakker9af723c2014-05-01 13:03:14 +0200351 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000352 { "a" },
353 { "abc" },
354 { "message digest" },
355 { "abcdefghijklmnopqrstuvwxyz" },
356 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
357 { "12345678901234567890123456789012345678901234567890123456789012" \
358 "345678901234567890" }
359};
360
361static const unsigned char md4_test_sum[7][16] =
362{
363 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
364 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
365 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
366 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
367 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
368 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
369 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
370 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
371 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
372 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
373 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
374 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
375 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
376 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
377};
378
379/*
380 * Checkup routine
381 */
382int md4_self_test( int verbose )
383{
384 int i;
385 unsigned char md4sum[16];
386
387 for( i = 0; i < 7; i++ )
388 {
389 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100390 polarssl_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
392 md4( (unsigned char *) md4_test_str[i],
393 strlen( md4_test_str[i] ), md4sum );
394
395 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
396 {
397 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100398 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
400 return( 1 );
401 }
402
403 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100404 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405 }
406
407 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100408 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000409
410 return( 0 );
411}
412
Paul Bakker9af723c2014-05-01 13:03:14 +0200413#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
Paul Bakker9af723c2014-05-01 13:03:14 +0200415#endif /* POLARSSL_MD4_C */