2 * RFC 1186/1320 compliant MD4 implementation
4 * Copyright (C) 2006-2007 Christophe Devine
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License, version 2.1 as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21 * The MD4 algorithm was designed by Ron Rivest in 1990.
23 * http://www.ietf.org/rfc/rfc1186.txt
24 * http://www.ietf.org/rfc/rfc1320.txt
27 #ifndef _CRT_SECURE_NO_DEPRECATE
28 #define _CRT_SECURE_NO_DEPRECATE 1
37 * 32-bit integer manipulation macros (little endian)
40 #define GET_UINT32_LE(n,b,i) \
42 (n) = ( (unsigned long) (b)[(i) ] ) \
43 | ( (unsigned long) (b)[(i) + 1] << 8 ) \
44 | ( (unsigned long) (b)[(i) + 2] << 16 ) \
45 | ( (unsigned long) (b)[(i) + 3] << 24 ); \
50 #define PUT_UINT32_LE(n,b,i) \
52 (b)[(i) ] = (unsigned char) ( (n) ); \
53 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
54 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
55 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
62 void md4_starts( md4_context *ctx )
67 ctx->state[0] = 0x67452301;
68 ctx->state[1] = 0xEFCDAB89;
69 ctx->state[2] = 0x98BADCFE;
70 ctx->state[3] = 0x10325476;
73 static void md4_process( md4_context *ctx, unsigned char data[64] )
75 unsigned long X[16], A, B, C, D;
77 GET_UINT32_LE( X[ 0], data, 0 );
78 GET_UINT32_LE( X[ 1], data, 4 );
79 GET_UINT32_LE( X[ 2], data, 8 );
80 GET_UINT32_LE( X[ 3], data, 12 );
81 GET_UINT32_LE( X[ 4], data, 16 );
82 GET_UINT32_LE( X[ 5], data, 20 );
83 GET_UINT32_LE( X[ 6], data, 24 );
84 GET_UINT32_LE( X[ 7], data, 28 );
85 GET_UINT32_LE( X[ 8], data, 32 );
86 GET_UINT32_LE( X[ 9], data, 36 );
87 GET_UINT32_LE( X[10], data, 40 );
88 GET_UINT32_LE( X[11], data, 44 );
89 GET_UINT32_LE( X[12], data, 48 );
90 GET_UINT32_LE( X[13], data, 52 );
91 GET_UINT32_LE( X[14], data, 56 );
92 GET_UINT32_LE( X[15], data, 60 );
94 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
101 #define F(x, y, z) ((x & y) | ((~x) & z))
102 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
104 P( A, B, C, D, X[ 0], 3 );
105 P( D, A, B, C, X[ 1], 7 );
106 P( C, D, A, B, X[ 2], 11 );
107 P( B, C, D, A, X[ 3], 19 );
108 P( A, B, C, D, X[ 4], 3 );
109 P( D, A, B, C, X[ 5], 7 );
110 P( C, D, A, B, X[ 6], 11 );
111 P( B, C, D, A, X[ 7], 19 );
112 P( A, B, C, D, X[ 8], 3 );
113 P( D, A, B, C, X[ 9], 7 );
114 P( C, D, A, B, X[10], 11 );
115 P( B, C, D, A, X[11], 19 );
116 P( A, B, C, D, X[12], 3 );
117 P( D, A, B, C, X[13], 7 );
118 P( C, D, A, B, X[14], 11 );
119 P( B, C, D, A, X[15], 19 );
124 #define F(x,y,z) ((x & y) | (x & z) | (y & z))
125 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
127 P( A, B, C, D, X[ 0], 3 );
128 P( D, A, B, C, X[ 4], 5 );
129 P( C, D, A, B, X[ 8], 9 );
130 P( B, C, D, A, X[12], 13 );
131 P( A, B, C, D, X[ 1], 3 );
132 P( D, A, B, C, X[ 5], 5 );
133 P( C, D, A, B, X[ 9], 9 );
134 P( B, C, D, A, X[13], 13 );
135 P( A, B, C, D, X[ 2], 3 );
136 P( D, A, B, C, X[ 6], 5 );
137 P( C, D, A, B, X[10], 9 );
138 P( B, C, D, A, X[14], 13 );
139 P( A, B, C, D, X[ 3], 3 );
140 P( D, A, B, C, X[ 7], 5 );
141 P( C, D, A, B, X[11], 9 );
142 P( B, C, D, A, X[15], 13 );
147 #define F(x,y,z) (x ^ y ^ z)
148 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
150 P( A, B, C, D, X[ 0], 3 );
151 P( D, A, B, C, X[ 8], 9 );
152 P( C, D, A, B, X[ 4], 11 );
153 P( B, C, D, A, X[12], 15 );
154 P( A, B, C, D, X[ 2], 3 );
155 P( D, A, B, C, X[10], 9 );
156 P( C, D, A, B, X[ 6], 11 );
157 P( B, C, D, A, X[14], 15 );
158 P( A, B, C, D, X[ 1], 3 );
159 P( D, A, B, C, X[ 9], 9 );
160 P( C, D, A, B, X[ 5], 11 );
161 P( B, C, D, A, X[13], 15 );
162 P( A, B, C, D, X[ 3], 3 );
163 P( D, A, B, C, X[11], 9 );
164 P( C, D, A, B, X[ 7], 11 );
165 P( B, C, D, A, X[15], 15 );
179 void md4_update( md4_context *ctx, unsigned char *input, int ilen )
187 left = ctx->total[0] & 0x3F;
190 ctx->total[0] += ilen;
191 ctx->total[0] &= 0xFFFFFFFF;
193 if( ctx->total[0] < (unsigned long) ilen )
196 if( left && ilen >= fill )
198 memcpy( (void *) (ctx->buffer + left),
199 (void *) input, fill );
200 md4_process( ctx, ctx->buffer );
208 md4_process( ctx, input );
215 memcpy( (void *) (ctx->buffer + left),
216 (void *) input, ilen );
220 static const unsigned char md4_padding[64] =
222 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
223 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
225 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
231 void md4_finish( md4_context *ctx, unsigned char *output )
233 unsigned long last, padn;
234 unsigned long high, low;
235 unsigned char msglen[8];
237 high = ( ctx->total[0] >> 29 )
238 | ( ctx->total[1] << 3 );
239 low = ( ctx->total[0] << 3 );
241 PUT_UINT32_LE( low, msglen, 0 );
242 PUT_UINT32_LE( high, msglen, 4 );
244 last = ctx->total[0] & 0x3F;
245 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
247 md4_update( ctx, (unsigned char *) md4_padding, padn );
248 md4_update( ctx, msglen, 8 );
250 PUT_UINT32_LE( ctx->state[0], output, 0 );
251 PUT_UINT32_LE( ctx->state[1], output, 4 );
252 PUT_UINT32_LE( ctx->state[2], output, 8 );
253 PUT_UINT32_LE( ctx->state[3], output, 12 );
257 * Output = MD4( input buffer )
259 void md4( unsigned char *input, int ilen,
260 unsigned char *output )
265 md4_update( &ctx, input, ilen );
266 md4_finish( &ctx, output );
268 memset( &ctx, 0, sizeof( md4_context ) );
272 * Output = MD4( file contents )
274 int md4_file( char *path, unsigned char *output )
279 unsigned char buf[1024];
281 if( ( f = fopen( path, "rb" ) ) == NULL )
286 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
287 md4_update( &ctx, buf, (int) n );
289 md4_finish( &ctx, output );
291 memset( &ctx, 0, sizeof( md4_context ) );
293 if( ferror( f ) != 0 )
304 * MD4 HMAC context setup
306 void md4_hmac_starts( md4_context *ctx,
307 unsigned char *key, int keylen )
311 memset( ctx->ipad, 0x36, 64 );
312 memset( ctx->opad, 0x5C, 64 );
314 for( i = 0; i < keylen; i++ )
318 ctx->ipad[i] ^= key[i];
319 ctx->opad[i] ^= key[i];
323 md4_update( ctx, ctx->ipad, 64 );
327 * MD4 HMAC process buffer
329 void md4_hmac_update( md4_context *ctx,
330 unsigned char *input, int ilen )
332 md4_update( ctx, input, ilen );
336 * MD4 HMAC final digest
338 void md4_hmac_finish( md4_context *ctx, unsigned char *output )
340 unsigned char tmpbuf[16];
342 md4_finish( ctx, tmpbuf );
344 md4_update( ctx, ctx->opad, 64 );
345 md4_update( ctx, tmpbuf, 16 );
346 md4_finish( ctx, output );
348 memset( tmpbuf, 0, sizeof( tmpbuf ) );
352 * Output = HMAC-MD4( hmac key, input buffer )
354 void md4_hmac( unsigned char *key, int keylen,
355 unsigned char *input, int ilen,
356 unsigned char *output )
360 md4_hmac_starts( &ctx, key, keylen );
361 md4_hmac_update( &ctx, input, ilen );
362 md4_hmac_finish( &ctx, output );
364 memset( &ctx, 0, sizeof( md4_context ) );
367 static const char _md4_src[] = "_md4_src";
369 #if defined(SELF_TEST)
371 * RFC 1320 test vectors
373 static const char md4_test_str[7][81] =
378 { "message digest" },
379 { "abcdefghijklmnopqrstuvwxyz" },
380 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
381 { "12345678901234567890123456789012345678901234567890123456789012" \
382 "345678901234567890" }
385 static const unsigned char md4_test_sum[7][16] =
387 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
388 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
389 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
390 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
391 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
392 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
393 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
394 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
395 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
396 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
397 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
398 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
399 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
400 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
406 int md4_self_test( int verbose )
409 unsigned char md4sum[16];
411 for( i = 0; i < 7; i++ )
414 printf( " MD4 test #%d: ", i + 1 );
416 md4( (unsigned char *) md4_test_str[i],
417 strlen( md4_test_str[i] ), md4sum );
419 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
422 printf( "failed\n" );
428 printf( "passed\n" );
437 int md4_self_test( int verbose )