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 /// \brief Initialize *check depending on type
99 extern void lzma_check_init(lzma_check_state *check, lzma_check type);
100
101 /// Update the check state
102 extern void lzma_check_update(lzma_check_state *check, lzma_check type,
103 const uint8_t *buf, size_t size);
104
105 /// Finish the check calculation and store the result to check->buffer.u8.
106 extern void lzma_check_finish(lzma_check_state *check, lzma_check type);
107
108
109 #ifndef LZMA_SHA256FUNC
110
111 /// Prepare SHA-256 state for new input.
112 extern void lzma_sha256_init(lzma_check_state *check);
113
114 /// Update the SHA-256 hash state
115 extern void lzma_sha256_update(
116 const uint8_t *buf, size_t size, lzma_check_state *check);
117
118 /// Finish the SHA-256 calculation and store the result to check->buffer.u8.
119 extern void lzma_sha256_finish(lzma_check_state *check);
120
121
122 #else
123
124 static inline void
lzma_sha256_init(lzma_check_state * check)125 lzma_sha256_init(lzma_check_state *check)
126 {
127 LZMA_SHA256FUNC(Init)(&check->state.sha256);
128 }
129
130
131 static inline void
lzma_sha256_update(const uint8_t * buf,size_t size,lzma_check_state * check)132 lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check)
133 {
134 #if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX
135 // Darwin's CC_SHA256_Update takes uint32_t as the buffer size,
136 // so use a loop to support size_t.
137 while (size > UINT32_MAX) {
138 LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX);
139 buf += UINT32_MAX;
140 size -= UINT32_MAX;
141 }
142 #endif
143
144 LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size);
145 }
146
147
148 static inline void
lzma_sha256_finish(lzma_check_state * check)149 lzma_sha256_finish(lzma_check_state *check)
150 {
151 LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256);
152 }
153
154 #endif
155
156 #endif
157