/src/botan/src/lib/hash/sha2_32/sha2_32.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * SHA-{224,256} |
3 | | * (C) 1999-2010,2017 Jack Lloyd |
4 | | * 2007 FlexSecure GmbH |
5 | | * |
6 | | * Botan is released under the Simplified BSD License (see license.txt) |
7 | | */ |
8 | | |
9 | | #include <botan/internal/sha2_32.h> |
10 | | |
11 | | #include <botan/internal/bit_ops.h> |
12 | | #include <botan/internal/loadstor.h> |
13 | | #include <botan/internal/rotate.h> |
14 | | #include <botan/internal/sha2_32_f.h> |
15 | | #include <botan/internal/stl_util.h> |
16 | | |
17 | | #if defined(BOTAN_HAS_CPUID) |
18 | | #include <botan/internal/cpuid.h> |
19 | | #endif |
20 | | |
21 | | namespace Botan { |
22 | | |
23 | | namespace { |
24 | | |
25 | 0 | std::string sha256_provider() { |
26 | | #if defined(BOTAN_HAS_SHA2_32_ARMV8) |
27 | | if(CPUID::has(CPUID::Feature::SHA2)) { |
28 | | return "armv8"; |
29 | | } |
30 | | #endif |
31 | |
|
32 | 0 | #if defined(BOTAN_HAS_SHA2_32_X86) |
33 | 0 | if(CPUID::has(CPUID::Feature::SHA)) { |
34 | 0 | return "shani"; |
35 | 0 | } |
36 | 0 | #endif |
37 | | |
38 | 0 | #if defined(BOTAN_HAS_SHA2_32_X86_AVX2) |
39 | 0 | if(CPUID::has(CPUID::Feature::AVX2) && CPUID::has(CPUID::Feature::BMI)) { |
40 | 0 | return "bmi2"; |
41 | 0 | } |
42 | 0 | #endif |
43 | | |
44 | 0 | #if defined(BOTAN_HAS_SHA2_32_SIMD) |
45 | 0 | if(CPUID::has_simd_4x32()) { |
46 | 0 | return "simd"; |
47 | 0 | } |
48 | 0 | #endif |
49 | | |
50 | 0 | return "base"; |
51 | 0 | } |
52 | | |
53 | | } // namespace |
54 | | |
55 | | /* |
56 | | * SHA-224 / SHA-256 compression function |
57 | | */ |
58 | 380k | void SHA_256::compress_digest(digest_type& digest, std::span<const uint8_t> input, size_t blocks) { |
59 | 380k | #if defined(BOTAN_HAS_SHA2_32_X86) |
60 | 380k | if(CPUID::has(CPUID::Feature::SHA)) { |
61 | 0 | return SHA_256::compress_digest_x86(digest, input, blocks); |
62 | 0 | } |
63 | 380k | #endif |
64 | | |
65 | | #if defined(BOTAN_HAS_SHA2_32_ARMV8) |
66 | | if(CPUID::has(CPUID::Feature::SHA2)) { |
67 | | return SHA_256::compress_digest_armv8(digest, input, blocks); |
68 | | } |
69 | | #endif |
70 | | |
71 | 380k | #if defined(BOTAN_HAS_SHA2_32_X86_AVX2) |
72 | 380k | if(CPUID::has(CPUID::Feature::AVX2) && CPUID::has(CPUID::Feature::BMI)) { |
73 | 380k | return SHA_256::compress_digest_x86_avx2(digest, input, blocks); |
74 | 380k | } |
75 | 0 | #endif |
76 | | |
77 | 0 | #if defined(BOTAN_HAS_SHA2_32_SIMD) |
78 | 0 | if(CPUID::has_simd_4x32()) { |
79 | 0 | return SHA_256::compress_digest_x86_simd(digest, input, blocks); |
80 | 0 | } |
81 | 0 | #endif |
82 | | |
83 | 0 | uint32_t A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4], F = digest[5], G = digest[6], |
84 | 0 | H = digest[7]; |
85 | |
|
86 | 0 | std::array<uint32_t, 16> W; |
87 | |
|
88 | 0 | BufferSlicer in(input); |
89 | |
|
90 | 0 | for(size_t i = 0; i != blocks; ++i) { |
91 | 0 | load_be(W, in.take<block_bytes>()); |
92 | | |
93 | | // clang-format off |
94 | |
|
95 | 0 | SHA2_32_F(A, B, C, D, E, F, G, H, W[ 0], W[14], W[ 9], W[ 1], 0x428A2F98); |
96 | 0 | SHA2_32_F(H, A, B, C, D, E, F, G, W[ 1], W[15], W[10], W[ 2], 0x71374491); |
97 | 0 | SHA2_32_F(G, H, A, B, C, D, E, F, W[ 2], W[ 0], W[11], W[ 3], 0xB5C0FBCF); |
98 | 0 | SHA2_32_F(F, G, H, A, B, C, D, E, W[ 3], W[ 1], W[12], W[ 4], 0xE9B5DBA5); |
99 | 0 | SHA2_32_F(E, F, G, H, A, B, C, D, W[ 4], W[ 2], W[13], W[ 5], 0x3956C25B); |
100 | 0 | SHA2_32_F(D, E, F, G, H, A, B, C, W[ 5], W[ 3], W[14], W[ 6], 0x59F111F1); |
101 | 0 | SHA2_32_F(C, D, E, F, G, H, A, B, W[ 6], W[ 4], W[15], W[ 7], 0x923F82A4); |
102 | 0 | SHA2_32_F(B, C, D, E, F, G, H, A, W[ 7], W[ 5], W[ 0], W[ 8], 0xAB1C5ED5); |
103 | 0 | SHA2_32_F(A, B, C, D, E, F, G, H, W[ 8], W[ 6], W[ 1], W[ 9], 0xD807AA98); |
104 | 0 | SHA2_32_F(H, A, B, C, D, E, F, G, W[ 9], W[ 7], W[ 2], W[10], 0x12835B01); |
105 | 0 | SHA2_32_F(G, H, A, B, C, D, E, F, W[10], W[ 8], W[ 3], W[11], 0x243185BE); |
106 | 0 | SHA2_32_F(F, G, H, A, B, C, D, E, W[11], W[ 9], W[ 4], W[12], 0x550C7DC3); |
107 | 0 | SHA2_32_F(E, F, G, H, A, B, C, D, W[12], W[10], W[ 5], W[13], 0x72BE5D74); |
108 | 0 | SHA2_32_F(D, E, F, G, H, A, B, C, W[13], W[11], W[ 6], W[14], 0x80DEB1FE); |
109 | 0 | SHA2_32_F(C, D, E, F, G, H, A, B, W[14], W[12], W[ 7], W[15], 0x9BDC06A7); |
110 | 0 | SHA2_32_F(B, C, D, E, F, G, H, A, W[15], W[13], W[ 8], W[ 0], 0xC19BF174); |
111 | |
|
112 | 0 | SHA2_32_F(A, B, C, D, E, F, G, H, W[ 0], W[14], W[ 9], W[ 1], 0xE49B69C1); |
113 | 0 | SHA2_32_F(H, A, B, C, D, E, F, G, W[ 1], W[15], W[10], W[ 2], 0xEFBE4786); |
114 | 0 | SHA2_32_F(G, H, A, B, C, D, E, F, W[ 2], W[ 0], W[11], W[ 3], 0x0FC19DC6); |
115 | 0 | SHA2_32_F(F, G, H, A, B, C, D, E, W[ 3], W[ 1], W[12], W[ 4], 0x240CA1CC); |
116 | 0 | SHA2_32_F(E, F, G, H, A, B, C, D, W[ 4], W[ 2], W[13], W[ 5], 0x2DE92C6F); |
117 | 0 | SHA2_32_F(D, E, F, G, H, A, B, C, W[ 5], W[ 3], W[14], W[ 6], 0x4A7484AA); |
118 | 0 | SHA2_32_F(C, D, E, F, G, H, A, B, W[ 6], W[ 4], W[15], W[ 7], 0x5CB0A9DC); |
119 | 0 | SHA2_32_F(B, C, D, E, F, G, H, A, W[ 7], W[ 5], W[ 0], W[ 8], 0x76F988DA); |
120 | 0 | SHA2_32_F(A, B, C, D, E, F, G, H, W[ 8], W[ 6], W[ 1], W[ 9], 0x983E5152); |
121 | 0 | SHA2_32_F(H, A, B, C, D, E, F, G, W[ 9], W[ 7], W[ 2], W[10], 0xA831C66D); |
122 | 0 | SHA2_32_F(G, H, A, B, C, D, E, F, W[10], W[ 8], W[ 3], W[11], 0xB00327C8); |
123 | 0 | SHA2_32_F(F, G, H, A, B, C, D, E, W[11], W[ 9], W[ 4], W[12], 0xBF597FC7); |
124 | 0 | SHA2_32_F(E, F, G, H, A, B, C, D, W[12], W[10], W[ 5], W[13], 0xC6E00BF3); |
125 | 0 | SHA2_32_F(D, E, F, G, H, A, B, C, W[13], W[11], W[ 6], W[14], 0xD5A79147); |
126 | 0 | SHA2_32_F(C, D, E, F, G, H, A, B, W[14], W[12], W[ 7], W[15], 0x06CA6351); |
127 | 0 | SHA2_32_F(B, C, D, E, F, G, H, A, W[15], W[13], W[ 8], W[ 0], 0x14292967); |
128 | |
|
129 | 0 | SHA2_32_F(A, B, C, D, E, F, G, H, W[ 0], W[14], W[ 9], W[ 1], 0x27B70A85); |
130 | 0 | SHA2_32_F(H, A, B, C, D, E, F, G, W[ 1], W[15], W[10], W[ 2], 0x2E1B2138); |
131 | 0 | SHA2_32_F(G, H, A, B, C, D, E, F, W[ 2], W[ 0], W[11], W[ 3], 0x4D2C6DFC); |
132 | 0 | SHA2_32_F(F, G, H, A, B, C, D, E, W[ 3], W[ 1], W[12], W[ 4], 0x53380D13); |
133 | 0 | SHA2_32_F(E, F, G, H, A, B, C, D, W[ 4], W[ 2], W[13], W[ 5], 0x650A7354); |
134 | 0 | SHA2_32_F(D, E, F, G, H, A, B, C, W[ 5], W[ 3], W[14], W[ 6], 0x766A0ABB); |
135 | 0 | SHA2_32_F(C, D, E, F, G, H, A, B, W[ 6], W[ 4], W[15], W[ 7], 0x81C2C92E); |
136 | 0 | SHA2_32_F(B, C, D, E, F, G, H, A, W[ 7], W[ 5], W[ 0], W[ 8], 0x92722C85); |
137 | 0 | SHA2_32_F(A, B, C, D, E, F, G, H, W[ 8], W[ 6], W[ 1], W[ 9], 0xA2BFE8A1); |
138 | 0 | SHA2_32_F(H, A, B, C, D, E, F, G, W[ 9], W[ 7], W[ 2], W[10], 0xA81A664B); |
139 | 0 | SHA2_32_F(G, H, A, B, C, D, E, F, W[10], W[ 8], W[ 3], W[11], 0xC24B8B70); |
140 | 0 | SHA2_32_F(F, G, H, A, B, C, D, E, W[11], W[ 9], W[ 4], W[12], 0xC76C51A3); |
141 | 0 | SHA2_32_F(E, F, G, H, A, B, C, D, W[12], W[10], W[ 5], W[13], 0xD192E819); |
142 | 0 | SHA2_32_F(D, E, F, G, H, A, B, C, W[13], W[11], W[ 6], W[14], 0xD6990624); |
143 | 0 | SHA2_32_F(C, D, E, F, G, H, A, B, W[14], W[12], W[ 7], W[15], 0xF40E3585); |
144 | 0 | SHA2_32_F(B, C, D, E, F, G, H, A, W[15], W[13], W[ 8], W[ 0], 0x106AA070); |
145 | |
|
146 | 0 | SHA2_32_F(A, B, C, D, E, F, G, H, W[ 0], W[14], W[ 9], W[ 1], 0x19A4C116); |
147 | 0 | SHA2_32_F(H, A, B, C, D, E, F, G, W[ 1], W[15], W[10], W[ 2], 0x1E376C08); |
148 | 0 | SHA2_32_F(G, H, A, B, C, D, E, F, W[ 2], W[ 0], W[11], W[ 3], 0x2748774C); |
149 | 0 | SHA2_32_F(F, G, H, A, B, C, D, E, W[ 3], W[ 1], W[12], W[ 4], 0x34B0BCB5); |
150 | 0 | SHA2_32_F(E, F, G, H, A, B, C, D, W[ 4], W[ 2], W[13], W[ 5], 0x391C0CB3); |
151 | 0 | SHA2_32_F(D, E, F, G, H, A, B, C, W[ 5], W[ 3], W[14], W[ 6], 0x4ED8AA4A); |
152 | 0 | SHA2_32_F(C, D, E, F, G, H, A, B, W[ 6], W[ 4], W[15], W[ 7], 0x5B9CCA4F); |
153 | 0 | SHA2_32_F(B, C, D, E, F, G, H, A, W[ 7], W[ 5], W[ 0], W[ 8], 0x682E6FF3); |
154 | 0 | SHA2_32_F(A, B, C, D, E, F, G, H, W[ 8], W[ 6], W[ 1], W[ 9], 0x748F82EE); |
155 | 0 | SHA2_32_F(H, A, B, C, D, E, F, G, W[ 9], W[ 7], W[ 2], W[10], 0x78A5636F); |
156 | 0 | SHA2_32_F(G, H, A, B, C, D, E, F, W[10], W[ 8], W[ 3], W[11], 0x84C87814); |
157 | 0 | SHA2_32_F(F, G, H, A, B, C, D, E, W[11], W[ 9], W[ 4], W[12], 0x8CC70208); |
158 | 0 | SHA2_32_F(E, F, G, H, A, B, C, D, W[12], W[10], W[ 5], W[13], 0x90BEFFFA); |
159 | 0 | SHA2_32_F(D, E, F, G, H, A, B, C, W[13], W[11], W[ 6], W[14], 0xA4506CEB); |
160 | 0 | SHA2_32_F(C, D, E, F, G, H, A, B, W[14], W[12], W[ 7], W[15], 0xBEF9A3F7); |
161 | 0 | SHA2_32_F(B, C, D, E, F, G, H, A, W[15], W[13], W[ 8], W[ 0], 0xC67178F2); |
162 | | |
163 | | // clang-format on |
164 | |
|
165 | 0 | A = (digest[0] += A); |
166 | 0 | B = (digest[1] += B); |
167 | 0 | C = (digest[2] += C); |
168 | 0 | D = (digest[3] += D); |
169 | 0 | E = (digest[4] += E); |
170 | 0 | F = (digest[5] += F); |
171 | 0 | G = (digest[6] += G); |
172 | 0 | H = (digest[7] += H); |
173 | 0 | } |
174 | 0 | } |
175 | | |
176 | 0 | std::string SHA_224::provider() const { |
177 | 0 | return sha256_provider(); |
178 | 0 | } |
179 | | |
180 | 26 | void SHA_224::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) { |
181 | 26 | SHA_256::compress_digest(digest, input, blocks); |
182 | 26 | } |
183 | | |
184 | 22 | void SHA_224::init(digest_type& digest) { |
185 | 22 | digest.assign({0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4}); |
186 | 22 | } |
187 | | |
188 | 0 | std::unique_ptr<HashFunction> SHA_224::new_object() const { |
189 | 0 | return std::make_unique<SHA_224>(); |
190 | 0 | } |
191 | | |
192 | 0 | std::unique_ptr<HashFunction> SHA_224::copy_state() const { |
193 | 0 | return std::make_unique<SHA_224>(*this); |
194 | 0 | } |
195 | | |
196 | 11 | void SHA_224::add_data(std::span<const uint8_t> input) { |
197 | 11 | m_md.update(input); |
198 | 11 | } |
199 | | |
200 | 11 | void SHA_224::final_result(std::span<uint8_t> output) { |
201 | 11 | m_md.final(output); |
202 | 11 | } |
203 | | |
204 | 0 | std::string SHA_256::provider() const { |
205 | 0 | return sha256_provider(); |
206 | 0 | } |
207 | | |
208 | 380k | void SHA_256::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) { |
209 | 380k | SHA_256::compress_digest(digest, input, blocks); |
210 | 380k | } |
211 | | |
212 | 326k | void SHA_256::init(digest_type& digest) { |
213 | 326k | digest.assign({0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19}); |
214 | 326k | } |
215 | | |
216 | 0 | std::unique_ptr<HashFunction> SHA_256::new_object() const { |
217 | 0 | return std::make_unique<SHA_256>(); |
218 | 0 | } |
219 | | |
220 | 26.9k | std::unique_ptr<HashFunction> SHA_256::copy_state() const { |
221 | 26.9k | return std::make_unique<SHA_256>(*this); |
222 | 26.9k | } |
223 | | |
224 | 356k | void SHA_256::add_data(std::span<const uint8_t> input) { |
225 | 356k | m_md.update(input); |
226 | 356k | } |
227 | | |
228 | 210k | void SHA_256::final_result(std::span<uint8_t> output) { |
229 | 210k | m_md.final(output); |
230 | 210k | } |
231 | | |
232 | | } // namespace Botan |