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.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
ns_sha256.c
00001 /* 00002 * Copyright (c) 2006-2018, 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 { 00038 volatile unsigned char *p = v; 00039 while (n--) { 00040 *p++ = 0; 00041 } 00042 } 00043 00044 /* 00045 * 32-bit integer manipulation macros (big endian) 00046 */ 00047 #ifndef GET_UINT32_BE 00048 #define GET_UINT32_BE(n,b,i) \ 00049 ( \ 00050 (n) = ( (uint32_t) (b)[(i) ] << 24 ) \ 00051 | ( (uint32_t) (b)[(i) + 1] << 16 ) \ 00052 | ( (uint32_t) (b)[(i) + 2] << 8 ) \ 00053 | ( (uint32_t) (b)[(i) + 3] ) \ 00054 ) 00055 #endif 00056 00057 #ifndef PUT_UINT32_BE 00058 #define PUT_UINT32_BE(n,b,i) \ 00059 do { \ 00060 (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ 00061 (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ 00062 (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ 00063 (b)[(i) + 3] = (unsigned char) ( (n) ); \ 00064 } while( 0 ) 00065 #endif 00066 00067 void ns_sha256_init(ns_sha256_context *ctx) 00068 { 00069 memset(ctx, 0, sizeof(ns_sha256_context)); 00070 } 00071 00072 void ns_sha256_free(ns_sha256_context *ctx) 00073 { 00074 ns_zeroize(ctx, sizeof(ns_sha256_context)); 00075 } 00076 00077 void ns_sha256_clone(ns_sha256_context *dst, 00078 const ns_sha256_context *src) 00079 { 00080 *dst = *src; 00081 } 00082 00083 /* 00084 * SHA-256 context setup 00085 */ 00086 void ns_sha256_starts(ns_sha256_context *ctx) 00087 { 00088 ctx->total [0] = 0; 00089 ctx->total [1] = 0; 00090 00091 /* SHA-256 */ 00092 ctx->state [0] = 0x6A09E667; 00093 ctx->state [1] = 0xBB67AE85; 00094 ctx->state [2] = 0x3C6EF372; 00095 ctx->state [3] = 0xA54FF53A; 00096 ctx->state [4] = 0x510E527F; 00097 ctx->state [5] = 0x9B05688C; 00098 ctx->state [6] = 0x1F83D9AB; 00099 ctx->state [7] = 0x5BE0CD19; 00100 } 00101 00102 static const uint32_t K[] = { 00103 0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5, 00104 0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5, 00105 0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3, 00106 0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174, 00107 0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC, 00108 0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA, 00109 0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7, 00110 0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967, 00111 0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13, 00112 0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85, 00113 0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3, 00114 0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070, 00115 0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5, 00116 0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3, 00117 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 00118 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2, 00119 }; 00120 00121 #define SHR(x,n) ((x & 0xFFFFFFFF) >> n) 00122 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) 00123 00124 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) 00125 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) 00126 00127 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) 00128 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) 00129 00130 #define F0(x,y,z) ((x & y) | (z & (x | y))) 00131 #define F1(x,y,z) (z ^ (x & (y ^ z))) 00132 00133 #define R(t) \ 00134 ( \ 00135 W[t & 15] += S1(W[(t - 2) & 15]) + W[(t - 7) & 15] + \ 00136 S0(W[(t - 15) & 15]) \ 00137 ) 00138 00139 #define P(a,b,c,d,e,f,g,h,x,K) \ 00140 { \ 00141 temp1 = h + S3(e) + F1(e,f,g) + K + x; \ 00142 temp2 = S2(a) + F0(a,b,c); \ 00143 d += temp1; h = temp1 + temp2; \ 00144 } 00145 00146 static void ns_sha256_process(ns_sha256_context *ctx, const unsigned char data[64]) 00147 { 00148 uint32_t temp1, temp2, W[16]; 00149 uint32_t A[8]; 00150 unsigned int i; 00151 00152 for (i = 0; i < 8; i++) { 00153 A[i] = ctx->state [i]; 00154 } 00155 00156 for (i = 0; i < 64; i++) { 00157 uint32_t Wi; 00158 if (i < 16) { 00159 Wi = GET_UINT32_BE(W[i], data, 4 * i); 00160 } else { 00161 Wi = R(i); 00162 } 00163 00164 P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], Wi, K[i]); 00165 00166 temp1 = A[7]; 00167 A[7] = A[6]; 00168 A[6] = A[5]; 00169 A[5] = A[4]; 00170 A[4] = A[3]; 00171 A[3] = A[2]; 00172 A[2] = A[1]; 00173 A[1] = A[0]; 00174 A[0] = temp1; 00175 } 00176 00177 for (i = 0; i < 8; i++) { 00178 ctx->state [i] += A[i]; 00179 } 00180 } 00181 00182 /* 00183 * SHA-256 process buffer 00184 */ 00185 void ns_sha256_update(ns_sha256_context *ctx, const void *inputv, 00186 size_t ilen) 00187 { 00188 const unsigned char *input = inputv; 00189 size_t fill; 00190 uint32_t left; 00191 00192 if (ilen == 0) { 00193 return; 00194 } 00195 00196 left = ctx->total [0] & 0x3F; 00197 fill = 64 - left; 00198 00199 ctx->total [0] += (uint32_t) ilen; 00200 ctx->total [0] &= 0xFFFFFFFF; 00201 00202 if (ctx->total [0] < (uint32_t) ilen) { 00203 ctx->total [1]++; 00204 } 00205 00206 if (left && ilen >= fill) { 00207 memcpy((void *)(ctx->buffer + left), input, fill); 00208 ns_sha256_process(ctx, ctx->buffer ); 00209 input += fill; 00210 ilen -= fill; 00211 left = 0; 00212 } 00213 00214 while (ilen >= 64) { 00215 ns_sha256_process(ctx, input); 00216 input += 64; 00217 ilen -= 64; 00218 } 00219 00220 if (ilen > 0) { 00221 memcpy((void *)(ctx->buffer + left), input, ilen); 00222 } 00223 } 00224 00225 /* 00226 * SHA-256 final digest 00227 */ 00228 void ns_sha256_finish_nbits(ns_sha256_context *ctx, void *outputv, unsigned obits) 00229 { 00230 unsigned char *output = outputv; 00231 uint32_t last, padn; 00232 uint32_t high, low; 00233 unsigned char msglen[8]; 00234 unsigned int i; 00235 00236 high = (ctx->total [0] >> 29) 00237 | (ctx->total [1] << 3); 00238 low = (ctx->total [0] << 3); 00239 00240 PUT_UINT32_BE(high, msglen, 0); 00241 PUT_UINT32_BE(low, msglen, 4); 00242 00243 last = ctx->total [0] & 0x3F; 00244 padn = (last < 56) ? (56 - last) : (120 - last); 00245 00246 /* Const compound literals need not designate distinct objects - this could 00247 * potentially save ROM over declaring the padding array. 00248 */ 00249 ns_sha256_update(ctx, (const unsigned char[64]) { 00250 0x80 00251 }, padn); 00252 ns_sha256_update(ctx, msglen, 8); 00253 00254 for (i = 0; i < 8 && obits > 0; i++, obits -= 32) { 00255 PUT_UINT32_BE(ctx->state [i], output, 4 * i); 00256 } 00257 } 00258 00259 void ns_sha256_finish(ns_sha256_context *ctx, void *output) 00260 { 00261 ns_sha256_finish_nbits(ctx, output, 256); 00262 } 00263 00264 /* 00265 * output = SHA-256( input buffer ) 00266 */ 00267 void ns_sha256_nbits(const void *input, size_t ilen, 00268 void *output, unsigned obits) 00269 { 00270 ns_sha256_context ctx; 00271 00272 ns_sha256_init(&ctx); 00273 ns_sha256_starts(&ctx); 00274 ns_sha256_update(&ctx, input, ilen); 00275 ns_sha256_finish_nbits(&ctx, output, obits); 00276 ns_sha256_free(&ctx); 00277 } 00278 00279 void ns_sha256(const void *input, size_t ilen, 00280 void *output) 00281 { 00282 ns_sha256_nbits(input, ilen, output, 256); 00283 } 00284 #endif /* NS_USE_EXTERNAL_MBED_TLS */
Generated on Tue Jul 12 2022 13:54:39 by
