check.h revision 312517
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 41typedef 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) 49typedef CC_SHA256_CTX lzma_sha256_state; 50#elif defined(HAVE_SHA256_CTX) 51typedef SHA256_CTX lzma_sha256_state; 52#elif defined(HAVE_SHA2_CTX) 53typedef 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. 81typedef 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 102extern uint32_t lzma_crc32_table[1][256]; 103extern void lzma_crc32_init(void); 104#else 105extern const uint32_t lzma_crc32_table[8][256]; 106extern 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. 115extern void lzma_check_init(lzma_check_state *check, lzma_check type); 116 117/// Update the check state 118extern 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. 122extern 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. 128extern void lzma_sha256_init(lzma_check_state *check); 129 130/// Update the SHA-256 hash state 131extern 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. 135extern void lzma_sha256_finish(lzma_check_state *check); 136 137 138#else 139 140static inline void 141lzma_sha256_init(lzma_check_state *check) 142{ 143 LZMA_SHA256FUNC(Init)(&check->state.sha256); 144} 145 146 147static inline void 148lzma_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 164static inline void 165lzma_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