Coverage Report

Created: 2025-04-11 06:34

/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