takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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