/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  |