1 /////////////////////////////////////////////////////////////////////////////// 2 // 3 /// \file check.h 4 /// \brief Internal API to different integrity check functions 5 // 6 // Author: Lasse Collin 7 // 8 // This file has been put into the public domain. 9 // You can do whatever you want with this file. 10 // 11 /////////////////////////////////////////////////////////////////////////////// 12 13 #ifndef LZMA_CHECK_H 14 #define LZMA_CHECK_H 15 16 #include "common.h" 17 18 // If the function for external SHA-256 is missing, use the internal SHA-256 19 // code. Due to how configure works, these defines can only get defined when 20 // both a usable header and a type have already been found. 21 #if !(defined(HAVE_CC_SHA256_INIT) \ 22 || defined(HAVE_SHA256_INIT) \ 23 || defined(HAVE_SHA256INIT)) 24 # define HAVE_INTERNAL_SHA256 1 25 #endif 26 27 #if defined(HAVE_INTERNAL_SHA256) 28 // Nothing 29 #elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) 30 # include <CommonCrypto/CommonDigest.h> 31 #elif defined(HAVE_SHA256_H) 32 # include <sys/types.h> 33 # include <sha256.h> 34 #elif defined(HAVE_SHA2_H) 35 # include <sys/types.h> 36 # include <sha2.h> 37 #endif 38 39 #if defined(HAVE_INTERNAL_SHA256) 40 /// State for the internal SHA-256 implementation 41 typedef struct { 42 /// Internal state 43 uint32_t state[8]; 44 45 /// Size of the message excluding padding 46 uint64_t size; 47 } lzma_sha256_state; 48 #elif defined(HAVE_CC_SHA256_CTX) 49 typedef CC_SHA256_CTX lzma_sha256_state; 50 #elif defined(HAVE_SHA256_CTX) 51 typedef SHA256_CTX lzma_sha256_state; 52 #elif defined(HAVE_SHA2_CTX) 53 typedef SHA2_CTX lzma_sha256_state; 54 #endif 55 56 #if defined(HAVE_INTERNAL_SHA256) 57 // Nothing 58 #elif defined(HAVE_CC_SHA256_INIT) 59 # define LZMA_SHA256FUNC(x) CC_SHA256_ ## x 60 #elif defined(HAVE_SHA256_INIT) 61 # define LZMA_SHA256FUNC(x) SHA256_ ## x 62 #elif defined(HAVE_SHA256INIT) 63 # define LZMA_SHA256FUNC(x) SHA256 ## x 64 #endif 65 66 // Index hashing needs the best possible hash function (preferably 67 // a cryptographic hash) for maximum reliability. 68 #if defined(HAVE_CHECK_SHA256) 69 # define LZMA_CHECK_BEST LZMA_CHECK_SHA256 70 #elif defined(HAVE_CHECK_CRC64) 71 # define LZMA_CHECK_BEST LZMA_CHECK_CRC64 72 #else 73 # define LZMA_CHECK_BEST LZMA_CHECK_CRC32 74 #endif 75 76 77 /// \brief Structure to hold internal state of the check being calculated 78 /// 79 /// \note This is not in the public API because this structure may 80 /// change in future if new integrity check algorithms are added. 81 typedef struct { 82 /// Buffer to hold the final result and a temporary buffer for SHA256. 83 union { 84 uint8_t u8[64]; 85 uint32_t u32[16]; 86 uint64_t u64[8]; 87 } buffer; 88 89 /// Check-specific data 90 union { 91 uint32_t crc32; 92 uint64_t crc64; 93 lzma_sha256_state sha256; 94 } state; 95 96 } lzma_check_state; 97 98 99 /// lzma_crc32_table[0] is needed by LZ encoder so we need to keep 100 /// the array two-dimensional. 101 #ifdef HAVE_SMALL 102 extern uint32_t lzma_crc32_table[1][256]; 103 extern void lzma_crc32_init(void); 104 #else 105 extern const uint32_t lzma_crc32_table[8][256]; 106 extern const uint64_t lzma_crc64_table[4][256]; 107 #endif 108 109 110 /// \brief Initialize *check depending on type 111 /// 112 /// \return LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not 113 /// supported by the current version or build of liblzma. 114 /// LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX. 115 extern void lzma_check_init(lzma_check_state *check, lzma_check type); 116 117 /// Update the check state 118 extern void lzma_check_update(lzma_check_state *check, lzma_check type, 119 const uint8_t *buf, size_t size); 120 121 /// Finish the check calculation and store the result to check->buffer.u8. 122 extern void lzma_check_finish(lzma_check_state *check, lzma_check type); 123 124 125 #ifndef LZMA_SHA256FUNC 126 127 /// Prepare SHA-256 state for new input. 128 extern void lzma_sha256_init(lzma_check_state *check); 129 130 /// Update the SHA-256 hash state 131 extern void lzma_sha256_update( 132 const uint8_t *buf, size_t size, lzma_check_state *check); 133 134 /// Finish the SHA-256 calculation and store the result to check->buffer.u8. 135 extern void lzma_sha256_finish(lzma_check_state *check); 136 137 138 #else 139 140 static inline void 141 lzma_sha256_init(lzma_check_state *check) 142 { 143 LZMA_SHA256FUNC(Init)(&check->state.sha256); 144 } 145 146 147 static inline void 148 lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check) 149 { 150 #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX 151 // Darwin's CC_SHA256_Update takes uint32_t as the buffer size, 152 // so use a loop to support size_t. 153 while (size > UINT32_MAX) { 154 LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX); 155 buf += UINT32_MAX; 156 size -= UINT32_MAX; 157 } 158 #endif 159 160 LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size); 161 } 162 163 164 static inline void 165 lzma_sha256_finish(lzma_check_state *check) 166 { 167 LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256); 168 } 169 170 #endif 171 172 #endif 173