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