mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

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