Botan  2.7.0
Crypto and TLS for C++11
sha1_x86.cpp
Go to the documentation of this file.
1 /*
2 * SHA-1 using Intel SHA intrinsic
3 *
4 * Based on public domain code by Sean Gulley
5 * (https://github.com/mitls/hacl-star/tree/master/experimental/hash)
6 * Adapted to Botan by Jeffrey Walton.
7 *
8 * Further changes
9 *
10 * (C) 2017 Jack Lloyd
11 *
12 * Botan is released under the Simplified BSD License (see license.txt)
13 */
14 
15 #include <botan/sha160.h>
16 #include <immintrin.h>
17 
18 namespace Botan {
19 
20 #if defined(BOTAN_HAS_SHA1_X86_SHA_NI)
21 BOTAN_FUNC_ISA("sha,ssse3,sse4.1")
22 void SHA_160::sha1_compress_x86(secure_vector<uint32_t>& digest,
23  const uint8_t input[],
24  size_t blocks)
25  {
26  const __m128i MASK = _mm_set_epi64x(0x0001020304050607ULL, 0x08090a0b0c0d0e0fULL);
27  const __m128i* input_mm = reinterpret_cast<const __m128i*>(input);
28 
29  uint32_t* state = digest.data();
30 
31  // Load initial values
32  __m128i ABCD = _mm_loadu_si128(reinterpret_cast<__m128i*>(state));
33  __m128i E0 = _mm_set_epi32(state[4], 0, 0, 0);
34  ABCD = _mm_shuffle_epi32(ABCD, 0x1B);
35 
36  while (blocks)
37  {
38  // Save current hash
39  const __m128i ABCD_SAVE = ABCD;
40  const __m128i E0_SAVE = E0;
41 
42  __m128i MSG0, MSG1, MSG2, MSG3;
43  __m128i E1;
44 
45  // Rounds 0-3
46  MSG0 = _mm_loadu_si128(input_mm+0);
47  MSG0 = _mm_shuffle_epi8(MSG0, MASK);
48  E0 = _mm_add_epi32(E0, MSG0);
49  E1 = ABCD;
50  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
51 
52  // Rounds 4-7
53  MSG1 = _mm_loadu_si128(input_mm+1);
54  MSG1 = _mm_shuffle_epi8(MSG1, MASK);
55  E1 = _mm_sha1nexte_epu32(E1, MSG1);
56  E0 = ABCD;
57  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0);
58  MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
59 
60  // Rounds 8-11
61  MSG2 = _mm_loadu_si128(input_mm+2);
62  MSG2 = _mm_shuffle_epi8(MSG2, MASK);
63  E0 = _mm_sha1nexte_epu32(E0, MSG2);
64  E1 = ABCD;
65  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
66  MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
67  MSG0 = _mm_xor_si128(MSG0, MSG2);
68 
69  // Rounds 12-15
70  MSG3 = _mm_loadu_si128(input_mm+3);
71  MSG3 = _mm_shuffle_epi8(MSG3, MASK);
72  E1 = _mm_sha1nexte_epu32(E1, MSG3);
73  E0 = ABCD;
74  MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
75  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 0);
76  MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
77  MSG1 = _mm_xor_si128(MSG1, MSG3);
78 
79  // Rounds 16-19
80  E0 = _mm_sha1nexte_epu32(E0, MSG0);
81  E1 = ABCD;
82  MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
83  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 0);
84  MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
85  MSG2 = _mm_xor_si128(MSG2, MSG0);
86 
87  // Rounds 20-23
88  E1 = _mm_sha1nexte_epu32(E1, MSG1);
89  E0 = ABCD;
90  MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
91  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
92  MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
93  MSG3 = _mm_xor_si128(MSG3, MSG1);
94 
95  // Rounds 24-27
96  E0 = _mm_sha1nexte_epu32(E0, MSG2);
97  E1 = ABCD;
98  MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
99  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1);
100  MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
101  MSG0 = _mm_xor_si128(MSG0, MSG2);
102 
103  // Rounds 28-31
104  E1 = _mm_sha1nexte_epu32(E1, MSG3);
105  E0 = ABCD;
106  MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
107  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
108  MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
109  MSG1 = _mm_xor_si128(MSG1, MSG3);
110 
111  // Rounds 32-35
112  E0 = _mm_sha1nexte_epu32(E0, MSG0);
113  E1 = ABCD;
114  MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
115  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 1);
116  MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
117  MSG2 = _mm_xor_si128(MSG2, MSG0);
118 
119  // Rounds 36-39
120  E1 = _mm_sha1nexte_epu32(E1, MSG1);
121  E0 = ABCD;
122  MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
123  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 1);
124  MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
125  MSG3 = _mm_xor_si128(MSG3, MSG1);
126 
127  // Rounds 40-43
128  E0 = _mm_sha1nexte_epu32(E0, MSG2);
129  E1 = ABCD;
130  MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
131  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
132  MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
133  MSG0 = _mm_xor_si128(MSG0, MSG2);
134 
135  // Rounds 44-47
136  E1 = _mm_sha1nexte_epu32(E1, MSG3);
137  E0 = ABCD;
138  MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
139  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2);
140  MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
141  MSG1 = _mm_xor_si128(MSG1, MSG3);
142 
143  // Rounds 48-51
144  E0 = _mm_sha1nexte_epu32(E0, MSG0);
145  E1 = ABCD;
146  MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
147  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
148  MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
149  MSG2 = _mm_xor_si128(MSG2, MSG0);
150 
151  // Rounds 52-55
152  E1 = _mm_sha1nexte_epu32(E1, MSG1);
153  E0 = ABCD;
154  MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
155  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 2);
156  MSG0 = _mm_sha1msg1_epu32(MSG0, MSG1);
157  MSG3 = _mm_xor_si128(MSG3, MSG1);
158 
159  // Rounds 56-59
160  E0 = _mm_sha1nexte_epu32(E0, MSG2);
161  E1 = ABCD;
162  MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
163  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 2);
164  MSG1 = _mm_sha1msg1_epu32(MSG1, MSG2);
165  MSG0 = _mm_xor_si128(MSG0, MSG2);
166 
167  // Rounds 60-63
168  E1 = _mm_sha1nexte_epu32(E1, MSG3);
169  E0 = ABCD;
170  MSG0 = _mm_sha1msg2_epu32(MSG0, MSG3);
171  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
172  MSG2 = _mm_sha1msg1_epu32(MSG2, MSG3);
173  MSG1 = _mm_xor_si128(MSG1, MSG3);
174 
175  // Rounds 64-67
176  E0 = _mm_sha1nexte_epu32(E0, MSG0);
177  E1 = ABCD;
178  MSG1 = _mm_sha1msg2_epu32(MSG1, MSG0);
179  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3);
180  MSG3 = _mm_sha1msg1_epu32(MSG3, MSG0);
181  MSG2 = _mm_xor_si128(MSG2, MSG0);
182 
183  // Rounds 68-71
184  E1 = _mm_sha1nexte_epu32(E1, MSG1);
185  E0 = ABCD;
186  MSG2 = _mm_sha1msg2_epu32(MSG2, MSG1);
187  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
188  MSG3 = _mm_xor_si128(MSG3, MSG1);
189 
190  // Rounds 72-75
191  E0 = _mm_sha1nexte_epu32(E0, MSG2);
192  E1 = ABCD;
193  MSG3 = _mm_sha1msg2_epu32(MSG3, MSG2);
194  ABCD = _mm_sha1rnds4_epu32(ABCD, E0, 3);
195 
196  // Rounds 76-79
197  E1 = _mm_sha1nexte_epu32(E1, MSG3);
198  E0 = ABCD;
199  ABCD = _mm_sha1rnds4_epu32(ABCD, E1, 3);
200 
201  // Add values back to state
202  E0 = _mm_sha1nexte_epu32(E0, E0_SAVE);
203  ABCD = _mm_add_epi32(ABCD, ABCD_SAVE);
204 
205  input_mm += 4;
206  blocks--;
207  }
208 
209  // Save state
210  ABCD = _mm_shuffle_epi32(ABCD, 0x1B);
211  _mm_storeu_si128(reinterpret_cast<__m128i*>(state), ABCD);
212  state[4] = _mm_extract_epi32(E0, 3);
213  }
214 #endif
215 
216 }
#define BOTAN_FUNC_ISA(isa)
Definition: compiler.h:75
Definition: alg_id.cpp:13
std::vector< T, secure_allocator< T > > secure_vector
Definition: secmem.h:88