/home/dko/projects/mobilec/trunk/src/security/xyssl-0.9/library/md2.c

Go to the documentation of this file.
00001 /*
00002  * RFC 1115/1319 compliant MD2 implementation
00003  *
00004  * Copyright (C) 2006-2007 Christophe Devine
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License along
00017  * with this program; if not, write to the Free Software Foundation, Inc.,
00018  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 /*
00021  * The MD2 algorithm was designed by Ron Rivest in 1989.
00022  *
00023  * http://www.ietf.org/rfc/rfc1115.txt
00024  * http://www.ietf.org/rfc/rfc1319.txt
00025  */
00026 
00027 #include "xyssl/config.h"
00028 
00029 #if defined(XYSSL_MD2_C)
00030 
00031 #include "xyssl/md2.h"
00032 
00033 #include <string.h>
00034 #include <stdio.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  * MD2 context setup
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] =
00083 (unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
00084 }
00085 
00086 for( i = 0; i < 18; i++ )
00087 {
00088 for( j = 0; j < 48; j++ )
00089 {
00090 ctx->state[j] = (unsigned char)
00091 ( ctx->state[j] ^ PI_SUBST[t] );
00092 t = ctx->state[j];
00093 }
00094 
00095 t = (unsigned char)( t + i );
00096 }
00097 
00098 t = ctx->cksum[15];
00099 
00100 for( i = 0; i < 16; i++ )
00101 {
00102 ctx->cksum[i] = (unsigned char)
00103 ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
00104 t = ctx->cksum[i];
00105 }
00106 }
00107 
00108 /*
00109  * MD2 process buffer
00110  */
00111 void md2_update( md2_context *ctx, unsigned char *input, int ilen )
00112 {
00113 int fill;
00114 
00115 while( ilen > 0 )
00116 {
00117 if( ctx->left + ilen > 16 )
00118 fill = 16 - ctx->left;
00119 else
00120 fill = ilen;
00121 
00122 memcpy( ctx->buffer + ctx->left, input, fill );
00123 
00124 ctx->left += fill;
00125 input += fill;
00126 ilen -= fill;
00127 
00128 if( ctx->left == 16 )
00129 {
00130 ctx->left = 0;
00131 md2_process( ctx );
00132 }
00133 }
00134 }
00135 
00136 /*
00137  * MD2 final digest
00138  */
00139 void md2_finish( md2_context *ctx, unsigned char output[16] )
00140 {
00141 int i;
00142 unsigned char x;
00143 
00144 x = (unsigned char)( 16 - ctx->left );
00145 
00146 for( i = ctx->left; i < 16; i++ )
00147 ctx->buffer[i] = x;
00148 
00149 md2_process( ctx );
00150 
00151 memcpy( ctx->buffer, ctx->cksum, 16 );
00152 md2_process( ctx );
00153 
00154 memcpy( output, ctx->state, 16 );
00155 }
00156 
00157 /*
00158  * output = MD2( input buffer )
00159  */
00160 void md2( unsigned char *input, int ilen, unsigned char output[16] )
00161 {
00162 md2_context ctx;
00163 
00164 md2_starts( &ctx );
00165 md2_update( &ctx, input, ilen );
00166 md2_finish( &ctx, output );
00167 
00168 memset( &ctx, 0, sizeof( md2_context ) );
00169 }
00170 
00171 /*
00172  * output = MD2( file contents )
00173  */
00174 int md2_file( char *path, unsigned char output[16] )
00175 {
00176 FILE *f;
00177 size_t n;
00178 md2_context ctx;
00179 unsigned char buf[1024];
00180 
00181 if( ( f = fopen( path, "rb" ) ) == NULL )
00182 return( 1 );
00183 
00184 md2_starts( &ctx );
00185 
00186 while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00187 md2_update( &ctx, buf, (int) n );
00188 
00189 md2_finish( &ctx, output );
00190 
00191 memset( &ctx, 0, sizeof( md2_context ) );
00192 
00193 if( ferror( f ) != 0 )
00194 {
00195 fclose( f );
00196 return( 2 );
00197 }
00198 
00199 fclose( f );
00200 return( 0 );
00201 }
00202 
00203 /*
00204  * MD2 HMAC context setup
00205  */
00206 void md2_hmac_starts( md2_context *ctx, unsigned char *key, int keylen )
00207 {
00208 int i;
00209 unsigned char sum[16];
00210 
00211 if( keylen > 64 )
00212 {
00213 md2( key, keylen, sum );
00214 keylen = 16;
00215 key = sum;
00216 }
00217 
00218 memset( ctx->ipad, 0x36, 64 );
00219 memset( ctx->opad, 0x5C, 64 );
00220 
00221 for( i = 0; i < keylen; i++ )
00222 {
00223 ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
00224 ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
00225 }
00226 
00227 md2_starts( ctx );
00228 md2_update( ctx, ctx->ipad, 64 );
00229 
00230 memset( sum, 0, sizeof( sum ) );
00231 }
00232 
00233 /*
00234  * MD2 HMAC process buffer
00235  */
00236 void md2_hmac_update( md2_context *ctx, unsigned char *input, int ilen )
00237 {
00238 md2_update( ctx, input, ilen );
00239 }
00240 
00241 /*
00242  * MD2 HMAC final digest
00243  */
00244 void md2_hmac_finish( md2_context *ctx, unsigned char output[16] )
00245 {
00246 unsigned char tmpbuf[16];
00247 
00248 md2_finish( ctx, tmpbuf );
00249 md2_starts( ctx );
00250 md2_update( ctx, ctx->opad, 64 );
00251 md2_update( ctx, tmpbuf, 16 );
00252 md2_finish( ctx, output );
00253 
00254 memset( tmpbuf, 0, sizeof( tmpbuf ) );
00255 }
00256 
00257 /*
00258  * output = HMAC-MD2( hmac key, input buffer )
00259  */
00260 void md2_hmac( unsigned char *key, int keylen, unsigned char *input, int ilen,
00261 unsigned char output[16] )
00262 {
00263 md2_context ctx;
00264 
00265 md2_hmac_starts( &ctx, key, keylen );
00266 md2_hmac_update( &ctx, input, ilen );
00267 md2_hmac_finish( &ctx, output );
00268 
00269 memset( &ctx, 0, sizeof( md2_context ) );
00270 }
00271 
00272 #if defined(XYSSL_SELF_TEST)
00273 
00274 /*
00275  * RFC 1319 test vectors
00276  */
00277 static const char md2_test_str[7][81] =
00278 {
00279 { "" },
00280 { "a" },
00281 { "abc" },
00282 { "message digest" },
00283 { "abcdefghijklmnopqrstuvwxyz" },
00284 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
00285 { "12345678901234567890123456789012345678901234567890123456789012" \
00286 "345678901234567890" }
00287 };
00288 
00289 static const unsigned char md2_test_sum[7][16] =
00290 {
00291 { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
00292 0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
00293 { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
00294 0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
00295 { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
00296 0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
00297 { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
00298 0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
00299 { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
00300 0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
00301 { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
00302 0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
00303 { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
00304 0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
00305 };
00306 
00307 /*
00308  * Checkup routine
00309  */
00310 int md2_self_test( int verbose )
00311 {
00312 int i;
00313 unsigned char md2sum[16];
00314 
00315 for( i = 0; i < 7; i++ )
00316 {
00317 if( verbose != 0 )
00318 printf( " MD2 test #%d: ", i + 1 );
00319 
00320 md2( (unsigned char *) md2_test_str[i],
00321 strlen( md2_test_str[i] ), md2sum );
00322 
00323 if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
00324 {
00325 if( verbose != 0 )
00326 printf( "failed\n" );
00327 
00328 return( 1 );
00329 }
00330 
00331 if( verbose != 0 )
00332 printf( "passed\n" );
00333 }
00334 
00335 if( verbose != 0 )
00336 printf( "\n" );
00337 
00338 return( 0 );
00339 }
00340 
00341 #endif
00342 
00343 #endif

Generated on Tue Oct 28 17:03:23 2008 for Mobile-C by doxygen 1.5.5

AltStyle によって変換されたページ (->オリジナル) /