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.
ns_sha256.c
00001 /* 00002 * Copyright (c) 2006-2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 /* 00018 * FIPS-180-2 compliant SHA-256 implementation 00019 * 00020 * This file is derived from sha256.h in mbed TLS 2.3.0. 00021 */ 00022 /* 00023 * The SHA-256 Secure Hash Standard was published by NIST in 2002. 00024 * 00025 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf 00026 */ 00027 00028 #include "nsconfig.h" 00029 #include "ns_sha256.h" 00030 00031 #ifndef NS_USE_EXTERNAL_MBED_TLS 00032 00033 #include <string.h> 00034 00035 /* Implementation that should never be optimized out by the compiler */ 00036 static void ns_zeroize( void *v, size_t n ) { 00037 volatile unsigned char *p = v; while( n-- ) *p++ = 0; 00038 } 00039 00040 /* 00041 * 32-bit integer manipulation macros (big endian) 00042 */ 00043 #ifndef GET_UINT32_BE 00044 #define GET_UINT32_BE(n,b,i) \ 00045 ( \ 00046 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 00047 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 00048 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 00049 | ( (uint32_t) (b)[(i) + 3] ) \ 00050 ) 00051 #endif 00052 00053 #ifndef PUT_UINT32_BE 00054 #define PUT_UINT32_BE(n,b,i) \ 00055 do { \ 00056 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 00057 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 00058 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 00059 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 00060 } while( 0 ) 00061 #endif 00062 00063 void ns_sha256_init( ns_sha256_context *ctx ) 00064 { 00065 memset( ctx, 0, sizeof( ns_sha256_context ) ); 00066 } 00067 00068 void ns_sha256_free( ns_sha256_context *ctx ) 00069 { 00070 ns_zeroize( ctx, sizeof( ns_sha256_context ) ); 00071 } 00072 00073 void ns_sha256_clone( ns_sha256_context *dst, 00074 const ns_sha256_context *src ) 00075 { 00076 *dst = *src; 00077 } 00078 00079 /* 00080 * SHA-256 context setup 00081 */ 00082 void ns_sha256_starts( ns_sha256_context *ctx ) 00083 { 00084 ctx->total [0] = 0; 00085 ctx->total [1] = 0; 00086 00087 /* SHA-256 */ 00088 ctx->state [0] = 0x6A09E667; 00089 ctx->state [1] = 0xBB67AE85; 00090 ctx->state [2] = 0x3C6EF372; 00091 ctx->state [3] = 0xA54FF53A; 00092 ctx->state [4] = 0x510E527F; 00093 ctx->state [5] = 0x9B05688C; 00094 ctx->state [6] = 0x1F83D9AB; 00095 ctx->state [7] = 0x5BE0CD19; 00096 } 00097 00098 static const uint32_t K[] = 00099 { 00100 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 00101 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 00102 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 00103 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 00104 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 00105 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 00106 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 00107 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, 00108 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 00109 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 00110 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 00111 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 00112 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 00113 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 00114 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 00115 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, 00116 }; 00117 00118 #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 00119 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 00120 00121 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 00122 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 00123 00124 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 00125 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 00126 00127 #define F0(x,y,z) ((x & y) | (z & (x | y))) 00128 #define F1(x,y,z) (z ^ (x & (y ^ z))) 00129 00130 #define R(t) \ 00131 ( \ 00132 W[t & 15] += S1(W[(t - 2) & 15]) + W[(t - 7) & 15] + \ 00133 S0(W[(t - 15) & 15]) \ 00134 ) 00135 00136 #define P(a,b,c,d,e,f,g,h,x,K) \ 00137 { \ 00138 temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 00139 temp2 = S2(a) + F0(a,b,c); \ 00140 d += temp1; h = temp1 + temp2; \ 00141 } 00142 00143 static void ns_sha256_process( ns_sha256_context *ctx, const unsigned char data[64] ) 00144 { 00145 uint32_t temp1, temp2, W[16]; 00146 uint32_t A[8]; 00147 unsigned int i; 00148 00149 for( i = 0; i < 8; i++ ) 00150 A[i] = ctx->state [i]; 00151 00152 for( i = 0; i < 64; i++ ) 00153 { 00154 uint32_t Wi; 00155 if( i < 16 ) 00156 Wi = GET_UINT32_BE( W[i], data, 4 * i ); 00157 else 00158 Wi = R( i ); 00159 00160 P( A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], Wi, K[i] ); 00161 00162 temp1 = A[7]; A[7] = A[6]; A[6] = A[5]; A[5] = A[4]; A[4] = A[3]; 00163 A[3] = A[2]; A[2] = A[1]; A[1] = A[0]; A[0] = temp1; 00164 } 00165 00166 for( i = 0; i < 8; i++ ) 00167 ctx->state [i] += A[i]; 00168 } 00169 00170 /* 00171 * SHA-256 process buffer 00172 */ 00173 void ns_sha256_update( ns_sha256_context *ctx, const void *inputv, 00174 size_t ilen ) 00175 { 00176 const unsigned char *input = inputv; 00177 size_t fill; 00178 uint32_t left; 00179 00180 if( ilen == 0 ) 00181 return; 00182 00183 left = ctx->total [0] & 0x3F; 00184 fill = 64 - left; 00185 00186 ctx->total [0] += (uint32_t) ilen; 00187 ctx->total [0] &= 0xFFFFFFFF; 00188 00189 if( ctx->total [0] < (uint32_t) ilen ) 00190 ctx->total [1]++; 00191 00192 if( left && ilen >= fill ) 00193 { 00194 memcpy( (void *) (ctx->buffer + left), input, fill ); 00195 ns_sha256_process( ctx, ctx->buffer ); 00196 input += fill; 00197 ilen -= fill; 00198 left = 0; 00199 } 00200 00201 while( ilen >= 64 ) 00202 { 00203 ns_sha256_process( ctx, input ); 00204 input += 64; 00205 ilen -= 64; 00206 } 00207 00208 if( ilen > 0 ) 00209 memcpy( (void *) (ctx->buffer + left), input, ilen ); 00210 } 00211 00212 /* 00213 * SHA-256 final digest 00214 */ 00215 void ns_sha256_finish_nbits( ns_sha256_context *ctx, void *outputv, unsigned obits ) 00216 { 00217 unsigned char *output = outputv; 00218 uint32_t last, padn; 00219 uint32_t high, low; 00220 unsigned char msglen[8]; 00221 unsigned int i; 00222 00223 high = ( ctx->total [0] >> 29 ) 00224 | ( ctx->total [1] << 3 ); 00225 low = ( ctx->total [0] << 3 ); 00226 00227 PUT_UINT32_BE( high, msglen, 0 ); 00228 PUT_UINT32_BE( low, msglen, 4 ); 00229 00230 last = ctx->total [0] & 0x3F; 00231 padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 00232 00233 /* Const compound literals need not designate distinct objects - this could 00234 * potentially save ROM over declaring the padding array. 00235 */ 00236 ns_sha256_update( ctx, (const unsigned char[64]) { 0x80 }, padn ); 00237 ns_sha256_update( ctx, msglen, 8 ); 00238 00239 for( i = 0; i < 8 && obits > 0; i++, obits -= 32 ) { 00240 PUT_UINT32_BE( ctx->state [i], output, 4 * i ); 00241 } 00242 } 00243 00244 void ns_sha256_finish( ns_sha256_context *ctx, void *output ) 00245 { 00246 ns_sha256_finish_nbits( ctx, output, 256 ); 00247 } 00248 00249 /* 00250 * output = SHA-256( input buffer ) 00251 */ 00252 void ns_sha256_nbits( const void *input, size_t ilen, 00253 void *output, unsigned obits ) 00254 { 00255 ns_sha256_context ctx; 00256 00257 ns_sha256_init( &ctx ); 00258 ns_sha256_starts( &ctx ); 00259 ns_sha256_update( &ctx, input, ilen ); 00260 ns_sha256_finish_nbits( &ctx, output, obits ); 00261 ns_sha256_free( &ctx ); 00262 } 00263 00264 void ns_sha256( const void *input, size_t ilen, 00265 void *output ) 00266 { 00267 ns_sha256_nbits( input, ilen, output, 256 ); 00268 } 00269 #endif /* NS_USE_EXTERNAL_MBED_TLS */
Generated on Tue Jul 12 2022 18:18:45 by
