Coverage Report

Created: 2022-01-14 08:07

/src/botan/src/lib/hash/sha1/sha160.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* SHA-160
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/sha160.h>
9
#include <botan/internal/loadstor.h>
10
#include <botan/internal/rotate.h>
11
#include <botan/internal/bit_ops.h>
12
#include <botan/internal/cpuid.h>
13
14
namespace Botan {
15
16
std::unique_ptr<HashFunction> SHA_160::copy_state() const
17
0
   {
18
0
   return std::make_unique<SHA_160>(*this);
19
0
   }
20
21
namespace SHA1_F {
22
23
namespace {
24
25
/*
26
* SHA-160 F1 Function
27
*/
28
inline void F1(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg)
29
0
   {
30
0
   E += choose(B, C, D) + msg + 0x5A827999 + rotl<5>(A);
31
0
   B  = rotl<30>(B);
32
0
   }
33
34
/*
35
* SHA-160 F2 Function
36
*/
37
inline void F2(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg)
38
0
   {
39
0
   E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotl<5>(A);
40
0
   B  = rotl<30>(B);
41
0
   }
42
43
/*
44
* SHA-160 F3 Function
45
*/
46
inline void F3(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg)
47
0
   {
48
0
   E += majority(B, C, D) + msg + 0x8F1BBCDC + rotl<5>(A);
49
0
   B  = rotl<30>(B);
50
0
   }
51
52
/*
53
* SHA-160 F4 Function
54
*/
55
inline void F4(uint32_t A, uint32_t& B, uint32_t C, uint32_t D, uint32_t& E, uint32_t msg)
56
0
   {
57
0
   E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotl<5>(A);
58
0
   B  = rotl<30>(B);
59
0
   }
60
61
}
62
63
}
64
65
/*
66
* SHA-160 Compression Function
67
*/
68
void SHA_160::compress_n(const uint8_t input[], size_t blocks)
69
46.0k
   {
70
46.0k
   using namespace SHA1_F;
71
72
46.0k
#if defined(BOTAN_HAS_SHA1_X86_SHA_NI)
73
46.0k
   if(CPUID::has_intel_sha())
74
0
      {
75
0
      return sha1_compress_x86(m_digest, input, blocks);
76
0
      }
77
46.0k
#endif
78
79
#if defined(BOTAN_HAS_SHA1_ARMV8)
80
   if(CPUID::has_arm_sha1())
81
      {
82
      return sha1_armv8_compress_n(m_digest, input, blocks);
83
      }
84
#endif
85
86
46.0k
#if defined(BOTAN_HAS_SHA1_SSE2)
87
46.0k
   if(CPUID::has_sse2())
88
46.0k
      {
89
46.0k
      return sse2_compress_n(m_digest, input, blocks);
90
46.0k
      }
91
92
0
#endif
93
94
0
   uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2],
95
0
          D = m_digest[3], E = m_digest[4];
96
97
0
   m_W.resize(80);
98
99
0
   for(size_t i = 0; i != blocks; ++i)
100
0
      {
101
0
      load_be(m_W.data(), input, 16);
102
103
0
      for(size_t j = 16; j != 80; j += 8)
104
0
         {
105
0
         m_W[j  ] = rotl<1>(m_W[j-3] ^ m_W[j-8] ^ m_W[j-14] ^ m_W[j-16]);
106
0
         m_W[j+1] = rotl<1>(m_W[j-2] ^ m_W[j-7] ^ m_W[j-13] ^ m_W[j-15]);
107
0
         m_W[j+2] = rotl<1>(m_W[j-1] ^ m_W[j-6] ^ m_W[j-12] ^ m_W[j-14]);
108
0
         m_W[j+3] = rotl<1>(m_W[j  ] ^ m_W[j-5] ^ m_W[j-11] ^ m_W[j-13]);
109
0
         m_W[j+4] = rotl<1>(m_W[j+1] ^ m_W[j-4] ^ m_W[j-10] ^ m_W[j-12]);
110
0
         m_W[j+5] = rotl<1>(m_W[j+2] ^ m_W[j-3] ^ m_W[j- 9] ^ m_W[j-11]);
111
0
         m_W[j+6] = rotl<1>(m_W[j+3] ^ m_W[j-2] ^ m_W[j- 8] ^ m_W[j-10]);
112
0
         m_W[j+7] = rotl<1>(m_W[j+4] ^ m_W[j-1] ^ m_W[j- 7] ^ m_W[j- 9]);
113
0
         }
114
115
0
      F1(A, B, C, D, E, m_W[ 0]);   F1(E, A, B, C, D, m_W[ 1]);
116
0
      F1(D, E, A, B, C, m_W[ 2]);   F1(C, D, E, A, B, m_W[ 3]);
117
0
      F1(B, C, D, E, A, m_W[ 4]);   F1(A, B, C, D, E, m_W[ 5]);
118
0
      F1(E, A, B, C, D, m_W[ 6]);   F1(D, E, A, B, C, m_W[ 7]);
119
0
      F1(C, D, E, A, B, m_W[ 8]);   F1(B, C, D, E, A, m_W[ 9]);
120
0
      F1(A, B, C, D, E, m_W[10]);   F1(E, A, B, C, D, m_W[11]);
121
0
      F1(D, E, A, B, C, m_W[12]);   F1(C, D, E, A, B, m_W[13]);
122
0
      F1(B, C, D, E, A, m_W[14]);   F1(A, B, C, D, E, m_W[15]);
123
0
      F1(E, A, B, C, D, m_W[16]);   F1(D, E, A, B, C, m_W[17]);
124
0
      F1(C, D, E, A, B, m_W[18]);   F1(B, C, D, E, A, m_W[19]);
125
126
0
      F2(A, B, C, D, E, m_W[20]);   F2(E, A, B, C, D, m_W[21]);
127
0
      F2(D, E, A, B, C, m_W[22]);   F2(C, D, E, A, B, m_W[23]);
128
0
      F2(B, C, D, E, A, m_W[24]);   F2(A, B, C, D, E, m_W[25]);
129
0
      F2(E, A, B, C, D, m_W[26]);   F2(D, E, A, B, C, m_W[27]);
130
0
      F2(C, D, E, A, B, m_W[28]);   F2(B, C, D, E, A, m_W[29]);
131
0
      F2(A, B, C, D, E, m_W[30]);   F2(E, A, B, C, D, m_W[31]);
132
0
      F2(D, E, A, B, C, m_W[32]);   F2(C, D, E, A, B, m_W[33]);
133
0
      F2(B, C, D, E, A, m_W[34]);   F2(A, B, C, D, E, m_W[35]);
134
0
      F2(E, A, B, C, D, m_W[36]);   F2(D, E, A, B, C, m_W[37]);
135
0
      F2(C, D, E, A, B, m_W[38]);   F2(B, C, D, E, A, m_W[39]);
136
137
0
      F3(A, B, C, D, E, m_W[40]);   F3(E, A, B, C, D, m_W[41]);
138
0
      F3(D, E, A, B, C, m_W[42]);   F3(C, D, E, A, B, m_W[43]);
139
0
      F3(B, C, D, E, A, m_W[44]);   F3(A, B, C, D, E, m_W[45]);
140
0
      F3(E, A, B, C, D, m_W[46]);   F3(D, E, A, B, C, m_W[47]);
141
0
      F3(C, D, E, A, B, m_W[48]);   F3(B, C, D, E, A, m_W[49]);
142
0
      F3(A, B, C, D, E, m_W[50]);   F3(E, A, B, C, D, m_W[51]);
143
0
      F3(D, E, A, B, C, m_W[52]);   F3(C, D, E, A, B, m_W[53]);
144
0
      F3(B, C, D, E, A, m_W[54]);   F3(A, B, C, D, E, m_W[55]);
145
0
      F3(E, A, B, C, D, m_W[56]);   F3(D, E, A, B, C, m_W[57]);
146
0
      F3(C, D, E, A, B, m_W[58]);   F3(B, C, D, E, A, m_W[59]);
147
148
0
      F4(A, B, C, D, E, m_W[60]);   F4(E, A, B, C, D, m_W[61]);
149
0
      F4(D, E, A, B, C, m_W[62]);   F4(C, D, E, A, B, m_W[63]);
150
0
      F4(B, C, D, E, A, m_W[64]);   F4(A, B, C, D, E, m_W[65]);
151
0
      F4(E, A, B, C, D, m_W[66]);   F4(D, E, A, B, C, m_W[67]);
152
0
      F4(C, D, E, A, B, m_W[68]);   F4(B, C, D, E, A, m_W[69]);
153
0
      F4(A, B, C, D, E, m_W[70]);   F4(E, A, B, C, D, m_W[71]);
154
0
      F4(D, E, A, B, C, m_W[72]);   F4(C, D, E, A, B, m_W[73]);
155
0
      F4(B, C, D, E, A, m_W[74]);   F4(A, B, C, D, E, m_W[75]);
156
0
      F4(E, A, B, C, D, m_W[76]);   F4(D, E, A, B, C, m_W[77]);
157
0
      F4(C, D, E, A, B, m_W[78]);   F4(B, C, D, E, A, m_W[79]);
158
159
0
      A = (m_digest[0] += A);
160
0
      B = (m_digest[1] += B);
161
0
      C = (m_digest[2] += C);
162
0
      D = (m_digest[3] += D);
163
0
      E = (m_digest[4] += E);
164
165
0
      input += hash_block_size();
166
0
      }
167
0
   }
168
169
/*
170
* Copy out the digest
171
*/
172
void SHA_160::copy_out(uint8_t output[])
173
22.8k
   {
174
22.8k
   copy_out_vec_be(output, output_length(), m_digest);
175
22.8k
   }
176
177
/*
178
* Clear memory of sensitive data
179
*/
180
void SHA_160::clear()
181
45.9k
   {
182
45.9k
   MDx_HashFunction::clear();
183
45.9k
   zeroise(m_W);
184
45.9k
   m_digest[0] = 0x67452301;
185
45.9k
   m_digest[1] = 0xEFCDAB89;
186
45.9k
   m_digest[2] = 0x98BADCFE;
187
45.9k
   m_digest[3] = 0x10325476;
188
45.9k
   m_digest[4] = 0xC3D2E1F0;
189
45.9k
   }
190
191
}