00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "polarssl/config.h"
00033
00034 #if defined(POLARSSL_MD4_C)
00035
00036 #include "polarssl/md4.h"
00037
00038 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
00039 #include <stdio.h>
00040 #endif
00041
00042 #if !defined(POLARSSL_MD4_ALT)
00043
00044
00045
00046
00047 #ifndef GET_UINT32_LE
00048 #define GET_UINT32_LE(n,b,i) \
00049 { \
00050 (n) = ( (uint32_t) (b)[(i) ] ) \
00051 | ( (uint32_t) (b)[(i) + 1] << 8 ) \
00052 | ( (uint32_t) (b)[(i) + 2] << 16 ) \
00053 | ( (uint32_t) (b)[(i) + 3] << 24 ); \
00054 }
00055 #endif
00056
00057 #ifndef PUT_UINT32_LE
00058 #define PUT_UINT32_LE(n,b,i) \
00059 { \
00060 (b)[(i) ] = (unsigned char) ( (n) ); \
00061 (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \
00062 (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \
00063 (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \
00064 }
00065 #endif
00066
00067
00068
00069
00070 void md4_starts( md4_context *ctx )
00071 {
00072 ctx->total[0] = 0;
00073 ctx->total[1] = 0;
00074
00075 ctx->state[0] = 0x67452301;
00076 ctx->state[1] = 0xEFCDAB89;
00077 ctx->state[2] = 0x98BADCFE;
00078 ctx->state[3] = 0x10325476;
00079 }
00080
00081 void md4_process( md4_context *ctx, const unsigned char data[64] )
00082 {
00083 uint32_t X[16], A, B, C, D;
00084
00085 GET_UINT32_LE( X[ 0], data, 0 );
00086 GET_UINT32_LE( X[ 1], data, 4 );
00087 GET_UINT32_LE( X[ 2], data, 8 );
00088 GET_UINT32_LE( X[ 3], data, 12 );
00089 GET_UINT32_LE( X[ 4], data, 16 );
00090 GET_UINT32_LE( X[ 5], data, 20 );
00091 GET_UINT32_LE( X[ 6], data, 24 );
00092 GET_UINT32_LE( X[ 7], data, 28 );
00093 GET_UINT32_LE( X[ 8], data, 32 );
00094 GET_UINT32_LE( X[ 9], data, 36 );
00095 GET_UINT32_LE( X[10], data, 40 );
00096 GET_UINT32_LE( X[11], data, 44 );
00097 GET_UINT32_LE( X[12], data, 48 );
00098 GET_UINT32_LE( X[13], data, 52 );
00099 GET_UINT32_LE( X[14], data, 56 );
00100 GET_UINT32_LE( X[15], data, 60 );
00101
00102 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00103
00104 A = ctx->state[0];
00105 B = ctx->state[1];
00106 C = ctx->state[2];
00107 D = ctx->state[3];
00108
00109 #define F(x, y, z) ((x & y) | ((~x) & z))
00110 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); }
00111
00112 P( A, B, C, D, X[ 0], 3 );
00113 P( D, A, B, C, X[ 1], 7 );
00114 P( C, D, A, B, X[ 2], 11 );
00115 P( B, C, D, A, X[ 3], 19 );
00116 P( A, B, C, D, X[ 4], 3 );
00117 P( D, A, B, C, X[ 5], 7 );
00118 P( C, D, A, B, X[ 6], 11 );
00119 P( B, C, D, A, X[ 7], 19 );
00120 P( A, B, C, D, X[ 8], 3 );
00121 P( D, A, B, C, X[ 9], 7 );
00122 P( C, D, A, B, X[10], 11 );
00123 P( B, C, D, A, X[11], 19 );
00124 P( A, B, C, D, X[12], 3 );
00125 P( D, A, B, C, X[13], 7 );
00126 P( C, D, A, B, X[14], 11 );
00127 P( B, C, D, A, X[15], 19 );
00128
00129 #undef P
00130 #undef F
00131
00132 #define F(x,y,z) ((x & y) | (x & z) | (y & z))
00133 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); }
00134
00135 P( A, B, C, D, X[ 0], 3 );
00136 P( D, A, B, C, X[ 4], 5 );
00137 P( C, D, A, B, X[ 8], 9 );
00138 P( B, C, D, A, X[12], 13 );
00139 P( A, B, C, D, X[ 1], 3 );
00140 P( D, A, B, C, X[ 5], 5 );
00141 P( C, D, A, B, X[ 9], 9 );
00142 P( B, C, D, A, X[13], 13 );
00143 P( A, B, C, D, X[ 2], 3 );
00144 P( D, A, B, C, X[ 6], 5 );
00145 P( C, D, A, B, X[10], 9 );
00146 P( B, C, D, A, X[14], 13 );
00147 P( A, B, C, D, X[ 3], 3 );
00148 P( D, A, B, C, X[ 7], 5 );
00149 P( C, D, A, B, X[11], 9 );
00150 P( B, C, D, A, X[15], 13 );
00151
00152 #undef P
00153 #undef F
00154
00155 #define F(x,y,z) (x ^ y ^ z)
00156 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); }
00157
00158 P( A, B, C, D, X[ 0], 3 );
00159 P( D, A, B, C, X[ 8], 9 );
00160 P( C, D, A, B, X[ 4], 11 );
00161 P( B, C, D, A, X[12], 15 );
00162 P( A, B, C, D, X[ 2], 3 );
00163 P( D, A, B, C, X[10], 9 );
00164 P( C, D, A, B, X[ 6], 11 );
00165 P( B, C, D, A, X[14], 15 );
00166 P( A, B, C, D, X[ 1], 3 );
00167 P( D, A, B, C, X[ 9], 9 );
00168 P( C, D, A, B, X[ 5], 11 );
00169 P( B, C, D, A, X[13], 15 );
00170 P( A, B, C, D, X[ 3], 3 );
00171 P( D, A, B, C, X[11], 9 );
00172 P( C, D, A, B, X[ 7], 11 );
00173 P( B, C, D, A, X[15], 15 );
00174
00175 #undef F
00176 #undef P
00177
00178 ctx->state[0] += A;
00179 ctx->state[1] += B;
00180 ctx->state[2] += C;
00181 ctx->state[3] += D;
00182 }
00183
00184
00185
00186
00187 void md4_update( md4_context *ctx, const unsigned char *input, size_t ilen )
00188 {
00189 size_t fill;
00190 uint32_t left;
00191
00192 if( ilen <= 0 )
00193 return;
00194
00195 left = ctx->total[0] & 0x3F;
00196 fill = 64 - left;
00197
00198 ctx->total[0] += (uint32_t) ilen;
00199 ctx->total[0] &= 0xFFFFFFFF;
00200
00201 if( ctx->total[0] < (uint32_t) ilen )
00202 ctx->total[1]++;
00203
00204 if( left && ilen >= fill )
00205 {
00206 memcpy( (void *) (ctx->buffer + left),
00207 (void *) input, fill );
00208 md4_process( ctx, ctx->buffer );
00209 input += fill;
00210 ilen -= fill;
00211 left = 0;
00212 }
00213
00214 while( ilen >= 64 )
00215 {
00216 md4_process( ctx, input );
00217 input += 64;
00218 ilen -= 64;
00219 }
00220
00221 if( ilen > 0 )
00222 {
00223 memcpy( (void *) (ctx->buffer + left),
00224 (void *) input, ilen );
00225 }
00226 }
00227
00228 static const unsigned char md4_padding[64] =
00229 {
00230 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00231 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00232 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00233 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00234 };
00235
00236
00237
00238
00239 void md4_finish( md4_context *ctx, unsigned char output[16] )
00240 {
00241 uint32_t last, padn;
00242 uint32_t high, low;
00243 unsigned char msglen[8];
00244
00245 high = ( ctx->total[0] >> 29 )
00246 | ( ctx->total[1] << 3 );
00247 low = ( ctx->total[0] << 3 );
00248
00249 PUT_UINT32_LE( low, msglen, 0 );
00250 PUT_UINT32_LE( high, msglen, 4 );
00251
00252 last = ctx->total[0] & 0x3F;
00253 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00254
00255 md4_update( ctx, (unsigned char *) md4_padding, padn );
00256 md4_update( ctx, msglen, 8 );
00257
00258 PUT_UINT32_LE( ctx->state[0], output, 0 );
00259 PUT_UINT32_LE( ctx->state[1], output, 4 );
00260 PUT_UINT32_LE( ctx->state[2], output, 8 );
00261 PUT_UINT32_LE( ctx->state[3], output, 12 );
00262 }
00263
00264 #endif
00265
00266
00267
00268
00269 void md4( const unsigned char *input, size_t ilen, unsigned char output[16] )
00270 {
00271 md4_context ctx;
00272
00273 md4_starts( &ctx );
00274 md4_update( &ctx, input, ilen );
00275 md4_finish( &ctx, output );
00276
00277 memset( &ctx, 0, sizeof( md4_context ) );
00278 }
00279
00280 #if defined(POLARSSL_FS_IO)
00281
00282
00283
00284 int md4_file( const char *path, unsigned char output[16] )
00285 {
00286 FILE *f;
00287 size_t n;
00288 md4_context ctx;
00289 unsigned char buf[1024];
00290
00291 if( ( f = fopen( path, "rb" ) ) == NULL )
00292 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
00293
00294 md4_starts( &ctx );
00295
00296 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00297 md4_update( &ctx, buf, n );
00298
00299 md4_finish( &ctx, output );
00300
00301 memset( &ctx, 0, sizeof( md4_context ) );
00302
00303 if( ferror( f ) != 0 )
00304 {
00305 fclose( f );
00306 return( POLARSSL_ERR_MD4_FILE_IO_ERROR );
00307 }
00308
00309 fclose( f );
00310 return( 0 );
00311 }
00312 #endif
00313
00314
00315
00316
00317 void md4_hmac_starts( md4_context *ctx, const unsigned char *key, size_t keylen )
00318 {
00319 size_t i;
00320 unsigned char sum[16];
00321
00322 if( keylen > 64 )
00323 {
00324 md4( key, keylen, sum );
00325 keylen = 16;
00326 key = sum;
00327 }
00328
00329 memset( ctx->ipad, 0x36, 64 );
00330 memset( ctx->opad, 0x5C, 64 );
00331
00332 for( i = 0; i < keylen; i++ )
00333 {
00334 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
00335 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
00336 }
00337
00338 md4_starts( ctx );
00339 md4_update( ctx, ctx->ipad, 64 );
00340
00341 memset( sum, 0, sizeof( sum ) );
00342 }
00343
00344
00345
00346
00347 void md4_hmac_update( md4_context *ctx, const unsigned char *input, size_t ilen )
00348 {
00349 md4_update( ctx, input, ilen );
00350 }
00351
00352
00353
00354
00355 void md4_hmac_finish( md4_context *ctx, unsigned char output[16] )
00356 {
00357 unsigned char tmpbuf[16];
00358
00359 md4_finish( ctx, tmpbuf );
00360 md4_starts( ctx );
00361 md4_update( ctx, ctx->opad, 64 );
00362 md4_update( ctx, tmpbuf, 16 );
00363 md4_finish( ctx, output );
00364
00365 memset( tmpbuf, 0, sizeof( tmpbuf ) );
00366 }
00367
00368
00369
00370
00371 void md4_hmac_reset( md4_context *ctx )
00372 {
00373 md4_starts( ctx );
00374 md4_update( ctx, ctx->ipad, 64 );
00375 }
00376
00377
00378
00379
00380 void md4_hmac( const unsigned char *key, size_t keylen,
00381 const unsigned char *input, size_t ilen,
00382 unsigned char output[16] )
00383 {
00384 md4_context ctx;
00385
00386 md4_hmac_starts( &ctx, key, keylen );
00387 md4_hmac_update( &ctx, input, ilen );
00388 md4_hmac_finish( &ctx, output );
00389
00390 memset( &ctx, 0, sizeof( md4_context ) );
00391 }
00392
00393 #if defined(POLARSSL_SELF_TEST)
00394
00395
00396
00397
00398 static const char md4_test_str[7][81] =
00399 {
00400 { "" },
00401 { "a" },
00402 { "abc" },
00403 { "message digest" },
00404 { "abcdefghijklmnopqrstuvwxyz" },
00405 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
00406 { "12345678901234567890123456789012345678901234567890123456789012" \
00407 "345678901234567890" }
00408 };
00409
00410 static const unsigned char md4_test_sum[7][16] =
00411 {
00412 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31,
00413 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 },
00414 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46,
00415 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 },
00416 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52,
00417 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D },
00418 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8,
00419 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B },
00420 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD,
00421 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 },
00422 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35,
00423 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 },
00424 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19,
00425 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 }
00426 };
00427
00428
00429
00430
00431 int md4_self_test( int verbose )
00432 {
00433 int i;
00434 unsigned char md4sum[16];
00435
00436 for( i = 0; i < 7; i++ )
00437 {
00438 if( verbose != 0 )
00439 printf( " MD4 test #%d: ", i + 1 );
00440
00441 md4( (unsigned char *) md4_test_str[i],
00442 strlen( md4_test_str[i] ), md4sum );
00443
00444 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 )
00445 {
00446 if( verbose != 0 )
00447 printf( "failed\n" );
00448
00449 return( 1 );
00450 }
00451
00452 if( verbose != 0 )
00453 printf( "passed\n" );
00454 }
00455
00456 if( verbose != 0 )
00457 printf( "\n" );
00458
00459 return( 0 );
00460 }
00461
00462 #endif
00463
00464 #endif