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