34 #if defined(POLARSSL_MD4_C)
38 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
43 static void polarssl_zeroize(
void *v,
size_t n ) {
44 volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
47 #if !defined(POLARSSL_MD4_ALT)
53 #define GET_UINT32_LE(n,b,i) \
55 (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 ); \
63 #define PUT_UINT32_LE(n,b,i) \
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 ); \
80 ctx->
state[0] = 0x67452301;
81 ctx->
state[1] = 0xEFCDAB89;
82 ctx->
state[2] = 0x98BADCFE;
83 ctx->
state[3] = 0x10325476;
86 static void md4_process(
md4_context *ctx,
const unsigned char data[64] )
88 uint32_t X[16], A, B, C, D;
90 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 );
107 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
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); }
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 );
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); }
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 );
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); }
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 );
200 left = ctx->
total[0] & 0x3F;
203 ctx->
total[0] += (uint32_t) ilen;
204 ctx->
total[0] &= 0xFFFFFFFF;
206 if( ctx->
total[0] < (uint32_t) ilen )
209 if( left && ilen >= fill )
211 memcpy( (
void *) (ctx->
buffer + left),
212 (
void *) input, fill );
213 md4_process( ctx, ctx->
buffer );
221 md4_process( ctx, input );
228 memcpy( (
void *) (ctx->
buffer + left),
229 (
void *) input, ilen );
233 static const unsigned char md4_padding[64] =
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
248 unsigned char msglen[8];
250 high = ( ctx->
total[0] >> 29 )
251 | ( ctx->
total[1] << 3 );
252 low = ( ctx->
total[0] << 3 );
254 PUT_UINT32_LE( low, msglen, 0 );
255 PUT_UINT32_LE( high, msglen, 4 );
257 last = ctx->
total[0] & 0x3F;
258 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
260 md4_update( ctx, (
unsigned char *) md4_padding, padn );
263 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 );
274 void md4(
const unsigned char *input,
size_t ilen,
unsigned char output[16] )
285 #if defined(POLARSSL_FS_IO)
289 int md4_file(
const char *path,
unsigned char output[16] )
294 unsigned char buf[1024];
296 if( ( f = fopen( path,
"rb" ) ) == NULL )
301 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
308 if( ferror( f ) != 0 )
325 unsigned char sum[16];
329 md4( key, keylen, sum );
334 memset( ctx->
ipad, 0x36, 64 );
335 memset( ctx->
opad, 0x5C, 64 );
337 for( i = 0; i < keylen; i++ )
339 ctx->
ipad[i] = (
unsigned char)( ctx->
ipad[i] ^ key[i] );
340 ctx->
opad[i] = (
unsigned char)( ctx->
opad[i] ^ key[i] );
346 polarssl_zeroize( sum,
sizeof( sum ) );
362 unsigned char tmpbuf[16];
370 polarssl_zeroize( tmpbuf,
sizeof( tmpbuf ) );
385 void md4_hmac(
const unsigned char *key,
size_t keylen,
386 const unsigned char *input,
size_t ilen,
387 unsigned char output[16] )
398 #if defined(POLARSSL_SELF_TEST)
403 static const char md4_test_str[7][81] =
408 {
"message digest" },
409 {
"abcdefghijklmnopqrstuvwxyz" },
410 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
411 {
"12345678901234567890123456789012345678901234567890123456789012" \
412 "345678901234567890" }
415 static const unsigned char md4_test_sum[7][16] =
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 }
439 unsigned char md4sum[16];
441 for( i = 0; i < 7; i++ )
444 printf(
" MD4 test #%d: ", i + 1 );
446 md4( (
unsigned char *) md4_test_str[i],
447 strlen( md4_test_str[i] ), md4sum );
449 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
452 printf(
"failed\n" );
458 printf(
"passed\n" );