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 53 static void polarssl_zeroize(
void *v,
size_t n ) {
54 volatile unsigned char *p = v;
while( n-- ) *p++ = 0;
57 #if !defined(POLARSSL_MD4_ALT) 63 #define GET_UINT32_LE(n,b,i) \ 65 (n) = ( (uint32_t) (b)[(i) ] ) \ 66 | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 67 | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 68 | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 73 #define PUT_UINT32_LE(n,b,i) \ 75 (b)[(i) ] = (unsigned char) ( (n) ); \ 76 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ 77 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ 78 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ 103 ctx->
state[0] = 0x67452301;
104 ctx->
state[1] = 0xEFCDAB89;
105 ctx->
state[2] = 0x98BADCFE;
106 ctx->
state[3] = 0x10325476;
111 uint32_t X[16], A, B, C, D;
113 GET_UINT32_LE( X[ 0], data, 0 );
114 GET_UINT32_LE( X[ 1], data, 4 );
115 GET_UINT32_LE( X[ 2], data, 8 );
116 GET_UINT32_LE( X[ 3], data, 12 );
117 GET_UINT32_LE( X[ 4], data, 16 );
118 GET_UINT32_LE( X[ 5], data, 20 );
119 GET_UINT32_LE( X[ 6], data, 24 );
120 GET_UINT32_LE( X[ 7], data, 28 );
121 GET_UINT32_LE( X[ 8], data, 32 );
122 GET_UINT32_LE( X[ 9], data, 36 );
123 GET_UINT32_LE( X[10], data, 40 );
124 GET_UINT32_LE( X[11], data, 44 );
125 GET_UINT32_LE( X[12], data, 48 );
126 GET_UINT32_LE( X[13], data, 52 );
127 GET_UINT32_LE( X[14], data, 56 );
128 GET_UINT32_LE( X[15], data, 60 );
130 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 137 #define F(x, y, z) ((x & y) | ((~x) & z)) 138 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } 140 P( A, B, C, D, X[ 0], 3 );
141 P( D, A, B, C, X[ 1], 7 );
142 P( C, D, A, B, X[ 2], 11 );
143 P( B, C, D, A, X[ 3], 19 );
144 P( A, B, C, D, X[ 4], 3 );
145 P( D, A, B, C, X[ 5], 7 );
146 P( C, D, A, B, X[ 6], 11 );
147 P( B, C, D, A, X[ 7], 19 );
148 P( A, B, C, D, X[ 8], 3 );
149 P( D, A, B, C, X[ 9], 7 );
150 P( C, D, A, B, X[10], 11 );
151 P( B, C, D, A, X[11], 19 );
152 P( A, B, C, D, X[12], 3 );
153 P( D, A, B, C, X[13], 7 );
154 P( C, D, A, B, X[14], 11 );
155 P( B, C, D, A, X[15], 19 );
160 #define F(x,y,z) ((x & y) | (x & z) | (y & z)) 161 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } 163 P( A, B, C, D, X[ 0], 3 );
164 P( D, A, B, C, X[ 4], 5 );
165 P( C, D, A, B, X[ 8], 9 );
166 P( B, C, D, A, X[12], 13 );
167 P( A, B, C, D, X[ 1], 3 );
168 P( D, A, B, C, X[ 5], 5 );
169 P( C, D, A, B, X[ 9], 9 );
170 P( B, C, D, A, X[13], 13 );
171 P( A, B, C, D, X[ 2], 3 );
172 P( D, A, B, C, X[ 6], 5 );
173 P( C, D, A, B, X[10], 9 );
174 P( B, C, D, A, X[14], 13 );
175 P( A, B, C, D, X[ 3], 3 );
176 P( D, A, B, C, X[ 7], 5 );
177 P( C, D, A, B, X[11], 9 );
178 P( B, C, D, A, X[15], 13 );
183 #define F(x,y,z) (x ^ y ^ z) 184 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } 186 P( A, B, C, D, X[ 0], 3 );
187 P( D, A, B, C, X[ 8], 9 );
188 P( C, D, A, B, X[ 4], 11 );
189 P( B, C, D, A, X[12], 15 );
190 P( A, B, C, D, X[ 2], 3 );
191 P( D, A, B, C, X[10], 9 );
192 P( C, D, A, B, X[ 6], 11 );
193 P( B, C, D, A, X[14], 15 );
194 P( A, B, C, D, X[ 1], 3 );
195 P( D, A, B, C, X[ 9], 9 );
196 P( C, D, A, B, X[ 5], 11 );
197 P( B, C, D, A, X[13], 15 );
198 P( A, B, C, D, X[ 3], 3 );
199 P( D, A, B, C, X[11], 9 );
200 P( C, D, A, B, X[ 7], 11 );
201 P( B, C, D, A, X[15], 15 );
223 left = ctx->
total[0] & 0x3F;
226 ctx->
total[0] += (uint32_t) ilen;
227 ctx->
total[0] &= 0xFFFFFFFF;
229 if( ctx->
total[0] < (uint32_t) ilen )
232 if( left && ilen >= fill )
234 memcpy( (
void *) (ctx->
buffer + left),
235 (
void *) input, fill );
251 memcpy( (
void *) (ctx->
buffer + left),
252 (
void *) input, ilen );
256 static const unsigned char md4_padding[64] =
258 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
259 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
271 unsigned char msglen[8];
273 high = ( ctx->
total[0] >> 29 )
274 | ( ctx->
total[1] << 3 );
275 low = ( ctx->
total[0] << 3 );
277 PUT_UINT32_LE( low, msglen, 0 );
278 PUT_UINT32_LE( high, msglen, 4 );
280 last = ctx->
total[0] & 0x3F;
281 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
283 md4_update( ctx, (
unsigned char *) md4_padding, padn );
286 PUT_UINT32_LE( ctx->
state[0], output, 0 );
287 PUT_UINT32_LE( ctx->
state[1], output, 4 );
288 PUT_UINT32_LE( ctx->
state[2], output, 8 );
289 PUT_UINT32_LE( ctx->
state[3], output, 12 );
297 void md4(
const unsigned char *input,
size_t ilen,
unsigned char output[16] )
308 #if defined(POLARSSL_FS_IO) 312 int md4_file(
const char *path,
unsigned char output[16] )
317 unsigned char buf[1024];
319 if( ( f = fopen( path,
"rb" ) ) == NULL )
325 while( ( n = fread( buf, 1,
sizeof( buf ), f ) ) > 0 )
331 if( ferror( f ) != 0 )
349 unsigned char sum[16];
353 md4( key, keylen, sum );
358 memset( ctx->
ipad, 0x36, 64 );
359 memset( ctx->
opad, 0x5C, 64 );
361 for( i = 0; i < keylen; i++ )
363 ctx->
ipad[i] = (
unsigned char)( ctx->
ipad[i] ^ key[i] );
364 ctx->
opad[i] = (
unsigned char)( ctx->
opad[i] ^ key[i] );
370 polarssl_zeroize( sum,
sizeof( sum ) );
387 unsigned char tmpbuf[16];
395 polarssl_zeroize( tmpbuf,
sizeof( tmpbuf ) );
410 void md4_hmac(
const unsigned char *key,
size_t keylen,
411 const unsigned char *input,
size_t ilen,
412 unsigned char output[16] )
423 #if defined(POLARSSL_SELF_TEST) 428 static const char md4_test_str[7][81] =
433 {
"message digest" },
434 {
"abcdefghijklmnopqrstuvwxyz" },
435 {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
436 {
"12345678901234567890123456789012345678901234567890123456789012" \
437 "345678901234567890" }
440 static const unsigned char md4_test_sum[7][16] =
442 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
443 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
444 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
445 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
446 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
447 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
448 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
449 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
450 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
451 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
452 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
453 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
454 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
455 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
464 unsigned char md4sum[16];
466 for( i = 0; i < 7; i++ )
471 md4( (
unsigned char *) md4_test_str[i],
472 strlen( md4_test_str[i] ), md4sum );
474 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_init(md4_context *ctx)
Initialize MD4 context.
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.
void md4_free(md4_context *ctx)
Clear MD4 context.
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.