1 | //====- SHA1.cpp - Private copy of the SHA1 implementation ---*- C++ -* ======// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This code is taken from public domain |
10 | // (http://oauth.googlecode.com/svn/code/c/liboauth/src/sha1.c and |
11 | // http://cvsweb.netbsd.org/bsdweb.cgi/src/common/lib/libc/hash/sha1/sha1.c?rev=1.6) |
12 | // and modified by wrapping it in a C++ interface for LLVM, |
13 | // and removing unnecessary code. |
14 | // |
15 | //===----------------------------------------------------------------------===// |
16 | |
17 | #include "llvm/Support/SHA1.h" |
18 | #include "llvm/ADT/ArrayRef.h" |
19 | #include "llvm/ADT/StringRef.h" |
20 | #include "llvm/Support/Endian.h" |
21 | #include "llvm/Support/SwapByteOrder.h" |
22 | #include <string.h> |
23 | |
24 | using namespace llvm; |
25 | |
26 | static inline uint32_t rol(uint32_t Number, int Bits) { |
27 | return (Number << Bits) | (Number >> (32 - Bits)); |
28 | } |
29 | |
30 | static inline uint32_t blk0(uint32_t *Buf, int I) { return Buf[I]; } |
31 | |
32 | static inline uint32_t blk(uint32_t *Buf, int I) { |
33 | Buf[I & 15] = rol(Number: Buf[(I + 13) & 15] ^ Buf[(I + 8) & 15] ^ Buf[(I + 2) & 15] ^ |
34 | Buf[I & 15], |
35 | Bits: 1); |
36 | return Buf[I & 15]; |
37 | } |
38 | |
39 | static inline void r0(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, |
40 | uint32_t &E, int I, uint32_t *Buf) { |
41 | E += ((B & (C ^ D)) ^ D) + blk0(Buf, I) + 0x5A827999 + rol(Number: A, Bits: 5); |
42 | B = rol(Number: B, Bits: 30); |
43 | } |
44 | |
45 | static inline void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, |
46 | uint32_t &E, int I, uint32_t *Buf) { |
47 | E += ((B & (C ^ D)) ^ D) + blk(Buf, I) + 0x5A827999 + rol(Number: A, Bits: 5); |
48 | B = rol(Number: B, Bits: 30); |
49 | } |
50 | |
51 | static inline void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, |
52 | uint32_t &E, int I, uint32_t *Buf) { |
53 | E += (B ^ C ^ D) + blk(Buf, I) + 0x6ED9EBA1 + rol(Number: A, Bits: 5); |
54 | B = rol(Number: B, Bits: 30); |
55 | } |
56 | |
57 | static inline void r3(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, |
58 | uint32_t &E, int I, uint32_t *Buf) { |
59 | E += (((B | C) & D) | (B & C)) + blk(Buf, I) + 0x8F1BBCDC + rol(Number: A, Bits: 5); |
60 | B = rol(Number: B, Bits: 30); |
61 | } |
62 | |
63 | static inline void r4(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, |
64 | uint32_t &E, int I, uint32_t *Buf) { |
65 | E += (B ^ C ^ D) + blk(Buf, I) + 0xCA62C1D6 + rol(Number: A, Bits: 5); |
66 | B = rol(Number: B, Bits: 30); |
67 | } |
68 | |
69 | /* code */ |
70 | #define SHA1_K0 0x5a827999 |
71 | #define SHA1_K20 0x6ed9eba1 |
72 | #define SHA1_K40 0x8f1bbcdc |
73 | #define SHA1_K60 0xca62c1d6 |
74 | |
75 | #define SEED_0 0x67452301 |
76 | #define SEED_1 0xefcdab89 |
77 | #define SEED_2 0x98badcfe |
78 | #define SEED_3 0x10325476 |
79 | #define SEED_4 0xc3d2e1f0 |
80 | |
81 | void SHA1::init() { |
82 | InternalState.State[0] = SEED_0; |
83 | InternalState.State[1] = SEED_1; |
84 | InternalState.State[2] = SEED_2; |
85 | InternalState.State[3] = SEED_3; |
86 | InternalState.State[4] = SEED_4; |
87 | InternalState.ByteCount = 0; |
88 | InternalState.BufferOffset = 0; |
89 | } |
90 | |
91 | void SHA1::hashBlock() { |
92 | uint32_t A = InternalState.State[0]; |
93 | uint32_t B = InternalState.State[1]; |
94 | uint32_t C = InternalState.State[2]; |
95 | uint32_t D = InternalState.State[3]; |
96 | uint32_t E = InternalState.State[4]; |
97 | |
98 | // 4 rounds of 20 operations each. Loop unrolled. |
99 | r0(A, B, C, D, E, I: 0, Buf: InternalState.Buffer.L); |
100 | r0(A&: E, B&: A, C&: B, D&: C, E&: D, I: 1, Buf: InternalState.Buffer.L); |
101 | r0(A&: D, B&: E, C&: A, D&: B, E&: C, I: 2, Buf: InternalState.Buffer.L); |
102 | r0(A&: C, B&: D, C&: E, D&: A, E&: B, I: 3, Buf: InternalState.Buffer.L); |
103 | r0(A&: B, B&: C, C&: D, D&: E, E&: A, I: 4, Buf: InternalState.Buffer.L); |
104 | r0(A, B, C, D, E, I: 5, Buf: InternalState.Buffer.L); |
105 | r0(A&: E, B&: A, C&: B, D&: C, E&: D, I: 6, Buf: InternalState.Buffer.L); |
106 | r0(A&: D, B&: E, C&: A, D&: B, E&: C, I: 7, Buf: InternalState.Buffer.L); |
107 | r0(A&: C, B&: D, C&: E, D&: A, E&: B, I: 8, Buf: InternalState.Buffer.L); |
108 | r0(A&: B, B&: C, C&: D, D&: E, E&: A, I: 9, Buf: InternalState.Buffer.L); |
109 | r0(A, B, C, D, E, I: 10, Buf: InternalState.Buffer.L); |
110 | r0(A&: E, B&: A, C&: B, D&: C, E&: D, I: 11, Buf: InternalState.Buffer.L); |
111 | r0(A&: D, B&: E, C&: A, D&: B, E&: C, I: 12, Buf: InternalState.Buffer.L); |
112 | r0(A&: C, B&: D, C&: E, D&: A, E&: B, I: 13, Buf: InternalState.Buffer.L); |
113 | r0(A&: B, B&: C, C&: D, D&: E, E&: A, I: 14, Buf: InternalState.Buffer.L); |
114 | r0(A, B, C, D, E, I: 15, Buf: InternalState.Buffer.L); |
115 | r1(A&: E, B&: A, C&: B, D&: C, E&: D, I: 16, Buf: InternalState.Buffer.L); |
116 | r1(A&: D, B&: E, C&: A, D&: B, E&: C, I: 17, Buf: InternalState.Buffer.L); |
117 | r1(A&: C, B&: D, C&: E, D&: A, E&: B, I: 18, Buf: InternalState.Buffer.L); |
118 | r1(A&: B, B&: C, C&: D, D&: E, E&: A, I: 19, Buf: InternalState.Buffer.L); |
119 | |
120 | r2(A, B, C, D, E, I: 20, Buf: InternalState.Buffer.L); |
121 | r2(A&: E, B&: A, C&: B, D&: C, E&: D, I: 21, Buf: InternalState.Buffer.L); |
122 | r2(A&: D, B&: E, C&: A, D&: B, E&: C, I: 22, Buf: InternalState.Buffer.L); |
123 | r2(A&: C, B&: D, C&: E, D&: A, E&: B, I: 23, Buf: InternalState.Buffer.L); |
124 | r2(A&: B, B&: C, C&: D, D&: E, E&: A, I: 24, Buf: InternalState.Buffer.L); |
125 | r2(A, B, C, D, E, I: 25, Buf: InternalState.Buffer.L); |
126 | r2(A&: E, B&: A, C&: B, D&: C, E&: D, I: 26, Buf: InternalState.Buffer.L); |
127 | r2(A&: D, B&: E, C&: A, D&: B, E&: C, I: 27, Buf: InternalState.Buffer.L); |
128 | r2(A&: C, B&: D, C&: E, D&: A, E&: B, I: 28, Buf: InternalState.Buffer.L); |
129 | r2(A&: B, B&: C, C&: D, D&: E, E&: A, I: 29, Buf: InternalState.Buffer.L); |
130 | r2(A, B, C, D, E, I: 30, Buf: InternalState.Buffer.L); |
131 | r2(A&: E, B&: A, C&: B, D&: C, E&: D, I: 31, Buf: InternalState.Buffer.L); |
132 | r2(A&: D, B&: E, C&: A, D&: B, E&: C, I: 32, Buf: InternalState.Buffer.L); |
133 | r2(A&: C, B&: D, C&: E, D&: A, E&: B, I: 33, Buf: InternalState.Buffer.L); |
134 | r2(A&: B, B&: C, C&: D, D&: E, E&: A, I: 34, Buf: InternalState.Buffer.L); |
135 | r2(A, B, C, D, E, I: 35, Buf: InternalState.Buffer.L); |
136 | r2(A&: E, B&: A, C&: B, D&: C, E&: D, I: 36, Buf: InternalState.Buffer.L); |
137 | r2(A&: D, B&: E, C&: A, D&: B, E&: C, I: 37, Buf: InternalState.Buffer.L); |
138 | r2(A&: C, B&: D, C&: E, D&: A, E&: B, I: 38, Buf: InternalState.Buffer.L); |
139 | r2(A&: B, B&: C, C&: D, D&: E, E&: A, I: 39, Buf: InternalState.Buffer.L); |
140 | |
141 | r3(A, B, C, D, E, I: 40, Buf: InternalState.Buffer.L); |
142 | r3(A&: E, B&: A, C&: B, D&: C, E&: D, I: 41, Buf: InternalState.Buffer.L); |
143 | r3(A&: D, B&: E, C&: A, D&: B, E&: C, I: 42, Buf: InternalState.Buffer.L); |
144 | r3(A&: C, B&: D, C&: E, D&: A, E&: B, I: 43, Buf: InternalState.Buffer.L); |
145 | r3(A&: B, B&: C, C&: D, D&: E, E&: A, I: 44, Buf: InternalState.Buffer.L); |
146 | r3(A, B, C, D, E, I: 45, Buf: InternalState.Buffer.L); |
147 | r3(A&: E, B&: A, C&: B, D&: C, E&: D, I: 46, Buf: InternalState.Buffer.L); |
148 | r3(A&: D, B&: E, C&: A, D&: B, E&: C, I: 47, Buf: InternalState.Buffer.L); |
149 | r3(A&: C, B&: D, C&: E, D&: A, E&: B, I: 48, Buf: InternalState.Buffer.L); |
150 | r3(A&: B, B&: C, C&: D, D&: E, E&: A, I: 49, Buf: InternalState.Buffer.L); |
151 | r3(A, B, C, D, E, I: 50, Buf: InternalState.Buffer.L); |
152 | r3(A&: E, B&: A, C&: B, D&: C, E&: D, I: 51, Buf: InternalState.Buffer.L); |
153 | r3(A&: D, B&: E, C&: A, D&: B, E&: C, I: 52, Buf: InternalState.Buffer.L); |
154 | r3(A&: C, B&: D, C&: E, D&: A, E&: B, I: 53, Buf: InternalState.Buffer.L); |
155 | r3(A&: B, B&: C, C&: D, D&: E, E&: A, I: 54, Buf: InternalState.Buffer.L); |
156 | r3(A, B, C, D, E, I: 55, Buf: InternalState.Buffer.L); |
157 | r3(A&: E, B&: A, C&: B, D&: C, E&: D, I: 56, Buf: InternalState.Buffer.L); |
158 | r3(A&: D, B&: E, C&: A, D&: B, E&: C, I: 57, Buf: InternalState.Buffer.L); |
159 | r3(A&: C, B&: D, C&: E, D&: A, E&: B, I: 58, Buf: InternalState.Buffer.L); |
160 | r3(A&: B, B&: C, C&: D, D&: E, E&: A, I: 59, Buf: InternalState.Buffer.L); |
161 | |
162 | r4(A, B, C, D, E, I: 60, Buf: InternalState.Buffer.L); |
163 | r4(A&: E, B&: A, C&: B, D&: C, E&: D, I: 61, Buf: InternalState.Buffer.L); |
164 | r4(A&: D, B&: E, C&: A, D&: B, E&: C, I: 62, Buf: InternalState.Buffer.L); |
165 | r4(A&: C, B&: D, C&: E, D&: A, E&: B, I: 63, Buf: InternalState.Buffer.L); |
166 | r4(A&: B, B&: C, C&: D, D&: E, E&: A, I: 64, Buf: InternalState.Buffer.L); |
167 | r4(A, B, C, D, E, I: 65, Buf: InternalState.Buffer.L); |
168 | r4(A&: E, B&: A, C&: B, D&: C, E&: D, I: 66, Buf: InternalState.Buffer.L); |
169 | r4(A&: D, B&: E, C&: A, D&: B, E&: C, I: 67, Buf: InternalState.Buffer.L); |
170 | r4(A&: C, B&: D, C&: E, D&: A, E&: B, I: 68, Buf: InternalState.Buffer.L); |
171 | r4(A&: B, B&: C, C&: D, D&: E, E&: A, I: 69, Buf: InternalState.Buffer.L); |
172 | r4(A, B, C, D, E, I: 70, Buf: InternalState.Buffer.L); |
173 | r4(A&: E, B&: A, C&: B, D&: C, E&: D, I: 71, Buf: InternalState.Buffer.L); |
174 | r4(A&: D, B&: E, C&: A, D&: B, E&: C, I: 72, Buf: InternalState.Buffer.L); |
175 | r4(A&: C, B&: D, C&: E, D&: A, E&: B, I: 73, Buf: InternalState.Buffer.L); |
176 | r4(A&: B, B&: C, C&: D, D&: E, E&: A, I: 74, Buf: InternalState.Buffer.L); |
177 | r4(A, B, C, D, E, I: 75, Buf: InternalState.Buffer.L); |
178 | r4(A&: E, B&: A, C&: B, D&: C, E&: D, I: 76, Buf: InternalState.Buffer.L); |
179 | r4(A&: D, B&: E, C&: A, D&: B, E&: C, I: 77, Buf: InternalState.Buffer.L); |
180 | r4(A&: C, B&: D, C&: E, D&: A, E&: B, I: 78, Buf: InternalState.Buffer.L); |
181 | r4(A&: B, B&: C, C&: D, D&: E, E&: A, I: 79, Buf: InternalState.Buffer.L); |
182 | |
183 | InternalState.State[0] += A; |
184 | InternalState.State[1] += B; |
185 | InternalState.State[2] += C; |
186 | InternalState.State[3] += D; |
187 | InternalState.State[4] += E; |
188 | } |
189 | |
190 | void SHA1::addUncounted(uint8_t Data) { |
191 | if constexpr (sys::IsBigEndianHost) |
192 | InternalState.Buffer.C[InternalState.BufferOffset] = Data; |
193 | else |
194 | InternalState.Buffer.C[InternalState.BufferOffset ^ 3] = Data; |
195 | |
196 | InternalState.BufferOffset++; |
197 | if (InternalState.BufferOffset == BLOCK_LENGTH) { |
198 | hashBlock(); |
199 | InternalState.BufferOffset = 0; |
200 | } |
201 | } |
202 | |
203 | void SHA1::writebyte(uint8_t Data) { |
204 | ++InternalState.ByteCount; |
205 | addUncounted(Data); |
206 | } |
207 | |
208 | void SHA1::update(ArrayRef<uint8_t> Data) { |
209 | InternalState.ByteCount += Data.size(); |
210 | |
211 | // Finish the current block. |
212 | if (InternalState.BufferOffset > 0) { |
213 | const size_t Remainder = std::min<size_t>( |
214 | a: Data.size(), b: BLOCK_LENGTH - InternalState.BufferOffset); |
215 | for (size_t I = 0; I < Remainder; ++I) |
216 | addUncounted(Data: Data[I]); |
217 | Data = Data.drop_front(N: Remainder); |
218 | } |
219 | |
220 | // Fast buffer filling for large inputs. |
221 | while (Data.size() >= BLOCK_LENGTH) { |
222 | assert(InternalState.BufferOffset == 0); |
223 | static_assert(BLOCK_LENGTH % 4 == 0); |
224 | constexpr size_t BLOCK_LENGTH_32 = BLOCK_LENGTH / 4; |
225 | for (size_t I = 0; I < BLOCK_LENGTH_32; ++I) |
226 | InternalState.Buffer.L[I] = support::endian::read32be(P: &Data[I * 4]); |
227 | hashBlock(); |
228 | Data = Data.drop_front(N: BLOCK_LENGTH); |
229 | } |
230 | |
231 | // Finish the remainder. |
232 | for (uint8_t C : Data) |
233 | addUncounted(Data: C); |
234 | } |
235 | |
236 | void SHA1::update(StringRef Str) { |
237 | update( |
238 | Data: ArrayRef<uint8_t>((uint8_t *)const_cast<char *>(Str.data()), Str.size())); |
239 | } |
240 | |
241 | void SHA1::pad() { |
242 | // Implement SHA-1 padding (fips180-2 5.1.1) |
243 | |
244 | // Pad with 0x80 followed by 0x00 until the end of the block |
245 | addUncounted(Data: 0x80); |
246 | while (InternalState.BufferOffset != 56) |
247 | addUncounted(Data: 0x00); |
248 | |
249 | // Append length in the last 8 bytes |
250 | addUncounted(Data: 0); // We're only using 32 bit lengths |
251 | addUncounted(Data: 0); // But SHA-1 supports 64 bit lengths |
252 | addUncounted(Data: 0); // So zero pad the top bits |
253 | addUncounted(Data: InternalState.ByteCount >> 29); // Shifting to multiply by 8 |
254 | addUncounted(Data: InternalState.ByteCount >> |
255 | 21); // as SHA-1 supports bitstreams as well as |
256 | addUncounted(Data: InternalState.ByteCount >> 13); // byte. |
257 | addUncounted(Data: InternalState.ByteCount >> 5); |
258 | addUncounted(Data: InternalState.ByteCount << 3); |
259 | } |
260 | |
261 | void SHA1::final(std::array<uint32_t, HASH_LENGTH / 4> &HashResult) { |
262 | // Pad to complete the last block |
263 | pad(); |
264 | |
265 | if constexpr (sys::IsBigEndianHost) { |
266 | // Just copy the current state |
267 | for (int i = 0; i < 5; i++) { |
268 | HashResult[i] = InternalState.State[i]; |
269 | } |
270 | } else { |
271 | // Swap byte order back |
272 | for (int i = 0; i < 5; i++) { |
273 | HashResult[i] = llvm::byteswap(V: InternalState.State[i]); |
274 | } |
275 | } |
276 | } |
277 | |
278 | std::array<uint8_t, 20> SHA1::final() { |
279 | union { |
280 | std::array<uint32_t, HASH_LENGTH / 4> HashResult; |
281 | std::array<uint8_t, HASH_LENGTH> ReturnResult; |
282 | }; |
283 | static_assert(sizeof(HashResult) == sizeof(ReturnResult)); |
284 | final(HashResult&: HashResult); |
285 | return ReturnResult; |
286 | } |
287 | |
288 | std::array<uint8_t, 20> SHA1::result() { |
289 | auto StateToRestore = InternalState; |
290 | |
291 | auto Hash = final(); |
292 | |
293 | // Restore the state |
294 | InternalState = StateToRestore; |
295 | |
296 | // Return pointer to hash (20 characters) |
297 | return Hash; |
298 | } |
299 | |
300 | std::array<uint8_t, 20> SHA1::hash(ArrayRef<uint8_t> Data) { |
301 | SHA1 Hash; |
302 | Hash.update(Data); |
303 | return Hash.final(); |
304 | } |
305 | |