Nicolas Borla / Mbed OS BBR_1Ebene
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-2015, ARM Limited, All Rights Reserved
00005  *  SPDX-License-Identifier: Apache-2.0
00006  *
00007  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
00008  *  not use this file except in compliance with the License.
00009  *  You may obtain a copy of the License at
00010  *
00011  *  http://www.apache.org/licenses/LICENSE-2.0
00012  *
00013  *  Unless required by applicable law or agreed to in writing, software
00014  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
00015  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00016  *  See the License for the specific language governing permissions and
00017  *  limitations under the License.
00018  *
00019  *  This file is part of mbed TLS (https://tls.mbed.org)
00020  */
00021 /*
00022  *  The MD2 algorithm was designed by Ron Rivest in 1989.
00023  *
00024  *  http://www.ietf.org/rfc/rfc1115.txt
00025  *  http://www.ietf.org/rfc/rfc1319.txt
00026  */
00027 
00028 #if !defined(MBEDTLS_CONFIG_FILE)
00029 #include "mbedtls/config.h"
00030 #else
00031 #include MBEDTLS_CONFIG_FILE
00032 #endif
00033 
00034 #if defined(MBEDTLS_MD2_C)
00035 
00036 #include "mbedtls/md2.h"
00037 
00038 #include <string.h>
00039 
00040 #if defined(MBEDTLS_SELF_TEST)
00041 #if defined(MBEDTLS_PLATFORM_C)
00042 #include "mbedtls/platform.h"
00043 #else
00044 #include <stdio.h>
00045 #define mbedtls_printf printf
00046 #endif /* MBEDTLS_PLATFORM_C */
00047 #endif /* MBEDTLS_SELF_TEST */
00048 
00049 #if !defined(MBEDTLS_MD2_ALT)
00050 
00051 /* Implementation that should never be optimized out by the compiler */
00052 static void mbedtls_zeroize( void *v, size_t n ) {
00053     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00054 }
00055 
00056 static const unsigned char PI_SUBST[256] =
00057 {
00058     0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
00059     0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
00060     0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
00061     0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
00062     0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
00063     0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
00064     0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
00065     0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
00066     0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
00067     0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
00068     0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
00069     0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
00070     0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
00071     0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
00072     0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
00073     0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
00074     0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
00075     0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
00076     0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
00077     0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
00078     0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
00079     0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
00080     0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
00081     0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
00082     0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
00083     0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
00084 };
00085 
00086 void mbedtls_md2_init( mbedtls_md2_context *ctx )
00087 {
00088     memset( ctx, 0, sizeof( mbedtls_md2_context ) );
00089 }
00090 
00091 void mbedtls_md2_free( mbedtls_md2_context *ctx )
00092 {
00093     if( ctx == NULL )
00094         return;
00095 
00096     mbedtls_zeroize( ctx, sizeof( mbedtls_md2_context ) );
00097 }
00098 
00099 void mbedtls_md2_clone( mbedtls_md2_context *dst,
00100                         const mbedtls_md2_context *src )
00101 {
00102     *dst = *src;
00103 }
00104 
00105 /*
00106  * MD2 context setup
00107  */
00108 int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx )
00109 {
00110     memset( ctx->cksum , 0, 16 );
00111     memset( ctx->state , 0, 46 );
00112     memset( ctx->buffer , 0, 16 );
00113     ctx->left  = 0;
00114 
00115     return( 0 );
00116 }
00117 
00118 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00119 void mbedtls_md2_starts( mbedtls_md2_context *ctx )
00120 {
00121     mbedtls_md2_starts_ret( ctx );
00122 }
00123 #endif
00124 
00125 #if !defined(MBEDTLS_MD2_PROCESS_ALT)
00126 int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
00127 {
00128     int i, j;
00129     unsigned char t = 0;
00130 
00131     for( i = 0; i < 16; i++ )
00132     {
00133         ctx->state [i + 16] = ctx->buffer [i];
00134         ctx->state [i + 32] =
00135             (unsigned char)( ctx->buffer [i] ^ ctx->state [i]);
00136     }
00137 
00138     for( i = 0; i < 18; i++ )
00139     {
00140         for( j = 0; j < 48; j++ )
00141         {
00142             ctx->state [j] = (unsigned char)
00143                ( ctx->state [j] ^ PI_SUBST[t] );
00144             t  = ctx->state [j];
00145         }
00146 
00147         t = (unsigned char)( t + i );
00148     }
00149 
00150     t = ctx->cksum [15];
00151 
00152     for( i = 0; i < 16; i++ )
00153     {
00154         ctx->cksum [i] = (unsigned char)
00155            ( ctx->cksum [i] ^ PI_SUBST[ctx->buffer [i] ^ t] );
00156         t  = ctx->cksum [i];
00157     }
00158 
00159     return( 0 );
00160 }
00161 
00162 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00163 void mbedtls_md2_process( mbedtls_md2_context *ctx )
00164 {
00165     mbedtls_internal_md2_process( ctx );
00166 }
00167 #endif
00168 #endif /* !MBEDTLS_MD2_PROCESS_ALT */
00169 
00170 /*
00171  * MD2 process buffer
00172  */
00173 int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
00174                             const unsigned char *input,
00175                             size_t ilen )
00176 {
00177     int ret;
00178     size_t fill;
00179 
00180     while( ilen > 0 )
00181     {
00182         if( ilen > 16 - ctx->left  )
00183             fill = 16 - ctx->left ;
00184         else
00185             fill = ilen;
00186 
00187         memcpy( ctx->buffer  + ctx->left , input, fill );
00188 
00189         ctx->left  += fill;
00190         input += fill;
00191         ilen  -= fill;
00192 
00193         if( ctx->left  == 16 )
00194         {
00195             ctx->left  = 0;
00196             if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
00197                 return( ret );
00198         }
00199     }
00200 
00201     return( 0 );
00202 }
00203 
00204 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00205 void mbedtls_md2_update( mbedtls_md2_context *ctx,
00206                          const unsigned char *input,
00207                          size_t ilen )
00208 {
00209     mbedtls_md2_update_ret( ctx, input, ilen );
00210 }
00211 #endif
00212 
00213 /*
00214  * MD2 final digest
00215  */
00216 int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
00217                             unsigned char output[16] )
00218 {
00219     int ret;
00220     size_t i;
00221     unsigned char x;
00222 
00223     x = (unsigned char)( 16 - ctx->left  );
00224 
00225     for( i = ctx->left ; i < 16; i++ )
00226         ctx->buffer [i] = x;
00227 
00228     if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
00229         return( ret );
00230 
00231     memcpy( ctx->buffer , ctx->cksum , 16 );
00232     if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
00233         return( ret );
00234 
00235     memcpy( output, ctx->state , 16 );
00236 
00237     return( 0 );
00238 }
00239 
00240 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00241 void mbedtls_md2_finish( mbedtls_md2_context *ctx,
00242                          unsigned char output[16] )
00243 {
00244     mbedtls_md2_finish_ret( ctx, output );
00245 }
00246 #endif
00247 
00248 #endif /* !MBEDTLS_MD2_ALT */
00249 
00250 /*
00251  * output = MD2( input buffer )
00252  */
00253 int mbedtls_md2_ret( const unsigned char *input,
00254                      size_t ilen,
00255                      unsigned char output[16] )
00256 {
00257     int ret;
00258     mbedtls_md2_context ctx;
00259 
00260     mbedtls_md2_init( &ctx );
00261 
00262     if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 )
00263         goto exit;
00264 
00265     if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 )
00266         goto exit;
00267 
00268     if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 )
00269         goto exit;
00270 
00271 exit:
00272     mbedtls_md2_free( &ctx );
00273 
00274     return( ret );
00275 }
00276 
00277 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
00278 void mbedtls_md2( const unsigned char *input,
00279                   size_t ilen,
00280                   unsigned char output[16] )
00281 {
00282     mbedtls_md2_ret( input, ilen, output );
00283 }
00284 #endif
00285 
00286 #if defined(MBEDTLS_SELF_TEST)
00287 
00288 /*
00289  * RFC 1319 test vectors
00290  */
00291 static const unsigned char md2_test_str[7][81] =
00292 {
00293     { "" },
00294     { "a" },
00295     { "abc" },
00296     { "message digest" },
00297     { "abcdefghijklmnopqrstuvwxyz" },
00298     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
00299     { "12345678901234567890123456789012345678901234567890123456789012"
00300       "345678901234567890" }
00301 };
00302 
00303 static const size_t md2_test_strlen[7] =
00304 {
00305     0, 1, 3, 14, 26, 62, 80
00306 };
00307 
00308 static const unsigned char md2_test_sum[7][16] =
00309 {
00310     { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
00311       0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
00312     { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
00313       0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
00314     { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
00315       0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
00316     { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
00317       0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
00318     { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
00319       0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
00320     { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
00321       0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
00322     { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
00323       0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
00324 };
00325 
00326 /*
00327  * Checkup routine
00328  */
00329 int mbedtls_md2_self_test( int verbose )
00330 {
00331     int i, ret = 0;
00332     unsigned char md2sum[16];
00333 
00334     for( i = 0; i < 7; i++ )
00335     {
00336         if( verbose != 0 )
00337             mbedtls_printf( "  MD2 test #%d: ", i + 1 );
00338 
00339         ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum );
00340         if( ret != 0 )
00341             goto fail;
00342 
00343         if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
00344         {
00345             ret = 1;
00346             goto fail;
00347         }
00348 
00349         if( verbose != 0 )
00350             mbedtls_printf( "passed\n" );
00351     }
00352 
00353     if( verbose != 0 )
00354         mbedtls_printf( "\n" );
00355 
00356     return( 0 );
00357 
00358 fail:
00359     if( verbose != 0 )
00360         mbedtls_printf( "failed\n" );
00361 
00362     return( ret );
00363 }
00364 
00365 #endif /* MBEDTLS_SELF_TEST */
00366 
00367 #endif /* MBEDTLS_MD2_C */