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 #ifdef NETBSD_NATIVE_SHA256
19 #include <sha2.h>
20 #else
21 #if defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H)
22 #	include <CommonCrypto/CommonDigest.h>
23 #elif defined(HAVE_SHA256_H)
24 #	include <sys/types.h>
25 #	include <sha256.h>
26 #elif defined(HAVE_SHA2_H)
27 #	include <sys/types.h>
28 #	include <sha2.h>
29 #elif defined(HAVE_MINIX_SHA2_H)
30 #	include <sys/types.h>
31 #	include <minix/sha2.h>
32 #endif
33 #endif
34 
35 #if defined(HAVE_CC_SHA256_CTX)
36 typedef CC_SHA256_CTX lzma_sha256_state;
37 #elif defined(HAVE_SHA256_CTX)
38 typedef SHA256_CTX lzma_sha256_state;
39 #elif defined(HAVE_SHA2_CTX)
40 typedef SHA2_CTX lzma_sha256_state;
41 #else
42 /// State for the internal SHA-256 implementation
43 typedef struct {
44 	/// Internal state
45 	uint32_t state[8];
46 
47 	/// Size of the message excluding padding
48 	uint64_t size;
49 } lzma_sha256_state;
50 #endif
51 
52 #if defined(HAVE_CC_SHA256_INIT)
53 #	define LZMA_SHA256FUNC(x) CC_SHA256_ ## x
54 #elif defined(HAVE_SHA256_INIT)
55 #	define LZMA_SHA256FUNC(x) SHA256_ ## x
56 #elif defined(HAVE_SHA256INIT)
57 #	define LZMA_SHA256FUNC(x) SHA256 ## x
58 #endif
59 
60 // Index hashing needs the best possible hash function (preferably
61 // a cryptographic hash) for maximum reliability.
62 #if defined(HAVE_CHECK_SHA256)
63 #	define LZMA_CHECK_BEST LZMA_CHECK_SHA256
64 #elif defined(HAVE_CHECK_CRC64)
65 #	define LZMA_CHECK_BEST LZMA_CHECK_CRC64
66 #else
67 #	define LZMA_CHECK_BEST LZMA_CHECK_CRC32
68 #endif
69 
70 
71 /// \brief      Structure to hold internal state of the check being calculated
72 ///
73 /// \note       This is not in the public API because this structure may
74 ///             change in future if new integrity check algorithms are added.
75 typedef struct {
76 	/// Buffer to hold the final result and a temporary buffer for SHA256.
77 	union {
78 		uint8_t u8[64];
79 		uint32_t u32[16];
80 		uint64_t u64[8];
81 	} buffer;
82 
83 	/// Check-specific data
84 	union {
85 		uint32_t crc32;
86 		uint64_t crc64;
87 #ifdef NETBSD_NATIVE_SHA256
88 		SHA256_CTX sha256;
89 #else
90 		lzma_sha256_state sha256;
91 #endif
92 	} state;
93 
94 } lzma_check_state;
95 #endif
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 extern uint32_t lzma_crc32_table[1][256];
102 extern void lzma_crc32_init(void);
103 #else
104 extern const uint32_t lzma_crc32_table[8][256];
105 extern const uint64_t lzma_crc64_table[4][256];
106 #endif
107 
108 
109 /// \brief      Initialize *check depending on type
110 ///
111 /// \return     LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type is not
112 ///             supported by the current version or build of liblzma.
113 ///             LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX.
114 extern void lzma_check_init(lzma_check_state *check, lzma_check type);
115 
116 /// Update the check state
117 extern void lzma_check_update(lzma_check_state *check, lzma_check type,
118 		const uint8_t *buf, size_t size);
119 
120 /// Finish the check calculation and store the result to check->buffer.u8.
121 extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
122 
123 #ifdef NETBSD_NATIVE_SHA256
124 #define lzma_sha256_init(check)	\
125 	SHA256_Init(&(check)->state.sha256)
126 #define lzma_sha256_update(buf,size,check) \
127 	SHA256_Update(&(check)->state.sha256, buf, size)
128 #define lzma_sha256_finish(check) \
129 	SHA256_Final((check)->buffer.u8, &(check)->state.sha256)
130 #else
131 
132 #ifndef LZMA_SHA256FUNC
133 
134 /// Prepare SHA-256 state for new input.
135 extern void lzma_sha256_init(lzma_check_state *check);
136 
137 /// Update the SHA-256 hash state
138 extern void lzma_sha256_update(
139 		const uint8_t *buf, size_t size, lzma_check_state *check);
140 
141 /// Finish the SHA-256 calculation and store the result to check->buffer.u8.
142 extern void lzma_sha256_finish(lzma_check_state *check);
143 
144 
145 #else
146 
147 static inline void
lzma_sha256_init(lzma_check_state * check)148 lzma_sha256_init(lzma_check_state *check)
149 {
150 	LZMA_SHA256FUNC(Init)(&check->state.sha256);
151 }
152 
153 
154 static inline void
lzma_sha256_update(const uint8_t * buf,size_t size,lzma_check_state * check)155 lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
156 {
157 #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX
158 	// Darwin's CC_SHA256_Update takes uint32_t as the buffer size,
159 	// so use a loop to support size_t.
160 	while (size > UINT32_MAX) {
161 		LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX);
162 		buf += UINT32_MAX;
163 		size -= UINT32_MAX;
164 	}
165 #endif
166 
167 	LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size);
168 }
169 
170 
171 static inline void
lzma_sha256_finish(lzma_check_state * check)172 lzma_sha256_finish(lzma_check_state *check)
173 {
174 	LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256);
175 }
176 
177 #endif
178 
179 #endif
180