blob: 597e5f4a49a9e6185915348fe386011653f51a67 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Paul Bakker4087c472013-06-12 16:49:10 +02004 * Copyright (C) 2006-2013, 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 Bakker312da332014-06-13 17:20:13 +020042/* Implementation that should never be optimized out by the compiler */
43static void polarssl_zeroize( void *v, size_t n ) {
44 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
45}
46
Paul Bakker4087c472013-06-12 16:49:10 +020047#if !defined(POLARSSL_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
63#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000064{ \
65 (b)[(i) ] = (unsigned char) ( (n) ); \
66 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
67 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
68 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
69}
70#endif
71
72/*
73 * MD4 context setup
74 */
75void md4_starts( md4_context *ctx )
76{
77 ctx->total[0] = 0;
78 ctx->total[1] = 0;
79
80 ctx->state[0] = 0x67452301;
81 ctx->state[1] = 0xEFCDAB89;
82 ctx->state[2] = 0x98BADCFE;
83 ctx->state[3] = 0x10325476;
84}
85
Paul Bakkerff60ee62010-03-16 21:09:09 +000086static void md4_process( md4_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000087{
Paul Bakker5c2364c2012-10-01 14:41:15 +000088 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000089
Paul Bakker5c2364c2012-10-01 14:41:15 +000090 GET_UINT32_LE( X[ 0], data, 0 );
91 GET_UINT32_LE( X[ 1], data, 4 );
92 GET_UINT32_LE( X[ 2], data, 8 );
93 GET_UINT32_LE( X[ 3], data, 12 );
94 GET_UINT32_LE( X[ 4], data, 16 );
95 GET_UINT32_LE( X[ 5], data, 20 );
96 GET_UINT32_LE( X[ 6], data, 24 );
97 GET_UINT32_LE( X[ 7], data, 28 );
98 GET_UINT32_LE( X[ 8], data, 32 );
99 GET_UINT32_LE( X[ 9], data, 36 );
100 GET_UINT32_LE( X[10], data, 40 );
101 GET_UINT32_LE( X[11], data, 44 );
102 GET_UINT32_LE( X[12], data, 48 );
103 GET_UINT32_LE( X[13], data, 52 );
104 GET_UINT32_LE( X[14], data, 56 );
105 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000106
107#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
108
109 A = ctx->state[0];
110 B = ctx->state[1];
111 C = ctx->state[2];
112 D = ctx->state[3];
113
114#define F(x, y, z) ((x & y) | ((~x) & z))
115#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
116
117 P( A, B, C, D, X[ 0], 3 );
118 P( D, A, B, C, X[ 1], 7 );
119 P( C, D, A, B, X[ 2], 11 );
120 P( B, C, D, A, X[ 3], 19 );
121 P( A, B, C, D, X[ 4], 3 );
122 P( D, A, B, C, X[ 5], 7 );
123 P( C, D, A, B, X[ 6], 11 );
124 P( B, C, D, A, X[ 7], 19 );
125 P( A, B, C, D, X[ 8], 3 );
126 P( D, A, B, C, X[ 9], 7 );
127 P( C, D, A, B, X[10], 11 );
128 P( B, C, D, A, X[11], 19 );
129 P( A, B, C, D, X[12], 3 );
130 P( D, A, B, C, X[13], 7 );
131 P( C, D, A, B, X[14], 11 );
132 P( B, C, D, A, X[15], 19 );
133
134#undef P
135#undef F
136
137#define F(x,y,z) ((x & y) | (x & z) | (y & z))
138#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
139
140 P( A, B, C, D, X[ 0], 3 );
141 P( D, A, B, C, X[ 4], 5 );
142 P( C, D, A, B, X[ 8], 9 );
143 P( B, C, D, A, X[12], 13 );
144 P( A, B, C, D, X[ 1], 3 );
145 P( D, A, B, C, X[ 5], 5 );
146 P( C, D, A, B, X[ 9], 9 );
147 P( B, C, D, A, X[13], 13 );
148 P( A, B, C, D, X[ 2], 3 );
149 P( D, A, B, C, X[ 6], 5 );
150 P( C, D, A, B, X[10], 9 );
151 P( B, C, D, A, X[14], 13 );
152 P( A, B, C, D, X[ 3], 3 );
153 P( D, A, B, C, X[ 7], 5 );
154 P( C, D, A, B, X[11], 9 );
155 P( B, C, D, A, X[15], 13 );
156
157#undef P
158#undef F
159
160#define F(x,y,z) (x ^ y ^ z)
161#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
162
163 P( A, B, C, D, X[ 0], 3 );
164 P( D, A, B, C, X[ 8], 9 );
165 P( C, D, A, B, X[ 4], 11 );
166 P( B, C, D, A, X[12], 15 );
167 P( A, B, C, D, X[ 2], 3 );
168 P( D, A, B, C, X[10], 9 );
169 P( C, D, A, B, X[ 6], 11 );
170 P( B, C, D, A, X[14], 15 );
171 P( A, B, C, D, X[ 1], 3 );
172 P( D, A, B, C, X[ 9], 9 );
173 P( C, D, A, B, X[ 5], 11 );
174 P( B, C, D, A, X[13], 15 );
175 P( A, B, C, D, X[ 3], 3 );
176 P( D, A, B, C, X[11], 9 );
177 P( C, D, A, B, X[ 7], 11 );
178 P( B, C, D, A, X[15], 15 );
179
180#undef F
181#undef P
182
183 ctx->state[0] += A;
184 ctx->state[1] += B;
185 ctx->state[2] += C;
186 ctx->state[3] += D;
187}
188
189/*
190 * MD4 process buffer
191 */
Paul Bakker23986e52011-04-24 08:57:21 +0000192void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000193{
Paul Bakker23986e52011-04-24 08:57:21 +0000194 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000195 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000196
197 if( ilen <= 0 )
198 return;
199
200 left = ctx->total[0] & 0x3F;
201 fill = 64 - left;
202
Paul Bakker5c2364c2012-10-01 14:41:15 +0000203 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000204 ctx->total[0] &= 0xFFFFFFFF;
205
Paul Bakker5c2364c2012-10-01 14:41:15 +0000206 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000207 ctx->total[1]++;
208
209 if( left && ilen >= fill )
210 {
211 memcpy( (void *) (ctx->buffer + left),
212 (void *) input, fill );
213 md4_process( ctx, ctx->buffer );
214 input += fill;
215 ilen -= fill;
216 left = 0;
217 }
218
219 while( ilen >= 64 )
220 {
221 md4_process( ctx, input );
222 input += 64;
223 ilen -= 64;
224 }
225
226 if( ilen > 0 )
227 {
228 memcpy( (void *) (ctx->buffer + left),
229 (void *) input, ilen );
230 }
231}
232
233static const unsigned char md4_padding[64] =
234{
235 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
236 0, 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};
240
241/*
242 * MD4 final digest
243 */
244void md4_finish( md4_context *ctx, unsigned char output[16] )
245{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000246 uint32_t last, padn;
247 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000248 unsigned char msglen[8];
249
250 high = ( ctx->total[0] >> 29 )
251 | ( ctx->total[1] << 3 );
252 low = ( ctx->total[0] << 3 );
253
Paul Bakker5c2364c2012-10-01 14:41:15 +0000254 PUT_UINT32_LE( low, msglen, 0 );
255 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000256
257 last = ctx->total[0] & 0x3F;
258 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
259
260 md4_update( ctx, (unsigned char *) md4_padding, padn );
261 md4_update( ctx, msglen, 8 );
262
Paul Bakker5c2364c2012-10-01 14:41:15 +0000263 PUT_UINT32_LE( ctx->state[0], output, 0 );
264 PUT_UINT32_LE( ctx->state[1], output, 4 );
265 PUT_UINT32_LE( ctx->state[2], output, 8 );
266 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000267}
268
Paul Bakker4087c472013-06-12 16:49:10 +0200269#endif /* !POLARSSL_MD4_ALT */
270
Paul Bakker5121ce52009-01-03 21:22:43 +0000271/*
272 * output = MD4( input buffer )
273 */
Paul Bakker23986e52011-04-24 08:57:21 +0000274void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000275{
276 md4_context ctx;
277
278 md4_starts( &ctx );
279 md4_update( &ctx, input, ilen );
280 md4_finish( &ctx, output );
281
Paul Bakker312da332014-06-13 17:20:13 +0200282 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000283}
284
Paul Bakker335db3f2011-04-25 15:28:35 +0000285#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000286/*
287 * output = MD4( file contents )
288 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000289int md4_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000290{
291 FILE *f;
292 size_t n;
293 md4_context ctx;
294 unsigned char buf[1024];
295
296 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000297 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000298
299 md4_starts( &ctx );
300
301 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000302 md4_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000303
304 md4_finish( &ctx, output );
305
Paul Bakker312da332014-06-13 17:20:13 +0200306 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
308 if( ferror( f ) != 0 )
309 {
310 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000311 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000312 }
313
314 fclose( f );
315 return( 0 );
316}
Paul Bakker335db3f2011-04-25 15:28:35 +0000317#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
319/*
320 * MD4 HMAC context setup
321 */
Paul Bakker23986e52011-04-24 08:57:21 +0000322void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000323{
Paul Bakker23986e52011-04-24 08:57:21 +0000324 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000325 unsigned char sum[16];
326
327 if( keylen > 64 )
328 {
329 md4( key, keylen, sum );
330 keylen = 16;
331 key = sum;
332 }
333
334 memset( ctx->ipad, 0x36, 64 );
335 memset( ctx->opad, 0x5C, 64 );
336
337 for( i = 0; i < keylen; i++ )
338 {
339 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
340 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
341 }
342
343 md4_starts( ctx );
344 md4_update( ctx, ctx->ipad, 64 );
345
Paul Bakker312da332014-06-13 17:20:13 +0200346 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000347}
348
349/*
350 * MD4 HMAC process buffer
351 */
Paul Bakker23986e52011-04-24 08:57:21 +0000352void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000353{
354 md4_update( ctx, input, ilen );
355}
356
357/*
358 * MD4 HMAC final digest
359 */
360void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
361{
362 unsigned char tmpbuf[16];
363
364 md4_finish( ctx, tmpbuf );
365 md4_starts( ctx );
366 md4_update( ctx, ctx->opad, 64 );
367 md4_update( ctx, tmpbuf, 16 );
368 md4_finish( ctx, output );
369
Paul Bakker312da332014-06-13 17:20:13 +0200370 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000371}
372
373/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000374 * MD4 HMAC context reset
375 */
376void md4_hmac_reset( md4_context *ctx )
377{
378 md4_starts( ctx );
379 md4_update( ctx, ctx->ipad, 64 );
380}
381
382/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 * output = HMAC-MD4( hmac key, input buffer )
384 */
Paul Bakker23986e52011-04-24 08:57:21 +0000385void md4_hmac( const unsigned char *key, size_t keylen,
386 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000387 unsigned char output[16] )
388{
389 md4_context ctx;
390
391 md4_hmac_starts( &ctx, key, keylen );
392 md4_hmac_update( &ctx, input, ilen );
393 md4_hmac_finish( &ctx, output );
394
Paul Bakker312da332014-06-13 17:20:13 +0200395 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000396}
397
Paul Bakker40e46942009-01-03 21:51:57 +0000398#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
400/*
401 * RFC 1320 test vectors
402 */
403static const char md4_test_str[7][81] =
404{
405 { "" },
406 { "a" },
407 { "abc" },
408 { "message digest" },
409 { "abcdefghijklmnopqrstuvwxyz" },
410 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
411 { "12345678901234567890123456789012345678901234567890123456789012" \
412 "345678901234567890" }
413};
414
415static const unsigned char md4_test_sum[7][16] =
416{
417 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
418 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
419 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
420 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
421 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
422 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
423 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
424 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
425 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
426 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
427 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
428 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
429 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
430 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
431};
432
433/*
434 * Checkup routine
435 */
436int md4_self_test( int verbose )
437{
438 int i;
439 unsigned char md4sum[16];
440
441 for( i = 0; i < 7; i++ )
442 {
443 if( verbose != 0 )
444 printf( " MD4 test #%d: ", i + 1 );
445
446 md4( (unsigned char *) md4_test_str[i],
447 strlen( md4_test_str[i] ), md4sum );
448
449 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
450 {
451 if( verbose != 0 )
452 printf( "failed\n" );
453
454 return( 1 );
455 }
456
457 if( verbose != 0 )
458 printf( "passed\n" );
459 }
460
461 if( verbose != 0 )
462 printf( "\n" );
463
464 return( 0 );
465}
466
467#endif
468
469#endif