PolarSSL v1.2.12
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 /* Implementation that should never be optimized out by the compiler */
43 static void polarssl_zeroize( void *v, size_t n ) {
44  volatile unsigned char *p = v; while( n-- ) *p++ = 0;
45 }
46 
47 #if !defined(POLARSSL_MD4_ALT)
48 
49 /*
50  * 32-bit integer manipulation macros (little endian)
51  */
52 #ifndef GET_UINT32_LE
53 #define GET_UINT32_LE(n,b,i) \
54 { \
55  (n) = ( (uint32_t) (b)[(i) ] ) \
56  | ( (uint32_t) (b)[(i) + 1] << 8 ) \
57  | ( (uint32_t) (b)[(i) + 2] << 16 ) \
58  | ( (uint32_t) (b)[(i) + 3] << 24 ); \
59 }
60 #endif
61 
62 #ifndef PUT_UINT32_LE
63 #define PUT_UINT32_LE(n,b,i) \
64 { \
65  (b)[(i) ] = (unsigned char) ( (n) ); \
66  (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
67  (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
68  (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
69 }
70 #endif
71 
72 /*
73  * MD4 context setup
74  */
75 void md4_starts( md4_context *ctx )
76 {
77  ctx->total[0] = 0;
78  ctx->total[1] = 0;
79 
80  ctx->state[0] = 0x67452301;
81  ctx->state[1] = 0xEFCDAB89;
82  ctx->state[2] = 0x98BADCFE;
83  ctx->state[3] = 0x10325476;
84 }
85 
86 static void md4_process( md4_context *ctx, const unsigned char data[64] )
87 {
88  uint32_t X[16], A, B, C, D;
89 
90  GET_UINT32_LE( X[ 0], data, 0 );
91  GET_UINT32_LE( X[ 1], data, 4 );
92  GET_UINT32_LE( X[ 2], data, 8 );
93  GET_UINT32_LE( X[ 3], data, 12 );
94  GET_UINT32_LE( X[ 4], data, 16 );
95  GET_UINT32_LE( X[ 5], data, 20 );
96  GET_UINT32_LE( X[ 6], data, 24 );
97  GET_UINT32_LE( X[ 7], data, 28 );
98  GET_UINT32_LE( X[ 8], data, 32 );
99  GET_UINT32_LE( X[ 9], data, 36 );
100  GET_UINT32_LE( X[10], data, 40 );
101  GET_UINT32_LE( X[11], data, 44 );
102  GET_UINT32_LE( X[12], data, 48 );
103  GET_UINT32_LE( X[13], data, 52 );
104  GET_UINT32_LE( X[14], data, 56 );
105  GET_UINT32_LE( X[15], data, 60 );
106 
107 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
108 
109  A = ctx->state[0];
110  B = ctx->state[1];
111  C = ctx->state[2];
112  D = ctx->state[3];
113 
114 #define F(x, y, z) ((x & y) | ((~x) & z))
115 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
116 
117  P( A, B, C, D, X[ 0], 3 );
118  P( D, A, B, C, X[ 1], 7 );
119  P( C, D, A, B, X[ 2], 11 );
120  P( B, C, D, A, X[ 3], 19 );
121  P( A, B, C, D, X[ 4], 3 );
122  P( D, A, B, C, X[ 5], 7 );
123  P( C, D, A, B, X[ 6], 11 );
124  P( B, C, D, A, X[ 7], 19 );
125  P( A, B, C, D, X[ 8], 3 );
126  P( D, A, B, C, X[ 9], 7 );
127  P( C, D, A, B, X[10], 11 );
128  P( B, C, D, A, X[11], 19 );
129  P( A, B, C, D, X[12], 3 );
130  P( D, A, B, C, X[13], 7 );
131  P( C, D, A, B, X[14], 11 );
132  P( B, C, D, A, X[15], 19 );
133 
134 #undef P
135 #undef F
136 
137 #define F(x,y,z) ((x & y) | (x & z) | (y & z))
138 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
139 
140  P( A, B, C, D, X[ 0], 3 );
141  P( D, A, B, C, X[ 4], 5 );
142  P( C, D, A, B, X[ 8], 9 );
143  P( B, C, D, A, X[12], 13 );
144  P( A, B, C, D, X[ 1], 3 );
145  P( D, A, B, C, X[ 5], 5 );
146  P( C, D, A, B, X[ 9], 9 );
147  P( B, C, D, A, X[13], 13 );
148  P( A, B, C, D, X[ 2], 3 );
149  P( D, A, B, C, X[ 6], 5 );
150  P( C, D, A, B, X[10], 9 );
151  P( B, C, D, A, X[14], 13 );
152  P( A, B, C, D, X[ 3], 3 );
153  P( D, A, B, C, X[ 7], 5 );
154  P( C, D, A, B, X[11], 9 );
155  P( B, C, D, A, X[15], 13 );
156 
157 #undef P
158 #undef F
159 
160 #define F(x,y,z) (x ^ y ^ z)
161 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
162 
163  P( A, B, C, D, X[ 0], 3 );
164  P( D, A, B, C, X[ 8], 9 );
165  P( C, D, A, B, X[ 4], 11 );
166  P( B, C, D, A, X[12], 15 );
167  P( A, B, C, D, X[ 2], 3 );
168  P( D, A, B, C, X[10], 9 );
169  P( C, D, A, B, X[ 6], 11 );
170  P( B, C, D, A, X[14], 15 );
171  P( A, B, C, D, X[ 1], 3 );
172  P( D, A, B, C, X[ 9], 9 );
173  P( C, D, A, B, X[ 5], 11 );
174  P( B, C, D, A, X[13], 15 );
175  P( A, B, C, D, X[ 3], 3 );
176  P( D, A, B, C, X[11], 9 );
177  P( C, D, A, B, X[ 7], 11 );
178  P( B, C, D, A, X[15], 15 );
179 
180 #undef F
181 #undef P
182 
183  ctx->state[0] += A;
184  ctx->state[1] += B;
185  ctx->state[2] += C;
186  ctx->state[3] += D;
187 }
188 
189 /*
190  * MD4 process buffer
191  */
192 void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
193 {
194  size_t fill;
195  uint32_t left;
196 
197  if( ilen <= 0 )
198  return;
199 
200  left = ctx->total[0] & 0x3F;
201  fill = 64 - left;
202 
203  ctx->total[0] += (uint32_t) ilen;
204  ctx->total[0] &= 0xFFFFFFFF;
205 
206  if( ctx->total[0] < (uint32_t) ilen )
207  ctx->total[1]++;
208 
209  if( left && ilen >= fill )
210  {
211  memcpy( (void *) (ctx->buffer + left),
212  (void *) input, fill );
213  md4_process( ctx, ctx->buffer );
214  input += fill;
215  ilen -= fill;
216  left = 0;
217  }
218 
219  while( ilen >= 64 )
220  {
221  md4_process( ctx, input );
222  input += 64;
223  ilen -= 64;
224  }
225 
226  if( ilen > 0 )
227  {
228  memcpy( (void *) (ctx->buffer + left),
229  (void *) input, ilen );
230  }
231 }
232 
233 static const unsigned char md4_padding[64] =
234 {
235  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
236  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
237  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
238  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
239 };
240 
241 /*
242  * MD4 final digest
243  */
244 void md4_finish( md4_context *ctx, unsigned char output[16] )
245 {
246  uint32_t last, padn;
247  uint32_t high, low;
248  unsigned char msglen[8];
249 
250  high = ( ctx->total[0] >> 29 )
251  | ( ctx->total[1] << 3 );
252  low = ( ctx->total[0] << 3 );
253 
254  PUT_UINT32_LE( low, msglen, 0 );
255  PUT_UINT32_LE( high, msglen, 4 );
256 
257  last = ctx->total[0] & 0x3F;
258  padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
259 
260  md4_update( ctx, (unsigned char *) md4_padding, padn );
261  md4_update( ctx, msglen, 8 );
262 
263  PUT_UINT32_LE( ctx->state[0], output, 0 );
264  PUT_UINT32_LE( ctx->state[1], output, 4 );
265  PUT_UINT32_LE( ctx->state[2], output, 8 );
266  PUT_UINT32_LE( ctx->state[3], output, 12 );
267 }
268 
269 #endif /* !POLARSSL_MD4_ALT */
270 
271 /*
272  * output = MD4( input buffer )
273  */
274 void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
275 {
276  md4_context ctx;
277 
278  md4_starts( &ctx );
279  md4_update( &ctx, input, ilen );
280  md4_finish( &ctx, output );
281 
282  polarssl_zeroize( &ctx, sizeof( md4_context ) );
283 }
284 
285 #if defined(POLARSSL_FS_IO)
286 /*
287  * output = MD4( file contents )
288  */
289 int md4_file( const char *path, unsigned char output[16] )
290 {
291  FILE *f;
292  size_t n;
293  md4_context ctx;
294  unsigned char buf[1024];
295 
296  if( ( f = fopen( path, "rb" ) ) == NULL )
298 
299  md4_starts( &ctx );
300 
301  while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
302  md4_update( &ctx, buf, n );
303 
304  md4_finish( &ctx, output );
305 
306  polarssl_zeroize( &ctx, sizeof( md4_context ) );
307 
308  if( ferror( f ) != 0 )
309  {
310  fclose( f );
312  }
313 
314  fclose( f );
315  return( 0 );
316 }
317 #endif /* POLARSSL_FS_IO */
318 
319 /*
320  * MD4 HMAC context setup
321  */
322 void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen )
323 {
324  size_t i;
325  unsigned char sum[16];
326 
327  if( keylen > 64 )
328  {
329  md4( key, keylen, sum );
330  keylen = 16;
331  key = sum;
332  }
333 
334  memset( ctx->ipad, 0x36, 64 );
335  memset( ctx->opad, 0x5C, 64 );
336 
337  for( i = 0; i < keylen; i++ )
338  {
339  ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
340  ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
341  }
342 
343  md4_starts( ctx );
344  md4_update( ctx, ctx->ipad, 64 );
345 
346  polarssl_zeroize( sum, sizeof( sum ) );
347 }
348 
349 /*
350  * MD4 HMAC process buffer
351  */
352 void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen )
353 {
354  md4_update( ctx, input, ilen );
355 }
356 
357 /*
358  * MD4 HMAC final digest
359  */
360 void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
361 {
362  unsigned char tmpbuf[16];
363 
364  md4_finish( ctx, tmpbuf );
365  md4_starts( ctx );
366  md4_update( ctx, ctx->opad, 64 );
367  md4_update( ctx, tmpbuf, 16 );
368  md4_finish( ctx, output );
369 
370  polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
371 }
372 
373 /*
374  * MD4 HMAC context reset
375  */
376 void md4_hmac_reset( md4_context *ctx )
377 {
378  md4_starts( ctx );
379  md4_update( ctx, ctx->ipad, 64 );
380 }
381 
382 /*
383  * output = HMAC-MD4( hmac key, input buffer )
384  */
385 void md4_hmac( const unsigned char *key, size_t keylen,
386  const unsigned char *input, size_t ilen,
387  unsigned char output[16] )
388 {
389  md4_context ctx;
390 
391  md4_hmac_starts( &ctx, key, keylen );
392  md4_hmac_update( &ctx, input, ilen );
393  md4_hmac_finish( &ctx, output );
394 
395  polarssl_zeroize( &ctx, sizeof( md4_context ) );
396 }
397 
398 #if defined(POLARSSL_SELF_TEST)
399 
400 /*
401  * RFC 1320 test vectors
402  */
403 static const char md4_test_str[7][81] =
404 {
405  { "" },
406  { "a" },
407  { "abc" },
408  { "message digest" },
409  { "abcdefghijklmnopqrstuvwxyz" },
410  { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
411  { "12345678901234567890123456789012345678901234567890123456789012" \
412  "345678901234567890" }
413 };
414 
415 static const unsigned char md4_test_sum[7][16] =
416 {
417  { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
418  0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
419  { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
420  0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
421  { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
422  0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
423  { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
424  0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
425  { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
426  0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
427  { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
428  0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
429  { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
430  0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
431 };
432 
433 /*
434  * Checkup routine
435  */
436 int md4_self_test( int verbose )
437 {
438  int i;
439  unsigned char md4sum[16];
440 
441  for( i = 0; i < 7; i++ )
442  {
443  if( verbose != 0 )
444  printf( " MD4 test #%d: ", i + 1 );
445 
446  md4( (unsigned char *) md4_test_str[i],
447  strlen( md4_test_str[i] ), md4sum );
448 
449  if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
450  {
451  if( verbose != 0 )
452  printf( "failed\n" );
453 
454  return( 1 );
455  }
456 
457  if( verbose != 0 )
458  printf( "passed\n" );
459  }
460 
461  if( verbose != 0 )
462  printf( "\n" );
463 
464  return( 0 );
465 }
466 
467 #endif
468 
469 #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.