32 #if !defined(POLARSSL_CONFIG_FILE)
35 #include POLARSSL_CONFIG_FILE
38 #if defined(POLARSSL_MD4_C)
42 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
46 #if defined(POLARSSL_PLATFORM_C)
49 #define polarssl_printf printf
52 #if !defined(POLARSSL_MD4_ALT)
58 #define GET_UINT32_LE(n,b,i) \
60 (n) = ( (uint32_t) (b)[(i) ] ) \
61 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
62 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
63 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
68 #define PUT_UINT32_LE(n,b,i) \
70 (b)[(i) ] = (unsigned char) ( (n) ); \
71 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
72 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
73 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
85 ctx->
state[0] = 0x67452301;
86 ctx->
state[1] = 0xEFCDAB89;
87 ctx->
state[2] = 0x98BADCFE;
88 ctx->
state[3] = 0x10325476;
93 uint32_t X[16], A, B, C, D;
95 GET_UINT32_LE( X[ 0], data, 0 );
96 GET_UINT32_LE( X[ 1], data, 4 );
97 GET_UINT32_LE( X[ 2], data, 8 );
98 GET_UINT32_LE( X[ 3], data, 12 );
99 GET_UINT32_LE( X[ 4], data, 16 );
100 GET_UINT32_LE( X[ 5], data, 20 );
101 GET_UINT32_LE( X[ 6], data, 24 );
102 GET_UINT32_LE( X[ 7], data, 28 );
103 GET_UINT32_LE( X[ 8], data, 32 );
104 GET_UINT32_LE( X[ 9], data, 36 );
105 GET_UINT32_LE( X[10], data, 40 );
106 GET_UINT32_LE( X[11], data, 44 );
107 GET_UINT32_LE( X[12], data, 48 );
108 GET_UINT32_LE( X[13], data, 52 );
109 GET_UINT32_LE( X[14], data, 56 );
110 GET_UINT32_LE( X[15], data, 60 );
112 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
119 #define F(x, y, z) ((x & y) | ((~x) & z))
120 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
122 P( A, B, C, D, X[ 0], 3 );
123 P( D, A, B, C, X[ 1], 7 );
124 P( C, D, A, B, X[ 2], 11 );
125 P( B, C, D, A, X[ 3], 19 );
126 P( A, B, C, D, X[ 4], 3 );
127 P( D, A, B, C, X[ 5], 7 );
128 P( C, D, A, B, X[ 6], 11 );
129 P( B, C, D, A, X[ 7], 19 );
130 P( A, B, C, D, X[ 8], 3 );
131 P( D, A, B, C, X[ 9], 7 );
132 P( C, D, A, B, X[10], 11 );
133 P( B, C, D, A, X[11], 19 );
134 P( A, B, C, D, X[12], 3 );
135 P( D, A, B, C, X[13], 7 );
136 P( C, D, A, B, X[14], 11 );
137 P( B, C, D, A, X[15], 19 );
142 #define F(x,y,z) ((x & y) | (x & z) | (y & z))
143 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
145 P( A, B, C, D, X[ 0], 3 );
146 P( D, A, B, C, X[ 4], 5 );
147 P( C, D, A, B, X[ 8], 9 );
148 P( B, C, D, A, X[12], 13 );
149 P( A, B, C, D, X[ 1], 3 );
150 P( D, A, B, C, X[ 5], 5 );
151 P( C, D, A, B, X[ 9], 9 );
152 P( B, C, D, A, X[13], 13 );
153 P( A, B, C, D, X[ 2], 3 );
154 P( D, A, B, C, X[ 6], 5 );
155 P( C, D, A, B, X[10], 9 );
156 P( B, C, D, A, X[14], 13 );
157 P( A, B, C, D, X[ 3], 3 );
158 P( D, A, B, C, X[ 7], 5 );
159 P( C, D, A, B, X[11], 9 );
160 P( B, C, D, A, X[15], 13 );
165 #define F(x,y,z) (x ^ y ^ z)
166 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
168 P( A, B, C, D, X[ 0], 3 );
169 P( D, A, B, C, X[ 8], 9 );
170 P( C, D, A, B, X[ 4], 11 );
171 P( B, C, D, A, X[12], 15 );
172 P( A, B, C, D, X[ 2], 3 );
173 P( D, A, B, C, X[10], 9 );
174 P( C, D, A, B, X[ 6], 11 );
175 P( B, C, D, A, X[14], 15 );
176 P( A, B, C, D, X[ 1], 3 );
177 P( D, A, B, C, X[ 9], 9 );
178 P( C, D, A, B, X[ 5], 11 );
179 P( B, C, D, A, X[13], 15 );
180 P( A, B, C, D, X[ 3], 3 );
181 P( D, A, B, C, X[11], 9 );
182 P( C, D, A, B, X[ 7], 11 );
183 P( B, C, D, A, X[15], 15 );
205 left = ctx->
total[0] & 0x3F;
208 ctx->
total[0] += (uint32_t) ilen;
209 ctx->
total[0] &= 0xFFFFFFFF;
211 if( ctx->
total[0] < (uint32_t) ilen )
214 if( left && ilen >= fill )
216 memcpy( (
void *) (ctx->
buffer + left),
217 (
void *) input, fill );
233 memcpy( (
void *) (ctx->
buffer + left),
234 (
void *) input, ilen );
238 static const unsigned char md4_padding[64] =
240 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
241 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
242 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
243 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
253 unsigned char msglen[8];
255 high = ( ctx->
total[0] >> 29 )
256 | ( ctx->
total[1] << 3 );
257 low = ( ctx->
total[0] << 3 );
259 PUT_UINT32_LE( low, msglen, 0 );
260 PUT_UINT32_LE( high, msglen, 4 );
262 last = ctx->
total[0] & 0x3F;
263 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
265 md4_update( ctx, (
unsigned char *) md4_padding, padn );
268 PUT_UINT32_LE( ctx->
state[0], output, 0 );
269 PUT_UINT32_LE( ctx->
state[1], output, 4 );
270 PUT_UINT32_LE( ctx->
state[2], output, 8 );
271 PUT_UINT32_LE( ctx->
state[3], output, 12 );
279 void md4(
const unsigned char *input,
size_t ilen,
unsigned char output[16] )
290 #if defined(POLARSSL_FS_IO)
294 int md4_file(
const char *path,
unsigned char output[16] )
299 unsigned char buf[1024];
301 if( ( f = fopen( path,
"rb" ) ) == NULL )
306 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
313 if( ferror( f ) != 0 )
331 unsigned char sum[16];
335 md4( key, keylen, sum );
340 memset( ctx->
ipad, 0x36, 64 );
341 memset( ctx->
opad, 0x5C, 64 );
343 for( i = 0; i < keylen; i++ )
345 ctx->
ipad[i] = (
unsigned char)( ctx->
ipad[i] ^ key[i] );
346 ctx->
opad[i] = (
unsigned char)( ctx->
opad[i] ^ key[i] );
352 memset( sum, 0,
sizeof( sum ) );
369 unsigned char tmpbuf[16];
377 memset( tmpbuf, 0,
sizeof( tmpbuf ) );
392 void md4_hmac(
const unsigned char *key,
size_t keylen,
393 const unsigned char *input,
size_t ilen,
394 unsigned char output[16] )
405 #if defined(POLARSSL_SELF_TEST)
410 static const char md4_test_str[7][81] =
415 {
"message digest" },
416 {
"abcdefghijklmnopqrstuvwxyz" },
417 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
418 {
"12345678901234567890123456789012345678901234567890123456789012" \
419 "345678901234567890" }
422 static const unsigned char md4_test_sum[7][16] =
424 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
425 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
426 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
427 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
428 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
429 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
430 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
431 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
432 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
433 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
434 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
435 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
436 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
437 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
446 unsigned char md4sum[16];
448 for( i = 0; i < 7; i++ )
453 md4( (
unsigned char *) md4_test_str[i],
454 strlen( md4_test_str[i] ), md4sum );
456 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
void md4_finish(md4_context *ctx, unsigned char output[16])
MD4 final digest.
int md4_self_test(int verbose)
Checkup routine.
void md4_hmac(const unsigned char *key, size_t keylen, const unsigned char *input, size_t ilen, unsigned char output[16])
Output = HMAC-MD4( hmac key, input buffer )
void md4_starts(md4_context *ctx)
MD4 context setup.
Configuration options (set of defines)
void md4(const unsigned char *input, size_t ilen, unsigned char output[16])
Output = MD4( input buffer )
void md4_process(md4_context *ctx, const unsigned char data[64])
void md4_update(md4_context *ctx, const unsigned char *input, size_t ilen)
MD4 process buffer.
void md4_hmac_starts(md4_context *ctx, const unsigned char *key, size_t keylen)
MD4 HMAC context setup.
void md4_hmac_finish(md4_context *ctx, unsigned char output[16])
MD4 HMAC final digest.
MD4 message digest algorithm (hash function)
int md4_file(const char *path, unsigned char output[16])
Output = MD4( file contents )
#define POLARSSL_ERR_MD4_FILE_IO_ERROR
Read/write error in file.
void md4_hmac_reset(md4_context *ctx)
MD4 HMAC context reset.
void md4_hmac_update(md4_context *ctx, const unsigned char *input, size_t ilen)
MD4 HMAC process buffer.