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*53200025SRui Paulo #if defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) 19*53200025SRui Paulo # include <CommonCrypto/CommonDigest.h> 20*53200025SRui Paulo #elif defined(HAVE_SHA256_H) 21*53200025SRui Paulo # include <sys/types.h> 22*53200025SRui Paulo # include <sha256.h> 23*53200025SRui Paulo #elif defined(HAVE_SHA2_H) 24*53200025SRui Paulo # include <sys/types.h> 25*53200025SRui Paulo # include <sha2.h> 26*53200025SRui Paulo #elif defined(HAVE_MINIX_SHA2_H) 27*53200025SRui Paulo # include <sys/types.h> 28*53200025SRui Paulo # include <minix/sha2.h> 29*53200025SRui Paulo #endif 30*53200025SRui Paulo 31*53200025SRui Paulo #if defined(HAVE_CC_SHA256_CTX) 32*53200025SRui Paulo typedef CC_SHA256_CTX lzma_sha256_state; 33*53200025SRui Paulo #elif defined(HAVE_SHA256_CTX) 34*53200025SRui Paulo typedef SHA256_CTX lzma_sha256_state; 35*53200025SRui Paulo #elif defined(HAVE_SHA2_CTX) 36*53200025SRui Paulo typedef SHA2_CTX lzma_sha256_state; 37*53200025SRui Paulo #else 38*53200025SRui Paulo /// State for the internal SHA-256 implementation 39*53200025SRui Paulo typedef struct { 40*53200025SRui Paulo /// Internal state 41*53200025SRui Paulo uint32_t state[8]; 42*53200025SRui Paulo 43*53200025SRui Paulo /// Size of the message excluding padding 44*53200025SRui Paulo uint64_t size; 45*53200025SRui Paulo } lzma_sha256_state; 46*53200025SRui Paulo #endif 47*53200025SRui Paulo 48*53200025SRui Paulo #if defined(HAVE_CC_SHA256_INIT) 49*53200025SRui Paulo # define LZMA_SHA256FUNC(x) CC_SHA256_ ## x 50*53200025SRui Paulo #elif defined(HAVE_SHA256_INIT) 51*53200025SRui Paulo # define LZMA_SHA256FUNC(x) SHA256_ ## x 52*53200025SRui Paulo #elif defined(HAVE_SHA256INIT) 53*53200025SRui Paulo # define LZMA_SHA256FUNC(x) SHA256 ## x 54*53200025SRui Paulo #endif 5581ad8388SMartin Matuska 5681ad8388SMartin Matuska // Index hashing needs the best possible hash function (preferably 5781ad8388SMartin Matuska // a cryptographic hash) for maximum reliability. 5881ad8388SMartin Matuska #if defined(HAVE_CHECK_SHA256) 5981ad8388SMartin Matuska # define LZMA_CHECK_BEST LZMA_CHECK_SHA256 6081ad8388SMartin Matuska #elif defined(HAVE_CHECK_CRC64) 6181ad8388SMartin Matuska # define LZMA_CHECK_BEST LZMA_CHECK_CRC64 6281ad8388SMartin Matuska #else 6381ad8388SMartin Matuska # define LZMA_CHECK_BEST LZMA_CHECK_CRC32 6481ad8388SMartin Matuska #endif 6581ad8388SMartin Matuska 6681ad8388SMartin Matuska 6781ad8388SMartin Matuska /// \brief Structure to hold internal state of the check being calculated 6881ad8388SMartin Matuska /// 6981ad8388SMartin Matuska /// \note This is not in the public API because this structure may 7081ad8388SMartin Matuska /// change in future if new integrity check algorithms are added. 7181ad8388SMartin Matuska typedef struct { 7281ad8388SMartin Matuska /// Buffer to hold the final result and a temporary buffer for SHA256. 7381ad8388SMartin Matuska union { 7481ad8388SMartin Matuska uint8_t u8[64]; 7581ad8388SMartin Matuska uint32_t u32[16]; 7681ad8388SMartin Matuska uint64_t u64[8]; 7781ad8388SMartin Matuska } buffer; 7881ad8388SMartin Matuska 7981ad8388SMartin Matuska /// Check-specific data 8081ad8388SMartin Matuska union { 8181ad8388SMartin Matuska uint32_t crc32; 8281ad8388SMartin Matuska uint64_t crc64; 83*53200025SRui Paulo lzma_sha256_state sha256; 8481ad8388SMartin Matuska } state; 8581ad8388SMartin Matuska 8681ad8388SMartin Matuska } lzma_check_state; 8781ad8388SMartin Matuska 8881ad8388SMartin Matuska 8981ad8388SMartin Matuska /// lzma_crc32_table[0] is needed by LZ encoder so we need to keep 9081ad8388SMartin Matuska /// the array two-dimensional. 9181ad8388SMartin Matuska #ifdef HAVE_SMALL 9281ad8388SMartin Matuska extern uint32_t lzma_crc32_table[1][256]; 9381ad8388SMartin Matuska extern void lzma_crc32_init(void); 9481ad8388SMartin Matuska #else 9581ad8388SMartin Matuska extern const uint32_t lzma_crc32_table[8][256]; 9681ad8388SMartin Matuska extern const uint64_t lzma_crc64_table[4][256]; 9781ad8388SMartin Matuska #endif 9881ad8388SMartin Matuska 9981ad8388SMartin Matuska 10081ad8388SMartin Matuska /// \brief Initialize *check depending on type 10181ad8388SMartin Matuska /// 10281ad8388SMartin Matuska /// \return LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not 10381ad8388SMartin Matuska /// supported by the current version or build of liblzma. 10481ad8388SMartin Matuska /// LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX. 10581ad8388SMartin Matuska extern void lzma_check_init(lzma_check_state *check, lzma_check type); 10681ad8388SMartin Matuska 10781ad8388SMartin Matuska /// Update the check state 10881ad8388SMartin Matuska extern void lzma_check_update(lzma_check_state *check, lzma_check type, 10981ad8388SMartin Matuska const uint8_t *buf, size_t size); 11081ad8388SMartin Matuska 11181ad8388SMartin Matuska /// Finish the check calculation and store the result to check->buffer.u8. 11281ad8388SMartin Matuska extern void lzma_check_finish(lzma_check_state *check, lzma_check type); 11381ad8388SMartin Matuska 11481ad8388SMartin Matuska 115*53200025SRui Paulo #ifndef LZMA_SHA256FUNC 116*53200025SRui Paulo 11781ad8388SMartin Matuska /// Prepare SHA-256 state for new input. 11881ad8388SMartin Matuska extern void lzma_sha256_init(lzma_check_state *check); 11981ad8388SMartin Matuska 12081ad8388SMartin Matuska /// Update the SHA-256 hash state 12181ad8388SMartin Matuska extern void lzma_sha256_update( 12281ad8388SMartin Matuska const uint8_t *buf, size_t size, lzma_check_state *check); 12381ad8388SMartin Matuska 12481ad8388SMartin Matuska /// Finish the SHA-256 calculation and store the result to check->buffer.u8. 12581ad8388SMartin Matuska extern void lzma_sha256_finish(lzma_check_state *check); 12681ad8388SMartin Matuska 127*53200025SRui Paulo 128*53200025SRui Paulo #else 129*53200025SRui Paulo 130*53200025SRui Paulo static inline void 131*53200025SRui Paulo lzma_sha256_init(lzma_check_state *check) 132*53200025SRui Paulo { 133*53200025SRui Paulo LZMA_SHA256FUNC(Init)(&check->state.sha256); 134*53200025SRui Paulo } 135*53200025SRui Paulo 136*53200025SRui Paulo 137*53200025SRui Paulo static inline void 138*53200025SRui Paulo lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check) 139*53200025SRui Paulo { 140*53200025SRui Paulo #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX 141*53200025SRui Paulo // Darwin's CC_SHA256_Update takes uint32_t as the buffer size, 142*53200025SRui Paulo // so use a loop to support size_t. 143*53200025SRui Paulo while (size > UINT32_MAX) { 144*53200025SRui Paulo LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX); 145*53200025SRui Paulo buf += UINT32_MAX; 146*53200025SRui Paulo size -= UINT32_MAX; 147*53200025SRui Paulo } 148*53200025SRui Paulo #endif 149*53200025SRui Paulo 150*53200025SRui Paulo LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size); 151*53200025SRui Paulo } 152*53200025SRui Paulo 153*53200025SRui Paulo 154*53200025SRui Paulo static inline void 155*53200025SRui Paulo lzma_sha256_finish(lzma_check_state *check) 156*53200025SRui Paulo { 157*53200025SRui Paulo LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256); 158*53200025SRui Paulo } 159*53200025SRui Paulo 160*53200025SRui Paulo #endif 161*53200025SRui Paulo 16281ad8388SMartin Matuska #endif 163