mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

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 void mbedtls_md2_starts( 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 
00116 #if !defined(MBEDTLS_MD2_PROCESS_ALT)
00117 void mbedtls_md2_process( mbedtls_md2_context *ctx )
00118 {
00119     int i, j;
00120     unsigned char t = 0;
00121 
00122     for( i = 0; i < 16; i++ )
00123     {
00124         ctx->state [i + 16] = ctx->buffer [i];
00125         ctx->state [i + 32] =
00126             (unsigned char)( ctx->buffer [i] ^ ctx->state [i]);
00127     }
00128 
00129     for( i = 0; i < 18; i++ )
00130     {
00131         for( j = 0; j < 48; j++ )
00132         {
00133             ctx->state [j] = (unsigned char)
00134                ( ctx->state [j] ^ PI_SUBST[t] );
00135             t  = ctx->state [j];
00136         }
00137 
00138         t = (unsigned char)( t + i );
00139     }
00140 
00141     t = ctx->cksum [15];
00142 
00143     for( i = 0; i < 16; i++ )
00144     {
00145         ctx->cksum [i] = (unsigned char)
00146            ( ctx->cksum [i] ^ PI_SUBST[ctx->buffer [i] ^ t] );
00147         t  = ctx->cksum [i];
00148     }
00149 }
00150 #endif /* !MBEDTLS_MD2_PROCESS_ALT */
00151 
00152 /*
00153  * MD2 process buffer
00154  */
00155 void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, size_t ilen )
00156 {
00157     size_t fill;
00158 
00159     while( ilen > 0 )
00160     {
00161         if( ctx->left  + ilen > 16 )
00162             fill = 16 - ctx->left ;
00163         else
00164             fill = ilen;
00165 
00166         memcpy( ctx->buffer  + ctx->left , input, fill );
00167 
00168         ctx->left  += fill;
00169         input += fill;
00170         ilen  -= fill;
00171 
00172         if( ctx->left  == 16 )
00173         {
00174             ctx->left  = 0;
00175             mbedtls_md2_process( ctx );
00176         }
00177     }
00178 }
00179 
00180 /*
00181  * MD2 final digest
00182  */
00183 void mbedtls_md2_finish( mbedtls_md2_context *ctx, unsigned char output[16] )
00184 {
00185     size_t i;
00186     unsigned char x;
00187 
00188     x = (unsigned char)( 16 - ctx->left  );
00189 
00190     for( i = ctx->left ; i < 16; i++ )
00191         ctx->buffer [i] = x;
00192 
00193     mbedtls_md2_process( ctx );
00194 
00195     memcpy( ctx->buffer , ctx->cksum , 16 );
00196     mbedtls_md2_process( ctx );
00197 
00198     memcpy( output, ctx->state , 16 );
00199 }
00200 
00201 #endif /* !MBEDTLS_MD2_ALT */
00202 
00203 /*
00204  * output = MD2( input buffer )
00205  */
00206 void mbedtls_md2( const unsigned char *input, size_t ilen, unsigned char output[16] )
00207 {
00208     mbedtls_md2_context ctx;
00209 
00210     mbedtls_md2_init( &ctx );
00211     mbedtls_md2_starts( &ctx );
00212     mbedtls_md2_update( &ctx, input, ilen );
00213     mbedtls_md2_finish( &ctx, output );
00214     mbedtls_md2_free( &ctx );
00215 }
00216 
00217 #if defined(MBEDTLS_SELF_TEST)
00218 
00219 /*
00220  * RFC 1319 test vectors
00221  */
00222 static const char md2_test_str[7][81] =
00223 {
00224     { "" },
00225     { "a" },
00226     { "abc" },
00227     { "message digest" },
00228     { "abcdefghijklmnopqrstuvwxyz" },
00229     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
00230     { "12345678901234567890123456789012345678901234567890123456789012" \
00231       "345678901234567890" }
00232 };
00233 
00234 static const unsigned char md2_test_sum[7][16] =
00235 {
00236     { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
00237       0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
00238     { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
00239       0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
00240     { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
00241       0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
00242     { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
00243       0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
00244     { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
00245       0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
00246     { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
00247       0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
00248     { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
00249       0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
00250 };
00251 
00252 /*
00253  * Checkup routine
00254  */
00255 int mbedtls_md2_self_test( int verbose )
00256 {
00257     int i;
00258     unsigned char md2sum[16];
00259 
00260     for( i = 0; i < 7; i++ )
00261     {
00262         if( verbose != 0 )
00263             mbedtls_printf( "  MD2 test #%d: ", i + 1 );
00264 
00265         mbedtls_md2( (unsigned char *) md2_test_str[i],
00266              strlen( md2_test_str[i] ), md2sum );
00267 
00268         if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
00269         {
00270             if( verbose != 0 )
00271                 mbedtls_printf( "failed\n" );
00272 
00273             return( 1 );
00274         }
00275 
00276         if( verbose != 0 )
00277             mbedtls_printf( "passed\n" );
00278     }
00279 
00280     if( verbose != 0 )
00281         mbedtls_printf( "\n" );
00282 
00283     return( 0 );
00284 }
00285 
00286 #endif /* MBEDTLS_SELF_TEST */
00287 
00288 #endif /* MBEDTLS_MD2_C */