libalpm
Arch Linux Package Manager Library
|
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 }