xref: /freebsd/contrib/xz/src/liblzma/check/check.h (revision 2da066ef6d85d3f7cd8aaec14369d66254836536)
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
41 typedef 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)
49 typedef CC_SHA256_CTX lzma_sha256_state;
50 #elif defined(HAVE_SHA256_CTX)
51 typedef SHA256_CTX lzma_sha256_state;
52 #elif defined(HAVE_SHA2_CTX)
53 typedef 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.
81 typedef 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
102 lzma_attr_visibility_hidden
103 extern uint32_t lzma_crc32_table[1][256];
104 
105 extern void lzma_crc32_init(void);
106 
107 #else
108 
109 lzma_attr_visibility_hidden
110 extern const uint32_t lzma_crc32_table[8][256];
111 
112 lzma_attr_visibility_hidden
113 extern const uint64_t lzma_crc64_table[4][256];
114 #endif
115 
116 
117 /// \brief      Initialize *check depending on type
118 extern void lzma_check_init(lzma_check_state *check, lzma_check type);
119 
120 /// Update the check state
121 extern void lzma_check_update(lzma_check_state *check, lzma_check type,
122 		const uint8_t *buf, size_t size);
123 
124 /// Finish the check calculation and store the result to check->buffer.u8.
125 extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
126 
127 
128 #ifndef LZMA_SHA256FUNC
129 
130 /// Prepare SHA-256 state for new input.
131 extern void lzma_sha256_init(lzma_check_state *check);
132 
133 /// Update the SHA-256 hash state
134 extern void lzma_sha256_update(
135 		const uint8_t *buf, size_t size, lzma_check_state *check);
136 
137 /// Finish the SHA-256 calculation and store the result to check->buffer.u8.
138 extern void lzma_sha256_finish(lzma_check_state *check);
139 
140 
141 #else
142 
143 static inline void
144 lzma_sha256_init(lzma_check_state *check)
145 {
146 	LZMA_SHA256FUNC(Init)(&check->state.sha256);
147 }
148 
149 
150 static inline void
151 lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
152 {
153 #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX
154 	// Darwin's CC_SHA256_Update takes uint32_t as the buffer size,
155 	// so use a loop to support size_t.
156 	while (size > UINT32_MAX) {
157 		LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX);
158 		buf += UINT32_MAX;
159 		size -= UINT32_MAX;
160 	}
161 #endif
162 
163 	LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size);
164 }
165 
166 
167 static inline void
168 lzma_sha256_finish(lzma_check_state *check)
169 {
170 	LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256);
171 }
172 
173 #endif
174 
175 #endif
176