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