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 40typedef 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) 48typedef CC_SHA256_CTX lzma_sha256_state; 49#elif defined(HAVE_SHA256_CTX) 50typedef SHA256_CTX lzma_sha256_state; 51#elif defined(HAVE_SHA2_CTX) 52typedef 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. 80typedef 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 101lzma_attr_visibility_hidden 102extern uint32_t lzma_crc32_table[1][256]; 103 104extern void lzma_crc32_init(void); 105 106#else 107 108lzma_attr_visibility_hidden 109extern const uint32_t lzma_crc32_table[8][256]; 110 111lzma_attr_visibility_hidden 112extern const uint64_t lzma_crc64_table[4][256]; 113#endif 114 115 116/// \brief Initialize *check depending on type 117extern void lzma_check_init(lzma_check_state *check, lzma_check type); 118 119/// Update the check state 120extern 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. 124extern 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. 130extern void lzma_sha256_init(lzma_check_state *check); 131 132/// Update the SHA-256 hash state 133extern 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. 137extern void lzma_sha256_finish(lzma_check_state *check); 138 139 140#else 141 142static inline void 143lzma_sha256_init(lzma_check_state *check) 144{ 145 LZMA_SHA256FUNC(Init)(&check->state.sha256); 146} 147 148 149static inline void 150lzma_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 166static inline void 167lzma_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