libalpm
Arch Linux Package Manager Library
sha2.c
Go to the documentation of this file.
00001 /*
00002  *  FIPS-180-2 compliant SHA-256 implementation
00003  *
00004  *  Copyright (C) 2006-2010, Brainspark B.V.
00005  *
00006  *  This file is part of PolarSSL (http://www.polarssl.org)
00007  *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
00008  *
00009  *  All rights reserved.
00010  *
00011  *  This program is free software; you can redistribute it and/or modify
00012  *  it under the terms of the GNU General Public License as published by
00013  *  the Free Software Foundation; either version 2 of the License, or
00014  *  (at your option) any later version.
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU General Public License for more details.
00020  *
00021  *  You should have received a copy of the GNU General Public License
00022  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00023  */
00024 /*
00025  *  The SHA-256 Secure Hash Standard was published by NIST in 2002.
00026  *
00027  *  http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf
00028  */
00029 /*
00030  *  Pacman Notes:
00031  *
00032  *  Taken from the PolarSSL project at http://polarssl.org under terms of the
00033  *  GPL. This is from version 1.0.0 of the library, and has been modified
00034  *  as following, which may be helpful for future updates:
00035  *  * remove "polarssl/config.h" include
00036  *  * change include from "polarssl/md5.h" to "md5.h"
00037  *  * removal of HMAC code
00038  *  * removal of SELF_TEST code
00039  *  * removal of ipad and opad from the sha2_context struct in sha2.h
00040  *  * increase the size of buffer for performance reasons
00041  *  * change 'unsigned long' to uint32_t
00042  */
00043 
00044 #include <stdio.h>
00045 #include <stdint.h>
00046 
00047 #include "sha2.h"
00048 
00049 /*
00050  * 32-bit integer manipulation macros (big endian)
00051  */
00052 #ifndef GET_U32_BE
00053 #define GET_U32_BE(n,b,i)                               \
00054 {                                                       \
00055     (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
00056         | ( (uint32_t) (b)[(i) + 1] << 16 )             \
00057         | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
00058         | ( (uint32_t) (b)[(i) + 3]       );            \
00059 }
00060 #endif
00061 
00062 #ifndef PUT_U32_BE
00063 #define PUT_U32_BE(n,b,i)                               \
00064 {                                                       \
00065     (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
00066     (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
00067     (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
00068     (b)[(i) + 3] = (unsigned char) ( (n)       );       \
00069 }
00070 #endif
00071 
00072 /*
00073  * SHA-256 context setup
00074  */
00075 static void sha2_starts( sha2_context *ctx, int is224 )
00076 {
00077     ctx->total[0] = 0;
00078     ctx->total[1] = 0;
00079 
00080     if( is224 == 0 )
00081     {
00082         /* SHA-256 */
00083         ctx->state[0] = 0x6A09E667;
00084         ctx->state[1] = 0xBB67AE85;
00085         ctx->state[2] = 0x3C6EF372;
00086         ctx->state[3] = 0xA54FF53A;
00087         ctx->state[4] = 0x510E527F;
00088         ctx->state[5] = 0x9B05688C;
00089         ctx->state[6] = 0x1F83D9AB;
00090         ctx->state[7] = 0x5BE0CD19;
00091     }
00092     else
00093     {
00094         /* SHA-224 */
00095         ctx->state[0] = 0xC1059ED8;
00096         ctx->state[1] = 0x367CD507;
00097         ctx->state[2] = 0x3070DD17;
00098         ctx->state[3] = 0xF70E5939;
00099         ctx->state[4] = 0xFFC00B31;
00100         ctx->state[5] = 0x68581511;
00101         ctx->state[6] = 0x64F98FA7;
00102         ctx->state[7] = 0xBEFA4FA4;
00103     }
00104 
00105     ctx->is224 = is224;
00106 }
00107 
00108 static void sha2_process( sha2_context *ctx, const unsigned char data[64] )
00109 {
00110     uint32_t temp1, temp2, W[64];
00111     uint32_t A, B, C, D, E, F, G, H;
00112 
00113     GET_U32_BE( W[ 0], data,  0 );
00114     GET_U32_BE( W[ 1], data,  4 );
00115     GET_U32_BE( W[ 2], data,  8 );
00116     GET_U32_BE( W[ 3], data, 12 );
00117     GET_U32_BE( W[ 4], data, 16 );
00118     GET_U32_BE( W[ 5], data, 20 );
00119     GET_U32_BE( W[ 6], data, 24 );
00120     GET_U32_BE( W[ 7], data, 28 );
00121     GET_U32_BE( W[ 8], data, 32 );
00122     GET_U32_BE( W[ 9], data, 36 );
00123     GET_U32_BE( W[10], data, 40 );
00124     GET_U32_BE( W[11], data, 44 );
00125     GET_U32_BE( W[12], data, 48 );
00126     GET_U32_BE( W[13], data, 52 );
00127     GET_U32_BE( W[14], data, 56 );
00128     GET_U32_BE( W[15], data, 60 );
00129 
00130 #define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
00131 #define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
00132 
00133 #define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
00134 #define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
00135 
00136 #define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
00137 #define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
00138 
00139 #define F0(x,y,z) ((x & y) | (z & (x | y)))
00140 #define F1(x,y,z) (z ^ (x & (y ^ z)))
00141 
00142 #define R(t)                                    \
00143 (                                               \
00144     W[t] = S1(W[t -  2]) + W[t -  7] +          \
00145            S0(W[t - 15]) + W[t - 16]            \
00146 )
00147 
00148 #define P(a,b,c,d,e,f,g,h,x,K)                  \
00149 {                                               \
00150     temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
00151     temp2 = S2(a) + F0(a,b,c);                  \
00152     d += temp1; h = temp1 + temp2;              \
00153 }
00154 
00155     A = ctx->state[0];
00156     B = ctx->state[1];
00157     C = ctx->state[2];
00158     D = ctx->state[3];
00159     E = ctx->state[4];
00160     F = ctx->state[5];
00161     G = ctx->state[6];
00162     H = ctx->state[7];
00163 
00164     P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 );
00165     P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 );
00166     P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF );
00167     P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 );
00168     P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B );
00169     P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 );
00170     P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 );
00171     P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 );
00172     P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 );
00173     P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 );
00174     P( G, H, A, B, C, D, E, F, W[10], 0x243185BE );
00175     P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 );
00176     P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 );
00177     P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE );
00178     P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 );
00179     P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 );
00180     P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 );
00181     P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 );
00182     P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 );
00183     P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC );
00184     P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F );
00185     P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA );
00186     P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC );
00187     P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA );
00188     P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 );
00189     P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D );
00190     P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 );
00191     P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 );
00192     P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 );
00193     P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 );
00194     P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 );
00195     P( B, C, D, E, F, G, H, A, R(31), 0x14292967 );
00196     P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 );
00197     P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 );
00198     P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC );
00199     P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 );
00200     P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 );
00201     P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB );
00202     P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E );
00203     P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 );
00204     P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 );
00205     P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B );
00206     P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 );
00207     P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 );
00208     P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 );
00209     P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 );
00210     P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 );
00211     P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 );
00212     P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 );
00213     P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 );
00214     P( G, H, A, B, C, D, E, F, R(50), 0x2748774C );
00215     P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 );
00216     P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 );
00217     P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A );
00218     P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F );
00219     P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 );
00220     P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE );
00221     P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F );
00222     P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 );
00223     P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 );
00224     P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA );
00225     P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB );
00226     P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 );
00227     P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 );
00228 
00229     ctx->state[0] += A;
00230     ctx->state[1] += B;
00231     ctx->state[2] += C;
00232     ctx->state[3] += D;
00233     ctx->state[4] += E;
00234     ctx->state[5] += F;
00235     ctx->state[6] += G;
00236     ctx->state[7] += H;
00237 }
00238 
00239 /*
00240  * SHA-256 process buffer
00241  */
00242 static void sha2_update( sha2_context *ctx, const unsigned char *input, 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),
00262                 (void *) input, fill );
00263         sha2_process( ctx, ctx->buffer );
00264         input += fill;
00265         ilen  -= fill;
00266         left = 0;
00267     }
00268 
00269     while( ilen >= 64 )
00270     {
00271         sha2_process( ctx, input );
00272         input += 64;
00273         ilen  -= 64;
00274     }
00275 
00276     if( ilen > 0 )
00277     {
00278         memcpy( (void *) (ctx->buffer + left),
00279                 (void *) input, ilen );
00280     }
00281 }
00282 
00283 static const unsigned char sha2_padding[64] =
00284 {
00285  0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00286     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00287     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00288     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
00289 };
00290 
00291 /*
00292  * SHA-256 final digest
00293  */
00294 static void sha2_finish( sha2_context *ctx, unsigned char output[32] )
00295 {
00296     uint32_t last, padn;
00297     uint32_t high, low;
00298     unsigned char msglen[8];
00299 
00300     high = ( ctx->total[0] >> 29 )
00301          | ( ctx->total[1] <<  3 );
00302     low  = ( ctx->total[0] <<  3 );
00303 
00304     PUT_U32_BE( high, msglen, 0 );
00305     PUT_U32_BE( low,  msglen, 4 );
00306 
00307     last = ctx->total[0] & 0x3F;
00308     padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
00309 
00310     sha2_update( ctx, (unsigned char *) sha2_padding, padn );
00311     sha2_update( ctx, msglen, 8 );
00312 
00313     PUT_U32_BE( ctx->state[0], output,  0 );
00314     PUT_U32_BE( ctx->state[1], output,  4 );
00315     PUT_U32_BE( ctx->state[2], output,  8 );
00316     PUT_U32_BE( ctx->state[3], output, 12 );
00317     PUT_U32_BE( ctx->state[4], output, 16 );
00318     PUT_U32_BE( ctx->state[5], output, 20 );
00319     PUT_U32_BE( ctx->state[6], output, 24 );
00320 
00321     if( ctx->is224 == 0 )
00322         PUT_U32_BE( ctx->state[7], output, 28 );
00323 }
00324 
00325 /*
00326  * output = SHA-256( input buffer )
00327  */
00328 void sha2( const unsigned char *input, size_t ilen,
00329            unsigned char output[32], int is224 )
00330 {
00331     sha2_context ctx;
00332 
00333     sha2_starts( &ctx, is224 );
00334     sha2_update( &ctx, input, ilen );
00335     sha2_finish( &ctx, output );
00336 
00337     memset( &ctx, 0, sizeof( sha2_context ) );
00338 }
00339 
00340 /*
00341  * output = SHA-256( file contents )
00342  */
00343 int sha2_file( const char *path, unsigned char output[32], int is224 )
00344 {
00345     FILE *f;
00346     size_t n;
00347     sha2_context ctx;
00348     unsigned char buf[4096];
00349 
00350     if( ( f = fopen( path, "rb" ) ) == NULL )
00351         return( 1 );
00352 
00353     sha2_starts( &ctx, is224 );
00354 
00355     while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
00356         sha2_update( &ctx, buf, n );
00357 
00358     sha2_finish( &ctx, output );
00359 
00360     memset( &ctx, 0, sizeof( sha2_context ) );
00361 
00362     if( ferror( f ) != 0 )
00363     {
00364         fclose( f );
00365         return( 2 );
00366     }
00367 
00368     fclose( f );
00369     return( 0 );
00370 }