blob: 97cb5f0aa8d7ed81eb29bbade39be1c21536b59e [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * The MD4 algorithm was designed by Ron Rivest in 1990.
27 *
28 * http://www.ietf.org/rfc/rfc1186.txt
29 * http://www.ietf.org/rfc/rfc1320.txt
30 */
31
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000033#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020034#else
35#include POLARSSL_CONFIG_FILE
36#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Paul Bakker40e46942009-01-03 21:51:57 +000038#if defined(POLARSSL_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Paul Bakker40e46942009-01-03 21:51:57 +000040#include "polarssl/md4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000041
Paul Bakker335db3f2011-04-25 15:28:35 +000042#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000043#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000044#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Paul Bakker7dc4c442014-02-01 22:50:26 +010046#if defined(POLARSSL_PLATFORM_C)
47#include "polarssl/platform.h"
48#else
49#define polarssl_printf printf
50#endif
51
Paul Bakker90995b52013-06-24 19:20:35 +020052#if !defined(POLARSSL_MD4_ALT)
53
Paul Bakker5121ce52009-01-03 21:22:43 +000054/*
55 * 32-bit integer manipulation macros (little endian)
56 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000057#ifndef GET_UINT32_LE
58#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000059{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000060 (n) = ( (uint32_t) (b)[(i) ] ) \
61 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
62 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
63 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000064}
65#endif
66
Paul Bakker5c2364c2012-10-01 14:41:15 +000067#ifndef PUT_UINT32_LE
68#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000069{ \
70 (b)[(i) ] = (unsigned char) ( (n) ); \
71 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
72 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
73 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
74}
75#endif
76
77/*
78 * MD4 context setup
79 */
80void md4_starts( md4_context *ctx )
81{
82 ctx->total[0] = 0;
83 ctx->total[1] = 0;
84
85 ctx->state[0] = 0x67452301;
86 ctx->state[1] = 0xEFCDAB89;
87 ctx->state[2] = 0x98BADCFE;
88 ctx->state[3] = 0x10325476;
89}
90
Paul Bakker1bd3ae82013-03-13 10:26:44 +010091void md4_process( md4_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000092{
Paul Bakker5c2364c2012-10-01 14:41:15 +000093 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000094
Paul Bakker5c2364c2012-10-01 14:41:15 +000095 GET_UINT32_LE( X[ 0], data, 0 );
96 GET_UINT32_LE( X[ 1], data, 4 );
97 GET_UINT32_LE( X[ 2], data, 8 );
98 GET_UINT32_LE( X[ 3], data, 12 );
99 GET_UINT32_LE( X[ 4], data, 16 );
100 GET_UINT32_LE( X[ 5], data, 20 );
101 GET_UINT32_LE( X[ 6], data, 24 );
102 GET_UINT32_LE( X[ 7], data, 28 );
103 GET_UINT32_LE( X[ 8], data, 32 );
104 GET_UINT32_LE( X[ 9], data, 36 );
105 GET_UINT32_LE( X[10], data, 40 );
106 GET_UINT32_LE( X[11], data, 44 );
107 GET_UINT32_LE( X[12], data, 48 );
108 GET_UINT32_LE( X[13], data, 52 );
109 GET_UINT32_LE( X[14], data, 56 );
110 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000111
112#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
113
114 A = ctx->state[0];
115 B = ctx->state[1];
116 C = ctx->state[2];
117 D = ctx->state[3];
118
119#define F(x, y, z) ((x & y) | ((~x) & z))
120#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
121
122 P( A, B, C, D, X[ 0], 3 );
123 P( D, A, B, C, X[ 1], 7 );
124 P( C, D, A, B, X[ 2], 11 );
125 P( B, C, D, A, X[ 3], 19 );
126 P( A, B, C, D, X[ 4], 3 );
127 P( D, A, B, C, X[ 5], 7 );
128 P( C, D, A, B, X[ 6], 11 );
129 P( B, C, D, A, X[ 7], 19 );
130 P( A, B, C, D, X[ 8], 3 );
131 P( D, A, B, C, X[ 9], 7 );
132 P( C, D, A, B, X[10], 11 );
133 P( B, C, D, A, X[11], 19 );
134 P( A, B, C, D, X[12], 3 );
135 P( D, A, B, C, X[13], 7 );
136 P( C, D, A, B, X[14], 11 );
137 P( B, C, D, A, X[15], 19 );
138
139#undef P
140#undef F
141
142#define F(x,y,z) ((x & y) | (x & z) | (y & z))
143#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
144
145 P( A, B, C, D, X[ 0], 3 );
146 P( D, A, B, C, X[ 4], 5 );
147 P( C, D, A, B, X[ 8], 9 );
148 P( B, C, D, A, X[12], 13 );
149 P( A, B, C, D, X[ 1], 3 );
150 P( D, A, B, C, X[ 5], 5 );
151 P( C, D, A, B, X[ 9], 9 );
152 P( B, C, D, A, X[13], 13 );
153 P( A, B, C, D, X[ 2], 3 );
154 P( D, A, B, C, X[ 6], 5 );
155 P( C, D, A, B, X[10], 9 );
156 P( B, C, D, A, X[14], 13 );
157 P( A, B, C, D, X[ 3], 3 );
158 P( D, A, B, C, X[ 7], 5 );
159 P( C, D, A, B, X[11], 9 );
160 P( B, C, D, A, X[15], 13 );
161
162#undef P
163#undef F
164
165#define F(x,y,z) (x ^ y ^ z)
166#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
167
168 P( A, B, C, D, X[ 0], 3 );
169 P( D, A, B, C, X[ 8], 9 );
170 P( C, D, A, B, X[ 4], 11 );
171 P( B, C, D, A, X[12], 15 );
172 P( A, B, C, D, X[ 2], 3 );
173 P( D, A, B, C, X[10], 9 );
174 P( C, D, A, B, X[ 6], 11 );
175 P( B, C, D, A, X[14], 15 );
176 P( A, B, C, D, X[ 1], 3 );
177 P( D, A, B, C, X[ 9], 9 );
178 P( C, D, A, B, X[ 5], 11 );
179 P( B, C, D, A, X[13], 15 );
180 P( A, B, C, D, X[ 3], 3 );
181 P( D, A, B, C, X[11], 9 );
182 P( C, D, A, B, X[ 7], 11 );
183 P( B, C, D, A, X[15], 15 );
184
185#undef F
186#undef P
187
188 ctx->state[0] += A;
189 ctx->state[1] += B;
190 ctx->state[2] += C;
191 ctx->state[3] += D;
192}
193
194/*
195 * MD4 process buffer
196 */
Paul Bakker23986e52011-04-24 08:57:21 +0000197void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000198{
Paul Bakker23986e52011-04-24 08:57:21 +0000199 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000200 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000201
Brian White12895d12014-04-11 11:29:42 -0400202 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000203 return;
204
205 left = ctx->total[0] & 0x3F;
206 fill = 64 - left;
207
Paul Bakker5c2364c2012-10-01 14:41:15 +0000208 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000209 ctx->total[0] &= 0xFFFFFFFF;
210
Paul Bakker5c2364c2012-10-01 14:41:15 +0000211 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000212 ctx->total[1]++;
213
214 if( left && ilen >= fill )
215 {
216 memcpy( (void *) (ctx->buffer + left),
217 (void *) input, fill );
218 md4_process( ctx, ctx->buffer );
219 input += fill;
220 ilen -= fill;
221 left = 0;
222 }
223
224 while( ilen >= 64 )
225 {
226 md4_process( ctx, input );
227 input += 64;
228 ilen -= 64;
229 }
230
231 if( ilen > 0 )
232 {
233 memcpy( (void *) (ctx->buffer + left),
234 (void *) input, ilen );
235 }
236}
237
238static const unsigned char md4_padding[64] =
239{
240 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
244};
245
246/*
247 * MD4 final digest
248 */
249void md4_finish( md4_context *ctx, unsigned char output[16] )
250{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000251 uint32_t last, padn;
252 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 unsigned char msglen[8];
254
255 high = ( ctx->total[0] >> 29 )
256 | ( ctx->total[1] << 3 );
257 low = ( ctx->total[0] << 3 );
258
Paul Bakker5c2364c2012-10-01 14:41:15 +0000259 PUT_UINT32_LE( low, msglen, 0 );
260 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000261
262 last = ctx->total[0] & 0x3F;
263 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
264
265 md4_update( ctx, (unsigned char *) md4_padding, padn );
266 md4_update( ctx, msglen, 8 );
267
Paul Bakker5c2364c2012-10-01 14:41:15 +0000268 PUT_UINT32_LE( ctx->state[0], output, 0 );
269 PUT_UINT32_LE( ctx->state[1], output, 4 );
270 PUT_UINT32_LE( ctx->state[2], output, 8 );
271 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000272}
273
Paul Bakker90995b52013-06-24 19:20:35 +0200274#endif /* !POLARSSL_MD4_ALT */
275
Paul Bakker5121ce52009-01-03 21:22:43 +0000276/*
277 * output = MD4( input buffer )
278 */
Paul Bakker23986e52011-04-24 08:57:21 +0000279void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000280{
281 md4_context ctx;
282
283 md4_starts( &ctx );
284 md4_update( &ctx, input, ilen );
285 md4_finish( &ctx, output );
286
287 memset( &ctx, 0, sizeof( md4_context ) );
288}
289
Paul Bakker335db3f2011-04-25 15:28:35 +0000290#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000291/*
292 * output = MD4( file contents )
293 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000294int md4_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000295{
296 FILE *f;
297 size_t n;
298 md4_context ctx;
299 unsigned char buf[1024];
300
301 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000302 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
304 md4_starts( &ctx );
305
306 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000307 md4_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
309 md4_finish( &ctx, output );
310
311 memset( &ctx, 0, sizeof( md4_context ) );
312
313 if( ferror( f ) != 0 )
314 {
315 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000316 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317 }
318
319 fclose( f );
320 return( 0 );
321}
Paul Bakker335db3f2011-04-25 15:28:35 +0000322#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000323
324/*
325 * MD4 HMAC context setup
326 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200327void md4_hmac_starts( md4_context *ctx, const unsigned char *key,
328 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000329{
Paul Bakker23986e52011-04-24 08:57:21 +0000330 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000331 unsigned char sum[16];
332
333 if( keylen > 64 )
334 {
335 md4( key, keylen, sum );
336 keylen = 16;
337 key = sum;
338 }
339
340 memset( ctx->ipad, 0x36, 64 );
341 memset( ctx->opad, 0x5C, 64 );
342
343 for( i = 0; i < keylen; i++ )
344 {
345 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
346 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
347 }
348
349 md4_starts( ctx );
350 md4_update( ctx, ctx->ipad, 64 );
351
352 memset( sum, 0, sizeof( sum ) );
353}
354
355/*
356 * MD4 HMAC process buffer
357 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200358void md4_hmac_update( md4_context *ctx, const unsigned char *input,
359 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000360{
361 md4_update( ctx, input, ilen );
362}
363
364/*
365 * MD4 HMAC final digest
366 */
367void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
368{
369 unsigned char tmpbuf[16];
370
371 md4_finish( ctx, tmpbuf );
372 md4_starts( ctx );
373 md4_update( ctx, ctx->opad, 64 );
374 md4_update( ctx, tmpbuf, 16 );
375 md4_finish( ctx, output );
376
377 memset( tmpbuf, 0, sizeof( tmpbuf ) );
378}
379
380/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000381 * MD4 HMAC context reset
382 */
383void md4_hmac_reset( md4_context *ctx )
384{
385 md4_starts( ctx );
386 md4_update( ctx, ctx->ipad, 64 );
387}
388
389/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000390 * output = HMAC-MD4( hmac key, input buffer )
391 */
Paul Bakker23986e52011-04-24 08:57:21 +0000392void md4_hmac( const unsigned char *key, size_t keylen,
393 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 unsigned char output[16] )
395{
396 md4_context ctx;
397
398 md4_hmac_starts( &ctx, key, keylen );
399 md4_hmac_update( &ctx, input, ilen );
400 md4_hmac_finish( &ctx, output );
401
402 memset( &ctx, 0, sizeof( md4_context ) );
403}
404
Paul Bakker40e46942009-01-03 21:51:57 +0000405#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
407/*
408 * RFC 1320 test vectors
409 */
410static const char md4_test_str[7][81] =
411{
Paul Bakker9af723c2014-05-01 13:03:14 +0200412 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 { "a" },
414 { "abc" },
415 { "message digest" },
416 { "abcdefghijklmnopqrstuvwxyz" },
417 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
418 { "12345678901234567890123456789012345678901234567890123456789012" \
419 "345678901234567890" }
420};
421
422static 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 */
443int md4_self_test( int verbose )
444{
445 int i;
446 unsigned char md4sum[16];
447
448 for( i = 0; i < 7; i++ )
449 {
450 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100451 polarssl_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453 md4( (unsigned char *) md4_test_str[i],
454 strlen( md4_test_str[i] ), md4sum );
455
456 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
457 {
458 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100459 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000460
461 return( 1 );
462 }
463
464 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100465 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000466 }
467
468 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100469 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
471 return( 0 );
472}
473
Paul Bakker9af723c2014-05-01 13:03:14 +0200474#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
Paul Bakker9af723c2014-05-01 13:03:14 +0200476#endif /* POLARSSL_MD4_C */