blob: 1fba4df846697a852829b8b37daaf4a50f974a5d [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Paul Bakker530927b2015-02-13 14:24:10 +01004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnarde12abf92015-01-28 17:13:45 +00006 * This file is part of mbed TLS (https://polarssl.org)
Paul Bakkere0ccd0a2009-01-04 16:27:10 +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
Paul Bakker40e46942009-01-03 21:51:57 +000029#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000030
Paul Bakker40e46942009-01-03 21:51:57 +000031#if defined(POLARSSL_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000032
Paul Bakker40e46942009-01-03 21:51:57 +000033#include "polarssl/md4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker335db3f2011-04-25 15:28:35 +000035#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000036#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000037#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Manuel Pégourié-Gonnardaa4e55b2015-08-31 11:22:01 +020039#if !defined(POLARSSL_MD4_ALT)
40
Paul Bakker312da332014-06-13 17:20:13 +020041/* Implementation that should never be optimized out by the compiler */
42static void polarssl_zeroize( void *v, size_t n ) {
43 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
44}
45
Paul Bakker5121ce52009-01-03 21:22:43 +000046/*
47 * 32-bit integer manipulation macros (little endian)
48 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000049#ifndef GET_UINT32_LE
50#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000051{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000052 (n) = ( (uint32_t) (b)[(i) ] ) \
53 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
54 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
55 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000056}
57#endif
58
Paul Bakker5c2364c2012-10-01 14:41:15 +000059#ifndef PUT_UINT32_LE
60#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000061{ \
62 (b)[(i) ] = (unsigned char) ( (n) ); \
63 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
64 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
65 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
66}
67#endif
68
69/*
70 * MD4 context setup
71 */
72void md4_starts( md4_context *ctx )
73{
74 ctx->total[0] = 0;
75 ctx->total[1] = 0;
76
77 ctx->state[0] = 0x67452301;
78 ctx->state[1] = 0xEFCDAB89;
79 ctx->state[2] = 0x98BADCFE;
80 ctx->state[3] = 0x10325476;
81}
82
Paul Bakkerff60ee62010-03-16 21:09:09 +000083static void md4_process( md4_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000084{
Paul Bakker5c2364c2012-10-01 14:41:15 +000085 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000086
Paul Bakker5c2364c2012-10-01 14:41:15 +000087 GET_UINT32_LE( X[ 0], data, 0 );
88 GET_UINT32_LE( X[ 1], data, 4 );
89 GET_UINT32_LE( X[ 2], data, 8 );
90 GET_UINT32_LE( X[ 3], data, 12 );
91 GET_UINT32_LE( X[ 4], data, 16 );
92 GET_UINT32_LE( X[ 5], data, 20 );
93 GET_UINT32_LE( X[ 6], data, 24 );
94 GET_UINT32_LE( X[ 7], data, 28 );
95 GET_UINT32_LE( X[ 8], data, 32 );
96 GET_UINT32_LE( X[ 9], data, 36 );
97 GET_UINT32_LE( X[10], data, 40 );
98 GET_UINT32_LE( X[11], data, 44 );
99 GET_UINT32_LE( X[12], data, 48 );
100 GET_UINT32_LE( X[13], data, 52 );
101 GET_UINT32_LE( X[14], data, 56 );
102 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000103
104#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
105
106 A = ctx->state[0];
107 B = ctx->state[1];
108 C = ctx->state[2];
109 D = ctx->state[3];
110
111#define F(x, y, z) ((x & y) | ((~x) & z))
112#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
113
114 P( A, B, C, D, X[ 0], 3 );
115 P( D, A, B, C, X[ 1], 7 );
116 P( C, D, A, B, X[ 2], 11 );
117 P( B, C, D, A, X[ 3], 19 );
118 P( A, B, C, D, X[ 4], 3 );
119 P( D, A, B, C, X[ 5], 7 );
120 P( C, D, A, B, X[ 6], 11 );
121 P( B, C, D, A, X[ 7], 19 );
122 P( A, B, C, D, X[ 8], 3 );
123 P( D, A, B, C, X[ 9], 7 );
124 P( C, D, A, B, X[10], 11 );
125 P( B, C, D, A, X[11], 19 );
126 P( A, B, C, D, X[12], 3 );
127 P( D, A, B, C, X[13], 7 );
128 P( C, D, A, B, X[14], 11 );
129 P( B, C, D, A, X[15], 19 );
130
131#undef P
132#undef F
133
134#define F(x,y,z) ((x & y) | (x & z) | (y & z))
135#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
136
137 P( A, B, C, D, X[ 0], 3 );
138 P( D, A, B, C, X[ 4], 5 );
139 P( C, D, A, B, X[ 8], 9 );
140 P( B, C, D, A, X[12], 13 );
141 P( A, B, C, D, X[ 1], 3 );
142 P( D, A, B, C, X[ 5], 5 );
143 P( C, D, A, B, X[ 9], 9 );
144 P( B, C, D, A, X[13], 13 );
145 P( A, B, C, D, X[ 2], 3 );
146 P( D, A, B, C, X[ 6], 5 );
147 P( C, D, A, B, X[10], 9 );
148 P( B, C, D, A, X[14], 13 );
149 P( A, B, C, D, X[ 3], 3 );
150 P( D, A, B, C, X[ 7], 5 );
151 P( C, D, A, B, X[11], 9 );
152 P( B, C, D, A, X[15], 13 );
153
154#undef P
155#undef F
156
157#define F(x,y,z) (x ^ y ^ z)
158#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
159
160 P( A, B, C, D, X[ 0], 3 );
161 P( D, A, B, C, X[ 8], 9 );
162 P( C, D, A, B, X[ 4], 11 );
163 P( B, C, D, A, X[12], 15 );
164 P( A, B, C, D, X[ 2], 3 );
165 P( D, A, B, C, X[10], 9 );
166 P( C, D, A, B, X[ 6], 11 );
167 P( B, C, D, A, X[14], 15 );
168 P( A, B, C, D, X[ 1], 3 );
169 P( D, A, B, C, X[ 9], 9 );
170 P( C, D, A, B, X[ 5], 11 );
171 P( B, C, D, A, X[13], 15 );
172 P( A, B, C, D, X[ 3], 3 );
173 P( D, A, B, C, X[11], 9 );
174 P( C, D, A, B, X[ 7], 11 );
175 P( B, C, D, A, X[15], 15 );
176
177#undef F
178#undef P
179
180 ctx->state[0] += A;
181 ctx->state[1] += B;
182 ctx->state[2] += C;
183 ctx->state[3] += D;
184}
185
186/*
187 * MD4 process buffer
188 */
Paul Bakker23986e52011-04-24 08:57:21 +0000189void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000190{
Paul Bakker23986e52011-04-24 08:57:21 +0000191 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000192 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000193
194 if( ilen <= 0 )
195 return;
196
197 left = ctx->total[0] & 0x3F;
198 fill = 64 - left;
199
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000201 ctx->total[0] &= 0xFFFFFFFF;
202
Paul Bakker5c2364c2012-10-01 14:41:15 +0000203 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000204 ctx->total[1]++;
205
206 if( left && ilen >= fill )
207 {
208 memcpy( (void *) (ctx->buffer + left),
209 (void *) input, fill );
210 md4_process( ctx, ctx->buffer );
211 input += fill;
212 ilen -= fill;
213 left = 0;
214 }
215
216 while( ilen >= 64 )
217 {
218 md4_process( ctx, input );
219 input += 64;
220 ilen -= 64;
221 }
222
223 if( ilen > 0 )
224 {
225 memcpy( (void *) (ctx->buffer + left),
226 (void *) input, ilen );
227 }
228}
229
230static const unsigned char md4_padding[64] =
231{
232 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
234 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
235 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
236};
237
238/*
239 * MD4 final digest
240 */
241void md4_finish( md4_context *ctx, unsigned char output[16] )
242{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000243 uint32_t last, padn;
244 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000245 unsigned char msglen[8];
246
247 high = ( ctx->total[0] >> 29 )
248 | ( ctx->total[1] << 3 );
249 low = ( ctx->total[0] << 3 );
250
Paul Bakker5c2364c2012-10-01 14:41:15 +0000251 PUT_UINT32_LE( low, msglen, 0 );
252 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
254 last = ctx->total[0] & 0x3F;
255 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
256
257 md4_update( ctx, (unsigned char *) md4_padding, padn );
258 md4_update( ctx, msglen, 8 );
259
Paul Bakker5c2364c2012-10-01 14:41:15 +0000260 PUT_UINT32_LE( ctx->state[0], output, 0 );
261 PUT_UINT32_LE( ctx->state[1], output, 4 );
262 PUT_UINT32_LE( ctx->state[2], output, 8 );
263 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000264}
265
Paul Bakker4087c472013-06-12 16:49:10 +0200266#endif /* !POLARSSL_MD4_ALT */
267
Paul Bakker5121ce52009-01-03 21:22:43 +0000268/*
269 * output = MD4( input buffer )
270 */
Paul Bakker23986e52011-04-24 08:57:21 +0000271void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000272{
273 md4_context ctx;
274
275 md4_starts( &ctx );
276 md4_update( &ctx, input, ilen );
277 md4_finish( &ctx, output );
278
Paul Bakker312da332014-06-13 17:20:13 +0200279 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000280}
281
Paul Bakker335db3f2011-04-25 15:28:35 +0000282#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000283/*
284 * output = MD4( file contents )
285 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000286int md4_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000287{
288 FILE *f;
289 size_t n;
290 md4_context ctx;
291 unsigned char buf[1024];
292
293 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000294 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000295
296 md4_starts( &ctx );
297
298 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000299 md4_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000300
301 md4_finish( &ctx, output );
302
Paul Bakker312da332014-06-13 17:20:13 +0200303 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 if( ferror( f ) != 0 )
306 {
307 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000308 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000309 }
310
311 fclose( f );
312 return( 0 );
313}
Paul Bakker335db3f2011-04-25 15:28:35 +0000314#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000315
316/*
317 * MD4 HMAC context setup
318 */
Paul Bakker23986e52011-04-24 08:57:21 +0000319void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000320{
Paul Bakker23986e52011-04-24 08:57:21 +0000321 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000322 unsigned char sum[16];
323
324 if( keylen > 64 )
325 {
326 md4( key, keylen, sum );
327 keylen = 16;
328 key = sum;
329 }
330
331 memset( ctx->ipad, 0x36, 64 );
332 memset( ctx->opad, 0x5C, 64 );
333
334 for( i = 0; i < keylen; i++ )
335 {
336 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
337 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
338 }
339
340 md4_starts( ctx );
341 md4_update( ctx, ctx->ipad, 64 );
342
Paul Bakker312da332014-06-13 17:20:13 +0200343 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000344}
345
346/*
347 * MD4 HMAC process buffer
348 */
Paul Bakker23986e52011-04-24 08:57:21 +0000349void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000350{
351 md4_update( ctx, input, ilen );
352}
353
354/*
355 * MD4 HMAC final digest
356 */
357void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
358{
359 unsigned char tmpbuf[16];
360
361 md4_finish( ctx, tmpbuf );
362 md4_starts( ctx );
363 md4_update( ctx, ctx->opad, 64 );
364 md4_update( ctx, tmpbuf, 16 );
365 md4_finish( ctx, output );
366
Paul Bakker312da332014-06-13 17:20:13 +0200367 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000368}
369
370/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000371 * MD4 HMAC context reset
372 */
373void md4_hmac_reset( md4_context *ctx )
374{
375 md4_starts( ctx );
376 md4_update( ctx, ctx->ipad, 64 );
377}
378
379/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000380 * output = HMAC-MD4( hmac key, input buffer )
381 */
Paul Bakker23986e52011-04-24 08:57:21 +0000382void md4_hmac( const unsigned char *key, size_t keylen,
383 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 unsigned char output[16] )
385{
386 md4_context ctx;
387
388 md4_hmac_starts( &ctx, key, keylen );
389 md4_hmac_update( &ctx, input, ilen );
390 md4_hmac_finish( &ctx, output );
391
Paul Bakker312da332014-06-13 17:20:13 +0200392 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000393}
394
Paul Bakker40e46942009-01-03 21:51:57 +0000395#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
397/*
398 * RFC 1320 test vectors
399 */
400static const char md4_test_str[7][81] =
401{
402 { "" },
403 { "a" },
404 { "abc" },
405 { "message digest" },
406 { "abcdefghijklmnopqrstuvwxyz" },
407 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
408 { "12345678901234567890123456789012345678901234567890123456789012" \
409 "345678901234567890" }
410};
411
412static const unsigned char md4_test_sum[7][16] =
413{
414 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
415 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
416 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
417 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
418 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
419 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
420 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
421 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
422 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
423 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
424 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
425 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
426 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
427 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
428};
429
430/*
431 * Checkup routine
432 */
433int md4_self_test( int verbose )
434{
435 int i;
436 unsigned char md4sum[16];
437
438 for( i = 0; i < 7; i++ )
439 {
440 if( verbose != 0 )
441 printf( " MD4 test #%d: ", i + 1 );
442
443 md4( (unsigned char *) md4_test_str[i],
444 strlen( md4_test_str[i] ), md4sum );
445
446 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
447 {
448 if( verbose != 0 )
449 printf( "failed\n" );
450
451 return( 1 );
452 }
453
454 if( verbose != 0 )
455 printf( "passed\n" );
456 }
457
458 if( verbose != 0 )
459 printf( "\n" );
460
461 return( 0 );
462}
463
464#endif
465
466#endif