Varun Bahl / CyaSSL-Encryp

Fork of CyaSSL-forEncrypt by Mobius IoT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers newSha256.c Source File

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