aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/check
diff options
context:
space:
mode:
Diffstat (limited to 'src/liblzma/check')
-rw-r--r--src/liblzma/check/Makefile.am1
-rw-r--r--src/liblzma/check/check.c55
-rw-r--r--src/liblzma/check/check.h47
-rw-r--r--src/liblzma/check/check_byteswap.h43
-rw-r--r--src/liblzma/check/crc32_init.c2
-rw-r--r--src/liblzma/check/crc64_init.c2
-rw-r--r--src/liblzma/check/crc_macros.h2
-rw-r--r--src/liblzma/check/sha256.c53
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;