blob: 8ac6c0181cc96f549011f2df90a198e44dc2d6c2 [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
Paul Bakker40e46942009-01-03 21:51:57 +000032#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Paul Bakker40e46942009-01-03 21:51:57 +000034#if defined(POLARSSL_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Paul Bakker40e46942009-01-03 21:51:57 +000036#include "polarssl/md4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Paul Bakker335db3f2011-04-25 15:28:35 +000038#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000039#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000040#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000041
Paul Bakker7dc4c442014-02-01 22:50:26 +010042#if defined(POLARSSL_PLATFORM_C)
43#include "polarssl/platform.h"
44#else
45#define polarssl_printf printf
46#endif
47
Paul Bakker90995b52013-06-24 19:20:35 +020048#if !defined(POLARSSL_MD4_ALT)
49
Paul Bakker5121ce52009-01-03 21:22:43 +000050/*
51 * 32-bit integer manipulation macros (little endian)
52 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000053#ifndef GET_UINT32_LE
54#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000055{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000056 (n) = ( (uint32_t) (b)[(i) ] ) \
57 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
58 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
59 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000060}
61#endif
62
Paul Bakker5c2364c2012-10-01 14:41:15 +000063#ifndef PUT_UINT32_LE
64#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000065{ \
66 (b)[(i) ] = (unsigned char) ( (n) ); \
67 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
68 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
69 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
70}
71#endif
72
73/*
74 * MD4 context setup
75 */
76void md4_starts( md4_context *ctx )
77{
78 ctx->total[0] = 0;
79 ctx->total[1] = 0;
80
81 ctx->state[0] = 0x67452301;
82 ctx->state[1] = 0xEFCDAB89;
83 ctx->state[2] = 0x98BADCFE;
84 ctx->state[3] = 0x10325476;
85}
86
Paul Bakker1bd3ae82013-03-13 10:26:44 +010087void md4_process( md4_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000088{
Paul Bakker5c2364c2012-10-01 14:41:15 +000089 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000090
Paul Bakker5c2364c2012-10-01 14:41:15 +000091 GET_UINT32_LE( X[ 0], data, 0 );
92 GET_UINT32_LE( X[ 1], data, 4 );
93 GET_UINT32_LE( X[ 2], data, 8 );
94 GET_UINT32_LE( X[ 3], data, 12 );
95 GET_UINT32_LE( X[ 4], data, 16 );
96 GET_UINT32_LE( X[ 5], data, 20 );
97 GET_UINT32_LE( X[ 6], data, 24 );
98 GET_UINT32_LE( X[ 7], data, 28 );
99 GET_UINT32_LE( X[ 8], data, 32 );
100 GET_UINT32_LE( X[ 9], data, 36 );
101 GET_UINT32_LE( X[10], data, 40 );
102 GET_UINT32_LE( X[11], data, 44 );
103 GET_UINT32_LE( X[12], data, 48 );
104 GET_UINT32_LE( X[13], data, 52 );
105 GET_UINT32_LE( X[14], data, 56 );
106 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
109
110 A = ctx->state[0];
111 B = ctx->state[1];
112 C = ctx->state[2];
113 D = ctx->state[3];
114
115#define F(x, y, z) ((x & y) | ((~x) & z))
116#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
117
118 P( A, B, C, D, X[ 0], 3 );
119 P( D, A, B, C, X[ 1], 7 );
120 P( C, D, A, B, X[ 2], 11 );
121 P( B, C, D, A, X[ 3], 19 );
122 P( A, B, C, D, X[ 4], 3 );
123 P( D, A, B, C, X[ 5], 7 );
124 P( C, D, A, B, X[ 6], 11 );
125 P( B, C, D, A, X[ 7], 19 );
126 P( A, B, C, D, X[ 8], 3 );
127 P( D, A, B, C, X[ 9], 7 );
128 P( C, D, A, B, X[10], 11 );
129 P( B, C, D, A, X[11], 19 );
130 P( A, B, C, D, X[12], 3 );
131 P( D, A, B, C, X[13], 7 );
132 P( C, D, A, B, X[14], 11 );
133 P( B, C, D, A, X[15], 19 );
134
135#undef P
136#undef F
137
138#define F(x,y,z) ((x & y) | (x & z) | (y & z))
139#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
140
141 P( A, B, C, D, X[ 0], 3 );
142 P( D, A, B, C, X[ 4], 5 );
143 P( C, D, A, B, X[ 8], 9 );
144 P( B, C, D, A, X[12], 13 );
145 P( A, B, C, D, X[ 1], 3 );
146 P( D, A, B, C, X[ 5], 5 );
147 P( C, D, A, B, X[ 9], 9 );
148 P( B, C, D, A, X[13], 13 );
149 P( A, B, C, D, X[ 2], 3 );
150 P( D, A, B, C, X[ 6], 5 );
151 P( C, D, A, B, X[10], 9 );
152 P( B, C, D, A, X[14], 13 );
153 P( A, B, C, D, X[ 3], 3 );
154 P( D, A, B, C, X[ 7], 5 );
155 P( C, D, A, B, X[11], 9 );
156 P( B, C, D, A, X[15], 13 );
157
158#undef P
159#undef F
160
161#define F(x,y,z) (x ^ y ^ z)
162#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
163
164 P( A, B, C, D, X[ 0], 3 );
165 P( D, A, B, C, X[ 8], 9 );
166 P( C, D, A, B, X[ 4], 11 );
167 P( B, C, D, A, X[12], 15 );
168 P( A, B, C, D, X[ 2], 3 );
169 P( D, A, B, C, X[10], 9 );
170 P( C, D, A, B, X[ 6], 11 );
171 P( B, C, D, A, X[14], 15 );
172 P( A, B, C, D, X[ 1], 3 );
173 P( D, A, B, C, X[ 9], 9 );
174 P( C, D, A, B, X[ 5], 11 );
175 P( B, C, D, A, X[13], 15 );
176 P( A, B, C, D, X[ 3], 3 );
177 P( D, A, B, C, X[11], 9 );
178 P( C, D, A, B, X[ 7], 11 );
179 P( B, C, D, A, X[15], 15 );
180
181#undef F
182#undef P
183
184 ctx->state[0] += A;
185 ctx->state[1] += B;
186 ctx->state[2] += C;
187 ctx->state[3] += D;
188}
189
190/*
191 * MD4 process buffer
192 */
Paul Bakker23986e52011-04-24 08:57:21 +0000193void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000194{
Paul Bakker23986e52011-04-24 08:57:21 +0000195 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000196 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000197
198 if( ilen <= 0 )
199 return;
200
201 left = ctx->total[0] & 0x3F;
202 fill = 64 - left;
203
Paul Bakker5c2364c2012-10-01 14:41:15 +0000204 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000205 ctx->total[0] &= 0xFFFFFFFF;
206
Paul Bakker5c2364c2012-10-01 14:41:15 +0000207 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000208 ctx->total[1]++;
209
210 if( left && ilen >= fill )
211 {
212 memcpy( (void *) (ctx->buffer + left),
213 (void *) input, fill );
214 md4_process( ctx, ctx->buffer );
215 input += fill;
216 ilen -= fill;
217 left = 0;
218 }
219
220 while( ilen >= 64 )
221 {
222 md4_process( ctx, input );
223 input += 64;
224 ilen -= 64;
225 }
226
227 if( ilen > 0 )
228 {
229 memcpy( (void *) (ctx->buffer + left),
230 (void *) input, ilen );
231 }
232}
233
234static const unsigned char md4_padding[64] =
235{
236 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
238 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
239 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
240};
241
242/*
243 * MD4 final digest
244 */
245void md4_finish( md4_context *ctx, unsigned char output[16] )
246{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000247 uint32_t last, padn;
248 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000249 unsigned char msglen[8];
250
251 high = ( ctx->total[0] >> 29 )
252 | ( ctx->total[1] << 3 );
253 low = ( ctx->total[0] << 3 );
254
Paul Bakker5c2364c2012-10-01 14:41:15 +0000255 PUT_UINT32_LE( low, msglen, 0 );
256 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258 last = ctx->total[0] & 0x3F;
259 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
260
261 md4_update( ctx, (unsigned char *) md4_padding, padn );
262 md4_update( ctx, msglen, 8 );
263
Paul Bakker5c2364c2012-10-01 14:41:15 +0000264 PUT_UINT32_LE( ctx->state[0], output, 0 );
265 PUT_UINT32_LE( ctx->state[1], output, 4 );
266 PUT_UINT32_LE( ctx->state[2], output, 8 );
267 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000268}
269
Paul Bakker90995b52013-06-24 19:20:35 +0200270#endif /* !POLARSSL_MD4_ALT */
271
Paul Bakker5121ce52009-01-03 21:22:43 +0000272/*
273 * output = MD4( input buffer )
274 */
Paul Bakker23986e52011-04-24 08:57:21 +0000275void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000276{
277 md4_context ctx;
278
279 md4_starts( &ctx );
280 md4_update( &ctx, input, ilen );
281 md4_finish( &ctx, output );
282
283 memset( &ctx, 0, sizeof( md4_context ) );
284}
285
Paul Bakker335db3f2011-04-25 15:28:35 +0000286#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000287/*
288 * output = MD4( file contents )
289 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000290int md4_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000291{
292 FILE *f;
293 size_t n;
294 md4_context ctx;
295 unsigned char buf[1024];
296
297 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000298 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000299
300 md4_starts( &ctx );
301
302 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000303 md4_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000304
305 md4_finish( &ctx, output );
306
307 memset( &ctx, 0, sizeof( md4_context ) );
308
309 if( ferror( f ) != 0 )
310 {
311 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000312 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313 }
314
315 fclose( f );
316 return( 0 );
317}
Paul Bakker335db3f2011-04-25 15:28:35 +0000318#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000319
320/*
321 * MD4 HMAC context setup
322 */
Paul Bakker23986e52011-04-24 08:57:21 +0000323void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000324{
Paul Bakker23986e52011-04-24 08:57:21 +0000325 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000326 unsigned char sum[16];
327
328 if( keylen > 64 )
329 {
330 md4( key, keylen, sum );
331 keylen = 16;
332 key = sum;
333 }
334
335 memset( ctx->ipad, 0x36, 64 );
336 memset( ctx->opad, 0x5C, 64 );
337
338 for( i = 0; i < keylen; i++ )
339 {
340 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
341 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
342 }
343
344 md4_starts( ctx );
345 md4_update( ctx, ctx->ipad, 64 );
346
347 memset( sum, 0, sizeof( sum ) );
348}
349
350/*
351 * MD4 HMAC process buffer
352 */
Paul Bakker23986e52011-04-24 08:57:21 +0000353void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000354{
355 md4_update( ctx, input, ilen );
356}
357
358/*
359 * MD4 HMAC final digest
360 */
361void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
362{
363 unsigned char tmpbuf[16];
364
365 md4_finish( ctx, tmpbuf );
366 md4_starts( ctx );
367 md4_update( ctx, ctx->opad, 64 );
368 md4_update( ctx, tmpbuf, 16 );
369 md4_finish( ctx, output );
370
371 memset( tmpbuf, 0, sizeof( tmpbuf ) );
372}
373
374/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000375 * MD4 HMAC context reset
376 */
377void md4_hmac_reset( md4_context *ctx )
378{
379 md4_starts( ctx );
380 md4_update( ctx, ctx->ipad, 64 );
381}
382
383/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 * output = HMAC-MD4( hmac key, input buffer )
385 */
Paul Bakker23986e52011-04-24 08:57:21 +0000386void md4_hmac( const unsigned char *key, size_t keylen,
387 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000388 unsigned char output[16] )
389{
390 md4_context ctx;
391
392 md4_hmac_starts( &ctx, key, keylen );
393 md4_hmac_update( &ctx, input, ilen );
394 md4_hmac_finish( &ctx, output );
395
396 memset( &ctx, 0, sizeof( md4_context ) );
397}
398
Paul Bakker40e46942009-01-03 21:51:57 +0000399#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
401/*
402 * RFC 1320 test vectors
403 */
404static const char md4_test_str[7][81] =
405{
406 { "" },
407 { "a" },
408 { "abc" },
409 { "message digest" },
410 { "abcdefghijklmnopqrstuvwxyz" },
411 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
412 { "12345678901234567890123456789012345678901234567890123456789012" \
413 "345678901234567890" }
414};
415
416static const unsigned char md4_test_sum[7][16] =
417{
418 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
419 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
420 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
421 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
422 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
423 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
424 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
425 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
426 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
427 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
428 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
429 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
430 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
431 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
432};
433
434/*
435 * Checkup routine
436 */
437int md4_self_test( int verbose )
438{
439 int i;
440 unsigned char md4sum[16];
441
442 for( i = 0; i < 7; i++ )
443 {
444 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100445 polarssl_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000446
447 md4( (unsigned char *) md4_test_str[i],
448 strlen( md4_test_str[i] ), md4sum );
449
450 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
451 {
452 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100453 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000454
455 return( 1 );
456 }
457
458 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100459 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000460 }
461
462 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100463 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464
465 return( 0 );
466}
467
468#endif
469
470#endif