/src/botan/src/lib/hash/sha1/sha1.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * SHA-1 |
3 | | * (C) 1999-2008,2011 Jack Lloyd |
4 | | * |
5 | | * Botan is released under the Simplified BSD License (see license.txt) |
6 | | */ |
7 | | |
8 | | #include <botan/internal/sha1.h> |
9 | | |
10 | | #include <botan/internal/bit_ops.h> |
11 | | #include <botan/internal/cpuid.h> |
12 | | #include <botan/internal/loadstor.h> |
13 | | #include <botan/internal/rotate.h> |
14 | | #include <botan/internal/stl_util.h> |
15 | | |
16 | | #include <array> |
17 | | |
18 | | namespace Botan { |
19 | | |
20 | | namespace SHA1_F { |
21 | | |
22 | | namespace { |
23 | | |
24 | | /* |
25 | | * SHA-1 F1 Function |
26 | | */ |
27 | 0 | inline void F1(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) { |
28 | 0 | E += choose(B, C, D) + msg + 0x5A827999 + rotl<5>(A); |
29 | 0 | B = rotl<30>(B); |
30 | 0 | } |
31 | | |
32 | | /* |
33 | | * SHA-1 F2 Function |
34 | | */ |
35 | 0 | inline void F2(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) { |
36 | 0 | E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotl<5>(A); |
37 | 0 | B = rotl<30>(B); |
38 | 0 | } |
39 | | |
40 | | /* |
41 | | * SHA-1 F3 Function |
42 | | */ |
43 | 0 | inline void F3(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) { |
44 | 0 | E += majority(B, C, D) + msg + 0x8F1BBCDC + rotl<5>(A); |
45 | 0 | B = rotl<30>(B); |
46 | 0 | } |
47 | | |
48 | | /* |
49 | | * SHA-1 F4 Function |
50 | | */ |
51 | 0 | inline void F4(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg) { |
52 | 0 | E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotl<5>(A); |
53 | 0 | B = rotl<30>(B); |
54 | 0 | } |
55 | | |
56 | | } // namespace |
57 | | |
58 | | } // namespace SHA1_F |
59 | | |
60 | | /* |
61 | | * SHA-1 Compression Function |
62 | | */ |
63 | 88.3k | void SHA_1::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) { |
64 | 88.3k | using namespace SHA1_F; |
65 | | |
66 | 88.3k | #if defined(BOTAN_HAS_SHA1_X86_SHA_NI) |
67 | 88.3k | if(CPUID::has_intel_sha()) { |
68 | 88.3k | return sha1_compress_x86(digest, input, blocks); |
69 | 88.3k | } |
70 | 0 | #endif |
71 | | |
72 | | #if defined(BOTAN_HAS_SHA1_ARMV8) |
73 | | if(CPUID::has_arm_sha1()) { |
74 | | return sha1_armv8_compress_n(digest, input, blocks); |
75 | | } |
76 | | #endif |
77 | | |
78 | 0 | #if defined(BOTAN_HAS_SHA1_SSE2) |
79 | 0 | if(CPUID::has_sse2()) { |
80 | 0 | return sse2_compress_n(digest, input, blocks); |
81 | 0 | } |
82 | | |
83 | 0 | #endif |
84 | | |
85 | 0 | uint32_t A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4]; |
86 | 0 | std::array<uint32_t, 80> W; |
87 | |
|
88 | 0 | BufferSlicer in(input); |
89 | |
|
90 | 0 | for(size_t i = 0; i != blocks; ++i) { |
91 | 0 | load_be(W.data(), in.take(block_bytes).data(), 16); |
92 | |
|
93 | 0 | for(size_t j = 16; j != 80; j += 8) { |
94 | 0 | W[j] = rotl<1>(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16]); |
95 | 0 | W[j + 1] = rotl<1>(W[j - 2] ^ W[j - 7] ^ W[j - 13] ^ W[j - 15]); |
96 | 0 | W[j + 2] = rotl<1>(W[j - 1] ^ W[j - 6] ^ W[j - 12] ^ W[j - 14]); |
97 | 0 | W[j + 3] = rotl<1>(W[j] ^ W[j - 5] ^ W[j - 11] ^ W[j - 13]); |
98 | 0 | W[j + 4] = rotl<1>(W[j + 1] ^ W[j - 4] ^ W[j - 10] ^ W[j - 12]); |
99 | 0 | W[j + 5] = rotl<1>(W[j + 2] ^ W[j - 3] ^ W[j - 9] ^ W[j - 11]); |
100 | 0 | W[j + 6] = rotl<1>(W[j + 3] ^ W[j - 2] ^ W[j - 8] ^ W[j - 10]); |
101 | 0 | W[j + 7] = rotl<1>(W[j + 4] ^ W[j - 1] ^ W[j - 7] ^ W[j - 9]); |
102 | 0 | } |
103 | |
|
104 | 0 | F1(A, B, C, D, E, W[0]); |
105 | 0 | F1(E, A, B, C, D, W[1]); |
106 | 0 | F1(D, E, A, B, C, W[2]); |
107 | 0 | F1(C, D, E, A, B, W[3]); |
108 | 0 | F1(B, C, D, E, A, W[4]); |
109 | 0 | F1(A, B, C, D, E, W[5]); |
110 | 0 | F1(E, A, B, C, D, W[6]); |
111 | 0 | F1(D, E, A, B, C, W[7]); |
112 | 0 | F1(C, D, E, A, B, W[8]); |
113 | 0 | F1(B, C, D, E, A, W[9]); |
114 | 0 | F1(A, B, C, D, E, W[10]); |
115 | 0 | F1(E, A, B, C, D, W[11]); |
116 | 0 | F1(D, E, A, B, C, W[12]); |
117 | 0 | F1(C, D, E, A, B, W[13]); |
118 | 0 | F1(B, C, D, E, A, W[14]); |
119 | 0 | F1(A, B, C, D, E, W[15]); |
120 | 0 | F1(E, A, B, C, D, W[16]); |
121 | 0 | F1(D, E, A, B, C, W[17]); |
122 | 0 | F1(C, D, E, A, B, W[18]); |
123 | 0 | F1(B, C, D, E, A, W[19]); |
124 | |
|
125 | 0 | F2(A, B, C, D, E, W[20]); |
126 | 0 | F2(E, A, B, C, D, W[21]); |
127 | 0 | F2(D, E, A, B, C, W[22]); |
128 | 0 | F2(C, D, E, A, B, W[23]); |
129 | 0 | F2(B, C, D, E, A, W[24]); |
130 | 0 | F2(A, B, C, D, E, W[25]); |
131 | 0 | F2(E, A, B, C, D, W[26]); |
132 | 0 | F2(D, E, A, B, C, W[27]); |
133 | 0 | F2(C, D, E, A, B, W[28]); |
134 | 0 | F2(B, C, D, E, A, W[29]); |
135 | 0 | F2(A, B, C, D, E, W[30]); |
136 | 0 | F2(E, A, B, C, D, W[31]); |
137 | 0 | F2(D, E, A, B, C, W[32]); |
138 | 0 | F2(C, D, E, A, B, W[33]); |
139 | 0 | F2(B, C, D, E, A, W[34]); |
140 | 0 | F2(A, B, C, D, E, W[35]); |
141 | 0 | F2(E, A, B, C, D, W[36]); |
142 | 0 | F2(D, E, A, B, C, W[37]); |
143 | 0 | F2(C, D, E, A, B, W[38]); |
144 | 0 | F2(B, C, D, E, A, W[39]); |
145 | |
|
146 | 0 | F3(A, B, C, D, E, W[40]); |
147 | 0 | F3(E, A, B, C, D, W[41]); |
148 | 0 | F3(D, E, A, B, C, W[42]); |
149 | 0 | F3(C, D, E, A, B, W[43]); |
150 | 0 | F3(B, C, D, E, A, W[44]); |
151 | 0 | F3(A, B, C, D, E, W[45]); |
152 | 0 | F3(E, A, B, C, D, W[46]); |
153 | 0 | F3(D, E, A, B, C, W[47]); |
154 | 0 | F3(C, D, E, A, B, W[48]); |
155 | 0 | F3(B, C, D, E, A, W[49]); |
156 | 0 | F3(A, B, C, D, E, W[50]); |
157 | 0 | F3(E, A, B, C, D, W[51]); |
158 | 0 | F3(D, E, A, B, C, W[52]); |
159 | 0 | F3(C, D, E, A, B, W[53]); |
160 | 0 | F3(B, C, D, E, A, W[54]); |
161 | 0 | F3(A, B, C, D, E, W[55]); |
162 | 0 | F3(E, A, B, C, D, W[56]); |
163 | 0 | F3(D, E, A, B, C, W[57]); |
164 | 0 | F3(C, D, E, A, B, W[58]); |
165 | 0 | F3(B, C, D, E, A, W[59]); |
166 | |
|
167 | 0 | F4(A, B, C, D, E, W[60]); |
168 | 0 | F4(E, A, B, C, D, W[61]); |
169 | 0 | F4(D, E, A, B, C, W[62]); |
170 | 0 | F4(C, D, E, A, B, W[63]); |
171 | 0 | F4(B, C, D, E, A, W[64]); |
172 | 0 | F4(A, B, C, D, E, W[65]); |
173 | 0 | F4(E, A, B, C, D, W[66]); |
174 | 0 | F4(D, E, A, B, C, W[67]); |
175 | 0 | F4(C, D, E, A, B, W[68]); |
176 | 0 | F4(B, C, D, E, A, W[69]); |
177 | 0 | F4(A, B, C, D, E, W[70]); |
178 | 0 | F4(E, A, B, C, D, W[71]); |
179 | 0 | F4(D, E, A, B, C, W[72]); |
180 | 0 | F4(C, D, E, A, B, W[73]); |
181 | 0 | F4(B, C, D, E, A, W[74]); |
182 | 0 | F4(A, B, C, D, E, W[75]); |
183 | 0 | F4(E, A, B, C, D, W[76]); |
184 | 0 | F4(D, E, A, B, C, W[77]); |
185 | 0 | F4(C, D, E, A, B, W[78]); |
186 | 0 | F4(B, C, D, E, A, W[79]); |
187 | |
|
188 | 0 | A = (digest[0] += A); |
189 | 0 | B = (digest[1] += B); |
190 | 0 | C = (digest[2] += C); |
191 | 0 | D = (digest[3] += D); |
192 | 0 | E = (digest[4] += E); |
193 | 0 | } |
194 | 0 | } |
195 | | |
196 | | /* |
197 | | * Clear memory of sensitive data |
198 | | */ |
199 | 38.9k | void SHA_1::init(digest_type& digest) { |
200 | 38.9k | digest.assign({0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0}); |
201 | 38.9k | } |
202 | | |
203 | 0 | std::string SHA_1::provider() const { |
204 | 0 | #if defined(BOTAN_HAS_SHA1_X86_SHA_NI) |
205 | 0 | if(CPUID::has_intel_sha()) { |
206 | 0 | return "intel_sha"; |
207 | 0 | } |
208 | 0 | #endif |
209 | | |
210 | | #if defined(BOTAN_HAS_SHA1_ARMV8) |
211 | | if(CPUID::has_arm_sha1()) { |
212 | | return "armv8_sha"; |
213 | | } |
214 | | #endif |
215 | | |
216 | 0 | #if defined(BOTAN_HAS_SHA1_SSE2) |
217 | 0 | if(CPUID::has_sse2()) { |
218 | 0 | return "sse2"; |
219 | 0 | } |
220 | 0 | #endif |
221 | | |
222 | 0 | return "base"; |
223 | 0 | } |
224 | | |
225 | 270 | std::unique_ptr<HashFunction> SHA_1::new_object() const { |
226 | 270 | return std::make_unique<SHA_1>(); |
227 | 270 | } |
228 | | |
229 | 0 | std::unique_ptr<HashFunction> SHA_1::copy_state() const { |
230 | 0 | return std::make_unique<SHA_1>(*this); |
231 | 0 | } |
232 | | |
233 | 130k | void SHA_1::add_data(std::span<const uint8_t> input) { |
234 | 130k | m_md.update(input); |
235 | 130k | } |
236 | | |
237 | 38.0k | void SHA_1::final_result(std::span<uint8_t> output) { |
238 | 38.0k | m_md.final(output); |
239 | 38.0k | } |
240 | | |
241 | | } // namespace Botan |