mbed TLS Build
Dependents: Encypting_Funcional
md4.c
00001 /* 00002 * RFC 1186/1320 compliant MD4 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 MD4 algorithm was designed by Ron Rivest in 1990. 00023 * 00024 * http://www.ietf.org/rfc/rfc1186.txt 00025 * http://www.ietf.org/rfc/rfc1320.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_MD4_C) 00035 00036 #include "mbedtls/md4.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_MD4_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 /* 00057 * 32-bit integer manipulation macros (little endian) 00058 */ 00059 #ifndef GET_UINT32_LE 00060 #define GET_UINT32_LE(n,b,i) \ 00061 { \ 00062 (n) = ( (uint32_t) (b)[(i) ] ) \ 00063 | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 00064 | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 00065 | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 00066 } 00067 #endif 00068 00069 #ifndef PUT_UINT32_LE 00070 #define PUT_UINT32_LE(n,b,i) \ 00071 { \ 00072 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ 00073 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ 00074 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ 00075 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ 00076 } 00077 #endif 00078 00079 void mbedtls_md4_init( mbedtls_md4_context *ctx ) 00080 { 00081 memset( ctx, 0, sizeof( mbedtls_md4_context ) ); 00082 } 00083 00084 void mbedtls_md4_free( mbedtls_md4_context *ctx ) 00085 { 00086 if( ctx == NULL ) 00087 return; 00088 00089 mbedtls_zeroize( ctx, sizeof( mbedtls_md4_context ) ); 00090 } 00091 00092 void mbedtls_md4_clone( mbedtls_md4_context *dst, 00093 const mbedtls_md4_context *src ) 00094 { 00095 *dst = *src; 00096 } 00097 00098 /* 00099 * MD4 context setup 00100 */ 00101 void mbedtls_md4_starts( mbedtls_md4_context *ctx ) 00102 { 00103 ctx->total [0] = 0; 00104 ctx->total [1] = 0; 00105 00106 ctx->state [0] = 0x67452301; 00107 ctx->state [1] = 0xEFCDAB89; 00108 ctx->state [2] = 0x98BADCFE; 00109 ctx->state [3] = 0x10325476; 00110 } 00111 00112 #if !defined(MBEDTLS_MD4_PROCESS_ALT) 00113 void mbedtls_md4_process( mbedtls_md4_context *ctx, const unsigned char data[64] ) 00114 { 00115 uint32_t X[16], A, B, C, D; 00116 00117 GET_UINT32_LE( X[ 0], data, 0 ); 00118 GET_UINT32_LE( X[ 1], data, 4 ); 00119 GET_UINT32_LE( X[ 2], data, 8 ); 00120 GET_UINT32_LE( X[ 3], data, 12 ); 00121 GET_UINT32_LE( X[ 4], data, 16 ); 00122 GET_UINT32_LE( X[ 5], data, 20 ); 00123 GET_UINT32_LE( X[ 6], data, 24 ); 00124 GET_UINT32_LE( X[ 7], data, 28 ); 00125 GET_UINT32_LE( X[ 8], data, 32 ); 00126 GET_UINT32_LE( X[ 9], data, 36 ); 00127 GET_UINT32_LE( X[10], data, 40 ); 00128 GET_UINT32_LE( X[11], data, 44 ); 00129 GET_UINT32_LE( X[12], data, 48 ); 00130 GET_UINT32_LE( X[13], data, 52 ); 00131 GET_UINT32_LE( X[14], data, 56 ); 00132 GET_UINT32_LE( X[15], data, 60 ); 00133 00134 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 00135 00136 A = ctx->state [0]; 00137 B = ctx->state [1]; 00138 C = ctx->state [2]; 00139 D = ctx->state [3]; 00140 00141 #define F(x, y, z) ((x & y) | ((~x) & z)) 00142 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } 00143 00144 P( A, B, C, D, X[ 0], 3 ); 00145 P( D, A, B, C, X[ 1], 7 ); 00146 P( C, D, A, B, X[ 2], 11 ); 00147 P( B, C, D, A, X[ 3], 19 ); 00148 P( A, B, C, D, X[ 4], 3 ); 00149 P( D, A, B, C, X[ 5], 7 ); 00150 P( C, D, A, B, X[ 6], 11 ); 00151 P( B, C, D, A, X[ 7], 19 ); 00152 P( A, B, C, D, X[ 8], 3 ); 00153 P( D, A, B, C, X[ 9], 7 ); 00154 P( C, D, A, B, X[10], 11 ); 00155 P( B, C, D, A, X[11], 19 ); 00156 P( A, B, C, D, X[12], 3 ); 00157 P( D, A, B, C, X[13], 7 ); 00158 P( C, D, A, B, X[14], 11 ); 00159 P( B, C, D, A, X[15], 19 ); 00160 00161 #undef P 00162 #undef F 00163 00164 #define F(x,y,z) ((x & y) | (x & z) | (y & z)) 00165 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } 00166 00167 P( A, B, C, D, X[ 0], 3 ); 00168 P( D, A, B, C, X[ 4], 5 ); 00169 P( C, D, A, B, X[ 8], 9 ); 00170 P( B, C, D, A, X[12], 13 ); 00171 P( A, B, C, D, X[ 1], 3 ); 00172 P( D, A, B, C, X[ 5], 5 ); 00173 P( C, D, A, B, X[ 9], 9 ); 00174 P( B, C, D, A, X[13], 13 ); 00175 P( A, B, C, D, X[ 2], 3 ); 00176 P( D, A, B, C, X[ 6], 5 ); 00177 P( C, D, A, B, X[10], 9 ); 00178 P( B, C, D, A, X[14], 13 ); 00179 P( A, B, C, D, X[ 3], 3 ); 00180 P( D, A, B, C, X[ 7], 5 ); 00181 P( C, D, A, B, X[11], 9 ); 00182 P( B, C, D, A, X[15], 13 ); 00183 00184 #undef P 00185 #undef F 00186 00187 #define F(x,y,z) (x ^ y ^ z) 00188 #define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } 00189 00190 P( A, B, C, D, X[ 0], 3 ); 00191 P( D, A, B, C, X[ 8], 9 ); 00192 P( C, D, A, B, X[ 4], 11 ); 00193 P( B, C, D, A, X[12], 15 ); 00194 P( A, B, C, D, X[ 2], 3 ); 00195 P( D, A, B, C, X[10], 9 ); 00196 P( C, D, A, B, X[ 6], 11 ); 00197 P( B, C, D, A, X[14], 15 ); 00198 P( A, B, C, D, X[ 1], 3 ); 00199 P( D, A, B, C, X[ 9], 9 ); 00200 P( C, D, A, B, X[ 5], 11 ); 00201 P( B, C, D, A, X[13], 15 ); 00202 P( A, B, C, D, X[ 3], 3 ); 00203 P( D, A, B, C, X[11], 9 ); 00204 P( C, D, A, B, X[ 7], 11 ); 00205 P( B, C, D, A, X[15], 15 ); 00206 00207 #undef F 00208 #undef P 00209 00210 ctx->state [0] += A; 00211 ctx->state [1] += B; 00212 ctx->state [2] += C; 00213 ctx->state [3] += D; 00214 } 00215 #endif /* !MBEDTLS_MD4_PROCESS_ALT */ 00216 00217 /* 00218 * MD4 process buffer 00219 */ 00220 void mbedtls_md4_update( mbedtls_md4_context *ctx, const unsigned char *input, size_t ilen ) 00221 { 00222 size_t fill; 00223 uint32_t left; 00224 00225 if( ilen == 0 ) 00226 return; 00227 00228 left = ctx->total [0] & 0x3F; 00229 fill = 64 - left; 00230 00231 ctx->total [0] += (uint32_t) ilen; 00232 ctx->total [0] &= 0xFFFFFFFF; 00233 00234 if( ctx->total [0] < (uint32_t) ilen ) 00235 ctx->total [1]++; 00236 00237 if( left && ilen >= fill ) 00238 { 00239 memcpy( (void *) (ctx->buffer + left), 00240 (void *) input, fill ); 00241 mbedtls_md4_process( ctx, ctx->buffer ); 00242 input += fill; 00243 ilen -= fill; 00244 left = 0; 00245 } 00246 00247 while( ilen >= 64 ) 00248 { 00249 mbedtls_md4_process( ctx, input ); 00250 input += 64; 00251 ilen -= 64; 00252 } 00253 00254 if( ilen > 0 ) 00255 { 00256 memcpy( (void *) (ctx->buffer + left), 00257 (void *) input, ilen ); 00258 } 00259 } 00260 00261 static const unsigned char md4_padding[64] = 00262 { 00263 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00264 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00265 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00266 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00267 }; 00268 00269 /* 00270 * MD4 final digest 00271 */ 00272 void mbedtls_md4_finish( mbedtls_md4_context *ctx, unsigned char output[16] ) 00273 { 00274 uint32_t last, padn; 00275 uint32_t high, low; 00276 unsigned char msglen[8]; 00277 00278 high = ( ctx->total [0] >> 29 ) 00279 | ( ctx->total [1] << 3 ); 00280 low = ( ctx->total [0] << 3 ); 00281 00282 PUT_UINT32_LE( low, msglen, 0 ); 00283 PUT_UINT32_LE( high, msglen, 4 ); 00284 00285 last = ctx->total [0] & 0x3F; 00286 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 00287 00288 mbedtls_md4_update( ctx, (unsigned char *) md4_padding, padn ); 00289 mbedtls_md4_update( ctx, msglen, 8 ); 00290 00291 PUT_UINT32_LE( ctx->state [0], output, 0 ); 00292 PUT_UINT32_LE( ctx->state [1], output, 4 ); 00293 PUT_UINT32_LE( ctx->state [2], output, 8 ); 00294 PUT_UINT32_LE( ctx->state [3], output, 12 ); 00295 } 00296 00297 #endif /* !MBEDTLS_MD4_ALT */ 00298 00299 /* 00300 * output = MD4( input buffer ) 00301 */ 00302 void mbedtls_md4( const unsigned char *input, size_t ilen, unsigned char output[16] ) 00303 { 00304 mbedtls_md4_context ctx; 00305 00306 mbedtls_md4_init( &ctx ); 00307 mbedtls_md4_starts( &ctx ); 00308 mbedtls_md4_update( &ctx, input, ilen ); 00309 mbedtls_md4_finish( &ctx, output ); 00310 mbedtls_md4_free( &ctx ); 00311 } 00312 00313 #if defined(MBEDTLS_SELF_TEST) 00314 00315 /* 00316 * RFC 1320 test vectors 00317 */ 00318 static const char md4_test_str[7][81] = 00319 { 00320 { "" }, 00321 { "a" }, 00322 { "abc" }, 00323 { "message digest" }, 00324 { "abcdefghijklmnopqrstuvwxyz" }, 00325 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 00326 { "12345678901234567890123456789012345678901234567890123456789012" \ 00327 "345678901234567890" } 00328 }; 00329 00330 static const unsigned char md4_test_sum[7][16] = 00331 { 00332 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, 00333 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, 00334 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, 00335 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, 00336 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, 00337 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, 00338 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, 00339 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, 00340 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, 00341 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, 00342 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, 00343 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, 00344 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, 00345 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } 00346 }; 00347 00348 /* 00349 * Checkup routine 00350 */ 00351 int mbedtls_md4_self_test( int verbose ) 00352 { 00353 int i; 00354 unsigned char md4sum[16]; 00355 00356 for( i = 0; i < 7; i++ ) 00357 { 00358 if( verbose != 0 ) 00359 mbedtls_printf( " MD4 test #%d: ", i + 1 ); 00360 00361 mbedtls_md4( (unsigned char *) md4_test_str[i], 00362 strlen( md4_test_str[i] ), md4sum ); 00363 00364 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) 00365 { 00366 if( verbose != 0 ) 00367 mbedtls_printf( "failed\n" ); 00368 00369 return( 1 ); 00370 } 00371 00372 if( verbose != 0 ) 00373 mbedtls_printf( "passed\n" ); 00374 } 00375 00376 if( verbose != 0 ) 00377 mbedtls_printf( "\n" ); 00378 00379 return( 0 ); 00380 } 00381 00382 #endif /* MBEDTLS_SELF_TEST */ 00383 00384 #endif /* MBEDTLS_MD4_C */
Generated on Wed Jul 13 2022 20:34:20 by 1.7.2