34 #if defined(POLARSSL_MD4_C)
38 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
42 #if !defined(POLARSSL_MD4_ALT)
48 #define GET_UINT32_LE(n,b,i) \
50 (n) = ( (uint32_t) (b)[(i) ] ) \
51 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
52 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
53 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
58 #define PUT_UINT32_LE(n,b,i) \
60 (b)[(i) ] = (unsigned char) ( (n) ); \
61 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
62 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
63 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
75 ctx->
state[0] = 0x67452301;
76 ctx->
state[1] = 0xEFCDAB89;
77 ctx->
state[2] = 0x98BADCFE;
78 ctx->
state[3] = 0x10325476;
81 static void md4_process(
md4_context *ctx,
const unsigned char data[64] )
83 uint32_t X[16], A, B, C, D;
85 GET_UINT32_LE( X[ 0], data, 0 );
86 GET_UINT32_LE( X[ 1], data, 4 );
87 GET_UINT32_LE( X[ 2], data, 8 );
88 GET_UINT32_LE( X[ 3], data, 12 );
89 GET_UINT32_LE( X[ 4], data, 16 );
90 GET_UINT32_LE( X[ 5], data, 20 );
91 GET_UINT32_LE( X[ 6], data, 24 );
92 GET_UINT32_LE( X[ 7], data, 28 );
93 GET_UINT32_LE( X[ 8], data, 32 );
94 GET_UINT32_LE( X[ 9], data, 36 );
95 GET_UINT32_LE( X[10], data, 40 );
96 GET_UINT32_LE( X[11], data, 44 );
97 GET_UINT32_LE( X[12], data, 48 );
98 GET_UINT32_LE( X[13], data, 52 );
99 GET_UINT32_LE( X[14], data, 56 );
100 GET_UINT32_LE( X[15], data, 60 );
102 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
109 #define F(x, y, z) ((x & y) | ((~x) & z))
110 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
112 P( A, B, C, D, X[ 0], 3 );
113 P( D, A, B, C, X[ 1], 7 );
114 P( C, D, A, B, X[ 2], 11 );
115 P( B, C, D, A, X[ 3], 19 );
116 P( A, B, C, D, X[ 4], 3 );
117 P( D, A, B, C, X[ 5], 7 );
118 P( C, D, A, B, X[ 6], 11 );
119 P( B, C, D, A, X[ 7], 19 );
120 P( A, B, C, D, X[ 8], 3 );
121 P( D, A, B, C, X[ 9], 7 );
122 P( C, D, A, B, X[10], 11 );
123 P( B, C, D, A, X[11], 19 );
124 P( A, B, C, D, X[12], 3 );
125 P( D, A, B, C, X[13], 7 );
126 P( C, D, A, B, X[14], 11 );
127 P( B, C, D, A, X[15], 19 );
132 #define F(x,y,z) ((x & y) | (x & z) | (y & z))
133 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
135 P( A, B, C, D, X[ 0], 3 );
136 P( D, A, B, C, X[ 4], 5 );
137 P( C, D, A, B, X[ 8], 9 );
138 P( B, C, D, A, X[12], 13 );
139 P( A, B, C, D, X[ 1], 3 );
140 P( D, A, B, C, X[ 5], 5 );
141 P( C, D, A, B, X[ 9], 9 );
142 P( B, C, D, A, X[13], 13 );
143 P( A, B, C, D, X[ 2], 3 );
144 P( D, A, B, C, X[ 6], 5 );
145 P( C, D, A, B, X[10], 9 );
146 P( B, C, D, A, X[14], 13 );
147 P( A, B, C, D, X[ 3], 3 );
148 P( D, A, B, C, X[ 7], 5 );
149 P( C, D, A, B, X[11], 9 );
150 P( B, C, D, A, X[15], 13 );
155 #define F(x,y,z) (x ^ y ^ z)
156 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
158 P( A, B, C, D, X[ 0], 3 );
159 P( D, A, B, C, X[ 8], 9 );
160 P( C, D, A, B, X[ 4], 11 );
161 P( B, C, D, A, X[12], 15 );
162 P( A, B, C, D, X[ 2], 3 );
163 P( D, A, B, C, X[10], 9 );
164 P( C, D, A, B, X[ 6], 11 );
165 P( B, C, D, A, X[14], 15 );
166 P( A, B, C, D, X[ 1], 3 );
167 P( D, A, B, C, X[ 9], 9 );
168 P( C, D, A, B, X[ 5], 11 );
169 P( B, C, D, A, X[13], 15 );
170 P( A, B, C, D, X[ 3], 3 );
171 P( D, A, B, C, X[11], 9 );
172 P( C, D, A, B, X[ 7], 11 );
173 P( B, C, D, A, X[15], 15 );
195 left = ctx->
total[0] & 0x3F;
198 ctx->
total[0] += (uint32_t) ilen;
199 ctx->
total[0] &= 0xFFFFFFFF;
201 if( ctx->
total[0] < (uint32_t) ilen )
204 if( left && ilen >= fill )
206 memcpy( (
void *) (ctx->
buffer + left),
207 (
void *) input, fill );
208 md4_process( ctx, ctx->
buffer );
216 md4_process( ctx, input );
223 memcpy( (
void *) (ctx->
buffer + left),
224 (
void *) input, ilen );
228 static const unsigned char md4_padding[64] =
230 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
233 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
243 unsigned char msglen[8];
245 high = ( ctx->
total[0] >> 29 )
246 | ( ctx->
total[1] << 3 );
247 low = ( ctx->
total[0] << 3 );
249 PUT_UINT32_LE( low, msglen, 0 );
250 PUT_UINT32_LE( high, msglen, 4 );
252 last = ctx->
total[0] & 0x3F;
253 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
255 md4_update( ctx, (
unsigned char *) md4_padding, padn );
258 PUT_UINT32_LE( ctx->
state[0], output, 0 );
259 PUT_UINT32_LE( ctx->
state[1], output, 4 );
260 PUT_UINT32_LE( ctx->
state[2], output, 8 );
261 PUT_UINT32_LE( ctx->
state[3], output, 12 );
269 void md4(
const unsigned char *input,
size_t ilen,
unsigned char output[16] )
280 #if defined(POLARSSL_FS_IO)
284 int md4_file(
const char *path,
unsigned char output[16] )
289 unsigned char buf[1024];
291 if( ( f = fopen( path,
"rb" ) ) == NULL )
296 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
303 if( ferror( f ) != 0 )
320 unsigned char sum[16];
324 md4( key, keylen, sum );
329 memset( ctx->
ipad, 0x36, 64 );
330 memset( ctx->
opad, 0x5C, 64 );
332 for( i = 0; i < keylen; i++ )
334 ctx->
ipad[i] = (
unsigned char)( ctx->
ipad[i] ^ key[i] );
335 ctx->
opad[i] = (
unsigned char)( ctx->
opad[i] ^ key[i] );
341 memset( sum, 0,
sizeof( sum ) );
357 unsigned char tmpbuf[16];
365 memset( tmpbuf, 0,
sizeof( tmpbuf ) );
380 void md4_hmac(
const unsigned char *key,
size_t keylen,
381 const unsigned char *input,
size_t ilen,
382 unsigned char output[16] )
393 #if defined(POLARSSL_SELF_TEST)
398 static const char md4_test_str[7][81] =
403 {
"message digest" },
404 {
"abcdefghijklmnopqrstuvwxyz" },
405 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
406 {
"12345678901234567890123456789012345678901234567890123456789012" \
407 "345678901234567890" }
410 static const unsigned char md4_test_sum[7][16] =
412 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
413 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
414 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
415 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
416 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
417 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
418 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
419 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
420 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
421 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
422 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
423 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
424 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
425 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
434 unsigned char md4sum[16];
436 for( i = 0; i < 7; i++ )
439 printf(
" MD4 test #%d: ", i + 1 );
441 md4( (
unsigned char *) md4_test_str[i],
442 strlen( md4_test_str[i] ), md4sum );
444 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
447 printf(
"failed\n" );
453 printf(
"passed\n" );