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