Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
sha256.c
00001 /* 00002 * FIPS-180-2 compliant SHA-256 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 SHA-256 Secure Hash Standard was published by NIST in 2002. 00023 * 00024 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf 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_SHA256_C) 00034 00035 #include "mbedtls/sha256.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 #include <stdlib.h> 00045 #define mbedtls_printf printf 00046 #define mbedtls_calloc calloc 00047 #define mbedtls_free free 00048 #endif /* MBEDTLS_PLATFORM_C */ 00049 #endif /* MBEDTLS_SELF_TEST */ 00050 00051 #if !defined(MBEDTLS_SHA256_ALT) 00052 00053 /* Implementation that should never be optimized out by the compiler */ 00054 static void mbedtls_zeroize( void *v, size_t n ) { 00055 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00056 } 00057 00058 /* 00059 * 32-bit integer manipulation macros (big endian) 00060 */ 00061 #ifndef GET_UINT32_BE 00062 #define GET_UINT32_BE(n,b,i) \ 00063 do { \ 00064 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 00065 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 00066 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 00067 | ( (uint32_t) (b)[(i) + 3] ); \ 00068 } while( 0 ) 00069 #endif 00070 00071 #ifndef PUT_UINT32_BE 00072 #define PUT_UINT32_BE(n,b,i) \ 00073 do { \ 00074 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 00075 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 00076 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 00077 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 00078 } while( 0 ) 00079 #endif 00080 00081 void mbedtls_sha256_init( mbedtls_sha256_context *ctx ) 00082 { 00083 memset( ctx, 0, sizeof( mbedtls_sha256_context ) ); 00084 } 00085 00086 void mbedtls_sha256_free( mbedtls_sha256_context *ctx ) 00087 { 00088 if( ctx == NULL ) 00089 return; 00090 00091 mbedtls_zeroize( ctx, sizeof( mbedtls_sha256_context ) ); 00092 } 00093 00094 void mbedtls_sha256_clone( mbedtls_sha256_context *dst, 00095 const mbedtls_sha256_context *src ) 00096 { 00097 *dst = *src; 00098 } 00099 00100 /* 00101 * SHA-256 context setup 00102 */ 00103 void mbedtls_sha256_starts( mbedtls_sha256_context *ctx, int is224 ) 00104 { 00105 ctx->total [0] = 0; 00106 ctx->total [1] = 0; 00107 00108 if( is224 == 0 ) 00109 { 00110 /* SHA-256 */ 00111 ctx->state [0] = 0x6A09E667; 00112 ctx->state [1] = 0xBB67AE85; 00113 ctx->state [2] = 0x3C6EF372; 00114 ctx->state [3] = 0xA54FF53A; 00115 ctx->state [4] = 0x510E527F; 00116 ctx->state [5] = 0x9B05688C; 00117 ctx->state [6] = 0x1F83D9AB; 00118 ctx->state [7] = 0x5BE0CD19; 00119 } 00120 else 00121 { 00122 /* SHA-224 */ 00123 ctx->state [0] = 0xC1059ED8; 00124 ctx->state [1] = 0x367CD507; 00125 ctx->state [2] = 0x3070DD17; 00126 ctx->state [3] = 0xF70E5939; 00127 ctx->state [4] = 0xFFC00B31; 00128 ctx->state [5] = 0x68581511; 00129 ctx->state [6] = 0x64F98FA7; 00130 ctx->state [7] = 0xBEFA4FA4; 00131 } 00132 00133 ctx->is224 = is224; 00134 } 00135 00136 #if !defined(MBEDTLS_SHA256_PROCESS_ALT) 00137 static const uint32_t K[] = 00138 { 00139 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 00140 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 00141 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 00142 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 00143 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 00144 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 00145 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 00146 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, 00147 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 00148 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 00149 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 00150 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 00151 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 00152 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 00153 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 00154 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, 00155 }; 00156 00157 #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 00158 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 00159 00160 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 00161 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 00162 00163 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 00164 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 00165 00166 #define F0(x,y,z) ((x & y) | (z & (x | y))) 00167 #define F1(x,y,z) (z ^ (x & (y ^ z))) 00168 00169 #define R(t) \ 00170 ( \ 00171 W[t] = S1(W[t - 2]) + W[t - 7] + \ 00172 S0(W[t - 15]) + W[t - 16] \ 00173 ) 00174 00175 #define P(a,b,c,d,e,f,g,h,x,K) \ 00176 { \ 00177 temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 00178 temp2 = S2(a) + F0(a,b,c); \ 00179 d += temp1; h = temp1 + temp2; \ 00180 } 00181 00182 void mbedtls_sha256_process( mbedtls_sha256_context *ctx, const unsigned char data[64] ) 00183 { 00184 uint32_t temp1, temp2, W[64]; 00185 uint32_t A[8]; 00186 unsigned int i; 00187 00188 for( i = 0; i < 8; i++ ) 00189 A[i] = ctx->state [i]; 00190 00191 #if defined(MBEDTLS_SHA256_SMALLER) 00192 for( i = 0; i < 64; i++ ) 00193 { 00194 if( i < 16 ) 00195 GET_UINT32_BE( W[i], data, 4 * i ); 00196 else 00197 R( i ); 00198 00199 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i] ); 00200 00201 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; 00202 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; 00203 } 00204 #else /* MBEDTLS_SHA256_SMALLER */ 00205 for( i = 0; i < 16; i++ ) 00206 GET_UINT32_BE( W[i], data, 4 * i ); 00207 00208 for( i = 0; i < 16; i += 8 ) 00209 { 00210 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i+0], K[i+0] ); 00211 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i+1], K[i+1] ); 00212 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i+2], K[i+2] ); 00213 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i+3], K[i+3] ); 00214 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i+4], K[i+4] ); 00215 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i+5], K[i+5] ); 00216 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i+6], K[i+6] ); 00217 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i+7], K[i+7] ); 00218 } 00219 00220 for( i = 16; i < 64; i += 8 ) 00221 { 00222 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i+0), K[i+0] ); 00223 P( A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i+1), K[i+1] ); 00224 P( A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i+2), K[i+2] ); 00225 P( A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i+3), K[i+3] ); 00226 P( A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i+4), K[i+4] ); 00227 P( A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i+5), K[i+5] ); 00228 P( A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i+6), K[i+6] ); 00229 P( A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i+7), K[i+7] ); 00230 } 00231 #endif /* MBEDTLS_SHA256_SMALLER */ 00232 00233 for( i = 0; i < 8; i++ ) 00234 ctx->state [i] += A[i]; 00235 } 00236 #endif /* !MBEDTLS_SHA256_PROCESS_ALT */ 00237 00238 /* 00239 * SHA-256 process buffer 00240 */ 00241 void mbedtls_sha256_update( mbedtls_sha256_context *ctx, const unsigned char *input, 00242 size_t ilen ) 00243 { 00244 size_t fill; 00245 uint32_t left; 00246 00247 if( ilen == 0 ) 00248 return; 00249 00250 left = ctx->total [0] & 0x3F; 00251 fill = 64 - left; 00252 00253 ctx->total [0] += (uint32_t) ilen; 00254 ctx->total [0] &= 0xFFFFFFFF; 00255 00256 if( ctx->total [0] < (uint32_t) ilen ) 00257 ctx->total [1]++; 00258 00259 if( left && ilen >= fill ) 00260 { 00261 memcpy( (void *) (ctx->buffer + left), input, fill ); 00262 mbedtls_sha256_process( ctx, ctx->buffer ); 00263 input += fill; 00264 ilen -= fill; 00265 left = 0; 00266 } 00267 00268 while( ilen >= 64 ) 00269 { 00270 mbedtls_sha256_process( ctx, input ); 00271 input += 64; 00272 ilen -= 64; 00273 } 00274 00275 if( ilen > 0 ) 00276 memcpy( (void *) (ctx->buffer + left), input, ilen ); 00277 } 00278 00279 static const unsigned char sha256_padding[64] = 00280 { 00281 0x80, 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 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 00285 }; 00286 00287 /* 00288 * SHA-256 final digest 00289 */ 00290 void mbedtls_sha256_finish( mbedtls_sha256_context *ctx, unsigned char output[32] ) 00291 { 00292 uint32_t last, padn; 00293 uint32_t high, low; 00294 unsigned char msglen[8]; 00295 00296 high = ( ctx->total [0] >> 29 ) 00297 | ( ctx->total [1] << 3 ); 00298 low = ( ctx->total [0] << 3 ); 00299 00300 PUT_UINT32_BE( high, msglen, 0 ); 00301 PUT_UINT32_BE( low, msglen, 4 ); 00302 00303 last = ctx->total [0] & 0x3F; 00304 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 00305 00306 mbedtls_sha256_update( ctx, sha256_padding, padn ); 00307 mbedtls_sha256_update( ctx, msglen, 8 ); 00308 00309 PUT_UINT32_BE( ctx->state [0], output, 0 ); 00310 PUT_UINT32_BE( ctx->state [1], output, 4 ); 00311 PUT_UINT32_BE( ctx->state [2], output, 8 ); 00312 PUT_UINT32_BE( ctx->state [3], output, 12 ); 00313 PUT_UINT32_BE( ctx->state [4], output, 16 ); 00314 PUT_UINT32_BE( ctx->state [5], output, 20 ); 00315 PUT_UINT32_BE( ctx->state [6], output, 24 ); 00316 00317 if( ctx->is224 == 0 ) 00318 PUT_UINT32_BE( ctx->state [7], output, 28 ); 00319 } 00320 00321 #endif /* !MBEDTLS_SHA256_ALT */ 00322 00323 /* 00324 * output = SHA-256( input buffer ) 00325 */ 00326 void mbedtls_sha256( const unsigned char *input, size_t ilen, 00327 unsigned char output[32], int is224 ) 00328 { 00329 mbedtls_sha256_context ctx; 00330 00331 mbedtls_sha256_init( &ctx ); 00332 mbedtls_sha256_starts( &ctx, is224 ); 00333 mbedtls_sha256_update( &ctx, input, ilen ); 00334 mbedtls_sha256_finish( &ctx, output ); 00335 mbedtls_sha256_free( &ctx ); 00336 } 00337 00338 #if defined(MBEDTLS_SELF_TEST) 00339 /* 00340 * FIPS-180-2 test vectors 00341 */ 00342 static const unsigned char sha256_test_buf[3][57] = 00343 { 00344 { "abc" }, 00345 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" }, 00346 { "" } 00347 }; 00348 00349 static const int sha256_test_buflen[3] = 00350 { 00351 3, 56, 1000 00352 }; 00353 00354 static const unsigned char sha256_test_sum[6][32] = 00355 { 00356 /* 00357 * SHA-224 test vectors 00358 */ 00359 { 0x23, 0x09, 0x7D, 0x22, 0x34, 0x05, 0xD8, 0x22, 00360 0x86, 0x42, 0xA4, 0x77, 0xBD, 0xA2, 0x55, 0xB3, 00361 0x2A, 0xAD, 0xBC, 0xE4, 0xBD, 0xA0, 0xB3, 0xF7, 00362 0xE3, 0x6C, 0x9D, 0xA7 }, 00363 { 0x75, 0x38, 0x8B, 0x16, 0x51, 0x27, 0x76, 0xCC, 00364 0x5D, 0xBA, 0x5D, 0xA1, 0xFD, 0x89, 0x01, 0x50, 00365 0xB0, 0xC6, 0x45, 0x5C, 0xB4, 0xF5, 0x8B, 0x19, 00366 0x52, 0x52, 0x25, 0x25 }, 00367 { 0x20, 0x79, 0x46, 0x55, 0x98, 0x0C, 0x91, 0xD8, 00368 0xBB, 0xB4, 0xC1, 0xEA, 0x97, 0x61, 0x8A, 0x4B, 00369 0xF0, 0x3F, 0x42, 0x58, 0x19, 0x48, 0xB2, 0xEE, 00370 0x4E, 0xE7, 0xAD, 0x67 }, 00371 00372 /* 00373 * SHA-256 test vectors 00374 */ 00375 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 00376 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, 00377 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C, 00378 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD }, 00379 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 00380 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, 00381 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67, 00382 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 }, 00383 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, 00384 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, 00385 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E, 00386 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 } 00387 }; 00388 00389 /* 00390 * Checkup routine 00391 */ 00392 int mbedtls_sha256_self_test( int verbose ) 00393 { 00394 int i, j, k, buflen, ret = 0; 00395 unsigned char *buf; 00396 unsigned char sha256sum[32]; 00397 mbedtls_sha256_context ctx; 00398 00399 buf = mbedtls_calloc( 1024, sizeof(unsigned char) ); 00400 if( NULL == buf ) 00401 { 00402 if( verbose != 0 ) 00403 mbedtls_printf( "Buffer allocation failed\n" ); 00404 00405 return( 1 ); 00406 } 00407 00408 mbedtls_sha256_init( &ctx ); 00409 00410 for( i = 0; i < 6; i++ ) 00411 { 00412 j = i % 3; 00413 k = i < 3; 00414 00415 if( verbose != 0 ) 00416 mbedtls_printf( " SHA-%d test #%d: ", 256 - k * 32, j + 1 ); 00417 00418 mbedtls_sha256_starts( &ctx, k ); 00419 00420 if( j == 2 ) 00421 { 00422 memset( buf, 'a', buflen = 1000 ); 00423 00424 for( j = 0; j < 1000; j++ ) 00425 mbedtls_sha256_update( &ctx, buf, buflen ); 00426 } 00427 else 00428 mbedtls_sha256_update( &ctx, sha256_test_buf[j], 00429 sha256_test_buflen[j] ); 00430 00431 mbedtls_sha256_finish( &ctx, sha256sum ); 00432 00433 if( memcmp( sha256sum, sha256_test_sum[i], 32 - k * 4 ) != 0 ) 00434 { 00435 if( verbose != 0 ) 00436 mbedtls_printf( "failed\n" ); 00437 00438 ret = 1; 00439 goto exit; 00440 } 00441 00442 if( verbose != 0 ) 00443 mbedtls_printf( "passed\n" ); 00444 } 00445 00446 if( verbose != 0 ) 00447 mbedtls_printf( "\n" ); 00448 00449 exit: 00450 mbedtls_sha256_free( &ctx ); 00451 mbedtls_free( buf ); 00452 00453 return( ret ); 00454 } 00455 00456 #endif /* MBEDTLS_SELF_TEST */ 00457 00458 #endif /* MBEDTLS_SHA256_C */
Generated on Sun Jul 17 2022 08:25:30 by 1.7.2