34 #if defined(POLARSSL_MD4_C)
38 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
46 #define GET_UINT32_LE(n,b,i) \
48 (n) = ( (uint32_t) (b)[(i) ] ) \
49 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
50 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
51 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
56 #define PUT_UINT32_LE(n,b,i) \
58 (b)[(i) ] = (unsigned char) ( (n) ); \
59 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
60 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
61 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
73 ctx->
state[0] = 0x67452301;
74 ctx->
state[1] = 0xEFCDAB89;
75 ctx->
state[2] = 0x98BADCFE;
76 ctx->
state[3] = 0x10325476;
79 static void md4_process(
md4_context *ctx,
const unsigned char data[64] )
81 uint32_t X[16], A, B, C, D;
83 GET_UINT32_LE( X[ 0], data, 0 );
84 GET_UINT32_LE( X[ 1], data, 4 );
85 GET_UINT32_LE( X[ 2], data, 8 );
86 GET_UINT32_LE( X[ 3], data, 12 );
87 GET_UINT32_LE( X[ 4], data, 16 );
88 GET_UINT32_LE( X[ 5], data, 20 );
89 GET_UINT32_LE( X[ 6], data, 24 );
90 GET_UINT32_LE( X[ 7], data, 28 );
91 GET_UINT32_LE( X[ 8], data, 32 );
92 GET_UINT32_LE( X[ 9], data, 36 );
93 GET_UINT32_LE( X[10], data, 40 );
94 GET_UINT32_LE( X[11], data, 44 );
95 GET_UINT32_LE( X[12], data, 48 );
96 GET_UINT32_LE( X[13], data, 52 );
97 GET_UINT32_LE( X[14], data, 56 );
98 GET_UINT32_LE( X[15], data, 60 );
100 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
107 #define F(x, y, z) ((x & y) | ((~x) & z))
108 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
110 P( A, B, C, D, X[ 0], 3 );
111 P( D, A, B, C, X[ 1], 7 );
112 P( C, D, A, B, X[ 2], 11 );
113 P( B, C, D, A, X[ 3], 19 );
114 P( A, B, C, D, X[ 4], 3 );
115 P( D, A, B, C, X[ 5], 7 );
116 P( C, D, A, B, X[ 6], 11 );
117 P( B, C, D, A, X[ 7], 19 );
118 P( A, B, C, D, X[ 8], 3 );
119 P( D, A, B, C, X[ 9], 7 );
120 P( C, D, A, B, X[10], 11 );
121 P( B, C, D, A, X[11], 19 );
122 P( A, B, C, D, X[12], 3 );
123 P( D, A, B, C, X[13], 7 );
124 P( C, D, A, B, X[14], 11 );
125 P( B, C, D, A, X[15], 19 );
130 #define F(x,y,z) ((x & y) | (x & z) | (y & z))
131 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
133 P( A, B, C, D, X[ 0], 3 );
134 P( D, A, B, C, X[ 4], 5 );
135 P( C, D, A, B, X[ 8], 9 );
136 P( B, C, D, A, X[12], 13 );
137 P( A, B, C, D, X[ 1], 3 );
138 P( D, A, B, C, X[ 5], 5 );
139 P( C, D, A, B, X[ 9], 9 );
140 P( B, C, D, A, X[13], 13 );
141 P( A, B, C, D, X[ 2], 3 );
142 P( D, A, B, C, X[ 6], 5 );
143 P( C, D, A, B, X[10], 9 );
144 P( B, C, D, A, X[14], 13 );
145 P( A, B, C, D, X[ 3], 3 );
146 P( D, A, B, C, X[ 7], 5 );
147 P( C, D, A, B, X[11], 9 );
148 P( B, C, D, A, X[15], 13 );
153 #define F(x,y,z) (x ^ y ^ z)
154 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
156 P( A, B, C, D, X[ 0], 3 );
157 P( D, A, B, C, X[ 8], 9 );
158 P( C, D, A, B, X[ 4], 11 );
159 P( B, C, D, A, X[12], 15 );
160 P( A, B, C, D, X[ 2], 3 );
161 P( D, A, B, C, X[10], 9 );
162 P( C, D, A, B, X[ 6], 11 );
163 P( B, C, D, A, X[14], 15 );
164 P( A, B, C, D, X[ 1], 3 );
165 P( D, A, B, C, X[ 9], 9 );
166 P( C, D, A, B, X[ 5], 11 );
167 P( B, C, D, A, X[13], 15 );
168 P( A, B, C, D, X[ 3], 3 );
169 P( D, A, B, C, X[11], 9 );
170 P( C, D, A, B, X[ 7], 11 );
171 P( B, C, D, A, X[15], 15 );
193 left = ctx->
total[0] & 0x3F;
196 ctx->
total[0] += (uint32_t) ilen;
197 ctx->
total[0] &= 0xFFFFFFFF;
199 if( ctx->
total[0] < (uint32_t) ilen )
202 if( left && ilen >= fill )
204 memcpy( (
void *) (ctx->
buffer + left),
205 (
void *) input, fill );
206 md4_process( ctx, ctx->
buffer );
214 md4_process( ctx, input );
221 memcpy( (
void *) (ctx->
buffer + left),
222 (
void *) input, ilen );
226 static const unsigned char md4_padding[64] =
228 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
229 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
230 0, 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
241 unsigned char msglen[8];
243 high = ( ctx->
total[0] >> 29 )
244 | ( ctx->
total[1] << 3 );
245 low = ( ctx->
total[0] << 3 );
247 PUT_UINT32_LE( low, msglen, 0 );
248 PUT_UINT32_LE( high, msglen, 4 );
250 last = ctx->
total[0] & 0x3F;
251 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
253 md4_update( ctx, (
unsigned char *) md4_padding, padn );
256 PUT_UINT32_LE( ctx->
state[0], output, 0 );
257 PUT_UINT32_LE( ctx->
state[1], output, 4 );
258 PUT_UINT32_LE( ctx->
state[2], output, 8 );
259 PUT_UINT32_LE( ctx->
state[3], output, 12 );
265 void md4(
const unsigned char *input,
size_t ilen,
unsigned char output[16] )
276 #if defined(POLARSSL_FS_IO)
280 int md4_file(
const char *path,
unsigned char output[16] )
285 unsigned char buf[1024];
287 if( ( f = fopen( path,
"rb" ) ) == NULL )
292 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
299 if( ferror( f ) != 0 )
316 unsigned char sum[16];
320 md4( key, keylen, sum );
325 memset( ctx->
ipad, 0x36, 64 );
326 memset( ctx->
opad, 0x5C, 64 );
328 for( i = 0; i < keylen; i++ )
330 ctx->
ipad[i] = (
unsigned char)( ctx->
ipad[i] ^ key[i] );
331 ctx->
opad[i] = (
unsigned char)( ctx->
opad[i] ^ key[i] );
337 memset( sum, 0,
sizeof( sum ) );
353 unsigned char tmpbuf[16];
361 memset( tmpbuf, 0,
sizeof( tmpbuf ) );
376 void md4_hmac(
const unsigned char *key,
size_t keylen,
377 const unsigned char *input,
size_t ilen,
378 unsigned char output[16] )
389 #if defined(POLARSSL_SELF_TEST)
394 static const char md4_test_str[7][81] =
399 {
"message digest" },
400 {
"abcdefghijklmnopqrstuvwxyz" },
401 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
402 {
"12345678901234567890123456789012345678901234567890123456789012" \
403 "345678901234567890" }
406 static const unsigned char md4_test_sum[7][16] =
408 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
409 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
410 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
411 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
412 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
413 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
414 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
415 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
416 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
417 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
418 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
419 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
420 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
421 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
430 unsigned char md4sum[16];
432 for( i = 0; i < 7; i++ )
435 printf(
" MD4 test #%d: ", i + 1 );
437 md4( (
unsigned char *) md4_test_str[i],
438 strlen( md4_test_str[i] ), md4sum );
440 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
443 printf(
"failed\n" );
449 printf(
"passed\n" );