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_MD2_C)
00035
00036 #include "polarssl/md2.h"
00037
00038 #if defined(POLARSSL_FS_IO) || defined(POLARSSL_SELF_TEST)
00039 #include <stdio.h>
00040 #endif
00041
00042 #if !defined(POLARSSL_MD2_ALT)
00043
00044 static const unsigned char PI_SUBST[256] =
00045 {
00046 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
00047 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
00048 0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
00049 0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
00050 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
00051 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
00052 0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
00053 0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
00054 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
00055 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
00056 0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
00057 0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
00058 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
00059 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
00060 0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
00061 0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
00062 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
00063 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
00064 0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
00065 0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
00066 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
00067 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
00068 0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
00069 0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
00070 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
00071 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
00072 };
00073
00074
00075
00076
00077 void md2_starts( md2_context *ctx )
00078 {
00079 memset( ctx->cksum, 0, 16 );
00080 memset( ctx->state, 0, 46 );
00081 memset( ctx->buffer, 0, 16 );
00082 ctx->left = 0;
00083 }
00084
00085 void md2_process( md2_context *ctx )
00086 {
00087 int i, j;
00088 unsigned char t = 0;
00089
00090 for( i = 0; i < 16; i++ )
00091 {
00092 ctx->state[i + 16] = ctx->buffer[i];
00093 ctx->state[i + 32] =
00094 (unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
00095 }
00096
00097 for( i = 0; i < 18; i++ )
00098 {
00099 for( j = 0; j < 48; j++ )
00100 {
00101 ctx->state[j] = (unsigned char)
00102 ( ctx->state[j] ^ PI_SUBST[t] );
00103 t = ctx->state[j];
00104 }
00105
00106 t = (unsigned char)( t + i );
00107 }
00108
00109 t = ctx->cksum[15];
00110
00111 for( i = 0; i < 16; i++ )
00112 {
00113 ctx->cksum[i] = (unsigned char)
00114 ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
00115 t = ctx->cksum[i];
00116 }
00117 }
00118
00119
00120
00121
00122 void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen )
00123 {
00124 size_t fill;
00125
00126 while( ilen > 0 )
00127 {
00128 if( ctx->left + ilen > 16 )
00129 fill = 16 - ctx->left;
00130 else
00131 fill = ilen;
00132
00133 memcpy( ctx->buffer + ctx->left, input, fill );
00134
00135 ctx->left += fill;
00136 input += fill;
00137 ilen -= fill;
00138
00139 if( ctx->left == 16 )
00140 {
00141 ctx->left = 0;
00142 md2_process( ctx );
00143 }
00144 }
00145 }
00146
00147
00148
00149
00150 void md2_finish( md2_context *ctx, unsigned char output[16] )
00151 {
00152 size_t i;
00153 unsigned char x;
00154
00155 x = (unsigned char)( 16 - ctx->left );
00156
00157 for( i = ctx->left; i < 16; i++ )
00158 ctx->buffer[i] = x;
00159
00160 md2_process( ctx );
00161
00162 memcpy( ctx->buffer, ctx->cksum, 16 );
00163 md2_process( ctx );
00164
00165 memcpy( output, ctx->state, 16 );
00166 }
00167
00168 #endif
00169
00170
00171
00172
00173 void md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
00174 {
00175 md2_context ctx;
00176
00177 md2_starts( &ctx );
00178 md2_update( &ctx, input, ilen );
00179 md2_finish( &ctx, output );
00180
00181 memset( &ctx, 0, sizeof( md2_context ) );
00182 }
00183
00184 #if defined(POLARSSL_FS_IO)
00185
00186
00187
00188 int md2_file( const char *path, unsigned char output[16] )
00189 {
00190 FILE *f;
00191 size_t n;
00192 md2_context ctx;
00193 unsigned char buf[1024];
00194
00195 if( ( f = fopen( path, "rb" ) ) == NULL )
00196 return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
00197
00198 md2_starts( &ctx );
00199
00200 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00201 md2_update( &ctx, buf, n );
00202
00203 md2_finish( &ctx, output );
00204
00205 memset( &ctx, 0, sizeof( md2_context ) );
00206
00207 if( ferror( f ) != 0 )
00208 {
00209 fclose( f );
00210 return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
00211 }
00212
00213 fclose( f );
00214 return( 0 );
00215 }
00216 #endif
00217
00218
00219
00220
00221 void md2_hmac_starts( md2_context *ctx, const unsigned char *key, size_t keylen )
00222 {
00223 size_t i;
00224 unsigned char sum[16];
00225
00226 if( keylen > 16 )
00227 {
00228 md2( key, keylen, sum );
00229 keylen = 16;
00230 key = sum;
00231 }
00232
00233 memset( ctx->ipad, 0x36, 16 );
00234 memset( ctx->opad, 0x5C, 16 );
00235
00236 for( i = 0; i < keylen; i++ )
00237 {
00238 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
00239 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
00240 }
00241
00242 md2_starts( ctx );
00243 md2_update( ctx, ctx->ipad, 16 );
00244
00245 memset( sum, 0, sizeof( sum ) );
00246 }
00247
00248
00249
00250
00251 void md2_hmac_update( md2_context *ctx, const unsigned char *input, size_t ilen )
00252 {
00253 md2_update( ctx, input, ilen );
00254 }
00255
00256
00257
00258
00259 void md2_hmac_finish( md2_context *ctx, unsigned char output[16] )
00260 {
00261 unsigned char tmpbuf[16];
00262
00263 md2_finish( ctx, tmpbuf );
00264 md2_starts( ctx );
00265 md2_update( ctx, ctx->opad, 16 );
00266 md2_update( ctx, tmpbuf, 16 );
00267 md2_finish( ctx, output );
00268
00269 memset( tmpbuf, 0, sizeof( tmpbuf ) );
00270 }
00271
00272
00273
00274
00275 void md2_hmac_reset( md2_context *ctx )
00276 {
00277 md2_starts( ctx );
00278 md2_update( ctx, ctx->ipad, 16 );
00279 }
00280
00281
00282
00283
00284 void md2_hmac( const unsigned char *key, size_t keylen,
00285 const unsigned char *input, size_t ilen,
00286 unsigned char output[16] )
00287 {
00288 md2_context ctx;
00289
00290 md2_hmac_starts( &ctx, key, keylen );
00291 md2_hmac_update( &ctx, input, ilen );
00292 md2_hmac_finish( &ctx, output );
00293
00294 memset( &ctx, 0, sizeof( md2_context ) );
00295 }
00296
00297 #if defined(POLARSSL_SELF_TEST)
00298
00299
00300
00301
00302 static const char md2_test_str[7][81] =
00303 {
00304 { "" },
00305 { "a" },
00306 { "abc" },
00307 { "message digest" },
00308 { "abcdefghijklmnopqrstuvwxyz" },
00309 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
00310 { "12345678901234567890123456789012345678901234567890123456789012" \
00311 "345678901234567890" }
00312 };
00313
00314 static const unsigned char md2_test_sum[7][16] =
00315 {
00316 { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
00317 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
00318 { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
00319 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
00320 { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
00321 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
00322 { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
00323 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
00324 { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
00325 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
00326 { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
00327 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
00328 { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
00329 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
00330 };
00331
00332
00333
00334
00335 int md2_self_test( int verbose )
00336 {
00337 int i;
00338 unsigned char md2sum[16];
00339
00340 for( i = 0; i < 7; i++ )
00341 {
00342 if( verbose != 0 )
00343 printf( " MD2 test #%d: ", i + 1 );
00344
00345 md2( (unsigned char *) md2_test_str[i],
00346 strlen( md2_test_str[i] ), md2sum );
00347
00348 if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
00349 {
00350 if( verbose != 0 )
00351 printf( "failed\n" );
00352
00353 return( 1 );
00354 }
00355
00356 if( verbose != 0 )
00357 printf( "passed\n" );
00358 }
00359
00360 if( verbose != 0 )
00361 printf( "\n" );
00362
00363 return( 0 );
00364 }
00365
00366 #endif
00367
00368 #endif