| /////////////////////////////////////////////////////////////////////////////// |
| // |
| /// \file check.h |
| /// \brief Internal API to different integrity check functions |
| // |
| // Author: Lasse Collin |
| // |
| // This file has been put into the public domain. |
| // You can do whatever you want with this file. |
| // |
| /////////////////////////////////////////////////////////////////////////////// |
| |
| #ifndef LZMA_CHECK_H |
| #define LZMA_CHECK_H |
| |
| #include "common.h" |
| |
| #if defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) |
| # include <CommonCrypto/CommonDigest.h> |
| #elif defined(HAVE_SHA256_H) |
| # include <sys/types.h> |
| # include <sha256.h> |
| #elif defined(HAVE_SHA2_H) |
| # include <sys/types.h> |
| # include <sha2.h> |
| #elif defined(HAVE_MINIX_SHA2_H) |
| # include <sys/types.h> |
| # include <minix/sha2.h> |
| #endif |
| |
| #if defined(HAVE_CC_SHA256_CTX) |
| typedef CC_SHA256_CTX lzma_sha256_state; |
| #elif defined(HAVE_SHA256_CTX) |
| typedef SHA256_CTX lzma_sha256_state; |
| #elif defined(HAVE_SHA2_CTX) |
| typedef SHA2_CTX lzma_sha256_state; |
| #else |
| /// State for the internal SHA-256 implementation |
| typedef struct { |
| /// Internal state |
| uint32_t state[8]; |
| |
| /// Size of the message excluding padding |
| uint64_t size; |
| } lzma_sha256_state; |
| #endif |
| |
| #if defined(HAVE_CC_SHA256_INIT) |
| # define LZMA_SHA256FUNC(x) CC_SHA256_ ## x |
| #elif defined(HAVE_SHA256_INIT) |
| # define LZMA_SHA256FUNC(x) SHA256_ ## x |
| #elif defined(HAVE_SHA256INIT) |
| # define LZMA_SHA256FUNC(x) SHA256 ## x |
| #endif |
| |
| // Index hashing needs the best possible hash function (preferably |
| // a cryptographic hash) for maximum reliability. |
| #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 |
| |
| |
| /// \brief Structure to hold internal state of the check being calculated |
| /// |
| /// \note This is not in the public API because this structure may |
| /// change in future if new integrity check algorithms are added. |
| typedef struct { |
| /// Buffer to hold the final result and a temporary buffer for SHA256. |
| union { |
| uint8_t u8[64]; |
| uint32_t u32[16]; |
| uint64_t u64[8]; |
| } buffer; |
| |
| /// Check-specific data |
| union { |
| uint32_t crc32; |
| uint64_t crc64; |
| lzma_sha256_state sha256; |
| } state; |
| |
| } lzma_check_state; |
| |
| |
| /// lzma_crc32_table[0] is needed by LZ encoder so we need to keep |
| /// the array two-dimensional. |
| #ifdef HAVE_SMALL |
| extern uint32_t lzma_crc32_table[1][256]; |
| extern void lzma_crc32_init(void); |
| #else |
| extern const uint32_t lzma_crc32_table[8][256]; |
| extern const uint64_t lzma_crc64_table[4][256]; |
| #endif |
| |
| |
| /// \brief Initialize *check depending on type |
| /// |
| /// \return LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not |
| /// supported by the current version or build of liblzma. |
| /// LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX. |
| extern void lzma_check_init(lzma_check_state *check, lzma_check type); |
| |
| /// Update the check state |
| extern void lzma_check_update(lzma_check_state *check, lzma_check type, |
| const uint8_t *buf, size_t size); |
| |
| /// Finish the check calculation and store the result to check->buffer.u8. |
| extern void lzma_check_finish(lzma_check_state *check, lzma_check type); |
| |
| |
| #ifndef LZMA_SHA256FUNC |
| |
| /// Prepare SHA-256 state for new input. |
| extern void lzma_sha256_init(lzma_check_state *check); |
| |
| /// Update the SHA-256 hash state |
| extern void lzma_sha256_update( |
| const uint8_t *buf, size_t size, lzma_check_state *check); |
| |
| /// Finish the SHA-256 calculation and store the result to check->buffer.u8. |
| extern void lzma_sha256_finish(lzma_check_state *check); |
| |
| |
| #else |
| |
| static inline void |
| lzma_sha256_init(lzma_check_state *check) |
| { |
| LZMA_SHA256FUNC(Init)(&check->state.sha256); |
| } |
| |
| |
| static inline void |
| lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check) |
| { |
| #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX |
| // Darwin's CC_SHA256_Update takes uint32_t as the buffer size, |
| // so use a loop to support size_t. |
| while (size > UINT32_MAX) { |
| LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX); |
| buf += UINT32_MAX; |
| size -= UINT32_MAX; |
| } |
| #endif |
| |
| LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size); |
| } |
| |
| |
| static inline void |
| lzma_sha256_finish(lzma_check_state *check) |
| { |
| LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256); |
| } |
| |
| #endif |
| |
| #endif |