mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers md2.c Source File

md2.c

00001 /*
00002  *  RFC 1115/1319 compliant MD2 implementation
00003  *
00004  *  Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
00005  *
00006  *  This file is part of mbed TLS (https://tls.mbed.org)
00007  *
00008  *  This program is free software; you can redistribute it and/or modify
00009  *  it under the terms of the GNU General Public License as published by
00010  *  the Free Software Foundation; either version 2 of the License, or
00011  *  (at your option) any later version.
00012  *
00013  *  This program is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *  GNU General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU General Public License along
00019  *  with this program; if not, write to the Free Software Foundation, Inc.,
00020  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00021  */
00022 /*
00023  *  The MD2 algorithm was designed by Ron Rivest in 1989.
00024  *
00025  *  http://www.ietf.org/rfc/rfc1115.txt
00026  *  http://www.ietf.org/rfc/rfc1319.txt
00027  */
00028 
00029 #if !defined(POLARSSL_CONFIG_FILE)
00030 #include "polarssl/config.h"
00031 #else
00032 #include POLARSSL_CONFIG_FILE
00033 #endif
00034 
00035 #if defined(POLARSSL_MD2_C)
00036 
00037 #include "polarssl/md2.h"
00038 
00039 #include <string.h>
00040 
00041 #if defined(POLARSSL_FS_IO)
00042 #include <stdio.h>
00043 #endif
00044 
00045 #if defined(POLARSSL_SELF_TEST)
00046 #if defined(POLARSSL_PLATFORM_C)
00047 #include "polarssl/platform.h"
00048 #else
00049 #include <stdio.h>
00050 #define polarssl_printf printf
00051 #endif /* POLARSSL_PLATFORM_C */
00052 #endif /* POLARSSL_SELF_TEST */
00053 
00054 /* Implementation that should never be optimized out by the compiler */
00055 static void polarssl_zeroize( void *v, size_t n ) {
00056     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00057 }
00058 
00059 #if !defined(POLARSSL_MD2_ALT)
00060 
00061 static const unsigned char PI_SUBST[256] =
00062 {
00063     0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
00064     0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
00065     0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
00066     0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
00067     0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
00068     0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
00069     0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
00070     0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
00071     0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
00072     0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
00073     0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
00074     0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
00075     0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
00076     0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
00077     0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
00078     0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
00079     0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
00080     0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
00081     0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
00082     0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
00083     0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
00084     0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
00085     0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
00086     0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
00087     0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
00088     0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
00089 };
00090 
00091 void md2_init( md2_context *ctx )
00092 {
00093     memset( ctx, 0, sizeof( md2_context ) );
00094 }
00095 
00096 void md2_free( md2_context *ctx )
00097 {
00098     if( ctx == NULL )
00099         return;
00100 
00101     polarssl_zeroize( ctx, sizeof( md2_context ) );
00102 }
00103 
00104 /*
00105  * MD2 context setup
00106  */
00107 void md2_starts( md2_context *ctx )
00108 {
00109     memset( ctx->cksum , 0, 16 );
00110     memset( ctx->state , 0, 46 );
00111     memset( ctx->buffer , 0, 16 );
00112     ctx->left  = 0;
00113 }
00114 
00115 void md2_process( md2_context *ctx )
00116 {
00117     int i, j;
00118     unsigned char t = 0;
00119 
00120     for( i = 0; i < 16; i++ )
00121     {
00122         ctx->state [i + 16] = ctx->buffer [i];
00123         ctx->state [i + 32] =
00124             (unsigned char)( ctx->buffer [i] ^ ctx->state [i]);
00125     }
00126 
00127     for( i = 0; i < 18; i++ )
00128     {
00129         for( j = 0; j < 48; j++ )
00130         {
00131             ctx->state [j] = (unsigned char)
00132                ( ctx->state [j] ^ PI_SUBST[t] );
00133             t  = ctx->state [j];
00134         }
00135 
00136         t = (unsigned char)( t + i );
00137     }
00138 
00139     t = ctx->cksum [15];
00140 
00141     for( i = 0; i < 16; i++ )
00142     {
00143         ctx->cksum [i] = (unsigned char)
00144            ( ctx->cksum [i] ^ PI_SUBST[ctx->buffer [i] ^ t] );
00145         t  = ctx->cksum [i];
00146     }
00147 }
00148 
00149 /*
00150  * MD2 process buffer
00151  */
00152 void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen )
00153 {
00154     size_t fill;
00155 
00156     while( ilen > 0 )
00157     {
00158         if( ctx->left  + ilen > 16 )
00159             fill = 16 - ctx->left ;
00160         else
00161             fill = ilen;
00162 
00163         memcpy( ctx->buffer  + ctx->left , input, fill );
00164 
00165         ctx->left  += fill;
00166         input += fill;
00167         ilen  -= fill;
00168 
00169         if( ctx->left  == 16 )
00170         {
00171             ctx->left  = 0;
00172             md2_process( ctx );
00173         }
00174     }
00175 }
00176 
00177 /*
00178  * MD2 final digest
00179  */
00180 void md2_finish( md2_context *ctx, unsigned char output[16] )
00181 {
00182     size_t i;
00183     unsigned char x;
00184 
00185     x = (unsigned char)( 16 - ctx->left  );
00186 
00187     for( i = ctx->left ; i < 16; i++ )
00188         ctx->buffer [i] = x;
00189 
00190     md2_process( ctx );
00191 
00192     memcpy( ctx->buffer , ctx->cksum , 16 );
00193     md2_process( ctx );
00194 
00195     memcpy( output, ctx->state , 16 );
00196 }
00197 
00198 #endif /* !POLARSSL_MD2_ALT */
00199 
00200 /*
00201  * output = MD2( input buffer )
00202  */
00203 void md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
00204 {
00205     md2_context ctx;
00206 
00207     md2_init( &ctx );
00208     md2_starts( &ctx );
00209     md2_update( &ctx, input, ilen );
00210     md2_finish( &ctx, output );
00211     md2_free( &ctx );
00212 }
00213 
00214 #if defined(POLARSSL_FS_IO)
00215 /*
00216  * output = MD2( file contents )
00217  */
00218 int md2_file( const char *path, unsigned char output[16] )
00219 {
00220     FILE *f;
00221     size_t n;
00222     md2_context ctx;
00223     unsigned char buf[1024];
00224 
00225     if( ( f = fopen( path, "rb" ) ) == NULL )
00226         return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
00227 
00228     md2_init( &ctx );
00229     md2_starts( &ctx );
00230 
00231     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00232         md2_update( &ctx, buf, n );
00233 
00234     md2_finish( &ctx, output );
00235     md2_free( &ctx );
00236 
00237     if( ferror( f ) != 0 )
00238     {
00239         fclose( f );
00240         return( POLARSSL_ERR_MD2_FILE_IO_ERROR );
00241     }
00242 
00243     fclose( f );
00244     return( 0 );
00245 }
00246 #endif /* POLARSSL_FS_IO */
00247 
00248 /*
00249  * MD2 HMAC context setup
00250  */
00251 void md2_hmac_starts( md2_context *ctx, const unsigned char *key,
00252                       size_t keylen )
00253 {
00254     size_t i;
00255     unsigned char sum[16];
00256 
00257     if( keylen > 16 )
00258     {
00259         md2( key, keylen, sum );
00260         keylen = 16;
00261         key = sum;
00262     }
00263 
00264     memset( ctx->ipad , 0x36, 16 );
00265     memset( ctx->opad , 0x5C, 16 );
00266 
00267     for( i = 0; i < keylen; i++ )
00268     {
00269         ctx->ipad [i] = (unsigned char)( ctx->ipad [i] ^ key[i] );
00270         ctx->opad [i] = (unsigned char)( ctx->opad [i] ^ key[i] );
00271     }
00272 
00273     md2_starts( ctx );
00274     md2_update( ctx, ctx->ipad , 16 );
00275 
00276     polarssl_zeroize( sum, sizeof( sum ) );
00277 }
00278 
00279 /*
00280  * MD2 HMAC process buffer
00281  */
00282 void md2_hmac_update( md2_context *ctx, const unsigned char *input,
00283                       size_t ilen )
00284 {
00285     md2_update( ctx, input, ilen );
00286 }
00287 
00288 /*
00289  * MD2 HMAC final digest
00290  */
00291 void md2_hmac_finish( md2_context *ctx, unsigned char output[16] )
00292 {
00293     unsigned char tmpbuf[16];
00294 
00295     md2_finish( ctx, tmpbuf );
00296     md2_starts( ctx );
00297     md2_update( ctx, ctx->opad , 16 );
00298     md2_update( ctx, tmpbuf, 16 );
00299     md2_finish( ctx, output );
00300 
00301     polarssl_zeroize( tmpbuf, sizeof( tmpbuf ) );
00302 }
00303 
00304 /*
00305  * MD2 HMAC context reset
00306  */
00307 void md2_hmac_reset( md2_context *ctx )
00308 {
00309     md2_starts( ctx );
00310     md2_update( ctx, ctx->ipad , 16 );
00311 }
00312 
00313 /*
00314  * output = HMAC-MD2( hmac key, input buffer )
00315  */
00316 void md2_hmac( const unsigned char *key, size_t keylen,
00317                const unsigned char *input, size_t ilen,
00318                unsigned char output[16] )
00319 {
00320     md2_context ctx;
00321 
00322     md2_init( &ctx );
00323     md2_hmac_starts( &ctx, key, keylen );
00324     md2_hmac_update( &ctx, input, ilen );
00325     md2_hmac_finish( &ctx, output );
00326     md2_free( &ctx );
00327 }
00328 
00329 #if defined(POLARSSL_SELF_TEST)
00330 
00331 /*
00332  * RFC 1319 test vectors
00333  */
00334 static const char md2_test_str[7][81] =
00335 {
00336     { "" },
00337     { "a" },
00338     { "abc" },
00339     { "message digest" },
00340     { "abcdefghijklmnopqrstuvwxyz" },
00341     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
00342     { "12345678901234567890123456789012345678901234567890123456789012" \
00343       "345678901234567890" }
00344 };
00345 
00346 static const unsigned char md2_test_sum[7][16] =
00347 {
00348     { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
00349       0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
00350     { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
00351       0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
00352     { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
00353       0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
00354     { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
00355       0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
00356     { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
00357       0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
00358     { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
00359       0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
00360     { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
00361       0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
00362 };
00363 
00364 /*
00365  * Checkup routine
00366  */
00367 int md2_self_test( int verbose )
00368 {
00369     int i;
00370     unsigned char md2sum[16];
00371 
00372     for( i = 0; i < 7; i++ )
00373     {
00374         if( verbose != 0 )
00375             polarssl_printf( "  MD2 test #%d: ", i + 1 );
00376 
00377         md2( (unsigned char *) md2_test_str[i],
00378              strlen( md2_test_str[i] ), md2sum );
00379 
00380         if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
00381         {
00382             if( verbose != 0 )
00383                 polarssl_printf( "failed\n" );
00384 
00385             return( 1 );
00386         }
00387 
00388         if( verbose != 0 )
00389             polarssl_printf( "passed\n" );
00390     }
00391 
00392     if( verbose != 0 )
00393         polarssl_printf( "\n" );
00394 
00395     return( 0 );
00396 }
00397 
00398 #endif /* POLARSSL_SELF_TEST */
00399 
00400 #endif /* POLARSSL_MD2_C */
00401