Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

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