/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.0k | { |
69 | 51.0k | using namespace SHA1_F; |
70 | 51.0k | |
71 | 51.0k | #if defined(BOTAN_HAS_SHA1_X86_SHA_NI) |
72 | 51.0k | if(CPUID::has_intel_sha()) |
73 | 0 | { |
74 | 0 | return sha1_compress_x86(m_digest, input, blocks); |
75 | 0 | } |
76 | 51.0k | #endif |
77 | 51.0k | |
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.0k | #if defined(BOTAN_HAS_SHA1_SSE2) |
86 | 51.0k | if(CPUID::has_sse2()) |
87 | 51.0k | { |
88 | 51.0k | return sse2_compress_n(m_digest, input, blocks); |
89 | 51.0k | } |
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 | | } |