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