diff options
Diffstat (limited to 'src/liblzma/check')
-rw-r--r-- | src/liblzma/check/Makefile.am | 1 | ||||
-rw-r--r-- | src/liblzma/check/check.c | 55 | ||||
-rw-r--r-- | src/liblzma/check/check.h | 47 | ||||
-rw-r--r-- | src/liblzma/check/check_byteswap.h | 43 | ||||
-rw-r--r-- | src/liblzma/check/crc32_init.c | 2 | ||||
-rw-r--r-- | src/liblzma/check/crc64_init.c | 2 | ||||
-rw-r--r-- | src/liblzma/check/crc_macros.h | 2 | ||||
-rw-r--r-- | src/liblzma/check/sha256.c | 53 |
8 files changed, 110 insertions, 95 deletions
diff --git a/src/liblzma/check/Makefile.am b/src/liblzma/check/Makefile.am index e436cb59..182e0868 100644 --- a/src/liblzma/check/Makefile.am +++ b/src/liblzma/check/Makefile.am @@ -14,7 +14,6 @@ libcheck_la_SOURCES = \ check.c \ check.h \ check_init.c \ - check_byteswap.h \ crc_macros.h libcheck_la_CPPFLAGS = \ -I@top_srcdir@/src/liblzma/api \ diff --git a/src/liblzma/check/check.c b/src/liblzma/check/check.c index ba59af2e..388b57e8 100644 --- a/src/liblzma/check/check.c +++ b/src/liblzma/check/check.c @@ -13,8 +13,15 @@ #include "check.h" -// See the .lzma header format specification section 2.2.2. -LZMA_API const uint32_t lzma_check_sizes[8] = { 0, 4, 4, 8, 16, 32, 32, 64 }; +// See the .lzma header format specification section 2.1.1.2. +LZMA_API const uint32_t lzma_check_sizes[LZMA_CHECK_ID_MAX + 1] = { + 0, + 4, 4, 4, + 8, 8, 8, + 16, 16, 16, + 32, 32, 32, + 64, 64, 64 +}; LZMA_API const lzma_bool lzma_available_checks[LZMA_CHECK_ID_MAX + 1] = { @@ -27,6 +34,7 @@ LZMA_API const lzma_bool lzma_available_checks[LZMA_CHECK_ID_MAX + 1] = { #endif false, // Reserved + false, // Reserved #ifdef HAVE_CHECK_CRC64 true, @@ -35,6 +43,10 @@ LZMA_API const lzma_bool lzma_available_checks[LZMA_CHECK_ID_MAX + 1] = { #endif false, // Reserved + false, // Reserved + false, // Reserved + false, // Reserved + false, // Reserved #ifdef HAVE_CHECK_SHA256 true, @@ -44,6 +56,9 @@ LZMA_API const lzma_bool lzma_available_checks[LZMA_CHECK_ID_MAX + 1] = { false, // Reserved false, // Reserved + false, // Reserved + false, // Reserved + false, // Reserved }; @@ -58,24 +73,24 @@ lzma_check_init(lzma_check *check, lzma_check_type type) #ifdef HAVE_CHECK_CRC32 case LZMA_CHECK_CRC32: - check->crc32 = 0; + check->state.crc32 = 0; break; #endif #ifdef HAVE_CHECK_CRC64 case LZMA_CHECK_CRC64: - check->crc64 = 0; + check->state.crc64 = 0; break; #endif #ifdef HAVE_CHECK_SHA256 case LZMA_CHECK_SHA256: - lzma_sha256_init(&check->sha256); + lzma_sha256_init(check); break; #endif default: - if (type <= LZMA_CHECK_ID_MAX) + if ((unsigned)(type) <= LZMA_CHECK_ID_MAX) ret = LZMA_UNSUPPORTED_CHECK; else ret = LZMA_PROG_ERROR; @@ -93,19 +108,19 @@ lzma_check_update(lzma_check *check, lzma_check_type type, switch (type) { #ifdef HAVE_CHECK_CRC32 case LZMA_CHECK_CRC32: - check->crc32 = lzma_crc32(buf, size, check->crc32); + check->state.crc32 = lzma_crc32(buf, size, check->state.crc32); break; #endif #ifdef HAVE_CHECK_CRC64 case LZMA_CHECK_CRC64: - check->crc64 = lzma_crc64(buf, size, check->crc64); + check->state.crc64 = lzma_crc64(buf, size, check->state.crc64); break; #endif #ifdef HAVE_CHECK_SHA256 case LZMA_CHECK_SHA256: - lzma_sha256_update(buf, size, &check->sha256); + lzma_sha256_update(buf, size, check); break; #endif @@ -120,11 +135,29 @@ lzma_check_update(lzma_check *check, lzma_check_type type, extern void lzma_check_finish(lzma_check *check, lzma_check_type type) { + switch (type) { +#ifdef HAVE_CHECK_CRC32 + case LZMA_CHECK_CRC32: + *(uint32_t *)(check->buffer) = check->state.crc32; + break; +#endif + +#ifdef HAVE_CHECK_CRC64 + case LZMA_CHECK_CRC64: + *(uint64_t *)(check->buffer) = check->state.crc64; + break; +#endif + #ifdef HAVE_CHECK_SHA256 - if (type == LZMA_CHECK_SHA256) - lzma_sha256_finish(&check->sha256); + case LZMA_CHECK_SHA256: + lzma_sha256_finish(check); + break; #endif + default: + break; + } + return; } diff --git a/src/liblzma/check/check.h b/src/liblzma/check/check.h index 74279ceb..45ca25e9 100644 --- a/src/liblzma/check/check.h +++ b/src/liblzma/check/check.h @@ -17,15 +17,21 @@ #include "common.h" +// Index hashing used to verify the Index with O(1) memory usage needs +// a good hash function. +#if defined(HAVE_CHECK_SHA256) +# define LZMA_CHECK_BEST LZMA_CHECK_SHA256 +#elif defined(HAVE_CHECK_CRC64) +# define LZMA_CHECK_BEST LZMA_CHECK_CRC64 +#else +# define LZMA_CHECK_BEST LZMA_CHECK_CRC32 +#endif + + typedef struct { /// Internal state uint32_t state[8]; - /// Temporary 8-byte aligned buffer to hold incomplete chunk. - /// After lzma_check_finish(), the first 32 bytes will contain - /// the final digest in big endian byte order. - uint8_t buffer[64]; - /// Size of the message excluding padding uint64_t size; @@ -34,10 +40,27 @@ typedef struct { /// \note This is not in the public API because this structure will /// change in future. -typedef union { - uint32_t crc32; - uint64_t crc64; - lzma_sha256 sha256; +typedef struct { + // FIXME Guarantee 8-byte alignment + + /// Buffer to hold the final result; this is also used as a temporary + /// buffer in SHA256. Note that this buffer must be 8-byte aligned. + uint8_t buffer[64]; + + /// Check-specific data + union { + uint32_t crc32; + uint64_t crc64; + + struct { + /// Internal state + uint32_t state[8]; + + /// Size of the message excluding padding + uint64_t size; + } sha256; + } state; + } lzma_check; @@ -91,12 +114,12 @@ extern void lzma_crc64_init(void); // SHA256 -extern void lzma_sha256_init(lzma_sha256 *sha256); +extern void lzma_sha256_init(lzma_check *check); extern void lzma_sha256_update( - const uint8_t *buf, size_t size, lzma_sha256 *sha256); + const uint8_t *buf, size_t size, lzma_check *check); -extern void lzma_sha256_finish(lzma_sha256 *sha256); +extern void lzma_sha256_finish(lzma_check *check); #endif diff --git a/src/liblzma/check/check_byteswap.h b/src/liblzma/check/check_byteswap.h deleted file mode 100644 index 264def26..00000000 --- a/src/liblzma/check/check_byteswap.h +++ /dev/null @@ -1,43 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file check_byteswap.h -/// \brief Byteswapping needed by the checks -// -// This code has been put into the public domain. -// -// This library 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. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_CHECK_BYTESWAP_H -#define LZMA_CHECK_BYTESWAP_H - -#ifdef HAVE_CONFIG_H -# include <config.h> -#endif - -// byteswap.h is a GNU extension. It contains inline assembly versions -// for byteswapping. When byteswap.h is not available, we use generic code. -#ifdef HAVE_BYTESWAP_H -# include <byteswap.h> -#else -# define bswap_32(num) \ - ( (((num) << 24) ) \ - | (((num) << 8) & UINT32_C(0x00FF0000)) \ - | (((num) >> 8) & UINT32_C(0x0000FF00)) \ - | (((num) >> 24) ) ) - -# define bswap_64(num) \ - ( (((num) << 56) ) \ - | (((num) << 40) & UINT64_C(0x00FF000000000000)) \ - | (((num) << 24) & UINT64_C(0x0000FF0000000000)) \ - | (((num) << 8) & UINT64_C(0x000000FF00000000)) \ - | (((num) >> 8) & UINT64_C(0x00000000FF000000)) \ - | (((num) >> 24) & UINT64_C(0x0000000000FF0000)) \ - | (((num) >> 40) & UINT64_C(0x000000000000FF00)) \ - | (((num) >> 56) ) ) -#endif - -#endif diff --git a/src/liblzma/check/crc32_init.c b/src/liblzma/check/crc32_init.c index 0dd402a4..8b596091 100644 --- a/src/liblzma/check/crc32_init.c +++ b/src/liblzma/check/crc32_init.c @@ -17,7 +17,7 @@ #endif #ifdef WORDS_BIGENDIAN -# include "check_byteswap.h" +# include "../../common/bswap.h" #endif diff --git a/src/liblzma/check/crc64_init.c b/src/liblzma/check/crc64_init.c index 4c91a771..0029987a 100644 --- a/src/liblzma/check/crc64_init.c +++ b/src/liblzma/check/crc64_init.c @@ -17,7 +17,7 @@ #endif #ifdef WORDS_BIGENDIAN -# include "check_byteswap.h" +# include "../../common/bswap.h" #endif diff --git a/src/liblzma/check/crc_macros.h b/src/liblzma/check/crc_macros.h index 5fbecf07..e827d07d 100644 --- a/src/liblzma/check/crc_macros.h +++ b/src/liblzma/check/crc_macros.h @@ -12,7 +12,7 @@ /////////////////////////////////////////////////////////////////////////////// #ifdef WORDS_BIGENDIAN -# include "check_byteswap.h" +# include "../../common/bswap.h" # define A(x) ((x) >> 24) # define B(x) (((x) >> 16) & 0xFF) diff --git a/src/liblzma/check/sha256.c b/src/liblzma/check/sha256.c index 8e3d375a..ea51896e 100644 --- a/src/liblzma/check/sha256.c +++ b/src/liblzma/check/sha256.c @@ -20,7 +20,7 @@ #include "check.h" #ifndef WORDS_BIGENDIAN -# include "check_byteswap.h" +# include "../../common/bswap.h" #endif // At least on x86, GCC is able to optimize this to a rotate instruction. @@ -104,18 +104,18 @@ transform(uint32_t state[static 8], const uint32_t data[static 16]) static void -process(lzma_sha256 *sha256) +process(lzma_check *check) { #ifdef WORDS_BIGENDIAN - transform(sha256->state, (uint32_t *)(sha256->buffer)); + transform(check->state.sha256.state, (uint32_t *)(check->buffer)); #else uint32_t data[16]; for (size_t i = 0; i < 16; ++i) - data[i] = bswap_32(*((uint32_t*)(sha256->buffer) + i)); + data[i] = bswap_32(*((uint32_t*)(check->buffer) + i)); - transform(sha256->state, data); + transform(check->state.sha256.state, data); #endif return; @@ -123,41 +123,41 @@ process(lzma_sha256 *sha256) extern void -lzma_sha256_init(lzma_sha256 *sha256) +lzma_sha256_init(lzma_check *check) { static const uint32_t s[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19, }; - memcpy(sha256->state, s, sizeof(s)); - sha256->size = 0; + memcpy(check->state.sha256.state, s, sizeof(s)); + check->state.sha256.size = 0; return; } extern void -lzma_sha256_update(const uint8_t *buf, size_t size, lzma_sha256 *sha256) +lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check *check) { // Copy the input data into a properly aligned temporary buffer. // This way we can be called with arbitrarily sized buffers // (no need to be multiple of 64 bytes), and the code works also // on architectures that don't allow unaligned memory access. while (size > 0) { - const size_t copy_start = sha256->size & 0x3F; + const size_t copy_start = check->state.sha256.size & 0x3F; size_t copy_size = 64 - copy_start; if (copy_size > size) copy_size = size; - memcpy(sha256->buffer + copy_start, buf, copy_size); + memcpy(check->buffer + copy_start, buf, copy_size); buf += copy_size; size -= copy_size; - sha256->size += copy_size; + check->state.sha256.size += copy_size; - if ((sha256->size & 0x3F) == 0) - process(sha256); + if ((check->state.sha256.size & 0x3F) == 0) + process(check); } return; @@ -165,38 +165,41 @@ lzma_sha256_update(const uint8_t *buf, size_t size, lzma_sha256 *sha256) extern void -lzma_sha256_finish(lzma_sha256 *sha256) +lzma_sha256_finish(lzma_check *check) { // Add padding as described in RFC 3174 (it describes SHA-1 but // the same padding style is used for SHA-256 too). - size_t pos = sha256->size & 0x3F; - sha256->buffer[pos++] = 0x80; + size_t pos = check->state.sha256.size & 0x3F; + check->buffer[pos++] = 0x80; while (pos != 64 - 8) { if (pos == 64) { - process(sha256); + process(check); pos = 0; } - sha256->buffer[pos++] = 0x00; + check->buffer[pos++] = 0x00; } // Convert the message size from bytes to bits. - sha256->size *= 8; + check->state.sha256.size *= 8; #ifdef WORDS_BIGENDIAN - *(uint64_t *)(sha256->buffer + 64 - 8) = sha256->size; + *(uint64_t *)(check->buffer + 64 - 8) = check->state.sha256.size; #else - *(uint64_t *)(sha256->buffer + 64 - 8) = bswap_64(sha256->size); + *(uint64_t *)(check->buffer + 64 - 8) + = bswap_64(check->state.sha256.size); #endif - process(sha256); + process(check); for (size_t i = 0; i < 8; ++i) #ifdef WORDS_BIGENDIAN - ((uint32_t *)(sha256->buffer))[i] = sha256->state[i]; + ((uint32_t *)(check->buffer))[i] + = check->state.sha256.state[i]; #else - ((uint32_t *)(sha256->buffer))[i] = bswap_32(sha256->state[i]); + ((uint32_t *)(check->buffer))[i] + = bswap_32(check->state.sha256.state[i]); #endif return; |