[pacman-dev] [PATCH 1/3] Update MD5 routines with changes from PolarSSL
Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/md5.c | 61 +++++++++++++++++++++------------------------------- lib/libalpm/md5.h | 12 +++++++-- 2 files changed, 34 insertions(+), 39 deletions(-) diff --git a/lib/libalpm/md5.c b/lib/libalpm/md5.c index 9063504..b4391a6 100644 --- a/lib/libalpm/md5.c +++ b/lib/libalpm/md5.c @@ -1,7 +1,12 @@ /* * RFC 1321 compliant MD5 implementation * - * Copyright (C) 2006-2007 Christophe Devine + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,29 +29,19 @@ /* * Pacman Notes: * - * Taken from the XySSL project at www.xyssl.org under terms of the - * GPL. This is from version 0.9 of the library, and has been modified + * Taken from the PolarSSL project at http://polarssl.org under terms of the + * GPL. This is from version 1.0.0 of the library, and has been modified * as following, which may be helpful for future updates: - * * remove "xyssl/config.h" include - * * change include from "xyssl/md5.h" to "md5.h" + * * remove "polarssl/config.h" include + * * change include from "polarssl/sha2.h" to "sha2.h" * * removal of HMAC code * * removal of SELF_TEST code - * * removal of ipad and opad from the md5_context struct in md5.h - * * change of md5_file prototype from - * int md5_file( char *path, unsigned char *output ) - * to - * int md5_file( const char *path, unsigned char *output ) - * * use a dynamically-allocated buffer in md5_file, and increase the size - * for performance reasons - * * various static/inline changes - * - * NOTE: XySSL has been renamed to PolarSSL, which is available at - * www.polarssl.org. If we update, we should get it from there. + * * removal of ipad and opad from the md5_context struct in sha2.h + * * increase the size of buffer for performance reasons + * * various static changes */ -#include <string.h> #include <stdio.h> -#include <stdlib.h> #include "md5.h" @@ -76,7 +71,7 @@ /* * MD5 context setup */ -static inline void md5_starts( md5_context *ctx ) +static void md5_starts( md5_context *ctx ) { ctx->total[0] = 0; ctx->total[1] = 0; @@ -87,7 +82,7 @@ static inline void md5_starts( md5_context *ctx ) ctx->state[3] = 0x10325476; } -static inline void md5_process( md5_context *ctx, unsigned char data[64] ) +static void md5_process( md5_context *ctx, const unsigned char data[64] ) { unsigned long X[16], A, B, C, D; @@ -161,7 +156,7 @@ static inline void md5_process( md5_context *ctx, unsigned char data[64] ) P( B, C, D, A, 12, 20, 0x8D2A4C8A ); #undef F - + #define F(x,y,z) (x ^ y ^ z) P( A, B, C, D, 5, 4, 0xFFFA3942 ); @@ -213,9 +208,9 @@ static inline void md5_process( md5_context *ctx, unsigned char data[64] ) /* * MD5 process buffer */ -static inline void md5_update( md5_context *ctx, unsigned char *input, int ilen ) +static void md5_update( md5_context *ctx, const unsigned char *input, size_t ilen ) { - int fill; + size_t fill; unsigned long left; if( ilen <= 0 ) @@ -224,7 +219,7 @@ static inline void md5_update( md5_context *ctx, unsigned char *input, int ilen left = ctx->total[0] & 0x3F; fill = 64 - left; - ctx->total[0] += ilen; + ctx->total[0] += (unsigned long) ilen; ctx->total[0] &= 0xFFFFFFFF; if( ctx->total[0] < (unsigned long) ilen ) @@ -254,7 +249,7 @@ static inline void md5_update( md5_context *ctx, unsigned char *input, int ilen } } -static unsigned char md5_padding[64] = +static const unsigned char md5_padding[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -265,7 +260,7 @@ static unsigned char md5_padding[64] = /* * MD5 final digest */ -static inline void md5_finish( md5_context *ctx, unsigned char output[16] ) +static void md5_finish( md5_context *ctx, unsigned char output[16] ) { unsigned long last, padn; unsigned long high, low; @@ -293,7 +288,7 @@ static inline void md5_finish( md5_context *ctx, unsigned char output[16] ) /* * output = MD5( input buffer ) */ -void md5( unsigned char *input, int ilen, unsigned char output[16] ) +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ) { md5_context ctx; @@ -312,25 +307,19 @@ int md5_file( const char *path, unsigned char output[16] ) FILE *f; size_t n; md5_context ctx; - unsigned char *buf; + unsigned char buf[4096]; - if( ( buf = calloc(8192, sizeof(unsigned char)) ) == NULL ) + if( ( f = fopen( path, "rb" ) ) == NULL ) return( 1 ); - if( ( f = fopen( path, "rb" ) ) == NULL ) { - free( buf ); - return( 1 ); - } - md5_starts( &ctx ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) - md5_update( &ctx, buf, (int) n ); + md5_update( &ctx, buf, n ); md5_finish( &ctx, output ); memset( &ctx, 0, sizeof( md5_context ) ); - free( buf ); if( ferror( f ) != 0 ) { diff --git a/lib/libalpm/md5.h b/lib/libalpm/md5.h index ddcea8c..d03013a 100644 --- a/lib/libalpm/md5.h +++ b/lib/libalpm/md5.h @@ -1,7 +1,12 @@ /* * RFC 1321 compliant MD5 implementation * - * Copyright (C) 2006-2007 Christophe Devine + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -16,10 +21,11 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - #ifndef _MD5_H #define _MD5_H +#include <string.h> + /** * \brief MD5 context structure */ @@ -38,7 +44,7 @@ md5_context; * \param ilen length of the input data * \param output MD5 checksum result */ -void md5( unsigned char *input, int ilen, unsigned char output[16] ); +void md5( const unsigned char *input, size_t ilen, unsigned char output[16] ); /** * \brief Output = MD5( file contents ) -- 1.7.6
Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/Makefile.am | 3 +- lib/libalpm/sha2.c | 369 +++++++++++++++++++++++++++++++++++++++++++++++ lib/libalpm/sha2.h | 65 +++++++++ 3 files changed, 436 insertions(+), 1 deletions(-) create mode 100644 lib/libalpm/sha2.c create mode 100644 lib/libalpm/sha2.h diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index c863fa9..99f9c1b 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -51,7 +51,8 @@ libalpm_la_SOURCES = \ if !HAVE_LIBSSL libalpm_la_SOURCES += \ - md5.h md5.c + md5.h md5.c \ + sha2.h sha2.c endif if HAVE_LIBGPGME diff --git a/lib/libalpm/sha2.c b/lib/libalpm/sha2.c new file mode 100644 index 0000000..3632c13 --- /dev/null +++ b/lib/libalpm/sha2.c @@ -0,0 +1,369 @@ +/* + * FIPS-180-2 compliant SHA-256 implementation + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +/* + * The SHA-256 Secure Hash Standard was published by NIST in 2002. + * + * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf + */ +/* + * Pacman Notes: + * + * Taken from the PolarSSL project at http://polarssl.org under terms of the + * GPL. This is from version 1.0.0 of the library, and has been modified + * as following, which may be helpful for future updates: + * * remove "polarssl/config.h" include + * * change include from "polarssl/md5.h" to "md5.h" + * * removal of HMAC code + * * removal of SELF_TEST code + * * removal of ipad and opad from the sha2_context struct in sha2.h + * * increase the size of buffer for performance reasons + * * various static changes + */ + +#include <stdio.h> + +#include "sha2.h" + +/* + * 32-bit integer manipulation macros (big endian) + */ +#ifndef GET_ULONG_BE +#define GET_ULONG_BE(n,b,i) \ +{ \ + (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ + | ( (unsigned long) (b)[(i) + 1] << 16 ) \ + | ( (unsigned long) (b)[(i) + 2] << 8 ) \ + | ( (unsigned long) (b)[(i) + 3] ); \ +} +#endif + +#ifndef PUT_ULONG_BE +#define PUT_ULONG_BE(n,b,i) \ +{ \ + (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ + (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ + (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ + (b)[(i) + 3] = (unsigned char) ( (n) ); \ +} +#endif + +/* + * SHA-256 context setup + */ +static void sha2_starts( sha2_context *ctx, int is224 ) +{ + ctx->total[0] = 0; + ctx->total[1] = 0; + + if( is224 == 0 ) + { + /* SHA-256 */ + ctx->state[0] = 0x6A09E667; + ctx->state[1] = 0xBB67AE85; + ctx->state[2] = 0x3C6EF372; + ctx->state[3] = 0xA54FF53A; + ctx->state[4] = 0x510E527F; + ctx->state[5] = 0x9B05688C; + ctx->state[6] = 0x1F83D9AB; + ctx->state[7] = 0x5BE0CD19; + } + else + { + /* SHA-224 */ + ctx->state[0] = 0xC1059ED8; + ctx->state[1] = 0x367CD507; + ctx->state[2] = 0x3070DD17; + ctx->state[3] = 0xF70E5939; + ctx->state[4] = 0xFFC00B31; + ctx->state[5] = 0x68581511; + ctx->state[6] = 0x64F98FA7; + ctx->state[7] = 0xBEFA4FA4; + } + + ctx->is224 = is224; +} + +static void sha2_process( sha2_context *ctx, const unsigned char data[64] ) +{ + unsigned long temp1, temp2, W[64]; + unsigned long A, B, C, D, E, F, G, H; + + GET_ULONG_BE( W[ 0], data, 0 ); + GET_ULONG_BE( W[ 1], data, 4 ); + GET_ULONG_BE( W[ 2], data, 8 ); + GET_ULONG_BE( W[ 3], data, 12 ); + GET_ULONG_BE( W[ 4], data, 16 ); + GET_ULONG_BE( W[ 5], data, 20 ); + GET_ULONG_BE( W[ 6], data, 24 ); + GET_ULONG_BE( W[ 7], data, 28 ); + GET_ULONG_BE( W[ 8], data, 32 ); + GET_ULONG_BE( W[ 9], data, 36 ); + GET_ULONG_BE( W[10], data, 40 ); + GET_ULONG_BE( W[11], data, 44 ); + GET_ULONG_BE( W[12], data, 48 ); + GET_ULONG_BE( W[13], data, 52 ); + GET_ULONG_BE( W[14], data, 56 ); + GET_ULONG_BE( W[15], data, 60 ); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR(x,n) | (x << (32 - n))) + +#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^ SHR(x, 3)) +#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^ SHR(x,10)) + +#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22)) +#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) \ +( \ + W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16] \ +) + +#define P(a,b,c,d,e,f,g,h,x,K) \ +{ \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; \ +} + + A = ctx->state[0]; + B = ctx->state[1]; + C = ctx->state[2]; + D = ctx->state[3]; + E = ctx->state[4]; + F = ctx->state[5]; + G = ctx->state[6]; + H = ctx->state[7]; + + P( A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98 ); + P( H, A, B, C, D, E, F, G, W[ 1], 0x71374491 ); + P( G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF ); + P( F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5 ); + P( E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B ); + P( D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1 ); + P( C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4 ); + P( B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5 ); + P( A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98 ); + P( H, A, B, C, D, E, F, G, W[ 9], 0x12835B01 ); + P( G, H, A, B, C, D, E, F, W[10], 0x243185BE ); + P( F, G, H, A, B, C, D, E, W[11], 0x550C7DC3 ); + P( E, F, G, H, A, B, C, D, W[12], 0x72BE5D74 ); + P( D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE ); + P( C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7 ); + P( B, C, D, E, F, G, H, A, W[15], 0xC19BF174 ); + P( A, B, C, D, E, F, G, H, R(16), 0xE49B69C1 ); + P( H, A, B, C, D, E, F, G, R(17), 0xEFBE4786 ); + P( G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6 ); + P( F, G, H, A, B, C, D, E, R(19), 0x240CA1CC ); + P( E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F ); + P( D, E, F, G, H, A, B, C, R(21), 0x4A7484AA ); + P( C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC ); + P( B, C, D, E, F, G, H, A, R(23), 0x76F988DA ); + P( A, B, C, D, E, F, G, H, R(24), 0x983E5152 ); + P( H, A, B, C, D, E, F, G, R(25), 0xA831C66D ); + P( G, H, A, B, C, D, E, F, R(26), 0xB00327C8 ); + P( F, G, H, A, B, C, D, E, R(27), 0xBF597FC7 ); + P( E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3 ); + P( D, E, F, G, H, A, B, C, R(29), 0xD5A79147 ); + P( C, D, E, F, G, H, A, B, R(30), 0x06CA6351 ); + P( B, C, D, E, F, G, H, A, R(31), 0x14292967 ); + P( A, B, C, D, E, F, G, H, R(32), 0x27B70A85 ); + P( H, A, B, C, D, E, F, G, R(33), 0x2E1B2138 ); + P( G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC ); + P( F, G, H, A, B, C, D, E, R(35), 0x53380D13 ); + P( E, F, G, H, A, B, C, D, R(36), 0x650A7354 ); + P( D, E, F, G, H, A, B, C, R(37), 0x766A0ABB ); + P( C, D, E, F, G, H, A, B, R(38), 0x81C2C92E ); + P( B, C, D, E, F, G, H, A, R(39), 0x92722C85 ); + P( A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1 ); + P( H, A, B, C, D, E, F, G, R(41), 0xA81A664B ); + P( G, H, A, B, C, D, E, F, R(42), 0xC24B8B70 ); + P( F, G, H, A, B, C, D, E, R(43), 0xC76C51A3 ); + P( E, F, G, H, A, B, C, D, R(44), 0xD192E819 ); + P( D, E, F, G, H, A, B, C, R(45), 0xD6990624 ); + P( C, D, E, F, G, H, A, B, R(46), 0xF40E3585 ); + P( B, C, D, E, F, G, H, A, R(47), 0x106AA070 ); + P( A, B, C, D, E, F, G, H, R(48), 0x19A4C116 ); + P( H, A, B, C, D, E, F, G, R(49), 0x1E376C08 ); + P( G, H, A, B, C, D, E, F, R(50), 0x2748774C ); + P( F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5 ); + P( E, F, G, H, A, B, C, D, R(52), 0x391C0CB3 ); + P( D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A ); + P( C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F ); + P( B, C, D, E, F, G, H, A, R(55), 0x682E6FF3 ); + P( A, B, C, D, E, F, G, H, R(56), 0x748F82EE ); + P( H, A, B, C, D, E, F, G, R(57), 0x78A5636F ); + P( G, H, A, B, C, D, E, F, R(58), 0x84C87814 ); + P( F, G, H, A, B, C, D, E, R(59), 0x8CC70208 ); + P( E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA ); + P( D, E, F, G, H, A, B, C, R(61), 0xA4506CEB ); + P( C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7 ); + P( B, C, D, E, F, G, H, A, R(63), 0xC67178F2 ); + + ctx->state[0] += A; + ctx->state[1] += B; + ctx->state[2] += C; + ctx->state[3] += D; + ctx->state[4] += E; + ctx->state[5] += F; + ctx->state[6] += G; + ctx->state[7] += H; +} + +/* + * SHA-256 process buffer + */ +static void sha2_update( sha2_context *ctx, const unsigned char *input, size_t ilen ) +{ + size_t fill; + unsigned long left; + + if( ilen <= 0 ) + return; + + left = ctx->total[0] & 0x3F; + fill = 64 - left; + + ctx->total[0] += (unsigned long) ilen; + ctx->total[0] &= 0xFFFFFFFF; + + if( ctx->total[0] < (unsigned long) ilen ) + ctx->total[1]++; + + if( left && ilen >= fill ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, fill ); + sha2_process( ctx, ctx->buffer ); + input += fill; + ilen -= fill; + left = 0; + } + + while( ilen >= 64 ) + { + sha2_process( ctx, input ); + input += 64; + ilen -= 64; + } + + if( ilen > 0 ) + { + memcpy( (void *) (ctx->buffer + left), + (void *) input, ilen ); + } +} + +static const unsigned char sha2_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* + * SHA-256 final digest + */ +static void sha2_finish( sha2_context *ctx, unsigned char output[32] ) +{ + unsigned long last, padn; + unsigned long high, low; + unsigned char msglen[8]; + + high = ( ctx->total[0] >> 29 ) + | ( ctx->total[1] << 3 ); + low = ( ctx->total[0] << 3 ); + + PUT_ULONG_BE( high, msglen, 0 ); + PUT_ULONG_BE( low, msglen, 4 ); + + last = ctx->total[0] & 0x3F; + padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); + + sha2_update( ctx, (unsigned char *) sha2_padding, padn ); + sha2_update( ctx, msglen, 8 ); + + PUT_ULONG_BE( ctx->state[0], output, 0 ); + PUT_ULONG_BE( ctx->state[1], output, 4 ); + PUT_ULONG_BE( ctx->state[2], output, 8 ); + PUT_ULONG_BE( ctx->state[3], output, 12 ); + PUT_ULONG_BE( ctx->state[4], output, 16 ); + PUT_ULONG_BE( ctx->state[5], output, 20 ); + PUT_ULONG_BE( ctx->state[6], output, 24 ); + + if( ctx->is224 == 0 ) + PUT_ULONG_BE( ctx->state[7], output, 28 ); +} + +/* + * output = SHA-256( input buffer ) + */ +void sha2( const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ) +{ + sha2_context ctx; + + sha2_starts( &ctx, is224 ); + sha2_update( &ctx, input, ilen ); + sha2_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha2_context ) ); +} + +/* + * output = SHA-256( file contents ) + */ +int sha2_file( const char *path, unsigned char output[32], int is224 ) +{ + FILE *f; + size_t n; + sha2_context ctx; + unsigned char buf[4096]; + + if( ( f = fopen( path, "rb" ) ) == NULL ) + return( 1 ); + + sha2_starts( &ctx, is224 ); + + while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) + sha2_update( &ctx, buf, n ); + + sha2_finish( &ctx, output ); + + memset( &ctx, 0, sizeof( sha2_context ) ); + + if( ferror( f ) != 0 ) + { + fclose( f ); + return( 2 ); + } + + fclose( f ); + return( 0 ); +} diff --git a/lib/libalpm/sha2.h b/lib/libalpm/sha2.h new file mode 100644 index 0000000..887b9c6 --- /dev/null +++ b/lib/libalpm/sha2.h @@ -0,0 +1,65 @@ +/* + * SHA-224 and SHA-256 cryptographic hash function + * + * Copyright (C) 2006-2010, Brainspark B.V. + * + * This file is part of PolarSSL (http://www.polarssl.org) + * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> + * + * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef _SHA2_H +#define _SHA2_H + +#include <string.h> + +/** + * \brief SHA-256 context structure + */ +typedef struct +{ + unsigned long total[2]; /*!< number of bytes processed */ + unsigned long state[8]; /*!< intermediate digest state */ + unsigned char buffer[64]; /*!< data block being processed */ + + int is224; /*!< 0 => SHA-256, else SHA-224 */ +} +sha2_context; + +/** + * \brief Output = SHA-256( input buffer ) + * + * \param input buffer holding the data + * \param ilen length of the input data + * \param output SHA-224/256 checksum result + * \param is224 0 = use SHA256, 1 = use SHA224 + */ +void sha2( const unsigned char *input, size_t ilen, + unsigned char output[32], int is224 ); + +/** + * \brief Output = SHA-256( file contents ) + * + * \param path input file name + * \param output SHA-224/256 checksum result + * \param is224 0 = use SHA256, 1 = use SHA224 + * + * \return 0 if successful, 1 if fopen failed, + * or 2 if fread failed + */ +int sha2_file( const char *path, unsigned char output[32], int is224 ); + +#endif /* sha2.h */ -- 1.7.6
These mirror ones we already have for md5sums. Signed-off-by: Dan McGee <dan@archlinux.org> --- lib/libalpm/alpm.h | 1 + lib/libalpm/util.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 0 deletions(-) diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 32db687..44f3d41 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -1052,6 +1052,7 @@ char *alpm_dep_compute_string(const alpm_depend_t *dep); /* checksums */ char *alpm_compute_md5sum(const char *name); +char *alpm_compute_sha256sum(const char *filename); /** @addtogroup alpm_api_errors Error Codes * @{ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index adb1d19..b1f37eb 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -46,8 +46,10 @@ #ifdef HAVE_LIBSSL #include <openssl/md5.h> +#include <openssl/sha.h> #else #include "md5.h" +#include "sha2.h" #endif /* libalpm */ @@ -747,6 +749,53 @@ static int md5_file(const char *path, unsigned char output[16]) fclose(f); return 0; } + +/* third param is so we match the PolarSSL definition */ +static int sha2_file(const char *path, unsigned char output[32], int is224) +{ + FILE *f; + size_t n; + SHA256_CTX ctx; + unsigned char *buf; + + CALLOC(buf, 8192, sizeof(unsigned char), return 1); + + if((f = fopen(path, "rb")) == NULL) { + free(buf); + return 1; + } + + if(is224) { + SHA224_Init(&ctx); + } else { + SHA256_Init(&ctx); + } + + while((n = fread(buf, 1, sizeof(buf), f)) > 0) { + if(is224) { + SHA224_Update(&ctx, buf, n); + } else { + SHA256_Update(&ctx, buf, n); + } + } + + if(is224) { + SHA224_Final(output, &ctx); + } else { + SHA256_Final(output, &ctx); + } + + memset(&ctx, 0, sizeof(SHA256_CTX)); + free(buf); + + if(ferror(f) != 0) { + fclose(f); + return 2; + } + + fclose(f); + return 0; +} #endif /** Get the md5 sum of file. @@ -799,6 +848,37 @@ int _alpm_test_md5sum(const char *filepath, const char *md5sum) return ret; } +/** Get the sha256 sum of file. + * @param filename name of the file + * @return the checksum on success, NULL on error + * @addtogroup alpm_misc + */ +char SYMEXPORT *alpm_compute_sha256sum(const char *filename) +{ + unsigned char output[16]; + char *sha256sum; + int ret, i; + + ASSERT(filename != NULL, return NULL); + + /* allocate 32 chars plus 1 for null */ + CALLOC(sha256sum, 65, sizeof(char), return NULL); + /* defined above for OpenSSL, otherwise defined in sha2.h */ + ret = sha2_file(filename, output, 0); + + if(ret > 0) { + return NULL; + } + + /* Convert the result to something readable */ + for (i = 0; i < 16; i++) { + /* sprintf is acceptable here because we know our output */ + sprintf(sha256sum +(i * 2), "%02x", output[i]); + } + + return sha256sum; +} + /* Note: does NOT handle sparse files on purpose for speed. */ int _alpm_archive_fgets(struct archive *a, struct archive_read_buffer *b) { -- 1.7.6
participants (1)
-
Dan McGee