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