mbedtls ported to mbed-classic

Fork of mbedtls by Christopher Haster

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sha1.c Source File

sha1.c

00001 /*
00002  *  FIPS-180-1 compliant SHA-1 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-1 standard was published by NIST in 1993.
00023  *
00024  *  http://www.itl.nist.gov/fipspubs/fip180-1.htm
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_SHA1_C)
00034 
00035 #include "mbedtls/sha1.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_SHA1_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 {                                                       \
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 }
00066 #endif
00067 
00068 #ifndef PUT_UINT32_BE
00069 #define PUT_UINT32_BE(n,b,i)                            \
00070 {                                                       \
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 }
00076 #endif
00077 
00078 void mbedtls_sha1_init( mbedtls_sha1_context *ctx )
00079 {
00080     memset( ctx, 0, sizeof( mbedtls_sha1_context ) );
00081 }
00082 
00083 void mbedtls_sha1_free( mbedtls_sha1_context *ctx )
00084 {
00085     if( ctx == NULL )
00086         return;
00087 
00088     mbedtls_zeroize( ctx, sizeof( mbedtls_sha1_context ) );
00089 }
00090 
00091 void mbedtls_sha1_clone( mbedtls_sha1_context *dst,
00092                          const mbedtls_sha1_context *src )
00093 {
00094     *dst = *src;
00095 }
00096 
00097 /*
00098  * SHA-1 context setup
00099  */
00100 void mbedtls_sha1_starts( mbedtls_sha1_context *ctx )
00101 {
00102     ctx->total [0] = 0;
00103     ctx->total [1] = 0;
00104 
00105     ctx->state [0] = 0x67452301;
00106     ctx->state [1] = 0xEFCDAB89;
00107     ctx->state [2] = 0x98BADCFE;
00108     ctx->state [3] = 0x10325476;
00109     ctx->state [4] = 0xC3D2E1F0;
00110 }
00111 
00112 #if !defined(MBEDTLS_SHA1_PROCESS_ALT)
00113 void mbedtls_sha1_process( mbedtls_sha1_context *ctx, const unsigned char data[64] )
00114 {
00115     uint32_t temp, W[16], A, B, C, D, E;
00116 
00117     GET_UINT32_BE( W[ 0], data,  0 );
00118     GET_UINT32_BE( W[ 1], data,  4 );
00119     GET_UINT32_BE( W[ 2], data,  8 );
00120     GET_UINT32_BE( W[ 3], data, 12 );
00121     GET_UINT32_BE( W[ 4], data, 16 );
00122     GET_UINT32_BE( W[ 5], data, 20 );
00123     GET_UINT32_BE( W[ 6], data, 24 );
00124     GET_UINT32_BE( W[ 7], data, 28 );
00125     GET_UINT32_BE( W[ 8], data, 32 );
00126     GET_UINT32_BE( W[ 9], data, 36 );
00127     GET_UINT32_BE( W[10], data, 40 );
00128     GET_UINT32_BE( W[11], data, 44 );
00129     GET_UINT32_BE( W[12], data, 48 );
00130     GET_UINT32_BE( W[13], data, 52 );
00131     GET_UINT32_BE( W[14], data, 56 );
00132     GET_UINT32_BE( W[15], data, 60 );
00133 
00134 #define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
00135 
00136 #define R(t)                                            \
00137 (                                                       \
00138     temp = W[( t -  3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
00139            W[( t - 14 ) & 0x0F] ^ W[  t       & 0x0F],  \
00140     ( W[t & 0x0F] = S(temp,1) )                         \
00141 )
00142 
00143 #define P(a,b,c,d,e,x)                                  \
00144 {                                                       \
00145     e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
00146 }
00147 
00148     A = ctx->state [0];
00149     B = ctx->state [1];
00150     C = ctx->state [2];
00151     D = ctx->state [3];
00152     E = ctx->state [4];
00153 
00154 #define F(x,y,z) (z ^ (x & (y ^ z)))
00155 #define K 0x5A827999
00156 
00157     P( A, B, C, D, E, W[0]  );
00158     P( E, A, B, C, D, W[1]  );
00159     P( D, E, A, B, C, W[2]  );
00160     P( C, D, E, A, B, W[3]  );
00161     P( B, C, D, E, A, W[4]  );
00162     P( A, B, C, D, E, W[5]  );
00163     P( E, A, B, C, D, W[6]  );
00164     P( D, E, A, B, C, W[7]  );
00165     P( C, D, E, A, B, W[8]  );
00166     P( B, C, D, E, A, W[9]  );
00167     P( A, B, C, D, E, W[10] );
00168     P( E, A, B, C, D, W[11] );
00169     P( D, E, A, B, C, W[12] );
00170     P( C, D, E, A, B, W[13] );
00171     P( B, C, D, E, A, W[14] );
00172     P( A, B, C, D, E, W[15] );
00173     P( E, A, B, C, D, R(16) );
00174     P( D, E, A, B, C, R(17) );
00175     P( C, D, E, A, B, R(18) );
00176     P( B, C, D, E, A, R(19) );
00177 
00178 #undef K
00179 #undef F
00180 
00181 #define F(x,y,z) (x ^ y ^ z)
00182 #define K 0x6ED9EBA1
00183 
00184     P( A, B, C, D, E, R(20) );
00185     P( E, A, B, C, D, R(21) );
00186     P( D, E, A, B, C, R(22) );
00187     P( C, D, E, A, B, R(23) );
00188     P( B, C, D, E, A, R(24) );
00189     P( A, B, C, D, E, R(25) );
00190     P( E, A, B, C, D, R(26) );
00191     P( D, E, A, B, C, R(27) );
00192     P( C, D, E, A, B, R(28) );
00193     P( B, C, D, E, A, R(29) );
00194     P( A, B, C, D, E, R(30) );
00195     P( E, A, B, C, D, R(31) );
00196     P( D, E, A, B, C, R(32) );
00197     P( C, D, E, A, B, R(33) );
00198     P( B, C, D, E, A, R(34) );
00199     P( A, B, C, D, E, R(35) );
00200     P( E, A, B, C, D, R(36) );
00201     P( D, E, A, B, C, R(37) );
00202     P( C, D, E, A, B, R(38) );
00203     P( B, C, D, E, A, R(39) );
00204 
00205 #undef K
00206 #undef F
00207 
00208 #define F(x,y,z) ((x & y) | (z & (x | y)))
00209 #define K 0x8F1BBCDC
00210 
00211     P( A, B, C, D, E, R(40) );
00212     P( E, A, B, C, D, R(41) );
00213     P( D, E, A, B, C, R(42) );
00214     P( C, D, E, A, B, R(43) );
00215     P( B, C, D, E, A, R(44) );
00216     P( A, B, C, D, E, R(45) );
00217     P( E, A, B, C, D, R(46) );
00218     P( D, E, A, B, C, R(47) );
00219     P( C, D, E, A, B, R(48) );
00220     P( B, C, D, E, A, R(49) );
00221     P( A, B, C, D, E, R(50) );
00222     P( E, A, B, C, D, R(51) );
00223     P( D, E, A, B, C, R(52) );
00224     P( C, D, E, A, B, R(53) );
00225     P( B, C, D, E, A, R(54) );
00226     P( A, B, C, D, E, R(55) );
00227     P( E, A, B, C, D, R(56) );
00228     P( D, E, A, B, C, R(57) );
00229     P( C, D, E, A, B, R(58) );
00230     P( B, C, D, E, A, R(59) );
00231 
00232 #undef K
00233 #undef F
00234 
00235 #define F(x,y,z) (x ^ y ^ z)
00236 #define K 0xCA62C1D6
00237 
00238     P( A, B, C, D, E, R(60) );
00239     P( E, A, B, C, D, R(61) );
00240     P( D, E, A, B, C, R(62) );
00241     P( C, D, E, A, B, R(63) );
00242     P( B, C, D, E, A, R(64) );
00243     P( A, B, C, D, E, R(65) );
00244     P( E, A, B, C, D, R(66) );
00245     P( D, E, A, B, C, R(67) );
00246     P( C, D, E, A, B, R(68) );
00247     P( B, C, D, E, A, R(69) );
00248     P( A, B, C, D, E, R(70) );
00249     P( E, A, B, C, D, R(71) );
00250     P( D, E, A, B, C, R(72) );
00251     P( C, D, E, A, B, R(73) );
00252     P( B, C, D, E, A, R(74) );
00253     P( A, B, C, D, E, R(75) );
00254     P( E, A, B, C, D, R(76) );
00255     P( D, E, A, B, C, R(77) );
00256     P( C, D, E, A, B, R(78) );
00257     P( B, C, D, E, A, R(79) );
00258 
00259 #undef K
00260 #undef F
00261 
00262     ctx->state [0] += A;
00263     ctx->state [1] += B;
00264     ctx->state [2] += C;
00265     ctx->state [3] += D;
00266     ctx->state [4] += E;
00267 }
00268 #endif /* !MBEDTLS_SHA1_PROCESS_ALT */
00269 
00270 /*
00271  * SHA-1 process buffer
00272  */
00273 void mbedtls_sha1_update( mbedtls_sha1_context *ctx, const unsigned char *input, size_t ilen )
00274 {
00275     size_t fill;
00276     uint32_t left;
00277 
00278     if( ilen == 0 )
00279         return;
00280 
00281     left = ctx->total [0] & 0x3F;
00282     fill = 64 - left;
00283 
00284     ctx->total [0] += (uint32_t) ilen;
00285     ctx->total [0] &= 0xFFFFFFFF;
00286 
00287     if( ctx->total [0] < (uint32_t) ilen )
00288         ctx->total [1]++;
00289 
00290     if( left && ilen >= fill )
00291     {
00292         memcpy( (void *) (ctx->buffer  + left), input, fill );
00293         mbedtls_sha1_process( ctx, ctx->buffer  );
00294         input += fill;
00295         ilen  -= fill;
00296         left = 0;
00297     }
00298 
00299     while( ilen >= 64 )
00300     {
00301         mbedtls_sha1_process( ctx, input );
00302         input += 64;
00303         ilen  -= 64;
00304     }
00305 
00306     if( ilen > 0 )
00307         memcpy( (void *) (ctx->buffer  + left), input, ilen );
00308 }
00309 
00310 static const unsigned char sha1_padding[64] =
00311 {
00312  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00313     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00314     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00315     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00316 };
00317 
00318 /*
00319  * SHA-1 final digest
00320  */
00321 void mbedtls_sha1_finish( mbedtls_sha1_context *ctx, unsigned char output[20] )
00322 {
00323     uint32_t last, padn;
00324     uint32_t high, low;
00325     unsigned char msglen[8];
00326 
00327     high = ( ctx->total [0] >> 29 )
00328          | ( ctx->total [1] <<  3 );
00329     low  = ( ctx->total [0] <<  3 );
00330 
00331     PUT_UINT32_BE( high, msglen, 0 );
00332     PUT_UINT32_BE( low,  msglen, 4 );
00333 
00334     last = ctx->total [0] & 0x3F;
00335     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00336 
00337     mbedtls_sha1_update( ctx, sha1_padding, padn );
00338     mbedtls_sha1_update( ctx, msglen, 8 );
00339 
00340     PUT_UINT32_BE( ctx->state [0], output,  0 );
00341     PUT_UINT32_BE( ctx->state [1], output,  4 );
00342     PUT_UINT32_BE( ctx->state [2], output,  8 );
00343     PUT_UINT32_BE( ctx->state [3], output, 12 );
00344     PUT_UINT32_BE( ctx->state [4], output, 16 );
00345 }
00346 
00347 #endif /* !MBEDTLS_SHA1_ALT */
00348 
00349 /*
00350  * output = SHA-1( input buffer )
00351  */
00352 void mbedtls_sha1( const unsigned char *input, size_t ilen, unsigned char output[20] )
00353 {
00354     mbedtls_sha1_context ctx;
00355 
00356     mbedtls_sha1_init( &ctx );
00357     mbedtls_sha1_starts( &ctx );
00358     mbedtls_sha1_update( &ctx, input, ilen );
00359     mbedtls_sha1_finish( &ctx, output );
00360     mbedtls_sha1_free( &ctx );
00361 }
00362 
00363 #if defined(MBEDTLS_SELF_TEST)
00364 /*
00365  * FIPS-180-1 test vectors
00366  */
00367 static const unsigned char sha1_test_buf[3][57] =
00368 {
00369     { "abc" },
00370     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
00371     { "" }
00372 };
00373 
00374 static const int sha1_test_buflen[3] =
00375 {
00376     3, 56, 1000
00377 };
00378 
00379 static const unsigned char sha1_test_sum[3][20] =
00380 {
00381     { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
00382       0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
00383     { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
00384       0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
00385     { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
00386       0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
00387 };
00388 
00389 /*
00390  * Checkup routine
00391  */
00392 int mbedtls_sha1_self_test( int verbose )
00393 {
00394     int i, j, buflen, ret = 0;
00395     unsigned char buf[1024];
00396     unsigned char sha1sum[20];
00397     mbedtls_sha1_context ctx;
00398 
00399     mbedtls_sha1_init( &ctx );
00400 
00401     /*
00402      * SHA-1
00403      */
00404     for( i = 0; i < 3; i++ )
00405     {
00406         if( verbose != 0 )
00407             mbedtls_printf( "  SHA-1 test #%d: ", i + 1 );
00408 
00409         mbedtls_sha1_starts( &ctx );
00410 
00411         if( i == 2 )
00412         {
00413             memset( buf, 'a', buflen = 1000 );
00414 
00415             for( j = 0; j < 1000; j++ )
00416                 mbedtls_sha1_update( &ctx, buf, buflen );
00417         }
00418         else
00419             mbedtls_sha1_update( &ctx, sha1_test_buf[i],
00420                                sha1_test_buflen[i] );
00421 
00422         mbedtls_sha1_finish( &ctx, sha1sum );
00423 
00424         if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
00425         {
00426             if( verbose != 0 )
00427                 mbedtls_printf( "failed\n" );
00428 
00429             ret = 1;
00430             goto exit;
00431         }
00432 
00433         if( verbose != 0 )
00434             mbedtls_printf( "passed\n" );
00435     }
00436 
00437     if( verbose != 0 )
00438         mbedtls_printf( "\n" );
00439 
00440 exit:
00441     mbedtls_sha1_free( &ctx );
00442 
00443     return( ret );
00444 }
00445 
00446 #endif /* MBEDTLS_SELF_TEST */
00447 
00448 #endif /* MBEDTLS_SHA1_C */