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