PolarSSL v1.3.7
md4.c
Go to the documentation of this file.
1 /*
2  * RFC 1186/1320 compliant MD4 implementation
3  *
4  * Copyright (C) 2006-2014, 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 #if !defined(POLARSSL_CONFIG_FILE)
33 #include "polarssl/config.h"
34 #else
35 #include POLARSSL_CONFIG_FILE
36 #endif
37 
38 #if defined(POLARSSL_MD4_C)
39 
40 #include "polarssl/md4.h"
41 
42 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
43 #include <stdio.h>
44 #endif
45 
46 #if defined(POLARSSL_PLATFORM_C)
47 #include "polarssl/platform.h"
48 #else
49 #define polarssl_printf printf
50 #endif
51 
52 #if !defined(POLARSSL_MD4_ALT)
53 
54 /*
55  * 32-bit integer manipulation macros (little endian)
56  */
57 #ifndef GET_UINT32_LE
58 #define GET_UINT32_LE(n,b,i) \
59 { \
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 ); \
64 }
65 #endif
66 
67 #ifndef PUT_UINT32_LE
68 #define PUT_UINT32_LE(n,b,i) \
69 { \
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 ); \
74 }
75 #endif
76 
77 /*
78  * MD4 context setup
79  */
80 void md4_starts( md4_context *ctx )
81 {
82  ctx->total[0] = 0;
83  ctx->total[1] = 0;
84 
85  ctx->state[0] = 0x67452301;
86  ctx->state[1] = 0xEFCDAB89;
87  ctx->state[2] = 0x98BADCFE;
88  ctx->state[3] = 0x10325476;
89 }
90 
91 void md4_process( md4_context *ctx, const unsigned char data[64] )
92 {
93  uint32_t X[16], A, B, C, D;
94 
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 );
111 
112 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
113 
114  A = ctx->state[0];
115  B = ctx->state[1];
116  C = ctx->state[2];
117  D = ctx->state[3];
118 
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); }
121 
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 );
138 
139 #undef P
140 #undef F
141 
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); }
144 
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 );
161 
162 #undef P
163 #undef F
164 
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); }
167 
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 );
184 
185 #undef F
186 #undef P
187 
188  ctx->state[0] += A;
189  ctx->state[1] += B;
190  ctx->state[2] += C;
191  ctx->state[3] += D;
192 }
193 
194 /*
195  * MD4 process buffer
196  */
197 void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
198 {
199  size_t fill;
200  uint32_t left;
201 
202  if( ilen <= 0 )
203  return;
204 
205  left = ctx->total[0] & 0x3F;
206  fill = 64 - left;
207 
208  ctx->total[0] += (uint32_t) ilen;
209  ctx->total[0] &= 0xFFFFFFFF;
210 
211  if( ctx->total[0] < (uint32_t) ilen )
212  ctx->total[1]++;
213 
214  if( left && ilen >= fill )
215  {
216  memcpy( (void *) (ctx->buffer + left),
217  (void *) input, fill );
218  md4_process( ctx, ctx->buffer );
219  input += fill;
220  ilen -= fill;
221  left = 0;
222  }
223 
224  while( ilen >= 64 )
225  {
226  md4_process( ctx, input );
227  input += 64;
228  ilen -= 64;
229  }
230 
231  if( ilen > 0 )
232  {
233  memcpy( (void *) (ctx->buffer + left),
234  (void *) input, ilen );
235  }
236 }
237 
238 static const unsigned char md4_padding[64] =
239 {
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
244 };
245 
246 /*
247  * MD4 final digest
248  */
249 void md4_finish( md4_context *ctx, unsigned char output[16] )
250 {
251  uint32_t last, padn;
252  uint32_t high, low;
253  unsigned char msglen[8];
254 
255  high = ( ctx->total[0] >> 29 )
256  | ( ctx->total[1] << 3 );
257  low = ( ctx->total[0] << 3 );
258 
259  PUT_UINT32_LE( low, msglen, 0 );
260  PUT_UINT32_LE( high, msglen, 4 );
261 
262  last = ctx->total[0] & 0x3F;
263  padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
264 
265  md4_update( ctx, (unsigned char *) md4_padding, padn );
266  md4_update( ctx, msglen, 8 );
267 
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 );
272 }
273 
274 #endif /* !POLARSSL_MD4_ALT */
275 
276 /*
277  * output = MD4( input buffer )
278  */
279 void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
280 {
281  md4_context ctx;
282 
283  md4_starts( &ctx );
284  md4_update( &ctx, input, ilen );
285  md4_finish( &ctx, output );
286 
287  memset( &ctx, 0, sizeof( md4_context ) );
288 }
289 
290 #if defined(POLARSSL_FS_IO)
291 /*
292  * output = MD4( file contents )
293  */
294 int md4_file( const char *path, unsigned char output[16] )
295 {
296  FILE *f;
297  size_t n;
298  md4_context ctx;
299  unsigned char buf[1024];
300 
301  if( ( f = fopen( path, "rb" ) ) == NULL )
303 
304  md4_starts( &ctx );
305 
306  while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
307  md4_update( &ctx, buf, n );
308 
309  md4_finish( &ctx, output );
310 
311  memset( &ctx, 0, sizeof( md4_context ) );
312 
313  if( ferror( f ) != 0 )
314  {
315  fclose( f );
317  }
318 
319  fclose( f );
320  return( 0 );
321 }
322 #endif /* POLARSSL_FS_IO */
323 
324 /*
325  * MD4 HMAC context setup
326  */
327 void md4_hmac_starts( md4_context *ctx, const unsigned char *key,
328  size_t keylen )
329 {
330  size_t i;
331  unsigned char sum[16];
332 
333  if( keylen > 64 )
334  {
335  md4( key, keylen, sum );
336  keylen = 16;
337  key = sum;
338  }
339 
340  memset( ctx->ipad, 0x36, 64 );
341  memset( ctx->opad, 0x5C, 64 );
342 
343  for( i = 0; i < keylen; i++ )
344  {
345  ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
346  ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
347  }
348 
349  md4_starts( ctx );
350  md4_update( ctx, ctx->ipad, 64 );
351 
352  memset( sum, 0, sizeof( sum ) );
353 }
354 
355 /*
356  * MD4 HMAC process buffer
357  */
358 void md4_hmac_update( md4_context *ctx, const unsigned char *input,
359  size_t ilen )
360 {
361  md4_update( ctx, input, ilen );
362 }
363 
364 /*
365  * MD4 HMAC final digest
366  */
367 void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
368 {
369  unsigned char tmpbuf[16];
370 
371  md4_finish( ctx, tmpbuf );
372  md4_starts( ctx );
373  md4_update( ctx, ctx->opad, 64 );
374  md4_update( ctx, tmpbuf, 16 );
375  md4_finish( ctx, output );
376 
377  memset( tmpbuf, 0, sizeof( tmpbuf ) );
378 }
379 
380 /*
381  * MD4 HMAC context reset
382  */
383 void md4_hmac_reset( md4_context *ctx )
384 {
385  md4_starts( ctx );
386  md4_update( ctx, ctx->ipad, 64 );
387 }
388 
389 /*
390  * output = HMAC-MD4( hmac key, input buffer )
391  */
392 void md4_hmac( const unsigned char *key, size_t keylen,
393  const unsigned char *input, size_t ilen,
394  unsigned char output[16] )
395 {
396  md4_context ctx;
397 
398  md4_hmac_starts( &ctx, key, keylen );
399  md4_hmac_update( &ctx, input, ilen );
400  md4_hmac_finish( &ctx, output );
401 
402  memset( &ctx, 0, sizeof( md4_context ) );
403 }
404 
405 #if defined(POLARSSL_SELF_TEST)
406 
407 /*
408  * RFC 1320 test vectors
409  */
410 static const char md4_test_str[7][81] =
411 {
412  { "" },
413  { "a" },
414  { "abc" },
415  { "message digest" },
416  { "abcdefghijklmnopqrstuvwxyz" },
417  { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
418  { "12345678901234567890123456789012345678901234567890123456789012" \
419  "345678901234567890" }
420 };
421 
422 static const unsigned char md4_test_sum[7][16] =
423 {
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 }
438 };
439 
440 /*
441  * Checkup routine
442  */
443 int md4_self_test( int verbose )
444 {
445  int i;
446  unsigned char md4sum[16];
447 
448  for( i = 0; i < 7; i++ )
449  {
450  if( verbose != 0 )
451  polarssl_printf( " MD4 test #%d: ", i + 1 );
452 
453  md4( (unsigned char *) md4_test_str[i],
454  strlen( md4_test_str[i] ), md4sum );
455 
456  if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
457  {
458  if( verbose != 0 )
459  polarssl_printf( "failed\n" );
460 
461  return( 1 );
462  }
463 
464  if( verbose != 0 )
465  polarssl_printf( "passed\n" );
466  }
467 
468  if( verbose != 0 )
469  polarssl_printf( "\n" );
470 
471  return( 0 );
472 }
473 
474 #endif /* POLARSSL_SELF_TEST */
475 
476 #endif /* POLARSSL_MD4_C */
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)
PolarSSL Platform abstraction layer.
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 context structure.
Definition: md4.h:58
unsigned char buffer[64]
Definition: md4.h:62
unsigned char ipad[64]
Definition: md4.h:64
uint32_t state[4]
Definition: md4.h:61
#define polarssl_printf
Definition: platform.h:109
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:45
unsigned char opad[64]
Definition: md4.h:65
uint32_t total[2]
Definition: md4.h:60
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.