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