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