Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
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 #include "mbedtls/platform_util.h" 00038 00039 #include <string.h> 00040 00041 #if defined(MBEDTLS_SELF_TEST) 00042 #if defined(MBEDTLS_PLATFORM_C) 00043 #include "mbedtls/platform.h" 00044 #else 00045 #include <stdio.h> 00046 #define mbedtls_printf printf 00047 #endif /* MBEDTLS_PLATFORM_C */ 00048 #endif /* MBEDTLS_SELF_TEST */ 00049 00050 #if !defined(MBEDTLS_MD4_ALT) 00051 00052 /* 00053 * 32-bit integer manipulation macros (little endian) 00054 */ 00055 #ifndef GET_UINT32_LE 00056 #define GET_UINT32_LE(n,b,i) \ 00057 { \ 00058 (n) = ( (uint32_t) (b)[(i) ] ) \ 00059 | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 00060 | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 00061 | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 00062 } 00063 #endif 00064 00065 #ifndef PUT_UINT32_LE 00066 #define PUT_UINT32_LE(n,b,i) \ 00067 { \ 00068 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ 00069 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ 00070 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ 00071 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ 00072 } 00073 #endif 00074 00075 void mbedtls_md4_init( mbedtls_md4_context *ctx ) 00076 { 00077 memset( ctx, 0, sizeof( mbedtls_md4_context ) ); 00078 } 00079 00080 void mbedtls_md4_free( mbedtls_md4_context *ctx ) 00081 { 00082 if( ctx == NULL ) 00083 return; 00084 00085 mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md4_context ) ); 00086 } 00087 00088 void mbedtls_md4_clone( mbedtls_md4_context *dst, 00089 const mbedtls_md4_context *src ) 00090 { 00091 *dst = *src; 00092 } 00093 00094 /* 00095 * MD4 context setup 00096 */ 00097 int mbedtls_md4_starts_ret( mbedtls_md4_context *ctx ) 00098 { 00099 ctx->total [0] = 0; 00100 ctx->total [1] = 0; 00101 00102 ctx->state [0] = 0x67452301; 00103 ctx->state [1] = 0xEFCDAB89; 00104 ctx->state [2] = 0x98BADCFE; 00105 ctx->state [3] = 0x10325476; 00106 00107 return( 0 ); 00108 } 00109 00110 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00111 void mbedtls_md4_starts( mbedtls_md4_context *ctx ) 00112 { 00113 mbedtls_md4_starts_ret( ctx ); 00114 } 00115 #endif 00116 00117 #if !defined(MBEDTLS_MD4_PROCESS_ALT) 00118 int mbedtls_internal_md4_process( mbedtls_md4_context *ctx, 00119 const unsigned char data[64] ) 00120 { 00121 uint32_t X[16], A, B, C, D; 00122 00123 GET_UINT32_LE( X[ 0], data, 0 ); 00124 GET_UINT32_LE( X[ 1], data, 4 ); 00125 GET_UINT32_LE( X[ 2], data, 8 ); 00126 GET_UINT32_LE( X[ 3], data, 12 ); 00127 GET_UINT32_LE( X[ 4], data, 16 ); 00128 GET_UINT32_LE( X[ 5], data, 20 ); 00129 GET_UINT32_LE( X[ 6], data, 24 ); 00130 GET_UINT32_LE( X[ 7], data, 28 ); 00131 GET_UINT32_LE( X[ 8], data, 32 ); 00132 GET_UINT32_LE( X[ 9], data, 36 ); 00133 GET_UINT32_LE( X[10], data, 40 ); 00134 GET_UINT32_LE( X[11], data, 44 ); 00135 GET_UINT32_LE( X[12], data, 48 ); 00136 GET_UINT32_LE( X[13], data, 52 ); 00137 GET_UINT32_LE( X[14], data, 56 ); 00138 GET_UINT32_LE( X[15], data, 60 ); 00139 00140 #define S(x,n) (((x) << (n)) | (((x) & 0xFFFFFFFF) >> (32 - (n)))) 00141 00142 A = ctx->state [0]; 00143 B = ctx->state [1]; 00144 C = ctx->state [2]; 00145 D = ctx->state [3]; 00146 00147 #define F(x, y, z) (((x) & (y)) | ((~(x)) & (z))) 00148 #define P(a,b,c,d,x,s) \ 00149 do \ 00150 { \ 00151 (a) += F((b),(c),(d)) + (x); \ 00152 (a) = S((a),(s)); \ 00153 } while( 0 ) 00154 00155 00156 P( A, B, C, D, X[ 0], 3 ); 00157 P( D, A, B, C, X[ 1], 7 ); 00158 P( C, D, A, B, X[ 2], 11 ); 00159 P( B, C, D, A, X[ 3], 19 ); 00160 P( A, B, C, D, X[ 4], 3 ); 00161 P( D, A, B, C, X[ 5], 7 ); 00162 P( C, D, A, B, X[ 6], 11 ); 00163 P( B, C, D, A, X[ 7], 19 ); 00164 P( A, B, C, D, X[ 8], 3 ); 00165 P( D, A, B, C, X[ 9], 7 ); 00166 P( C, D, A, B, X[10], 11 ); 00167 P( B, C, D, A, X[11], 19 ); 00168 P( A, B, C, D, X[12], 3 ); 00169 P( D, A, B, C, X[13], 7 ); 00170 P( C, D, A, B, X[14], 11 ); 00171 P( B, C, D, A, X[15], 19 ); 00172 00173 #undef P 00174 #undef F 00175 00176 #define F(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) 00177 #define P(a,b,c,d,x,s) \ 00178 do \ 00179 { \ 00180 (a) += F((b),(c),(d)) + (x) + 0x5A827999; \ 00181 (a) = S((a),(s)); \ 00182 } while( 0 ) 00183 00184 P( A, B, C, D, X[ 0], 3 ); 00185 P( D, A, B, C, X[ 4], 5 ); 00186 P( C, D, A, B, X[ 8], 9 ); 00187 P( B, C, D, A, X[12], 13 ); 00188 P( A, B, C, D, X[ 1], 3 ); 00189 P( D, A, B, C, X[ 5], 5 ); 00190 P( C, D, A, B, X[ 9], 9 ); 00191 P( B, C, D, A, X[13], 13 ); 00192 P( A, B, C, D, X[ 2], 3 ); 00193 P( D, A, B, C, X[ 6], 5 ); 00194 P( C, D, A, B, X[10], 9 ); 00195 P( B, C, D, A, X[14], 13 ); 00196 P( A, B, C, D, X[ 3], 3 ); 00197 P( D, A, B, C, X[ 7], 5 ); 00198 P( C, D, A, B, X[11], 9 ); 00199 P( B, C, D, A, X[15], 13 ); 00200 00201 #undef P 00202 #undef F 00203 00204 #define F(x,y,z) ((x) ^ (y) ^ (z)) 00205 #define P(a,b,c,d,x,s) \ 00206 do \ 00207 { \ 00208 (a) += F((b),(c),(d)) + (x) + 0x6ED9EBA1; \ 00209 (a) = S((a),(s)); \ 00210 } while( 0 ) 00211 00212 P( A, B, C, D, X[ 0], 3 ); 00213 P( D, A, B, C, X[ 8], 9 ); 00214 P( C, D, A, B, X[ 4], 11 ); 00215 P( B, C, D, A, X[12], 15 ); 00216 P( A, B, C, D, X[ 2], 3 ); 00217 P( D, A, B, C, X[10], 9 ); 00218 P( C, D, A, B, X[ 6], 11 ); 00219 P( B, C, D, A, X[14], 15 ); 00220 P( A, B, C, D, X[ 1], 3 ); 00221 P( D, A, B, C, X[ 9], 9 ); 00222 P( C, D, A, B, X[ 5], 11 ); 00223 P( B, C, D, A, X[13], 15 ); 00224 P( A, B, C, D, X[ 3], 3 ); 00225 P( D, A, B, C, X[11], 9 ); 00226 P( C, D, A, B, X[ 7], 11 ); 00227 P( B, C, D, A, X[15], 15 ); 00228 00229 #undef F 00230 #undef P 00231 00232 ctx->state [0] += A; 00233 ctx->state [1] += B; 00234 ctx->state [2] += C; 00235 ctx->state [3] += D; 00236 00237 return( 0 ); 00238 } 00239 00240 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00241 void mbedtls_md4_process( mbedtls_md4_context *ctx, 00242 const unsigned char data[64] ) 00243 { 00244 mbedtls_internal_md4_process( ctx, data ); 00245 } 00246 #endif 00247 #endif /* !MBEDTLS_MD4_PROCESS_ALT */ 00248 00249 /* 00250 * MD4 process buffer 00251 */ 00252 int mbedtls_md4_update_ret( mbedtls_md4_context *ctx, 00253 const unsigned char *input, 00254 size_t ilen ) 00255 { 00256 int ret; 00257 size_t fill; 00258 uint32_t left; 00259 00260 if( ilen == 0 ) 00261 return( 0 ); 00262 00263 left = ctx->total [0] & 0x3F; 00264 fill = 64 - left; 00265 00266 ctx->total [0] += (uint32_t) ilen; 00267 ctx->total [0] &= 0xFFFFFFFF; 00268 00269 if( ctx->total [0] < (uint32_t) ilen ) 00270 ctx->total [1]++; 00271 00272 if( left && ilen >= fill ) 00273 { 00274 memcpy( (void *) (ctx->buffer + left), 00275 (void *) input, fill ); 00276 00277 if( ( ret = mbedtls_internal_md4_process( ctx, ctx->buffer ) ) != 0 ) 00278 return( ret ); 00279 00280 input += fill; 00281 ilen -= fill; 00282 left = 0; 00283 } 00284 00285 while( ilen >= 64 ) 00286 { 00287 if( ( ret = mbedtls_internal_md4_process( ctx, input ) ) != 0 ) 00288 return( ret ); 00289 00290 input += 64; 00291 ilen -= 64; 00292 } 00293 00294 if( ilen > 0 ) 00295 { 00296 memcpy( (void *) (ctx->buffer + left), 00297 (void *) input, ilen ); 00298 } 00299 00300 return( 0 ); 00301 } 00302 00303 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00304 void mbedtls_md4_update( mbedtls_md4_context *ctx, 00305 const unsigned char *input, 00306 size_t ilen ) 00307 { 00308 mbedtls_md4_update_ret( ctx, input, ilen ); 00309 } 00310 #endif 00311 00312 static const unsigned char md4_padding[64] = 00313 { 00314 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00315 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00316 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00317 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00318 }; 00319 00320 /* 00321 * MD4 final digest 00322 */ 00323 int mbedtls_md4_finish_ret( mbedtls_md4_context *ctx, 00324 unsigned char output[16] ) 00325 { 00326 int ret; 00327 uint32_t last, padn; 00328 uint32_t high, low; 00329 unsigned char msglen[8]; 00330 00331 high = ( ctx->total [0] >> 29 ) 00332 | ( ctx->total [1] << 3 ); 00333 low = ( ctx->total [0] << 3 ); 00334 00335 PUT_UINT32_LE( low, msglen, 0 ); 00336 PUT_UINT32_LE( high, msglen, 4 ); 00337 00338 last = ctx->total [0] & 0x3F; 00339 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 00340 00341 ret = mbedtls_md4_update_ret( ctx, (unsigned char *)md4_padding, padn ); 00342 if( ret != 0 ) 00343 return( ret ); 00344 00345 if( ( ret = mbedtls_md4_update_ret( ctx, msglen, 8 ) ) != 0 ) 00346 return( ret ); 00347 00348 00349 PUT_UINT32_LE( ctx->state [0], output, 0 ); 00350 PUT_UINT32_LE( ctx->state [1], output, 4 ); 00351 PUT_UINT32_LE( ctx->state [2], output, 8 ); 00352 PUT_UINT32_LE( ctx->state [3], output, 12 ); 00353 00354 return( 0 ); 00355 } 00356 00357 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00358 void mbedtls_md4_finish( mbedtls_md4_context *ctx, 00359 unsigned char output[16] ) 00360 { 00361 mbedtls_md4_finish_ret( ctx, output ); 00362 } 00363 #endif 00364 00365 #endif /* !MBEDTLS_MD4_ALT */ 00366 00367 /* 00368 * output = MD4( input buffer ) 00369 */ 00370 int mbedtls_md4_ret( const unsigned char *input, 00371 size_t ilen, 00372 unsigned char output[16] ) 00373 { 00374 int ret; 00375 mbedtls_md4_context ctx; 00376 00377 mbedtls_md4_init( &ctx ); 00378 00379 if( ( ret = mbedtls_md4_starts_ret( &ctx ) ) != 0 ) 00380 goto exit; 00381 00382 if( ( ret = mbedtls_md4_update_ret( &ctx, input, ilen ) ) != 0 ) 00383 goto exit; 00384 00385 if( ( ret = mbedtls_md4_finish_ret( &ctx, output ) ) != 0 ) 00386 goto exit; 00387 00388 exit: 00389 mbedtls_md4_free( &ctx ); 00390 00391 return( ret ); 00392 } 00393 00394 #if !defined(MBEDTLS_DEPRECATED_REMOVED) 00395 void mbedtls_md4( const unsigned char *input, 00396 size_t ilen, 00397 unsigned char output[16] ) 00398 { 00399 mbedtls_md4_ret( input, ilen, output ); 00400 } 00401 #endif 00402 00403 #if defined(MBEDTLS_SELF_TEST) 00404 00405 /* 00406 * RFC 1320 test vectors 00407 */ 00408 static const unsigned char md4_test_str[7][81] = 00409 { 00410 { "" }, 00411 { "a" }, 00412 { "abc" }, 00413 { "message digest" }, 00414 { "abcdefghijklmnopqrstuvwxyz" }, 00415 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 00416 { "12345678901234567890123456789012345678901234567890123456789012" 00417 "345678901234567890" } 00418 }; 00419 00420 static const size_t md4_test_strlen[7] = 00421 { 00422 0, 1, 3, 14, 26, 62, 80 00423 }; 00424 00425 static const unsigned char md4_test_sum[7][16] = 00426 { 00427 { 0x31, 0xD6, 0xCF, 0xE0, 0xD1, 0x6A, 0xE9, 0x31, 00428 0xB7, 0x3C, 0x59, 0xD7, 0xE0, 0xC0, 0x89, 0xC0 }, 00429 { 0xBD, 0xE5, 0x2C, 0xB3, 0x1D, 0xE3, 0x3E, 0x46, 00430 0x24, 0x5E, 0x05, 0xFB, 0xDB, 0xD6, 0xFB, 0x24 }, 00431 { 0xA4, 0x48, 0x01, 0x7A, 0xAF, 0x21, 0xD8, 0x52, 00432 0x5F, 0xC1, 0x0A, 0xE8, 0x7A, 0xA6, 0x72, 0x9D }, 00433 { 0xD9, 0x13, 0x0A, 0x81, 0x64, 0x54, 0x9F, 0xE8, 00434 0x18, 0x87, 0x48, 0x06, 0xE1, 0xC7, 0x01, 0x4B }, 00435 { 0xD7, 0x9E, 0x1C, 0x30, 0x8A, 0xA5, 0xBB, 0xCD, 00436 0xEE, 0xA8, 0xED, 0x63, 0xDF, 0x41, 0x2D, 0xA9 }, 00437 { 0x04, 0x3F, 0x85, 0x82, 0xF2, 0x41, 0xDB, 0x35, 00438 0x1C, 0xE6, 0x27, 0xE1, 0x53, 0xE7, 0xF0, 0xE4 }, 00439 { 0xE3, 0x3B, 0x4D, 0xDC, 0x9C, 0x38, 0xF2, 0x19, 00440 0x9C, 0x3E, 0x7B, 0x16, 0x4F, 0xCC, 0x05, 0x36 } 00441 }; 00442 00443 /* 00444 * Checkup routine 00445 */ 00446 int mbedtls_md4_self_test( int verbose ) 00447 { 00448 int i, ret = 0; 00449 unsigned char md4sum[16]; 00450 00451 for( i = 0; i < 7; i++ ) 00452 { 00453 if( verbose != 0 ) 00454 mbedtls_printf( " MD4 test #%d: ", i + 1 ); 00455 00456 ret = mbedtls_md4_ret( md4_test_str[i], md4_test_strlen[i], md4sum ); 00457 if( ret != 0 ) 00458 goto fail; 00459 00460 if( memcmp( md4sum, md4_test_sum[i], 16 ) != 0 ) 00461 { 00462 ret = 1; 00463 goto fail; 00464 } 00465 00466 if( verbose != 0 ) 00467 mbedtls_printf( "passed\n" ); 00468 } 00469 00470 if( verbose != 0 ) 00471 mbedtls_printf( "\n" ); 00472 00473 return( 0 ); 00474 00475 fail: 00476 if( verbose != 0 ) 00477 mbedtls_printf( "failed\n" ); 00478 00479 return( ret ); 00480 } 00481 00482 #endif /* MBEDTLS_SELF_TEST */ 00483 00484 #endif /* MBEDTLS_MD4_C */
Generated on Tue Jul 12 2022 13:54:34 by
1.7.2