Gleb Klochkov / Mbed OS Climatcontroll_Main

Dependencies:   esp8266-driver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ns_sha256.c Source File

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 */