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