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