Botan 3.9.0
Crypto and TLS for C&
sha1.cpp
Go to the documentation of this file.
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/loadstor.h>
12#include <botan/internal/rotate.h>
13#include <botan/internal/sha1_f.h>
14#include <array>
15
16#if defined(BOTAN_HAS_CPUID)
17 #include <botan/internal/cpuid.h>
18#endif
19
20namespace Botan {
21
22/*
23* SHA-1 Compression Function
24*/
25void SHA_1::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
26 using namespace SHA1_F;
27
28#if defined(BOTAN_HAS_SHA1_X86_SHA_NI)
30 return sha1_compress_x86(digest, input, blocks);
31 }
32#endif
33
34#if defined(BOTAN_HAS_SHA1_ARMV8)
36 return sha1_armv8_compress_n(digest, input, blocks);
37 }
38#endif
39
40#if defined(BOTAN_HAS_SHA1_AVX2)
42 return avx2_compress_n(digest, input, blocks);
43 }
44#endif
45
46#if defined(BOTAN_HAS_SHA1_SIMD_4X32)
48 return simd_compress_n(digest, input, blocks);
49 }
50#endif
51
52 uint32_t A = digest[0];
53 uint32_t B = digest[1];
54 uint32_t C = digest[2];
55 uint32_t D = digest[3];
56 uint32_t E = digest[4];
57 std::array<uint32_t, 80> W{};
58 auto W_in = std::span{W}.first<block_bytes / sizeof(uint32_t)>();
59
60 BufferSlicer in(input);
61
62 for(size_t i = 0; i != blocks; ++i) {
63 load_be(W_in, in.take<block_bytes>());
64
65 // clang-format off
66
67 for(size_t j = 16; j != 80; j += 8) {
68 W[j + 0] = rotl<1>(W[j - 3] ^ W[j - 8] ^ W[j - 14] ^ W[j - 16]);
69 W[j + 1] = rotl<1>(W[j - 2] ^ W[j - 7] ^ W[j - 13] ^ W[j - 15]);
70 W[j + 2] = rotl<1>(W[j - 1] ^ W[j - 6] ^ W[j - 12] ^ W[j - 14]);
71 W[j + 3] = rotl<1>(W[j ] ^ W[j - 5] ^ W[j - 11] ^ W[j - 13]);
72 W[j + 4] = rotl<1>(W[j + 1] ^ W[j - 4] ^ W[j - 10] ^ W[j - 12]);
73 W[j + 5] = rotl<1>(W[j + 2] ^ W[j - 3] ^ W[j - 9] ^ W[j - 11]);
74 W[j + 6] = rotl<1>(W[j + 3] ^ W[j - 2] ^ W[j - 8] ^ W[j - 10]);
75 W[j + 7] = rotl<1>(W[j + 4] ^ W[j - 1] ^ W[j - 7] ^ W[j - 9]);
76 }
77
78 // clang-format on
79
80 F1(A, B, C, D, E, W[0] + K1);
81 F1(E, A, B, C, D, W[1] + K1);
82 F1(D, E, A, B, C, W[2] + K1);
83 F1(C, D, E, A, B, W[3] + K1);
84 F1(B, C, D, E, A, W[4] + K1);
85 F1(A, B, C, D, E, W[5] + K1);
86 F1(E, A, B, C, D, W[6] + K1);
87 F1(D, E, A, B, C, W[7] + K1);
88 F1(C, D, E, A, B, W[8] + K1);
89 F1(B, C, D, E, A, W[9] + K1);
90 F1(A, B, C, D, E, W[10] + K1);
91 F1(E, A, B, C, D, W[11] + K1);
92 F1(D, E, A, B, C, W[12] + K1);
93 F1(C, D, E, A, B, W[13] + K1);
94 F1(B, C, D, E, A, W[14] + K1);
95 F1(A, B, C, D, E, W[15] + K1);
96 F1(E, A, B, C, D, W[16] + K1);
97 F1(D, E, A, B, C, W[17] + K1);
98 F1(C, D, E, A, B, W[18] + K1);
99 F1(B, C, D, E, A, W[19] + K1);
100
101 F2(A, B, C, D, E, W[20] + K2);
102 F2(E, A, B, C, D, W[21] + K2);
103 F2(D, E, A, B, C, W[22] + K2);
104 F2(C, D, E, A, B, W[23] + K2);
105 F2(B, C, D, E, A, W[24] + K2);
106 F2(A, B, C, D, E, W[25] + K2);
107 F2(E, A, B, C, D, W[26] + K2);
108 F2(D, E, A, B, C, W[27] + K2);
109 F2(C, D, E, A, B, W[28] + K2);
110 F2(B, C, D, E, A, W[29] + K2);
111 F2(A, B, C, D, E, W[30] + K2);
112 F2(E, A, B, C, D, W[31] + K2);
113 F2(D, E, A, B, C, W[32] + K2);
114 F2(C, D, E, A, B, W[33] + K2);
115 F2(B, C, D, E, A, W[34] + K2);
116 F2(A, B, C, D, E, W[35] + K2);
117 F2(E, A, B, C, D, W[36] + K2);
118 F2(D, E, A, B, C, W[37] + K2);
119 F2(C, D, E, A, B, W[38] + K2);
120 F2(B, C, D, E, A, W[39] + K2);
121
122 F3(A, B, C, D, E, W[40] + K3);
123 F3(E, A, B, C, D, W[41] + K3);
124 F3(D, E, A, B, C, W[42] + K3);
125 F3(C, D, E, A, B, W[43] + K3);
126 F3(B, C, D, E, A, W[44] + K3);
127 F3(A, B, C, D, E, W[45] + K3);
128 F3(E, A, B, C, D, W[46] + K3);
129 F3(D, E, A, B, C, W[47] + K3);
130 F3(C, D, E, A, B, W[48] + K3);
131 F3(B, C, D, E, A, W[49] + K3);
132 F3(A, B, C, D, E, W[50] + K3);
133 F3(E, A, B, C, D, W[51] + K3);
134 F3(D, E, A, B, C, W[52] + K3);
135 F3(C, D, E, A, B, W[53] + K3);
136 F3(B, C, D, E, A, W[54] + K3);
137 F3(A, B, C, D, E, W[55] + K3);
138 F3(E, A, B, C, D, W[56] + K3);
139 F3(D, E, A, B, C, W[57] + K3);
140 F3(C, D, E, A, B, W[58] + K3);
141 F3(B, C, D, E, A, W[59] + K3);
142
143 F4(A, B, C, D, E, W[60] + K4);
144 F4(E, A, B, C, D, W[61] + K4);
145 F4(D, E, A, B, C, W[62] + K4);
146 F4(C, D, E, A, B, W[63] + K4);
147 F4(B, C, D, E, A, W[64] + K4);
148 F4(A, B, C, D, E, W[65] + K4);
149 F4(E, A, B, C, D, W[66] + K4);
150 F4(D, E, A, B, C, W[67] + K4);
151 F4(C, D, E, A, B, W[68] + K4);
152 F4(B, C, D, E, A, W[69] + K4);
153 F4(A, B, C, D, E, W[70] + K4);
154 F4(E, A, B, C, D, W[71] + K4);
155 F4(D, E, A, B, C, W[72] + K4);
156 F4(C, D, E, A, B, W[73] + K4);
157 F4(B, C, D, E, A, W[74] + K4);
158 F4(A, B, C, D, E, W[75] + K4);
159 F4(E, A, B, C, D, W[76] + K4);
160 F4(D, E, A, B, C, W[77] + K4);
161 F4(C, D, E, A, B, W[78] + K4);
162 F4(B, C, D, E, A, W[79] + K4);
163
164 A = (digest[0] += A);
165 B = (digest[1] += B);
166 C = (digest[2] += C);
167 D = (digest[3] += D);
168 E = (digest[4] += E);
169 }
170}
171
172/*
173* Clear memory of sensitive data
174*/
176 digest.assign({0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0});
177}
178
179std::string SHA_1::provider() const {
180#if defined(BOTAN_HAS_SHA1_X86_SHA_NI)
181 if(auto feat = CPUID::check(CPUID::Feature::SHA)) {
182 return *feat;
183 }
184#endif
185
186#if defined(BOTAN_HAS_SHA1_ARMV8)
187 if(auto feat = CPUID::check(CPUID::Feature::SHA1)) {
188 return *feat;
189 }
190#endif
191
192#if defined(BOTAN_HAS_SHA1_AVX2)
194 return *feat;
195 }
196#endif
197
198#if defined(BOTAN_HAS_SHA1_SIMD_4X32)
199 if(auto feat = CPUID::check(CPUID::Feature::SIMD_4X32)) {
200 return *feat;
201 }
202#endif
203
204 return "base";
205}
206
207std::unique_ptr<HashFunction> SHA_1::new_object() const {
208 return std::make_unique<SHA_1>();
209}
210
211std::unique_ptr<HashFunction> SHA_1::copy_state() const {
212 return std::make_unique<SHA_1>(*this);
213}
214
215void SHA_1::add_data(std::span<const uint8_t> input) {
216 m_md.update(input);
217}
218
219void SHA_1::final_result(std::span<uint8_t> output) {
220 m_md.final(output);
221}
222
223} // namespace Botan
std::span< const uint8_t > take(const size_t count)
Definition stl_util.h:90
static std::optional< std::string > check(CPUID::Feature feat)
Definition cpuid.h:67
static bool has(CPUID::Feature feat)
Definition cpuid.h:94
std::unique_ptr< HashFunction > new_object() const override
Definition sha1.cpp:207
std::unique_ptr< HashFunction > copy_state() const override
Definition sha1.cpp:211
static void sha1_compress_x86(digest_type &digest, std::span< const uint8_t > blocks, size_t block_count)
Definition sha1_x86.cpp:58
std::string provider() const override
Definition sha1.cpp:179
static void sha1_armv8_compress_n(digest_type &digest, std::span< const uint8_t > blocks, size_t block_count)
static constexpr size_t block_bytes
Definition sha1.h:24
static void compress_n(digest_type &digest, std::span< const uint8_t > input, size_t blocks)
Definition sha1.cpp:25
static void init(digest_type &digest)
Definition sha1.cpp:175
secure_vector< uint32_t > digest_type
Definition sha1.h:20
BOTAN_FORCE_INLINE constexpr T rotl(T input)
Definition rotate.h:23
constexpr auto load_be(ParamTs &&... params)
Definition loadstor.h:504