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 lzma_attr_visibility_hidden 103 extern uint32_t lzma_crc32_table[1][256]; 104 105 extern void lzma_crc32_init(void); 106 107 #else 108 109 lzma_attr_visibility_hidden 110 extern const uint32_t lzma_crc32_table[8][256]; 111 112 lzma_attr_visibility_hidden 113 extern const uint64_t lzma_crc64_table[4][256]; 114 #endif 115 116 117 /// \brief Initialize *check depending on type 118 extern void lzma_check_init(lzma_check_state *check, lzma_check type); 119 120 /// Update the check state 121 extern void lzma_check_update(lzma_check_state *check, lzma_check type, 122 const uint8_t *buf, size_t size); 123 124 /// Finish the check calculation and store the result to check->buffer.u8. 125 extern void lzma_check_finish(lzma_check_state *check, lzma_check type); 126 127 128 #ifndef LZMA_SHA256FUNC 129 130 /// Prepare SHA-256 state for new input. 131 extern void lzma_sha256_init(lzma_check_state *check); 132 133 /// Update the SHA-256 hash state 134 extern void lzma_sha256_update( 135 const uint8_t *buf, size_t size, lzma_check_state *check); 136 137 /// Finish the SHA-256 calculation and store the result to check->buffer.u8. 138 extern void lzma_sha256_finish(lzma_check_state *check); 139 140 141 #else 142 143 static inline void 144 lzma_sha256_init(lzma_check_state *check) 145 { 146 LZMA_SHA256FUNC(Init)(&check->state.sha256); 147 } 148 149 150 static inline void 151 lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check) 152 { 153 #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX 154 // Darwin's CC_SHA256_Update takes uint32_t as the buffer size, 155 // so use a loop to support size_t. 156 while (size > UINT32_MAX) { 157 LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX); 158 buf += UINT32_MAX; 159 size -= UINT32_MAX; 160 } 161 #endif 162 163 LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size); 164 } 165 166 167 static inline void 168 lzma_sha256_finish(lzma_check_state *check) 169 { 170 LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256); 171 } 172 173 #endif 174 175 #endif 176