Coverage Report

Created: 2020-02-14 15:38

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