PolarSSL v1.2.10
md4.c
Go to the documentation of this file.
1 /*
2  * RFC 1186/1320 compliant MD4 implementation
3  *
4  * Copyright (C) 2006-2013, Brainspark B.V.
5  *
6  * This file is part of PolarSSL (http://www.polarssl.org)
7  * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8  *
9  * All rights reserved.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License along
22  * with this program; if not, write to the Free Software Foundation, Inc.,
23  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24  */
25 /*
26  * The MD4 algorithm was designed by Ron Rivest in 1990.
27  *
28  * http://www.ietf.org/rfc/rfc1186.txt
29  * http://www.ietf.org/rfc/rfc1320.txt
30  */
31 
32 #include "polarssl/config.h"
33 
34 #if defined(POLARSSL_MD4_C)
35 
36 #include "polarssl/md4.h"
37 
38 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
39 #include <stdio.h>
40 #endif
41 
42 #if !defined(POLARSSL_MD4_ALT)
43 
44 /*
45  * 32-bit integer manipulation macros (little endian)
46  */
47 #ifndef GET_UINT32_LE
48 #define GET_UINT32_LE(n,b,i) \
49 { \
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 ); \
54 }
55 #endif
56 
57 #ifndef PUT_UINT32_LE
58 #define PUT_UINT32_LE(n,b,i) \
59 { \
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 ); \
64 }
65 #endif
66 
67 /*
68  * MD4 context setup
69  */
70 void md4_starts( md4_context *ctx )
71 {
72  ctx->total[0] = 0;
73  ctx->total[1] = 0;
74 
75  ctx->state[0] = 0x67452301;
76  ctx->state[1] = 0xEFCDAB89;
77  ctx->state[2] = 0x98BADCFE;
78  ctx->state[3] = 0x10325476;
79 }
80 
81 static void md4_process( md4_context *ctx, const unsigned char data[64] )
82 {
83  uint32_t X[16], A, B, C, D;
84 
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 );
101 
102 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
103 
104  A = ctx->state[0];
105  B = ctx->state[1];
106  C = ctx->state[2];
107  D = ctx->state[3];
108 
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); }
111 
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 );
128 
129 #undef P
130 #undef F
131 
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); }
134 
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 );
151 
152 #undef P
153 #undef F
154 
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); }
157 
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 );
174 
175 #undef F
176 #undef P
177 
178  ctx->state[0] += A;
179  ctx->state[1] += B;
180  ctx->state[2] += C;
181  ctx->state[3] += D;
182 }
183 
184 /*
185  * MD4 process buffer
186  */
187 void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
188 {
189  size_t fill;
190  uint32_t left;
191 
192  if( ilen <= 0 )
193  return;
194 
195  left = ctx->total[0] & 0x3F;
196  fill = 64 - left;
197 
198  ctx->total[0] += (uint32_t) ilen;
199  ctx->total[0] &= 0xFFFFFFFF;
200 
201  if( ctx->total[0] < (uint32_t) ilen )
202  ctx->total[1]++;
203 
204  if( left && ilen >= fill )
205  {
206  memcpy( (void *) (ctx->buffer + left),
207  (void *) input, fill );
208  md4_process( ctx, ctx->buffer );
209  input += fill;
210  ilen -= fill;
211  left = 0;
212  }
213 
214  while( ilen >= 64 )
215  {
216  md4_process( ctx, input );
217  input += 64;
218  ilen -= 64;
219  }
220 
221  if( ilen > 0 )
222  {
223  memcpy( (void *) (ctx->buffer + left),
224  (void *) input, ilen );
225  }
226 }
227 
228 static const unsigned char md4_padding[64] =
229 {
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
234 };
235 
236 /*
237  * MD4 final digest
238  */
239 void md4_finish( md4_context *ctx, unsigned char output[16] )
240 {
241  uint32_t last, padn;
242  uint32_t high, low;
243  unsigned char msglen[8];
244 
245  high = ( ctx->total[0] >> 29 )
246  | ( ctx->total[1] << 3 );
247  low = ( ctx->total[0] << 3 );
248 
249  PUT_UINT32_LE( low, msglen, 0 );
250  PUT_UINT32_LE( high, msglen, 4 );
251 
252  last = ctx->total[0] & 0x3F;
253  padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
254 
255  md4_update( ctx, (unsigned char *) md4_padding, padn );
256  md4_update( ctx, msglen, 8 );
257 
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 );
262 }
263 
264 #endif /* !POLARSSL_MD4_ALT */
265 
266 /*
267  * output = MD4( input buffer )
268  */
269 void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
270 {
271  md4_context ctx;
272 
273  md4_starts( &ctx );
274  md4_update( &ctx, input, ilen );
275  md4_finish( &ctx, output );
276 
277  memset( &ctx, 0, sizeof( md4_context ) );
278 }
279 
280 #if defined(POLARSSL_FS_IO)
281 /*
282  * output = MD4( file contents )
283  */
284 int md4_file( const char *path, unsigned char output[16] )
285 {
286  FILE *f;
287  size_t n;
288  md4_context ctx;
289  unsigned char buf[1024];
290 
291  if( ( f = fopen( path, "rb" ) ) == NULL )
293 
294  md4_starts( &ctx );
295 
296  while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
297  md4_update( &ctx, buf, n );
298 
299  md4_finish( &ctx, output );
300 
301  memset( &ctx, 0, sizeof( md4_context ) );
302 
303  if( ferror( f ) != 0 )
304  {
305  fclose( f );
307  }
308 
309  fclose( f );
310  return( 0 );
311 }
312 #endif /* POLARSSL_FS_IO */
313 
314 /*
315  * MD4 HMAC context setup
316  */
317 void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen )
318 {
319  size_t i;
320  unsigned char sum[16];
321 
322  if( keylen > 64 )
323  {
324  md4( key, keylen, sum );
325  keylen = 16;
326  key = sum;
327  }
328 
329  memset( ctx->ipad, 0x36, 64 );
330  memset( ctx->opad, 0x5C, 64 );
331 
332  for( i = 0; i < keylen; i++ )
333  {
334  ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
335  ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
336  }
337 
338  md4_starts( ctx );
339  md4_update( ctx, ctx->ipad, 64 );
340 
341  memset( sum, 0, sizeof( sum ) );
342 }
343 
344 /*
345  * MD4 HMAC process buffer
346  */
347 void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen )
348 {
349  md4_update( ctx, input, ilen );
350 }
351 
352 /*
353  * MD4 HMAC final digest
354  */
355 void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
356 {
357  unsigned char tmpbuf[16];
358 
359  md4_finish( ctx, tmpbuf );
360  md4_starts( ctx );
361  md4_update( ctx, ctx->opad, 64 );
362  md4_update( ctx, tmpbuf, 16 );
363  md4_finish( ctx, output );
364 
365  memset( tmpbuf, 0, sizeof( tmpbuf ) );
366 }
367 
368 /*
369  * MD4 HMAC context reset
370  */
371 void md4_hmac_reset( md4_context *ctx )
372 {
373  md4_starts( ctx );
374  md4_update( ctx, ctx->ipad, 64 );
375 }
376 
377 /*
378  * output = HMAC-MD4( hmac key, input buffer )
379  */
380 void md4_hmac( const unsigned char *key, size_t keylen,
381  const unsigned char *input, size_t ilen,
382  unsigned char output[16] )
383 {
384  md4_context ctx;
385 
386  md4_hmac_starts( &ctx, key, keylen );
387  md4_hmac_update( &ctx, input, ilen );
388  md4_hmac_finish( &ctx, output );
389 
390  memset( &ctx, 0, sizeof( md4_context ) );
391 }
392 
393 #if defined(POLARSSL_SELF_TEST)
394 
395 /*
396  * RFC 1320 test vectors
397  */
398 static const char md4_test_str[7][81] =
399 {
400  { "" },
401  { "a" },
402  { "abc" },
403  { "message digest" },
404  { "abcdefghijklmnopqrstuvwxyz" },
405  { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
406  { "12345678901234567890123456789012345678901234567890123456789012" \
407  "345678901234567890" }
408 };
409 
410 static const unsigned char md4_test_sum[7][16] =
411 {
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 }
426 };
427 
428 /*
429  * Checkup routine
430  */
431 int md4_self_test( int verbose )
432 {
433  int i;
434  unsigned char md4sum[16];
435 
436  for( i = 0; i < 7; i++ )
437  {
438  if( verbose != 0 )
439  printf( " MD4 test #%d: ", i + 1 );
440 
441  md4( (unsigned char *) md4_test_str[i],
442  strlen( md4_test_str[i] ), md4sum );
443 
444  if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
445  {
446  if( verbose != 0 )
447  printf( "failed\n" );
448 
449  return( 1 );
450  }
451 
452  if( verbose != 0 )
453  printf( "passed\n" );
454  }
455 
456  if( verbose != 0 )
457  printf( "\n" );
458 
459  return( 0 );
460 }
461 
462 #endif
463 
464 #endif
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_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 context structure.
Definition: md4.h:50
unsigned char buffer[64]
Definition: md4.h:54
unsigned char ipad[64]
Definition: md4.h:56
uint32_t state[4]
Definition: md4.h:53
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.
Definition: md4.h:41
unsigned char opad[64]
Definition: md4.h:57
uint32_t total[2]
Definition: md4.h:52
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.