Coverage Report

Created: 2023-09-19 06:05

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