blob: ccde1a16bddef2dbfa4f5933cb55fefb2a3cc426 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * RFC 1186/1320 compliant MD4 implementation
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * 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
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000033#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020034#else
35#include POLARSSL_CONFIG_FILE
36#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Paul Bakker40e46942009-01-03 21:51:57 +000038#if defined(POLARSSL_MD4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Paul Bakker40e46942009-01-03 21:51:57 +000040#include "polarssl/md4.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000041
Paul Bakker335db3f2011-04-25 15:28:35 +000042#if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +000043#include <stdio.h>
Paul Bakker335db3f2011-04-25 15:28:35 +000044#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000045
Paul Bakker7dc4c442014-02-01 22:50:26 +010046#if defined(POLARSSL_PLATFORM_C)
47#include "polarssl/platform.h"
48#else
49#define polarssl_printf printf
50#endif
51
Paul Bakker34617722014-06-13 17:20:13 +020052/* Implementation that should never be optimized out by the compiler */
53static void polarssl_zeroize( void *v, size_t n ) {
54 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
55}
56
Paul Bakker90995b52013-06-24 19:20:35 +020057#if !defined(POLARSSL_MD4_ALT)
58
Paul Bakker5121ce52009-01-03 21:22:43 +000059/*
60 * 32-bit integer manipulation macros (little endian)
61 */
Paul Bakker5c2364c2012-10-01 14:41:15 +000062#ifndef GET_UINT32_LE
63#define GET_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000064{ \
Paul Bakker5c2364c2012-10-01 14:41:15 +000065 (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 ); \
Paul Bakker5121ce52009-01-03 21:22:43 +000069}
70#endif
71
Paul Bakker5c2364c2012-10-01 14:41:15 +000072#ifndef PUT_UINT32_LE
73#define PUT_UINT32_LE(n,b,i) \
Paul Bakker5121ce52009-01-03 21:22:43 +000074{ \
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 ); \
79}
80#endif
81
82/*
83 * MD4 context setup
84 */
85void md4_starts( md4_context *ctx )
86{
87 ctx->total[0] = 0;
88 ctx->total[1] = 0;
89
90 ctx->state[0] = 0x67452301;
91 ctx->state[1] = 0xEFCDAB89;
92 ctx->state[2] = 0x98BADCFE;
93 ctx->state[3] = 0x10325476;
94}
95
Paul Bakker1bd3ae82013-03-13 10:26:44 +010096void md4_process( md4_context *ctx, const unsigned char data[64] )
Paul Bakker5121ce52009-01-03 21:22:43 +000097{
Paul Bakker5c2364c2012-10-01 14:41:15 +000098 uint32_t X[16], A, B, C, D;
Paul Bakker5121ce52009-01-03 21:22:43 +000099
Paul Bakker5c2364c2012-10-01 14:41:15 +0000100 GET_UINT32_LE( X[ 0], data, 0 );
101 GET_UINT32_LE( X[ 1], data, 4 );
102 GET_UINT32_LE( X[ 2], data, 8 );
103 GET_UINT32_LE( X[ 3], data, 12 );
104 GET_UINT32_LE( X[ 4], data, 16 );
105 GET_UINT32_LE( X[ 5], data, 20 );
106 GET_UINT32_LE( X[ 6], data, 24 );
107 GET_UINT32_LE( X[ 7], data, 28 );
108 GET_UINT32_LE( X[ 8], data, 32 );
109 GET_UINT32_LE( X[ 9], data, 36 );
110 GET_UINT32_LE( X[10], data, 40 );
111 GET_UINT32_LE( X[11], data, 44 );
112 GET_UINT32_LE( X[12], data, 48 );
113 GET_UINT32_LE( X[13], data, 52 );
114 GET_UINT32_LE( X[14], data, 56 );
115 GET_UINT32_LE( X[15], data, 60 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000116
117#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
118
119 A = ctx->state[0];
120 B = ctx->state[1];
121 C = ctx->state[2];
122 D = ctx->state[3];
123
124#define F(x, y, z) ((x & y) | ((~x) & z))
125#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
126
127 P( A, B, C, D, X[ 0], 3 );
128 P( D, A, B, C, X[ 1], 7 );
129 P( C, D, A, B, X[ 2], 11 );
130 P( B, C, D, A, X[ 3], 19 );
131 P( A, B, C, D, X[ 4], 3 );
132 P( D, A, B, C, X[ 5], 7 );
133 P( C, D, A, B, X[ 6], 11 );
134 P( B, C, D, A, X[ 7], 19 );
135 P( A, B, C, D, X[ 8], 3 );
136 P( D, A, B, C, X[ 9], 7 );
137 P( C, D, A, B, X[10], 11 );
138 P( B, C, D, A, X[11], 19 );
139 P( A, B, C, D, X[12], 3 );
140 P( D, A, B, C, X[13], 7 );
141 P( C, D, A, B, X[14], 11 );
142 P( B, C, D, A, X[15], 19 );
143
144#undef P
145#undef F
146
147#define F(x,y,z) ((x & y) | (x & z) | (y & z))
148#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
149
150 P( A, B, C, D, X[ 0], 3 );
151 P( D, A, B, C, X[ 4], 5 );
152 P( C, D, A, B, X[ 8], 9 );
153 P( B, C, D, A, X[12], 13 );
154 P( A, B, C, D, X[ 1], 3 );
155 P( D, A, B, C, X[ 5], 5 );
156 P( C, D, A, B, X[ 9], 9 );
157 P( B, C, D, A, X[13], 13 );
158 P( A, B, C, D, X[ 2], 3 );
159 P( D, A, B, C, X[ 6], 5 );
160 P( C, D, A, B, X[10], 9 );
161 P( B, C, D, A, X[14], 13 );
162 P( A, B, C, D, X[ 3], 3 );
163 P( D, A, B, C, X[ 7], 5 );
164 P( C, D, A, B, X[11], 9 );
165 P( B, C, D, A, X[15], 13 );
166
167#undef P
168#undef F
169
170#define F(x,y,z) (x ^ y ^ z)
171#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
172
173 P( A, B, C, D, X[ 0], 3 );
174 P( D, A, B, C, X[ 8], 9 );
175 P( C, D, A, B, X[ 4], 11 );
176 P( B, C, D, A, X[12], 15 );
177 P( A, B, C, D, X[ 2], 3 );
178 P( D, A, B, C, X[10], 9 );
179 P( C, D, A, B, X[ 6], 11 );
180 P( B, C, D, A, X[14], 15 );
181 P( A, B, C, D, X[ 1], 3 );
182 P( D, A, B, C, X[ 9], 9 );
183 P( C, D, A, B, X[ 5], 11 );
184 P( B, C, D, A, X[13], 15 );
185 P( A, B, C, D, X[ 3], 3 );
186 P( D, A, B, C, X[11], 9 );
187 P( C, D, A, B, X[ 7], 11 );
188 P( B, C, D, A, X[15], 15 );
189
190#undef F
191#undef P
192
193 ctx->state[0] += A;
194 ctx->state[1] += B;
195 ctx->state[2] += C;
196 ctx->state[3] += D;
197}
198
199/*
200 * MD4 process buffer
201 */
Paul Bakker23986e52011-04-24 08:57:21 +0000202void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000203{
Paul Bakker23986e52011-04-24 08:57:21 +0000204 size_t fill;
Paul Bakker5c2364c2012-10-01 14:41:15 +0000205 uint32_t left;
Paul Bakker5121ce52009-01-03 21:22:43 +0000206
Brian White12895d12014-04-11 11:29:42 -0400207 if( ilen == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000208 return;
209
210 left = ctx->total[0] & 0x3F;
211 fill = 64 - left;
212
Paul Bakker5c2364c2012-10-01 14:41:15 +0000213 ctx->total[0] += (uint32_t) ilen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000214 ctx->total[0] &= 0xFFFFFFFF;
215
Paul Bakker5c2364c2012-10-01 14:41:15 +0000216 if( ctx->total[0] < (uint32_t) ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000217 ctx->total[1]++;
218
219 if( left && ilen >= fill )
220 {
221 memcpy( (void *) (ctx->buffer + left),
222 (void *) input, fill );
223 md4_process( ctx, ctx->buffer );
224 input += fill;
225 ilen -= fill;
226 left = 0;
227 }
228
229 while( ilen >= 64 )
230 {
231 md4_process( ctx, input );
232 input += 64;
233 ilen -= 64;
234 }
235
236 if( ilen > 0 )
237 {
238 memcpy( (void *) (ctx->buffer + left),
239 (void *) input, ilen );
240 }
241}
242
243static const unsigned char md4_padding[64] =
244{
245 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
246 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
247 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
249};
250
251/*
252 * MD4 final digest
253 */
254void md4_finish( md4_context *ctx, unsigned char output[16] )
255{
Paul Bakker5c2364c2012-10-01 14:41:15 +0000256 uint32_t last, padn;
257 uint32_t high, low;
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 unsigned char msglen[8];
259
260 high = ( ctx->total[0] >> 29 )
261 | ( ctx->total[1] << 3 );
262 low = ( ctx->total[0] << 3 );
263
Paul Bakker5c2364c2012-10-01 14:41:15 +0000264 PUT_UINT32_LE( low, msglen, 0 );
265 PUT_UINT32_LE( high, msglen, 4 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000266
267 last = ctx->total[0] & 0x3F;
268 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
269
270 md4_update( ctx, (unsigned char *) md4_padding, padn );
271 md4_update( ctx, msglen, 8 );
272
Paul Bakker5c2364c2012-10-01 14:41:15 +0000273 PUT_UINT32_LE( ctx->state[0], output, 0 );
274 PUT_UINT32_LE( ctx->state[1], output, 4 );
275 PUT_UINT32_LE( ctx->state[2], output, 8 );
276 PUT_UINT32_LE( ctx->state[3], output, 12 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000277}
278
Paul Bakker90995b52013-06-24 19:20:35 +0200279#endif /* !POLARSSL_MD4_ALT */
280
Paul Bakker5121ce52009-01-03 21:22:43 +0000281/*
282 * output = MD4( input buffer )
283 */
Paul Bakker23986e52011-04-24 08:57:21 +0000284void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000285{
286 md4_context ctx;
287
288 md4_starts( &ctx );
289 md4_update( &ctx, input, ilen );
290 md4_finish( &ctx, output );
291
Paul Bakker34617722014-06-13 17:20:13 +0200292 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000293}
294
Paul Bakker335db3f2011-04-25 15:28:35 +0000295#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000296/*
297 * output = MD4( file contents )
298 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000299int md4_file( const char *path, unsigned char output[16] )
Paul Bakker5121ce52009-01-03 21:22:43 +0000300{
301 FILE *f;
302 size_t n;
303 md4_context ctx;
304 unsigned char buf[1024];
305
306 if( ( f = fopen( path, "rb" ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000307 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000308
309 md4_starts( &ctx );
310
311 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
Paul Bakker27fdf462011-06-09 13:55:13 +0000312 md4_update( &ctx, buf, n );
Paul Bakker5121ce52009-01-03 21:22:43 +0000313
314 md4_finish( &ctx, output );
315
Paul Bakker34617722014-06-13 17:20:13 +0200316 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000317
318 if( ferror( f ) != 0 )
319 {
320 fclose( f );
Paul Bakker69e095c2011-12-10 21:55:01 +0000321 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000322 }
323
324 fclose( f );
325 return( 0 );
326}
Paul Bakker335db3f2011-04-25 15:28:35 +0000327#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000328
329/*
330 * MD4 HMAC context setup
331 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200332void md4_hmac_starts( md4_context *ctx, const unsigned char *key,
333 size_t keylen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000334{
Paul Bakker23986e52011-04-24 08:57:21 +0000335 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000336 unsigned char sum[16];
337
338 if( keylen > 64 )
339 {
340 md4( key, keylen, sum );
341 keylen = 16;
342 key = sum;
343 }
344
345 memset( ctx->ipad, 0x36, 64 );
346 memset( ctx->opad, 0x5C, 64 );
347
348 for( i = 0; i < keylen; i++ )
349 {
350 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
351 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
352 }
353
354 md4_starts( ctx );
355 md4_update( ctx, ctx->ipad, 64 );
356
Paul Bakker34617722014-06-13 17:20:13 +0200357 polarssl_zeroize( sum, sizeof( sum ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000358}
359
360/*
361 * MD4 HMAC process buffer
362 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200363void md4_hmac_update( md4_context *ctx, const unsigned char *input,
364 size_t ilen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000365{
366 md4_update( ctx, input, ilen );
367}
368
369/*
370 * MD4 HMAC final digest
371 */
372void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
373{
374 unsigned char tmpbuf[16];
375
376 md4_finish( ctx, tmpbuf );
377 md4_starts( ctx );
378 md4_update( ctx, ctx->opad, 64 );
379 md4_update( ctx, tmpbuf, 16 );
380 md4_finish( ctx, output );
381
Paul Bakker34617722014-06-13 17:20:13 +0200382 polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000383}
384
385/*
Paul Bakker7d3b6612010-03-21 16:23:13 +0000386 * MD4 HMAC context reset
387 */
388void md4_hmac_reset( md4_context *ctx )
389{
390 md4_starts( ctx );
391 md4_update( ctx, ctx->ipad, 64 );
392}
393
394/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 * output = HMAC-MD4( hmac key, input buffer )
396 */
Paul Bakker23986e52011-04-24 08:57:21 +0000397void md4_hmac( const unsigned char *key, size_t keylen,
398 const unsigned char *input, size_t ilen,
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 unsigned char output[16] )
400{
401 md4_context ctx;
402
403 md4_hmac_starts( &ctx, key, keylen );
404 md4_hmac_update( &ctx, input, ilen );
405 md4_hmac_finish( &ctx, output );
406
Paul Bakker34617722014-06-13 17:20:13 +0200407 polarssl_zeroize( &ctx, sizeof( md4_context ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000408}
409
Paul Bakker40e46942009-01-03 21:51:57 +0000410#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412/*
413 * RFC 1320 test vectors
414 */
415static const char md4_test_str[7][81] =
416{
Paul Bakker9af723c2014-05-01 13:03:14 +0200417 { "" },
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 { "a" },
419 { "abc" },
420 { "message digest" },
421 { "abcdefghijklmnopqrstuvwxyz" },
422 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
423 { "12345678901234567890123456789012345678901234567890123456789012" \
424 "345678901234567890" }
425};
426
427static const unsigned char md4_test_sum[7][16] =
428{
429 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
430 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
431 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
432 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
433 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
434 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
435 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
436 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
437 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
438 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
439 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
440 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
441 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
442 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
443};
444
445/*
446 * Checkup routine
447 */
448int md4_self_test( int verbose )
449{
450 int i;
451 unsigned char md4sum[16];
452
453 for( i = 0; i < 7; i++ )
454 {
455 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100456 polarssl_printf( " MD4 test #%d: ", i + 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000457
458 md4( (unsigned char *) md4_test_str[i],
459 strlen( md4_test_str[i] ), md4sum );
460
461 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
462 {
463 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100464 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
466 return( 1 );
467 }
468
469 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100470 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000471 }
472
473 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +0100474 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
476 return( 0 );
477}
478
Paul Bakker9af723c2014-05-01 13:03:14 +0200479#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
Paul Bakker9af723c2014-05-01 13:03:14 +0200481#endif /* POLARSSL_MD4_C */