181ad8388SMartin Matuska /////////////////////////////////////////////////////////////////////////////// 281ad8388SMartin Matuska // 381ad8388SMartin Matuska /// \file check.h 481ad8388SMartin Matuska /// \brief Internal API to different integrity check functions 581ad8388SMartin Matuska // 681ad8388SMartin Matuska // Author: Lasse Collin 781ad8388SMartin Matuska // 881ad8388SMartin Matuska // This file has been put into the public domain. 981ad8388SMartin Matuska // You can do whatever you want with this file. 1081ad8388SMartin Matuska // 1181ad8388SMartin Matuska /////////////////////////////////////////////////////////////////////////////// 1281ad8388SMartin Matuska 1381ad8388SMartin Matuska #ifndef LZMA_CHECK_H 1481ad8388SMartin Matuska #define LZMA_CHECK_H 1581ad8388SMartin Matuska 1681ad8388SMartin Matuska #include "common.h" 1781ad8388SMartin Matuska 18*1456f0f9SXin LI // If the function for external SHA-256 is missing, use the internal SHA-256 19*1456f0f9SXin LI // code. Due to how configure works, these defines can only get defined when 20*1456f0f9SXin LI // both a usable header and a type have already been found. 21*1456f0f9SXin LI #if !(defined(HAVE_CC_SHA256_INIT) \ 22*1456f0f9SXin LI || defined(HAVE_SHA256_INIT) \ 23*1456f0f9SXin LI || defined(HAVE_SHA256INIT)) 24*1456f0f9SXin LI # define HAVE_INTERNAL_SHA256 1 25*1456f0f9SXin LI #endif 26*1456f0f9SXin LI 27*1456f0f9SXin LI #if defined(HAVE_INTERNAL_SHA256) 28*1456f0f9SXin LI // Nothing 29*1456f0f9SXin LI #elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) 3053200025SRui Paulo # include <CommonCrypto/CommonDigest.h> 3153200025SRui Paulo #elif defined(HAVE_SHA256_H) 3253200025SRui Paulo # include <sys/types.h> 3353200025SRui Paulo # include <sha256.h> 3453200025SRui Paulo #elif defined(HAVE_SHA2_H) 3553200025SRui Paulo # include <sys/types.h> 3653200025SRui Paulo # include <sha2.h> 3753200025SRui Paulo #endif 3853200025SRui Paulo 39*1456f0f9SXin LI #if defined(HAVE_INTERNAL_SHA256) 4053200025SRui Paulo /// State for the internal SHA-256 implementation 4153200025SRui Paulo typedef struct { 4253200025SRui Paulo /// Internal state 4353200025SRui Paulo uint32_t state[8]; 4453200025SRui Paulo 4553200025SRui Paulo /// Size of the message excluding padding 4653200025SRui Paulo uint64_t size; 4753200025SRui Paulo } lzma_sha256_state; 48*1456f0f9SXin LI #elif defined(HAVE_CC_SHA256_CTX) 49*1456f0f9SXin LI typedef CC_SHA256_CTX lzma_sha256_state; 50*1456f0f9SXin LI #elif defined(HAVE_SHA256_CTX) 51*1456f0f9SXin LI typedef SHA256_CTX lzma_sha256_state; 52*1456f0f9SXin LI #elif defined(HAVE_SHA2_CTX) 53*1456f0f9SXin LI typedef SHA2_CTX lzma_sha256_state; 5453200025SRui Paulo #endif 5553200025SRui Paulo 56*1456f0f9SXin LI #if defined(HAVE_INTERNAL_SHA256) 57*1456f0f9SXin LI // Nothing 58*1456f0f9SXin LI #elif defined(HAVE_CC_SHA256_INIT) 5953200025SRui Paulo # define LZMA_SHA256FUNC(x) CC_SHA256_ ## x 6053200025SRui Paulo #elif defined(HAVE_SHA256_INIT) 6153200025SRui Paulo # define LZMA_SHA256FUNC(x) SHA256_ ## x 6253200025SRui Paulo #elif defined(HAVE_SHA256INIT) 6353200025SRui Paulo # define LZMA_SHA256FUNC(x) SHA256 ## x 6453200025SRui Paulo #endif 6581ad8388SMartin Matuska 6681ad8388SMartin Matuska // Index hashing needs the best possible hash function (preferably 6781ad8388SMartin Matuska // a cryptographic hash) for maximum reliability. 6881ad8388SMartin Matuska #if defined(HAVE_CHECK_SHA256) 6981ad8388SMartin Matuska # define LZMA_CHECK_BEST LZMA_CHECK_SHA256 7081ad8388SMartin Matuska #elif defined(HAVE_CHECK_CRC64) 7181ad8388SMartin Matuska # define LZMA_CHECK_BEST LZMA_CHECK_CRC64 7281ad8388SMartin Matuska #else 7381ad8388SMartin Matuska # define LZMA_CHECK_BEST LZMA_CHECK_CRC32 7481ad8388SMartin Matuska #endif 7581ad8388SMartin Matuska 7681ad8388SMartin Matuska 7781ad8388SMartin Matuska /// \brief Structure to hold internal state of the check being calculated 7881ad8388SMartin Matuska /// 7981ad8388SMartin Matuska /// \note This is not in the public API because this structure may 8081ad8388SMartin Matuska /// change in future if new integrity check algorithms are added. 8181ad8388SMartin Matuska typedef struct { 8281ad8388SMartin Matuska /// Buffer to hold the final result and a temporary buffer for SHA256. 8381ad8388SMartin Matuska union { 8481ad8388SMartin Matuska uint8_t u8[64]; 8581ad8388SMartin Matuska uint32_t u32[16]; 8681ad8388SMartin Matuska uint64_t u64[8]; 8781ad8388SMartin Matuska } buffer; 8881ad8388SMartin Matuska 8981ad8388SMartin Matuska /// Check-specific data 9081ad8388SMartin Matuska union { 9181ad8388SMartin Matuska uint32_t crc32; 9281ad8388SMartin Matuska uint64_t crc64; 9353200025SRui Paulo lzma_sha256_state sha256; 9481ad8388SMartin Matuska } state; 9581ad8388SMartin Matuska 9681ad8388SMartin Matuska } lzma_check_state; 9781ad8388SMartin Matuska 9881ad8388SMartin Matuska 9981ad8388SMartin Matuska /// lzma_crc32_table[0] is needed by LZ encoder so we need to keep 10081ad8388SMartin Matuska /// the array two-dimensional. 10181ad8388SMartin Matuska #ifdef HAVE_SMALL 10281ad8388SMartin Matuska extern uint32_t lzma_crc32_table[1][256]; 10381ad8388SMartin Matuska extern void lzma_crc32_init(void); 10481ad8388SMartin Matuska #else 10581ad8388SMartin Matuska extern const uint32_t lzma_crc32_table[8][256]; 10681ad8388SMartin Matuska extern const uint64_t lzma_crc64_table[4][256]; 10781ad8388SMartin Matuska #endif 10881ad8388SMartin Matuska 10981ad8388SMartin Matuska 11081ad8388SMartin Matuska /// \brief Initialize *check depending on type 11181ad8388SMartin Matuska /// 11281ad8388SMartin Matuska /// \return LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not 11381ad8388SMartin Matuska /// supported by the current version or build of liblzma. 11481ad8388SMartin Matuska /// LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX. 11581ad8388SMartin Matuska extern void lzma_check_init(lzma_check_state *check, lzma_check type); 11681ad8388SMartin Matuska 11781ad8388SMartin Matuska /// Update the check state 11881ad8388SMartin Matuska extern void lzma_check_update(lzma_check_state *check, lzma_check type, 11981ad8388SMartin Matuska const uint8_t *buf, size_t size); 12081ad8388SMartin Matuska 12181ad8388SMartin Matuska /// Finish the check calculation and store the result to check->buffer.u8. 12281ad8388SMartin Matuska extern void lzma_check_finish(lzma_check_state *check, lzma_check type); 12381ad8388SMartin Matuska 12481ad8388SMartin Matuska 12553200025SRui Paulo #ifndef LZMA_SHA256FUNC 12653200025SRui Paulo 12781ad8388SMartin Matuska /// Prepare SHA-256 state for new input. 12881ad8388SMartin Matuska extern void lzma_sha256_init(lzma_check_state *check); 12981ad8388SMartin Matuska 13081ad8388SMartin Matuska /// Update the SHA-256 hash state 13181ad8388SMartin Matuska extern void lzma_sha256_update( 13281ad8388SMartin Matuska const uint8_t *buf, size_t size, lzma_check_state *check); 13381ad8388SMartin Matuska 13481ad8388SMartin Matuska /// Finish the SHA-256 calculation and store the result to check->buffer.u8. 13581ad8388SMartin Matuska extern void lzma_sha256_finish(lzma_check_state *check); 13681ad8388SMartin Matuska 13753200025SRui Paulo 13853200025SRui Paulo #else 13953200025SRui Paulo 14053200025SRui Paulo static inline void 14153200025SRui Paulo lzma_sha256_init(lzma_check_state *check) 14253200025SRui Paulo { 14353200025SRui Paulo LZMA_SHA256FUNC(Init)(&check->state.sha256); 14453200025SRui Paulo } 14553200025SRui Paulo 14653200025SRui Paulo 14753200025SRui Paulo static inline void 14853200025SRui Paulo lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check) 14953200025SRui Paulo { 15053200025SRui Paulo #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX 15153200025SRui Paulo // Darwin's CC_SHA256_Update takes uint32_t as the buffer size, 15253200025SRui Paulo // so use a loop to support size_t. 15353200025SRui Paulo while (size > UINT32_MAX) { 15453200025SRui Paulo LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX); 15553200025SRui Paulo buf += UINT32_MAX; 15653200025SRui Paulo size -= UINT32_MAX; 15753200025SRui Paulo } 15853200025SRui Paulo #endif 15953200025SRui Paulo 16053200025SRui Paulo LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size); 16153200025SRui Paulo } 16253200025SRui Paulo 16353200025SRui Paulo 16453200025SRui Paulo static inline void 16553200025SRui Paulo lzma_sha256_finish(lzma_check_state *check) 16653200025SRui Paulo { 16753200025SRui Paulo LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256); 16853200025SRui Paulo } 16953200025SRui Paulo 17053200025SRui Paulo #endif 17153200025SRui Paulo 17281ad8388SMartin Matuska #endif 173