/////////////////////////////////////////////////////////////////////////////// // /// \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 #elif defined(HAVE_SHA256_H) # include # include #elif defined(HAVE_SHA2_H) # include # include #elif defined(HAVE_MINIX_SHA2_H) # include # include #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