X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fsha1.c;h=0553b63cf8e4091de7e11a7bab1fb86983386da6;hp=b65d25d6c57c1a31f8912664c9b64de1fbb3a020;hb=9fb3aaca115429b0af2a623bf20bfceef74f047f;hpb=6f77434ea6ff1407603410e28d1edb966c40e568 diff --git a/src/sha1.c b/src/sha1.c index b65d25d6..0553b63c 100644 --- a/src/sha1.c +++ b/src/sha1.c @@ -4,22 +4,22 @@ * Parts of this file are based on public domain code written by Steve Reid. */ -/* - * Copyright (C) 2012 Eric Biggers +/* + * Copyright (C) 2012, 2013 Eric Biggers * * This file is part of wimlib, a library for working with WIM files. * * wimlib is free software; you can redistribute it and/or modify it under the - * terms of the GNU Lesser General Public License as published by the Free - * Software Foundation; either version 2.1 of the License, or (at your option) + * terms of the GNU General Public License as published by the Free + * Software Foundation; either version 3 of the License, or (at your option) * any later version. * * wimlib 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 Lesser General Public License for more + * A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * - * You should have received a copy of the GNU Lesser General Public License + * You should have received a copy of the GNU General Public License * along with wimlib; if not, see http://www.gnu.org/licenses/. */ @@ -34,61 +34,52 @@ * Steve Reid's public domain code, or based on Intel's SSSE3 SHA1 code. */ -const u8 empty_file_sha1sum[SHA1_HASH_SIZE] = { - 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55, - 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09, +const u8 zero_hash[SHA1_HASH_SIZE] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, }; -#ifdef WITH_LIBCRYPTO - -#define sha1_init SHA1_Init -#define sha1_update SHA1_Update -#define sha1_final SHA1_Final +#ifndef WITH_LIBCRYPTO -#else /* WITH_LIBCRYPTO */ - -typedef struct { - u32 state[5]; - u32 count[2]; - u8 buffer[64]; -} SHA_CTX; +/* Initialize new context */ +void +sha1_init(SHA_CTX* context) +{ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} #ifdef ENABLE_SSSE3_SHA1 -extern void sha1_update_intel(int *hash, const char* input, size_t num_blocks); +extern void +sha1_update_intel(int *hash, const void* input, size_t num_blocks); -static inline void sha1_update(SHA_CTX *context, const void *data, size_t len) +void +sha1_update(SHA_CTX *context, const void *data, size_t len) { sha1_update_intel((int*)&context->state, data, len / 64); size_t j = (context->count[0] >> 3) & 63; if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; context->count[1] += (len >> 29); } - #include -void ssse3_not_found() +void +ssse3_not_found() { - fprintf(stderr, + fprintf(stderr, "Cannot calculate SHA1 message digest: CPU does not support SSSE3\n" "instructions! Recompile wimlib without the --enable-ssse3-sha1 flag\n" "to use wimlib on this CPU.\n"); abort(); } -#endif - -/* Initialize new context */ -static void sha1_init(SHA_CTX* context) -{ - /* SHA1 initialization constants */ - context->state[0] = 0x67452301; - context->state[1] = 0xEFCDAB89; - context->state[2] = 0x98BADCFE; - context->state[3] = 0x10325476; - context->state[4] = 0xC3D2E1F0; - context->count[0] = context->count[1] = 0; -} - -#ifndef ENABLE_SSSE3_SHA1 +#else /* ENABLE_SSSE3_SHA1 */ #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) @@ -112,7 +103,8 @@ static void sha1_init(SHA_CTX* context) #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); /* Hash a single 512-bit block. This is the core of the algorithm. */ -static void sha1_transform(u32 state[5], const u8 buffer[64]) +static void +sha1_transform(u32 state[5], const u8 buffer[64]) { u32 a, b, c, d, e; typedef union { @@ -162,8 +154,8 @@ static void sha1_transform(u32 state[5], const u8 buffer[64]) state[4] += e; } -/* Run your data through this. */ -static void sha1_update(SHA_CTX* context, const u8* data, const size_t len) +void +sha1_update(SHA_CTX* context, const void *data, const size_t len) { size_t i, j; @@ -181,12 +173,14 @@ static void sha1_update(SHA_CTX* context, const u8* data, const size_t len) } else { i = 0; } - memcpy(&context->buffer[j], &data[i], len - i); + memcpy(&context->buffer[j], data + i, len - i); } -#endif + +#endif /* !ENABLE_SSSE3_SHA1 */ /* Add padding and return the message digest. */ -static void sha1_final(u8 *md, SHA_CTX* context) +void +sha1_final(u8 md[SHA1_HASH_SIZE], SHA_CTX* context) { u32 i; u8 finalcount[8]; @@ -199,13 +193,14 @@ static void sha1_final(u8 *md, SHA_CTX* context) while ((context->count[0] & 504) != 448) { sha1_update(context, (u8 *)"\0", 1); } - sha1_update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ + sha1_update(context, finalcount, 8); /* Should cause a sha1_transform() */ for (i = 0; i < SHA1_HASH_SIZE; i++) { md[i] = (u8)((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } } -void sha1_buffer(const void *buffer, size_t len, void *md) +void +sha1_buffer(const void *buffer, size_t len, u8 md[SHA1_HASH_SIZE]) { SHA_CTX ctx; sha1_init(&ctx); @@ -213,9 +208,10 @@ void sha1_buffer(const void *buffer, size_t len, void *md) sha1_final(md, &ctx); } -#endif /* WITH_LIBCRYPTO */ +#endif /* !WITH_LIBCRYPTO */ -static int sha1_stream(FILE *fp, void *md) +static int +sha1_stream(FILE *fp, u8 md[SHA1_HASH_SIZE]) { char buf[BUFFER_SIZE]; size_t bytes_read; @@ -235,20 +231,25 @@ static int sha1_stream(FILE *fp, void *md) } -/* Calculates the SHA1 message digest given the name of a file. @md must point - * to a buffer of length 20 bytes into which the message digest is written. - */ -int sha1sum(const char *filename, void *md) +/* Calculates the SHA1 message digest of a file. @md must point to a buffer of + * length 20 bytes into which the message digest is written. */ +int +sha1sum(const mbchar *filename, u8 md[SHA1_HASH_SIZE]) { FILE *fp; int ret; fp = fopen(filename, "rb"); if (!fp) { - ERROR("Cannot open the file `%s' for reading: %m\n", filename); + ERROR_WITH_ERRNO("Cannot open the file `%s' for reading", + filename); return WIMLIB_ERR_OPEN; } ret = sha1_stream(fp, md); + if (ret != 0) { + ERROR_WITH_ERRNO("Error calculating SHA1 message digest of " + "`%s'", filename); + } fclose(fp); return ret; }