Rtos API example

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sha256.c Source File

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