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 #ifndef _CRT_SECURE_NO_DEPRECATE
00031 #define _CRT_SECURE_NO_DEPRECATE 1
00032 #endif
00033
00034 #include <string.h>
00035 #include <stdio.h>
00036
00037 #include "xyssl/md2.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, 0, sizeof( md2_context ) );
00075 }
00076
00077 static void md2_process( md2_context *ctx )
00078 {
00079 int i, j;
00080 unsigned char t = 0;
00081
00082 for( i = 0; i < 16; i++ )
00083 {
00084 ctx->state[i + 16] = ctx->buffer[i];
00085 ctx->state[i + 32] = ctx->buffer[i] ^ ctx->state[i];
00086 }
00087
00088 for( i = 0; i < 18; i++ )
00089 {
00090 for( j = 0; j < 48; j++ )
00091 t = (ctx->state[j] ^= PI_SUBST[t]);
00092
00093 t = (t + i) & 0xFF;
00094 }
00095
00096 t = ctx->cksum[15];
00097
00098 for( i = 0; i < 16; i++ )
00099 t = (ctx->cksum[i] ^= PI_SUBST[ctx->buffer[i] ^ t]);
00100 }
00101
00102
00103
00104
00105 void md2_update( md2_context *ctx, unsigned char *input, int ilen )
00106 {
00107 int fill;
00108
00109 while( ilen > 0 )
00110 {
00111 if( ctx->left + ilen > 16 )
00112 fill = 16 - ctx->left;
00113 else
00114 fill = ilen;
00115
00116 memcpy( ctx->buffer + ctx->left, input, fill );
00117
00118 ctx->left += fill;
00119 input += fill;
00120 ilen -= fill;
00121
00122 if( ctx->left == 16 )
00123 {
00124 ctx->left = 0;
00125 md2_process( ctx );
00126 }
00127 }
00128 }
00129
00130
00131
00132
00133 void md2_finish( md2_context *ctx, unsigned char *output )
00134 {
00135 int i;
00136 unsigned char x;
00137
00138 x = (unsigned char)( 16 - ctx->left );
00139
00140 for( i = ctx->left; i < 16; i++ )
00141 ctx->buffer[i] = x;
00142
00143 md2_process( ctx );
00144
00145 memcpy( ctx->buffer, ctx->cksum, 16 );
00146 md2_process( ctx );
00147
00148 memcpy( output, ctx->state, 16 );
00149 }
00150
00151
00152
00153
00154 void md2( unsigned char *input, int ilen,
00155 unsigned char *output )
00156 {
00157 md2_context ctx;
00158
00159 md2_starts( &ctx );
00160 md2_update( &ctx, input, ilen );
00161 md2_finish( &ctx, output );
00162
00163 memset( &ctx, 0, sizeof( md2_context ) );
00164 }
00165
00166
00167
00168
00169 int md2_file( char *path, unsigned char *output )
00170 {
00171 FILE *f;
00172 size_t n;
00173 md2_context ctx;
00174 unsigned char buf[1024];
00175
00176 if( ( f = fopen( path, "rb" ) ) == NULL )
00177 return( 1 );
00178
00179 md2_starts( &ctx );
00180
00181 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00182 md2_update( &ctx, buf, (int) n );
00183
00184 md2_finish( &ctx, output );
00185
00186 memset( &ctx, 0, sizeof( md2_context ) );
00187
00188 if( ferror( f ) != 0 )
00189 {
00190 fclose( f );
00191 return( 2 );
00192 }
00193
00194 fclose( f );
00195 return( 0 );
00196 }
00197
00198
00199
00200
00201 void md2_hmac_starts( md2_context *ctx,
00202 unsigned char *key, int keylen )
00203 {
00204 int i;
00205
00206 memset( ctx->ipad, 0x36, 64 );
00207 memset( ctx->opad, 0x5C, 64 );
00208
00209 for( i = 0; i < keylen; i++ )
00210 {
00211 if( i >= 64 ) break;
00212
00213 ctx->ipad[i] ^= key[i];
00214 ctx->opad[i] ^= key[i];
00215 }
00216
00217 md2_starts( ctx );
00218 md2_update( ctx, ctx->ipad, 64 );
00219 }
00220
00221
00222
00223
00224 void md2_hmac_update( md2_context *ctx,
00225 unsigned char *input, int ilen )
00226 {
00227 md2_update( ctx, input, ilen );
00228 }
00229
00230
00231
00232
00233 void md2_hmac_finish( md2_context *ctx, unsigned char *output )
00234 {
00235 unsigned char tmpbuf[16];
00236
00237 md2_finish( ctx, tmpbuf );
00238 md2_starts( ctx );
00239 md2_update( ctx, ctx->opad, 64 );
00240 md2_update( ctx, tmpbuf, 16 );
00241 md2_finish( ctx, output );
00242
00243 memset( tmpbuf, 0, sizeof( tmpbuf ) );
00244 }
00245
00246
00247
00248
00249 void md2_hmac( unsigned char *key, int keylen,
00250 unsigned char *input, int ilen,
00251 unsigned char *output )
00252 {
00253 md2_context ctx;
00254
00255 md2_hmac_starts( &ctx, key, keylen );
00256 md2_hmac_update( &ctx, input, ilen );
00257 md2_hmac_finish( &ctx, output );
00258
00259 memset( &ctx, 0, sizeof( md2_context ) );
00260 }
00261
00262 static const char _md2_src[] = "_md2_src";
00263
00264 #if defined(SELF_TEST)
00265
00266
00267
00268 static const char md2_test_str[7][81] =
00269 {
00270 { "" },
00271 { "a" },
00272 { "abc" },
00273 { "message digest" },
00274 { "abcdefghijklmnopqrstuvwxyz" },
00275 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
00276 { "12345678901234567890123456789012345678901234567890123456789012" \
00277 "345678901234567890" }
00278 };
00279
00280 static const unsigned char md2_test_sum[7][16] =
00281 {
00282 { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
00283 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
00284 { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
00285 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
00286 { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
00287 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
00288 { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
00289 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
00290 { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
00291 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
00292 { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
00293 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
00294 { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
00295 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
00296 };
00297
00298
00299
00300
00301 int md2_self_test( int verbose )
00302 {
00303 int i;
00304 unsigned char md2sum[16];
00305
00306 for( i = 0; i < 7; i++ )
00307 {
00308 if( verbose != 0 )
00309 printf( " MD2 test #%d: ", i + 1 );
00310
00311 md2( (unsigned char *) md2_test_str[i],
00312 strlen( md2_test_str[i] ), md2sum );
00313
00314 if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
00315 {
00316 if( verbose != 0 )
00317 printf( "failed\n" );
00318
00319 return( 1 );
00320 }
00321
00322 if( verbose != 0 )
00323 printf( "passed\n" );
00324 }
00325
00326 if( verbose != 0 )
00327 printf( "\n" );
00328
00329 return( 0 );
00330 }
00331 #else
00332 int md2_self_test( int verbose )
00333 {
00334 return( 0 );
00335 }
00336 #endif