Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
md5.c
00001 /* 00002 * RFC 1321 compliant MD5 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 MD5 algorithm was designed by Ron Rivest in 1991. 00023 * 00024 * http://www.ietf.org/rfc/rfc1321.txt 00025 */ 00026 00027 #if !defined(MBEDTLS_CONFIG_FILE) 00028 #include "mbedtls/config.h" 00029 #else 00030 #include MBEDTLS_CONFIG_FILE 00031 #endif 00032 00033 #if defined(MBEDTLS_MD5_C) 00034 00035 #include "mbedtls/md5.h" 00036 00037 #include <string.h> 00038 00039 #if defined(MBEDTLS_SELF_TEST) 00040 #if defined(MBEDTLS_PLATFORM_C) 00041 #include "mbedtls/platform.h" 00042 #else 00043 #include <stdio.h> 00044 #define mbedtls_printf printf 00045 #endif /* MBEDTLS_PLATFORM_C */ 00046 #endif /* MBEDTLS_SELF_TEST */ 00047 00048 #if !defined(MBEDTLS_MD5_ALT) 00049 00050 /* Implementation that should never be optimized out by the compiler */ 00051 static void mbedtls_zeroize( void *v, size_t n ) { 00052 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00053 } 00054 00055 /* 00056 * 32-bit integer manipulation macros (little endian) 00057 */ 00058 #ifndef GET_UINT32_LE 00059 #define GET_UINT32_LE(n,b,i) \ 00060 { \ 00061 (n) = ( (uint32_t) (b)[(i) ] ) \ 00062 | ( (uint32_t) (b)[(i) + 1] << 8 ) \ 00063 | ( (uint32_t) (b)[(i) + 2] << 16 ) \ 00064 | ( (uint32_t) (b)[(i) + 3] << 24 ); \ 00065 } 00066 #endif 00067 00068 #ifndef PUT_UINT32_LE 00069 #define PUT_UINT32_LE(n,b,i) \ 00070 { \ 00071 (b)[(i) ] = (unsigned char) ( ( (n) ) & 0xFF ); \ 00072 (b)[(i) + 1] = (unsigned char) ( ( (n) >> 8 ) & 0xFF ); \ 00073 (b)[(i) + 2] = (unsigned char) ( ( (n) >> 16 ) & 0xFF ); \ 00074 (b)[(i) + 3] = (unsigned char) ( ( (n) >> 24 ) & 0xFF ); \ 00075 } 00076 #endif 00077 00078 void mbedtls_md5_init( mbedtls_md5_context *ctx ) 00079 { 00080 memset( ctx, 0, sizeof( mbedtls_md5_context ) ); 00081 } 00082 00083 void mbedtls_md5_free( mbedtls_md5_context *ctx ) 00084 { 00085 if( ctx == NULL ) 00086 return; 00087 00088 mbedtls_zeroize( ctx, sizeof( mbedtls_md5_context ) ); 00089 } 00090 00091 void mbedtls_md5_clone( mbedtls_md5_context *dst, 00092 const mbedtls_md5_context *src ) 00093 { 00094 *dst = *src; 00095 } 00096 00097 /* 00098 * MD5 context setup 00099 */ 00100 void mbedtls_md5_starts( mbedtls_md5_context *ctx ) 00101 { 00102 ctx->total [0] = 0; 00103 ctx->total [1] = 0; 00104 00105 ctx->state [0] = 0x67452301; 00106 ctx->state [1] = 0xEFCDAB89; 00107 ctx->state [2] = 0x98BADCFE; 00108 ctx->state [3] = 0x10325476; 00109 } 00110 00111 #if !defined(MBEDTLS_MD5_PROCESS_ALT) 00112 void mbedtls_md5_process( mbedtls_md5_context *ctx, const unsigned char data[64] ) 00113 { 00114 uint32_t X[16], A, B, C, D; 00115 00116 GET_UINT32_LE( X[ 0], data, 0 ); 00117 GET_UINT32_LE( X[ 1], data, 4 ); 00118 GET_UINT32_LE( X[ 2], data, 8 ); 00119 GET_UINT32_LE( X[ 3], data, 12 ); 00120 GET_UINT32_LE( X[ 4], data, 16 ); 00121 GET_UINT32_LE( X[ 5], data, 20 ); 00122 GET_UINT32_LE( X[ 6], data, 24 ); 00123 GET_UINT32_LE( X[ 7], data, 28 ); 00124 GET_UINT32_LE( X[ 8], data, 32 ); 00125 GET_UINT32_LE( X[ 9], data, 36 ); 00126 GET_UINT32_LE( X[10], data, 40 ); 00127 GET_UINT32_LE( X[11], data, 44 ); 00128 GET_UINT32_LE( X[12], data, 48 ); 00129 GET_UINT32_LE( X[13], data, 52 ); 00130 GET_UINT32_LE( X[14], data, 56 ); 00131 GET_UINT32_LE( X[15], data, 60 ); 00132 00133 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 00134 00135 #define P(a,b,c,d,k,s,t) \ 00136 { \ 00137 a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ 00138 } 00139 00140 A = ctx->state [0]; 00141 B = ctx->state [1]; 00142 C = ctx->state [2]; 00143 D = ctx->state [3]; 00144 00145 #define F(x,y,z) (z ^ (x & (y ^ z))) 00146 00147 P( A, B, C, D, 0, 7, 0xD76AA478 ); 00148 P( D, A, B, C, 1, 12, 0xE8C7B756 ); 00149 P( C, D, A, B, 2, 17, 0x242070DB ); 00150 P( B, C, D, A, 3, 22, 0xC1BDCEEE ); 00151 P( A, B, C, D, 4, 7, 0xF57C0FAF ); 00152 P( D, A, B, C, 5, 12, 0x4787C62A ); 00153 P( C, D, A, B, 6, 17, 0xA8304613 ); 00154 P( B, C, D, A, 7, 22, 0xFD469501 ); 00155 P( A, B, C, D, 8, 7, 0x698098D8 ); 00156 P( D, A, B, C, 9, 12, 0x8B44F7AF ); 00157 P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); 00158 P( B, C, D, A, 11, 22, 0x895CD7BE ); 00159 P( A, B, C, D, 12, 7, 0x6B901122 ); 00160 P( D, A, B, C, 13, 12, 0xFD987193 ); 00161 P( C, D, A, B, 14, 17, 0xA679438E ); 00162 P( B, C, D, A, 15, 22, 0x49B40821 ); 00163 00164 #undef F 00165 00166 #define F(x,y,z) (y ^ (z & (x ^ y))) 00167 00168 P( A, B, C, D, 1, 5, 0xF61E2562 ); 00169 P( D, A, B, C, 6, 9, 0xC040B340 ); 00170 P( C, D, A, B, 11, 14, 0x265E5A51 ); 00171 P( B, C, D, A, 0, 20, 0xE9B6C7AA ); 00172 P( A, B, C, D, 5, 5, 0xD62F105D ); 00173 P( D, A, B, C, 10, 9, 0x02441453 ); 00174 P( C, D, A, B, 15, 14, 0xD8A1E681 ); 00175 P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); 00176 P( A, B, C, D, 9, 5, 0x21E1CDE6 ); 00177 P( D, A, B, C, 14, 9, 0xC33707D6 ); 00178 P( C, D, A, B, 3, 14, 0xF4D50D87 ); 00179 P( B, C, D, A, 8, 20, 0x455A14ED ); 00180 P( A, B, C, D, 13, 5, 0xA9E3E905 ); 00181 P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); 00182 P( C, D, A, B, 7, 14, 0x676F02D9 ); 00183 P( B, C, D, A, 12, 20, 0x8D2A4C8A ); 00184 00185 #undef F 00186 00187 #define F(x,y,z) (x ^ y ^ z) 00188 00189 P( A, B, C, D, 5, 4, 0xFFFA3942 ); 00190 P( D, A, B, C, 8, 11, 0x8771F681 ); 00191 P( C, D, A, B, 11, 16, 0x6D9D6122 ); 00192 P( B, C, D, A, 14, 23, 0xFDE5380C ); 00193 P( A, B, C, D, 1, 4, 0xA4BEEA44 ); 00194 P( D, A, B, C, 4, 11, 0x4BDECFA9 ); 00195 P( C, D, A, B, 7, 16, 0xF6BB4B60 ); 00196 P( B, C, D, A, 10, 23, 0xBEBFBC70 ); 00197 P( A, B, C, D, 13, 4, 0x289B7EC6 ); 00198 P( D, A, B, C, 0, 11, 0xEAA127FA ); 00199 P( C, D, A, B, 3, 16, 0xD4EF3085 ); 00200 P( B, C, D, A, 6, 23, 0x04881D05 ); 00201 P( A, B, C, D, 9, 4, 0xD9D4D039 ); 00202 P( D, A, B, C, 12, 11, 0xE6DB99E5 ); 00203 P( C, D, A, B, 15, 16, 0x1FA27CF8 ); 00204 P( B, C, D, A, 2, 23, 0xC4AC5665 ); 00205 00206 #undef F 00207 00208 #define F(x,y,z) (y ^ (x | ~z)) 00209 00210 P( A, B, C, D, 0, 6, 0xF4292244 ); 00211 P( D, A, B, C, 7, 10, 0x432AFF97 ); 00212 P( C, D, A, B, 14, 15, 0xAB9423A7 ); 00213 P( B, C, D, A, 5, 21, 0xFC93A039 ); 00214 P( A, B, C, D, 12, 6, 0x655B59C3 ); 00215 P( D, A, B, C, 3, 10, 0x8F0CCC92 ); 00216 P( C, D, A, B, 10, 15, 0xFFEFF47D ); 00217 P( B, C, D, A, 1, 21, 0x85845DD1 ); 00218 P( A, B, C, D, 8, 6, 0x6FA87E4F ); 00219 P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); 00220 P( C, D, A, B, 6, 15, 0xA3014314 ); 00221 P( B, C, D, A, 13, 21, 0x4E0811A1 ); 00222 P( A, B, C, D, 4, 6, 0xF7537E82 ); 00223 P( D, A, B, C, 11, 10, 0xBD3AF235 ); 00224 P( C, D, A, B, 2, 15, 0x2AD7D2BB ); 00225 P( B, C, D, A, 9, 21, 0xEB86D391 ); 00226 00227 #undef F 00228 00229 ctx->state [0] += A; 00230 ctx->state [1] += B; 00231 ctx->state [2] += C; 00232 ctx->state [3] += D; 00233 } 00234 #endif /* !MBEDTLS_MD5_PROCESS_ALT */ 00235 00236 /* 00237 * MD5 process buffer 00238 */ 00239 void mbedtls_md5_update( mbedtls_md5_context *ctx, const unsigned char *input, size_t ilen ) 00240 { 00241 size_t fill; 00242 uint32_t left; 00243 00244 if( ilen == 0 ) 00245 return; 00246 00247 left = ctx->total [0] & 0x3F; 00248 fill = 64 - left; 00249 00250 ctx->total [0] += (uint32_t) ilen; 00251 ctx->total [0] &= 0xFFFFFFFF; 00252 00253 if( ctx->total [0] < (uint32_t) ilen ) 00254 ctx->total [1]++; 00255 00256 if( left && ilen >= fill ) 00257 { 00258 memcpy( (void *) (ctx->buffer + left), input, fill ); 00259 mbedtls_md5_process( ctx, ctx->buffer ); 00260 input += fill; 00261 ilen -= fill; 00262 left = 0; 00263 } 00264 00265 while( ilen >= 64 ) 00266 { 00267 mbedtls_md5_process( ctx, input ); 00268 input += 64; 00269 ilen -= 64; 00270 } 00271 00272 if( ilen > 0 ) 00273 { 00274 memcpy( (void *) (ctx->buffer + left), input, ilen ); 00275 } 00276 } 00277 00278 static const unsigned char md5_padding[64] = 00279 { 00280 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00281 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00282 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 00283 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00284 }; 00285 00286 /* 00287 * MD5 final digest 00288 */ 00289 void mbedtls_md5_finish( mbedtls_md5_context *ctx, unsigned char output[16] ) 00290 { 00291 uint32_t last, padn; 00292 uint32_t high, low; 00293 unsigned char msglen[8]; 00294 00295 high = ( ctx->total [0] >> 29 ) 00296 | ( ctx->total [1] << 3 ); 00297 low = ( ctx->total [0] << 3 ); 00298 00299 PUT_UINT32_LE( low, msglen, 0 ); 00300 PUT_UINT32_LE( high, msglen, 4 ); 00301 00302 last = ctx->total [0] & 0x3F; 00303 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 00304 00305 mbedtls_md5_update( ctx, md5_padding, padn ); 00306 mbedtls_md5_update( ctx, msglen, 8 ); 00307 00308 PUT_UINT32_LE( ctx->state [0], output, 0 ); 00309 PUT_UINT32_LE( ctx->state [1], output, 4 ); 00310 PUT_UINT32_LE( ctx->state [2], output, 8 ); 00311 PUT_UINT32_LE( ctx->state [3], output, 12 ); 00312 } 00313 00314 #endif /* !MBEDTLS_MD5_ALT */ 00315 00316 /* 00317 * output = MD5( input buffer ) 00318 */ 00319 void mbedtls_md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) 00320 { 00321 mbedtls_md5_context ctx; 00322 00323 mbedtls_md5_init( &ctx ); 00324 mbedtls_md5_starts( &ctx ); 00325 mbedtls_md5_update( &ctx, input, ilen ); 00326 mbedtls_md5_finish( &ctx, output ); 00327 mbedtls_md5_free( &ctx ); 00328 } 00329 00330 #if defined(MBEDTLS_SELF_TEST) 00331 /* 00332 * RFC 1321 test vectors 00333 */ 00334 static const unsigned char md5_test_buf[7][81] = 00335 { 00336 { "" }, 00337 { "a" }, 00338 { "abc" }, 00339 { "message digest" }, 00340 { "abcdefghijklmnopqrstuvwxyz" }, 00341 { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" }, 00342 { "12345678901234567890123456789012345678901234567890123456789012" \ 00343 "345678901234567890" } 00344 }; 00345 00346 static const int md5_test_buflen[7] = 00347 { 00348 0, 1, 3, 14, 26, 62, 80 00349 }; 00350 00351 static const unsigned char md5_test_sum[7][16] = 00352 { 00353 { 0xD4, 0x1D, 0x8C, 0xD9, 0x8F, 0x00, 0xB2, 0x04, 00354 0xE9, 0x80, 0x09, 0x98, 0xEC, 0xF8, 0x42, 0x7E }, 00355 { 0x0C, 0xC1, 0x75, 0xB9, 0xC0, 0xF1, 0xB6, 0xA8, 00356 0x31, 0xC3, 0x99, 0xE2, 0x69, 0x77, 0x26, 0x61 }, 00357 { 0x90, 0x01, 0x50, 0x98, 0x3C, 0xD2, 0x4F, 0xB0, 00358 0xD6, 0x96, 0x3F, 0x7D, 0x28, 0xE1, 0x7F, 0x72 }, 00359 { 0xF9, 0x6B, 0x69, 0x7D, 0x7C, 0xB7, 0x93, 0x8D, 00360 0x52, 0x5A, 0x2F, 0x31, 0xAA, 0xF1, 0x61, 0xD0 }, 00361 { 0xC3, 0xFC, 0xD3, 0xD7, 0x61, 0x92, 0xE4, 0x00, 00362 0x7D, 0xFB, 0x49, 0x6C, 0xCA, 0x67, 0xE1, 0x3B }, 00363 { 0xD1, 0x74, 0xAB, 0x98, 0xD2, 0x77, 0xD9, 0xF5, 00364 0xA5, 0x61, 0x1C, 0x2C, 0x9F, 0x41, 0x9D, 0x9F }, 00365 { 0x57, 0xED, 0xF4, 0xA2, 0x2B, 0xE3, 0xC9, 0x55, 00366 0xAC, 0x49, 0xDA, 0x2E, 0x21, 0x07, 0xB6, 0x7A } 00367 }; 00368 00369 /* 00370 * Checkup routine 00371 */ 00372 int mbedtls_md5_self_test( int verbose ) 00373 { 00374 int i; 00375 unsigned char md5sum[16]; 00376 00377 for( i = 0; i < 7; i++ ) 00378 { 00379 if( verbose != 0 ) 00380 mbedtls_printf( " MD5 test #%d: ", i + 1 ); 00381 00382 mbedtls_md5( md5_test_buf[i], md5_test_buflen[i], md5sum ); 00383 00384 if( memcmp( md5sum, md5_test_sum[i], 16 ) != 0 ) 00385 { 00386 if( verbose != 0 ) 00387 mbedtls_printf( "failed\n" ); 00388 00389 return( 1 ); 00390 } 00391 00392 if( verbose != 0 ) 00393 mbedtls_printf( "passed\n" ); 00394 } 00395 00396 if( verbose != 0 ) 00397 mbedtls_printf( "\n" ); 00398 00399 return( 0 ); 00400 } 00401 00402 #endif /* MBEDTLS_SELF_TEST */ 00403 00404 #endif /* MBEDTLS_MD5_C */
Generated on Sun Jul 17 2022 08:25:28 by 1.7.2