1*f6dc9357SAndroid Build Coastguard Worker /* Sha1Opt.c -- SHA-1 optimized code for SHA-1 hardware instructions
2*f6dc9357SAndroid Build Coastguard Worker : Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker
4*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
5*f6dc9357SAndroid Build Coastguard Worker #include "Compiler.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "CpuArch.h"
7*f6dc9357SAndroid Build Coastguard Worker
8*f6dc9357SAndroid Build Coastguard Worker // #define Z7_USE_HW_SHA_STUB // for debug
9*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_X86_OR_AMD64
10*f6dc9357SAndroid Build Coastguard Worker #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 1600) // fix that check
11*f6dc9357SAndroid Build Coastguard Worker #define USE_HW_SHA
12*f6dc9357SAndroid Build Coastguard Worker #elif defined(Z7_LLVM_CLANG_VERSION) && (Z7_LLVM_CLANG_VERSION >= 30800) \
13*f6dc9357SAndroid Build Coastguard Worker || defined(Z7_APPLE_CLANG_VERSION) && (Z7_APPLE_CLANG_VERSION >= 50100) \
14*f6dc9357SAndroid Build Coastguard Worker || defined(Z7_GCC_VERSION) && (Z7_GCC_VERSION >= 40900)
15*f6dc9357SAndroid Build Coastguard Worker #define USE_HW_SHA
16*f6dc9357SAndroid Build Coastguard Worker #if !defined(__INTEL_COMPILER)
17*f6dc9357SAndroid Build Coastguard Worker // icc defines __GNUC__, but icc doesn't support __attribute__(__target__)
18*f6dc9357SAndroid Build Coastguard Worker #if !defined(__SHA__) || !defined(__SSSE3__)
19*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_SHA __attribute__((__target__("sha,ssse3")))
20*f6dc9357SAndroid Build Coastguard Worker #endif
21*f6dc9357SAndroid Build Coastguard Worker #endif
22*f6dc9357SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
23*f6dc9357SAndroid Build Coastguard Worker #if (_MSC_VER >= 1900)
24*f6dc9357SAndroid Build Coastguard Worker #define USE_HW_SHA
25*f6dc9357SAndroid Build Coastguard Worker #else
26*f6dc9357SAndroid Build Coastguard Worker #define Z7_USE_HW_SHA_STUB
27*f6dc9357SAndroid Build Coastguard Worker #endif
28*f6dc9357SAndroid Build Coastguard Worker #endif
29*f6dc9357SAndroid Build Coastguard Worker // #endif // MY_CPU_X86_OR_AMD64
30*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_HW_SHA
31*f6dc9357SAndroid Build Coastguard Worker // #define Z7_USE_HW_SHA_STUB // for debug
32*f6dc9357SAndroid Build Coastguard Worker #endif
33*f6dc9357SAndroid Build Coastguard Worker
34*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_HW_SHA
35*f6dc9357SAndroid Build Coastguard Worker
36*f6dc9357SAndroid Build Coastguard Worker // #pragma message("Sha1 HW")
37*f6dc9357SAndroid Build Coastguard Worker
38*f6dc9357SAndroid Build Coastguard Worker
39*f6dc9357SAndroid Build Coastguard Worker
40*f6dc9357SAndroid Build Coastguard Worker
41*f6dc9357SAndroid Build Coastguard Worker // sse/sse2/ssse3:
42*f6dc9357SAndroid Build Coastguard Worker #include <tmmintrin.h>
43*f6dc9357SAndroid Build Coastguard Worker // sha*:
44*f6dc9357SAndroid Build Coastguard Worker #include <immintrin.h>
45*f6dc9357SAndroid Build Coastguard Worker
46*f6dc9357SAndroid Build Coastguard Worker #if defined (__clang__) && defined(_MSC_VER)
47*f6dc9357SAndroid Build Coastguard Worker #if !defined(__SHA__)
48*f6dc9357SAndroid Build Coastguard Worker #include <shaintrin.h>
49*f6dc9357SAndroid Build Coastguard Worker #endif
50*f6dc9357SAndroid Build Coastguard Worker #else
51*f6dc9357SAndroid Build Coastguard Worker
52*f6dc9357SAndroid Build Coastguard Worker #endif
53*f6dc9357SAndroid Build Coastguard Worker
54*f6dc9357SAndroid Build Coastguard Worker /*
55*f6dc9357SAndroid Build Coastguard Worker SHA1 uses:
56*f6dc9357SAndroid Build Coastguard Worker SSE2:
57*f6dc9357SAndroid Build Coastguard Worker _mm_loadu_si128
58*f6dc9357SAndroid Build Coastguard Worker _mm_storeu_si128
59*f6dc9357SAndroid Build Coastguard Worker _mm_set_epi32
60*f6dc9357SAndroid Build Coastguard Worker _mm_add_epi32
61*f6dc9357SAndroid Build Coastguard Worker _mm_shuffle_epi32 / pshufd
62*f6dc9357SAndroid Build Coastguard Worker _mm_xor_si128
63*f6dc9357SAndroid Build Coastguard Worker _mm_cvtsi128_si32
64*f6dc9357SAndroid Build Coastguard Worker _mm_cvtsi32_si128
65*f6dc9357SAndroid Build Coastguard Worker SSSE3:
66*f6dc9357SAndroid Build Coastguard Worker _mm_shuffle_epi8 / pshufb
67*f6dc9357SAndroid Build Coastguard Worker
68*f6dc9357SAndroid Build Coastguard Worker SHA:
69*f6dc9357SAndroid Build Coastguard Worker _mm_sha1*
70*f6dc9357SAndroid Build Coastguard Worker */
71*f6dc9357SAndroid Build Coastguard Worker
72*f6dc9357SAndroid Build Coastguard Worker #define XOR_SI128(dest, src) dest = _mm_xor_si128(dest, src);
73*f6dc9357SAndroid Build Coastguard Worker #define SHUFFLE_EPI8(dest, mask) dest = _mm_shuffle_epi8(dest, mask);
74*f6dc9357SAndroid Build Coastguard Worker #define SHUFFLE_EPI32(dest, mask) dest = _mm_shuffle_epi32(dest, mask);
75*f6dc9357SAndroid Build Coastguard Worker #ifdef __clang__
76*f6dc9357SAndroid Build Coastguard Worker #define SHA1_RNDS4_RET_TYPE_CAST (__m128i)
77*f6dc9357SAndroid Build Coastguard Worker #else
78*f6dc9357SAndroid Build Coastguard Worker #define SHA1_RNDS4_RET_TYPE_CAST
79*f6dc9357SAndroid Build Coastguard Worker #endif
80*f6dc9357SAndroid Build Coastguard Worker #define SHA1_RND4(abcd, e0, f) abcd = SHA1_RNDS4_RET_TYPE_CAST _mm_sha1rnds4_epu32(abcd, e0, f);
81*f6dc9357SAndroid Build Coastguard Worker #define SHA1_NEXTE(e, m) e = _mm_sha1nexte_epu32(e, m);
82*f6dc9357SAndroid Build Coastguard Worker #define ADD_EPI32(dest, src) dest = _mm_add_epi32(dest, src);
83*f6dc9357SAndroid Build Coastguard Worker #define SHA1_MSG1(dest, src) dest = _mm_sha1msg1_epu32(dest, src);
84*f6dc9357SAndroid Build Coastguard Worker #define SHA1_MSG2(dest, src) dest = _mm_sha1msg2_epu32(dest, src);
85*f6dc9357SAndroid Build Coastguard Worker
86*f6dc9357SAndroid Build Coastguard Worker #define LOAD_SHUFFLE(m, k) \
87*f6dc9357SAndroid Build Coastguard Worker m = _mm_loadu_si128((const __m128i *)(const void *)(data + (k) * 16)); \
88*f6dc9357SAndroid Build Coastguard Worker SHUFFLE_EPI8(m, mask) \
89*f6dc9357SAndroid Build Coastguard Worker
90*f6dc9357SAndroid Build Coastguard Worker #define NNN(m0, m1, m2, m3)
91*f6dc9357SAndroid Build Coastguard Worker
92*f6dc9357SAndroid Build Coastguard Worker #define SM1(m0, m1, m2, m3) \
93*f6dc9357SAndroid Build Coastguard Worker SHA1_MSG1(m0, m1) \
94*f6dc9357SAndroid Build Coastguard Worker
95*f6dc9357SAndroid Build Coastguard Worker #define SM2(m0, m1, m2, m3) \
96*f6dc9357SAndroid Build Coastguard Worker XOR_SI128(m3, m1) \
97*f6dc9357SAndroid Build Coastguard Worker SHA1_MSG2(m3, m2) \
98*f6dc9357SAndroid Build Coastguard Worker
99*f6dc9357SAndroid Build Coastguard Worker #define SM3(m0, m1, m2, m3) \
100*f6dc9357SAndroid Build Coastguard Worker XOR_SI128(m3, m1) \
101*f6dc9357SAndroid Build Coastguard Worker SM1(m0, m1, m2, m3) \
102*f6dc9357SAndroid Build Coastguard Worker SHA1_MSG2(m3, m2) \
103*f6dc9357SAndroid Build Coastguard Worker
104*f6dc9357SAndroid Build Coastguard Worker #define R4(k, m0, m1, m2, m3, e0, e1, OP) \
105*f6dc9357SAndroid Build Coastguard Worker e1 = abcd; \
106*f6dc9357SAndroid Build Coastguard Worker SHA1_RND4(abcd, e0, (k) / 5) \
107*f6dc9357SAndroid Build Coastguard Worker SHA1_NEXTE(e1, m1) \
108*f6dc9357SAndroid Build Coastguard Worker OP(m0, m1, m2, m3) \
109*f6dc9357SAndroid Build Coastguard Worker
110*f6dc9357SAndroid Build Coastguard Worker
111*f6dc9357SAndroid Build Coastguard Worker
112*f6dc9357SAndroid Build Coastguard Worker #define R16(k, mx, OP0, OP1, OP2, OP3) \
113*f6dc9357SAndroid Build Coastguard Worker R4 ( (k)*4+0, m0,m1,m2,m3, e0,e1, OP0 ) \
114*f6dc9357SAndroid Build Coastguard Worker R4 ( (k)*4+1, m1,m2,m3,m0, e1,e0, OP1 ) \
115*f6dc9357SAndroid Build Coastguard Worker R4 ( (k)*4+2, m2,m3,m0,m1, e0,e1, OP2 ) \
116*f6dc9357SAndroid Build Coastguard Worker R4 ( (k)*4+3, m3,mx,m1,m2, e1,e0, OP3 ) \
117*f6dc9357SAndroid Build Coastguard Worker
118*f6dc9357SAndroid Build Coastguard Worker #define PREPARE_STATE \
119*f6dc9357SAndroid Build Coastguard Worker SHUFFLE_EPI32 (abcd, 0x1B) \
120*f6dc9357SAndroid Build Coastguard Worker SHUFFLE_EPI32 (e0, 0x1B) \
121*f6dc9357SAndroid Build Coastguard Worker
122*f6dc9357SAndroid Build Coastguard Worker
123*f6dc9357SAndroid Build Coastguard Worker
124*f6dc9357SAndroid Build Coastguard Worker
125*f6dc9357SAndroid Build Coastguard Worker
126*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks);
127*f6dc9357SAndroid Build Coastguard Worker #ifdef ATTRIB_SHA
128*f6dc9357SAndroid Build Coastguard Worker ATTRIB_SHA
129*f6dc9357SAndroid Build Coastguard Worker #endif
Sha1_UpdateBlocks_HW(UInt32 state[5],const Byte * data,size_t numBlocks)130*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks)
131*f6dc9357SAndroid Build Coastguard Worker {
132*f6dc9357SAndroid Build Coastguard Worker const __m128i mask = _mm_set_epi32(0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f);
133*f6dc9357SAndroid Build Coastguard Worker
134*f6dc9357SAndroid Build Coastguard Worker
135*f6dc9357SAndroid Build Coastguard Worker __m128i abcd, e0;
136*f6dc9357SAndroid Build Coastguard Worker
137*f6dc9357SAndroid Build Coastguard Worker if (numBlocks == 0)
138*f6dc9357SAndroid Build Coastguard Worker return;
139*f6dc9357SAndroid Build Coastguard Worker
140*f6dc9357SAndroid Build Coastguard Worker abcd = _mm_loadu_si128((const __m128i *) (const void *) &state[0]); // dbca
141*f6dc9357SAndroid Build Coastguard Worker e0 = _mm_cvtsi32_si128((int)state[4]); // 000e
142*f6dc9357SAndroid Build Coastguard Worker
143*f6dc9357SAndroid Build Coastguard Worker PREPARE_STATE
144*f6dc9357SAndroid Build Coastguard Worker
145*f6dc9357SAndroid Build Coastguard Worker do
146*f6dc9357SAndroid Build Coastguard Worker {
147*f6dc9357SAndroid Build Coastguard Worker __m128i abcd_save, e2;
148*f6dc9357SAndroid Build Coastguard Worker __m128i m0, m1, m2, m3;
149*f6dc9357SAndroid Build Coastguard Worker __m128i e1;
150*f6dc9357SAndroid Build Coastguard Worker
151*f6dc9357SAndroid Build Coastguard Worker
152*f6dc9357SAndroid Build Coastguard Worker abcd_save = abcd;
153*f6dc9357SAndroid Build Coastguard Worker e2 = e0;
154*f6dc9357SAndroid Build Coastguard Worker
155*f6dc9357SAndroid Build Coastguard Worker LOAD_SHUFFLE (m0, 0)
156*f6dc9357SAndroid Build Coastguard Worker LOAD_SHUFFLE (m1, 1)
157*f6dc9357SAndroid Build Coastguard Worker LOAD_SHUFFLE (m2, 2)
158*f6dc9357SAndroid Build Coastguard Worker LOAD_SHUFFLE (m3, 3)
159*f6dc9357SAndroid Build Coastguard Worker
160*f6dc9357SAndroid Build Coastguard Worker ADD_EPI32(e0, m0)
161*f6dc9357SAndroid Build Coastguard Worker
162*f6dc9357SAndroid Build Coastguard Worker R16 ( 0, m0, SM1, SM3, SM3, SM3 )
163*f6dc9357SAndroid Build Coastguard Worker R16 ( 1, m0, SM3, SM3, SM3, SM3 )
164*f6dc9357SAndroid Build Coastguard Worker R16 ( 2, m0, SM3, SM3, SM3, SM3 )
165*f6dc9357SAndroid Build Coastguard Worker R16 ( 3, m0, SM3, SM3, SM3, SM3 )
166*f6dc9357SAndroid Build Coastguard Worker R16 ( 4, e2, SM2, NNN, NNN, NNN )
167*f6dc9357SAndroid Build Coastguard Worker
168*f6dc9357SAndroid Build Coastguard Worker ADD_EPI32(abcd, abcd_save)
169*f6dc9357SAndroid Build Coastguard Worker
170*f6dc9357SAndroid Build Coastguard Worker data += 64;
171*f6dc9357SAndroid Build Coastguard Worker }
172*f6dc9357SAndroid Build Coastguard Worker while (--numBlocks);
173*f6dc9357SAndroid Build Coastguard Worker
174*f6dc9357SAndroid Build Coastguard Worker PREPARE_STATE
175*f6dc9357SAndroid Build Coastguard Worker
176*f6dc9357SAndroid Build Coastguard Worker _mm_storeu_si128((__m128i *) (void *) state, abcd);
177*f6dc9357SAndroid Build Coastguard Worker *(state + 4) = (UInt32)_mm_cvtsi128_si32(e0);
178*f6dc9357SAndroid Build Coastguard Worker }
179*f6dc9357SAndroid Build Coastguard Worker
180*f6dc9357SAndroid Build Coastguard Worker #endif // USE_HW_SHA
181*f6dc9357SAndroid Build Coastguard Worker
182*f6dc9357SAndroid Build Coastguard Worker #elif defined(MY_CPU_ARM_OR_ARM64) && defined(MY_CPU_LE) \
183*f6dc9357SAndroid Build Coastguard Worker && (!defined(Z7_MSC_VER_ORIGINAL) || (_MSC_VER >= 1929) && (_MSC_FULL_VER >= 192930037))
184*f6dc9357SAndroid Build Coastguard Worker #if defined(__ARM_FEATURE_SHA2) \
185*f6dc9357SAndroid Build Coastguard Worker || defined(__ARM_FEATURE_CRYPTO)
186*f6dc9357SAndroid Build Coastguard Worker #define USE_HW_SHA
187*f6dc9357SAndroid Build Coastguard Worker #else
188*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM64) \
189*f6dc9357SAndroid Build Coastguard Worker || defined(__ARM_ARCH) && (__ARM_ARCH >= 4) \
190*f6dc9357SAndroid Build Coastguard Worker || defined(Z7_MSC_VER_ORIGINAL)
191*f6dc9357SAndroid Build Coastguard Worker #if defined(__ARM_FP) && \
192*f6dc9357SAndroid Build Coastguard Worker ( defined(Z7_CLANG_VERSION) && (Z7_CLANG_VERSION >= 30800) \
193*f6dc9357SAndroid Build Coastguard Worker || defined(__GNUC__) && (__GNUC__ >= 6) \
194*f6dc9357SAndroid Build Coastguard Worker ) \
195*f6dc9357SAndroid Build Coastguard Worker || defined(Z7_MSC_VER_ORIGINAL) && (_MSC_VER >= 1910)
196*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM64) \
197*f6dc9357SAndroid Build Coastguard Worker || !defined(Z7_CLANG_VERSION) \
198*f6dc9357SAndroid Build Coastguard Worker || defined(__ARM_NEON) && \
199*f6dc9357SAndroid Build Coastguard Worker (Z7_CLANG_VERSION < 170000 || \
200*f6dc9357SAndroid Build Coastguard Worker Z7_CLANG_VERSION > 170001)
201*f6dc9357SAndroid Build Coastguard Worker #define USE_HW_SHA
202*f6dc9357SAndroid Build Coastguard Worker #endif
203*f6dc9357SAndroid Build Coastguard Worker #endif
204*f6dc9357SAndroid Build Coastguard Worker #endif
205*f6dc9357SAndroid Build Coastguard Worker #endif
206*f6dc9357SAndroid Build Coastguard Worker
207*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_HW_SHA
208*f6dc9357SAndroid Build Coastguard Worker
209*f6dc9357SAndroid Build Coastguard Worker // #pragma message("=== Sha1 HW === ")
210*f6dc9357SAndroid Build Coastguard Worker // __ARM_FEATURE_CRYPTO macro is deprecated in favor of the finer grained feature macro __ARM_FEATURE_SHA2
211*f6dc9357SAndroid Build Coastguard Worker
212*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__) || defined(__GNUC__)
213*f6dc9357SAndroid Build Coastguard Worker #if !defined(__ARM_FEATURE_SHA2) && \
214*f6dc9357SAndroid Build Coastguard Worker !defined(__ARM_FEATURE_CRYPTO)
215*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_ARM64
216*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__)
217*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_SHA __attribute__((__target__("crypto")))
218*f6dc9357SAndroid Build Coastguard Worker #else
219*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_SHA __attribute__((__target__("+crypto")))
220*f6dc9357SAndroid Build Coastguard Worker #endif
221*f6dc9357SAndroid Build Coastguard Worker #else
222*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__) && (__clang_major__ >= 1)
223*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_SHA __attribute__((__target__("armv8-a,sha2")))
224*f6dc9357SAndroid Build Coastguard Worker #else
225*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_SHA __attribute__((__target__("fpu=crypto-neon-fp-armv8")))
226*f6dc9357SAndroid Build Coastguard Worker #endif
227*f6dc9357SAndroid Build Coastguard Worker #endif
228*f6dc9357SAndroid Build Coastguard Worker #endif
229*f6dc9357SAndroid Build Coastguard Worker #else
230*f6dc9357SAndroid Build Coastguard Worker // _MSC_VER
231*f6dc9357SAndroid Build Coastguard Worker // for arm32
232*f6dc9357SAndroid Build Coastguard Worker #define _ARM_USE_NEW_NEON_INTRINSICS
233*f6dc9357SAndroid Build Coastguard Worker #endif
234*f6dc9357SAndroid Build Coastguard Worker
235*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_MSC_VER_ORIGINAL) && defined(MY_CPU_ARM64)
236*f6dc9357SAndroid Build Coastguard Worker #include <arm64_neon.h>
237*f6dc9357SAndroid Build Coastguard Worker #else
238*f6dc9357SAndroid Build Coastguard Worker
239*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__) && __clang_major__ < 16
240*f6dc9357SAndroid Build Coastguard Worker #if !defined(__ARM_FEATURE_SHA2) && \
241*f6dc9357SAndroid Build Coastguard Worker !defined(__ARM_FEATURE_CRYPTO)
242*f6dc9357SAndroid Build Coastguard Worker // #pragma message("=== we set __ARM_FEATURE_CRYPTO 1 === ")
243*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
244*f6dc9357SAndroid Build Coastguard Worker #define Z7_ARM_FEATURE_CRYPTO_WAS_SET 1
245*f6dc9357SAndroid Build Coastguard Worker // #if defined(__clang__) && __clang_major__ < 13
246*f6dc9357SAndroid Build Coastguard Worker #define __ARM_FEATURE_CRYPTO 1
247*f6dc9357SAndroid Build Coastguard Worker // #else
248*f6dc9357SAndroid Build Coastguard Worker #define __ARM_FEATURE_SHA2 1
249*f6dc9357SAndroid Build Coastguard Worker // #endif
250*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
251*f6dc9357SAndroid Build Coastguard Worker #endif
252*f6dc9357SAndroid Build Coastguard Worker #endif // clang
253*f6dc9357SAndroid Build Coastguard Worker
254*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__)
255*f6dc9357SAndroid Build Coastguard Worker
256*f6dc9357SAndroid Build Coastguard Worker #if defined(__ARM_ARCH) && __ARM_ARCH < 8
257*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
258*f6dc9357SAndroid Build Coastguard Worker // #pragma message("#define __ARM_ARCH 8")
259*f6dc9357SAndroid Build Coastguard Worker #undef __ARM_ARCH
260*f6dc9357SAndroid Build Coastguard Worker #define __ARM_ARCH 8
261*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
262*f6dc9357SAndroid Build Coastguard Worker #endif
263*f6dc9357SAndroid Build Coastguard Worker
264*f6dc9357SAndroid Build Coastguard Worker #endif // clang
265*f6dc9357SAndroid Build Coastguard Worker
266*f6dc9357SAndroid Build Coastguard Worker #include <arm_neon.h>
267*f6dc9357SAndroid Build Coastguard Worker
268*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_ARM_FEATURE_CRYPTO_WAS_SET) && \
269*f6dc9357SAndroid Build Coastguard Worker defined(__ARM_FEATURE_CRYPTO) && \
270*f6dc9357SAndroid Build Coastguard Worker defined(__ARM_FEATURE_SHA2)
271*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
272*f6dc9357SAndroid Build Coastguard Worker #undef __ARM_FEATURE_CRYPTO
273*f6dc9357SAndroid Build Coastguard Worker #undef __ARM_FEATURE_SHA2
274*f6dc9357SAndroid Build Coastguard Worker #undef Z7_ARM_FEATURE_CRYPTO_WAS_SET
275*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
276*f6dc9357SAndroid Build Coastguard Worker // #pragma message("=== we undefine __ARM_FEATURE_CRYPTO === ")
277*f6dc9357SAndroid Build Coastguard Worker #endif
278*f6dc9357SAndroid Build Coastguard Worker
279*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_MSC_VER_ORIGINAL
280*f6dc9357SAndroid Build Coastguard Worker
281*f6dc9357SAndroid Build Coastguard Worker typedef uint32x4_t v128;
282*f6dc9357SAndroid Build Coastguard Worker // typedef __n128 v128; // MSVC
283*f6dc9357SAndroid Build Coastguard Worker // the bug in clang 3.8.1:
284*f6dc9357SAndroid Build Coastguard Worker // __builtin_neon_vgetq_lane_i32((int8x16_t)__s0, __p1);
285*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__) && (__clang_major__ <= 9)
286*f6dc9357SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wvector-conversion"
287*f6dc9357SAndroid Build Coastguard Worker #endif
288*f6dc9357SAndroid Build Coastguard Worker
289*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_BE
290*f6dc9357SAndroid Build Coastguard Worker #define MY_rev32_for_LE(x) x
291*f6dc9357SAndroid Build Coastguard Worker #else
292*f6dc9357SAndroid Build Coastguard Worker #define MY_rev32_for_LE(x) vrev32q_u8(x)
293*f6dc9357SAndroid Build Coastguard Worker #endif
294*f6dc9357SAndroid Build Coastguard Worker
295*f6dc9357SAndroid Build Coastguard Worker #define LOAD_128_32(_p) vld1q_u32(_p)
296*f6dc9357SAndroid Build Coastguard Worker #define LOAD_128_8(_p) vld1q_u8 (_p)
297*f6dc9357SAndroid Build Coastguard Worker #define STORE_128_32(_p, _v) vst1q_u32(_p, _v)
298*f6dc9357SAndroid Build Coastguard Worker
299*f6dc9357SAndroid Build Coastguard Worker #define LOAD_SHUFFLE(m, k) \
300*f6dc9357SAndroid Build Coastguard Worker m = vreinterpretq_u32_u8( \
301*f6dc9357SAndroid Build Coastguard Worker MY_rev32_for_LE( \
302*f6dc9357SAndroid Build Coastguard Worker LOAD_128_8(data + (k) * 16))); \
303*f6dc9357SAndroid Build Coastguard Worker
304*f6dc9357SAndroid Build Coastguard Worker #define N0(dest, src2, src3)
305*f6dc9357SAndroid Build Coastguard Worker #define N1(dest, src)
306*f6dc9357SAndroid Build Coastguard Worker #define U0(dest, src2, src3) dest = vsha1su0q_u32(dest, src2, src3);
307*f6dc9357SAndroid Build Coastguard Worker #define U1(dest, src) dest = vsha1su1q_u32(dest, src);
308*f6dc9357SAndroid Build Coastguard Worker #define C(e) abcd = vsha1cq_u32(abcd, e, t)
309*f6dc9357SAndroid Build Coastguard Worker #define P(e) abcd = vsha1pq_u32(abcd, e, t)
310*f6dc9357SAndroid Build Coastguard Worker #define M(e) abcd = vsha1mq_u32(abcd, e, t)
311*f6dc9357SAndroid Build Coastguard Worker #define H(e) e = vsha1h_u32(vgetq_lane_u32(abcd, 0))
312*f6dc9357SAndroid Build Coastguard Worker #define T(m, c) t = vaddq_u32(m, c)
313*f6dc9357SAndroid Build Coastguard Worker
314*f6dc9357SAndroid Build Coastguard Worker #define R16(d0,d1,d2,d3, f0,z0, f1,z1, f2,z2, f3,z3, w0,w1,w2,w3) \
315*f6dc9357SAndroid Build Coastguard Worker T(m0, d0); f0(m3, m0, m1) z0(m2, m1) H(e1); w0(e0); \
316*f6dc9357SAndroid Build Coastguard Worker T(m1, d1); f1(m0, m1, m2) z1(m3, m2) H(e0); w1(e1); \
317*f6dc9357SAndroid Build Coastguard Worker T(m2, d2); f2(m1, m2, m3) z2(m0, m3) H(e1); w2(e0); \
318*f6dc9357SAndroid Build Coastguard Worker T(m3, d3); f3(m2, m3, m0) z3(m1, m0) H(e0); w3(e1); \
319*f6dc9357SAndroid Build Coastguard Worker
320*f6dc9357SAndroid Build Coastguard Worker
321*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks);
322*f6dc9357SAndroid Build Coastguard Worker #ifdef ATTRIB_SHA
323*f6dc9357SAndroid Build Coastguard Worker ATTRIB_SHA
324*f6dc9357SAndroid Build Coastguard Worker #endif
Sha1_UpdateBlocks_HW(UInt32 state[8],const Byte * data,size_t numBlocks)325*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[8], const Byte *data, size_t numBlocks)
326*f6dc9357SAndroid Build Coastguard Worker {
327*f6dc9357SAndroid Build Coastguard Worker v128 abcd;
328*f6dc9357SAndroid Build Coastguard Worker v128 c0, c1, c2, c3;
329*f6dc9357SAndroid Build Coastguard Worker uint32_t e0;
330*f6dc9357SAndroid Build Coastguard Worker
331*f6dc9357SAndroid Build Coastguard Worker if (numBlocks == 0)
332*f6dc9357SAndroid Build Coastguard Worker return;
333*f6dc9357SAndroid Build Coastguard Worker
334*f6dc9357SAndroid Build Coastguard Worker c0 = vdupq_n_u32(0x5a827999);
335*f6dc9357SAndroid Build Coastguard Worker c1 = vdupq_n_u32(0x6ed9eba1);
336*f6dc9357SAndroid Build Coastguard Worker c2 = vdupq_n_u32(0x8f1bbcdc);
337*f6dc9357SAndroid Build Coastguard Worker c3 = vdupq_n_u32(0xca62c1d6);
338*f6dc9357SAndroid Build Coastguard Worker
339*f6dc9357SAndroid Build Coastguard Worker abcd = LOAD_128_32(&state[0]);
340*f6dc9357SAndroid Build Coastguard Worker e0 = state[4];
341*f6dc9357SAndroid Build Coastguard Worker
342*f6dc9357SAndroid Build Coastguard Worker do
343*f6dc9357SAndroid Build Coastguard Worker {
344*f6dc9357SAndroid Build Coastguard Worker v128 abcd_save;
345*f6dc9357SAndroid Build Coastguard Worker v128 m0, m1, m2, m3;
346*f6dc9357SAndroid Build Coastguard Worker v128 t;
347*f6dc9357SAndroid Build Coastguard Worker uint32_t e0_save, e1;
348*f6dc9357SAndroid Build Coastguard Worker
349*f6dc9357SAndroid Build Coastguard Worker abcd_save = abcd;
350*f6dc9357SAndroid Build Coastguard Worker e0_save = e0;
351*f6dc9357SAndroid Build Coastguard Worker
352*f6dc9357SAndroid Build Coastguard Worker LOAD_SHUFFLE (m0, 0)
353*f6dc9357SAndroid Build Coastguard Worker LOAD_SHUFFLE (m1, 1)
354*f6dc9357SAndroid Build Coastguard Worker LOAD_SHUFFLE (m2, 2)
355*f6dc9357SAndroid Build Coastguard Worker LOAD_SHUFFLE (m3, 3)
356*f6dc9357SAndroid Build Coastguard Worker
357*f6dc9357SAndroid Build Coastguard Worker R16 ( c0,c0,c0,c0, N0,N1, U0,N1, U0,U1, U0,U1, C,C,C,C )
358*f6dc9357SAndroid Build Coastguard Worker R16 ( c0,c1,c1,c1, U0,U1, U0,U1, U0,U1, U0,U1, C,P,P,P )
359*f6dc9357SAndroid Build Coastguard Worker R16 ( c1,c1,c2,c2, U0,U1, U0,U1, U0,U1, U0,U1, P,P,M,M )
360*f6dc9357SAndroid Build Coastguard Worker R16 ( c2,c2,c2,c3, U0,U1, U0,U1, U0,U1, U0,U1, M,M,M,P )
361*f6dc9357SAndroid Build Coastguard Worker R16 ( c3,c3,c3,c3, U0,U1, N0,U1, N0,N1, N0,N1, P,P,P,P )
362*f6dc9357SAndroid Build Coastguard Worker
363*f6dc9357SAndroid Build Coastguard Worker abcd = vaddq_u32(abcd, abcd_save);
364*f6dc9357SAndroid Build Coastguard Worker e0 += e0_save;
365*f6dc9357SAndroid Build Coastguard Worker
366*f6dc9357SAndroid Build Coastguard Worker data += 64;
367*f6dc9357SAndroid Build Coastguard Worker }
368*f6dc9357SAndroid Build Coastguard Worker while (--numBlocks);
369*f6dc9357SAndroid Build Coastguard Worker
370*f6dc9357SAndroid Build Coastguard Worker STORE_128_32(&state[0], abcd);
371*f6dc9357SAndroid Build Coastguard Worker state[4] = e0;
372*f6dc9357SAndroid Build Coastguard Worker }
373*f6dc9357SAndroid Build Coastguard Worker
374*f6dc9357SAndroid Build Coastguard Worker #endif // USE_HW_SHA
375*f6dc9357SAndroid Build Coastguard Worker
376*f6dc9357SAndroid Build Coastguard Worker #endif // MY_CPU_ARM_OR_ARM64
377*f6dc9357SAndroid Build Coastguard Worker
378*f6dc9357SAndroid Build Coastguard Worker #if !defined(USE_HW_SHA) && defined(Z7_USE_HW_SHA_STUB)
379*f6dc9357SAndroid Build Coastguard Worker // #error Stop_Compiling_UNSUPPORTED_SHA
380*f6dc9357SAndroid Build Coastguard Worker // #include <stdlib.h>
381*f6dc9357SAndroid Build Coastguard Worker // #include "Sha1.h"
382*f6dc9357SAndroid Build Coastguard Worker // #if defined(_MSC_VER)
383*f6dc9357SAndroid Build Coastguard Worker #pragma message("Sha1 HW-SW stub was used")
384*f6dc9357SAndroid Build Coastguard Worker // #endif
385*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Sha1_UpdateBlocks (UInt32 state[5], const Byte *data, size_t numBlocks);
386*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks);
Sha1_UpdateBlocks_HW(UInt32 state[5],const Byte * data,size_t numBlocks)387*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Sha1_UpdateBlocks_HW(UInt32 state[5], const Byte *data, size_t numBlocks)
388*f6dc9357SAndroid Build Coastguard Worker {
389*f6dc9357SAndroid Build Coastguard Worker Sha1_UpdateBlocks(state, data, numBlocks);
390*f6dc9357SAndroid Build Coastguard Worker /*
391*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(state);
392*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(data);
393*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(numBlocks);
394*f6dc9357SAndroid Build Coastguard Worker exit(1);
395*f6dc9357SAndroid Build Coastguard Worker return;
396*f6dc9357SAndroid Build Coastguard Worker */
397*f6dc9357SAndroid Build Coastguard Worker }
398*f6dc9357SAndroid Build Coastguard Worker #endif
399*f6dc9357SAndroid Build Coastguard Worker
400*f6dc9357SAndroid Build Coastguard Worker #undef U0
401*f6dc9357SAndroid Build Coastguard Worker #undef U1
402*f6dc9357SAndroid Build Coastguard Worker #undef N0
403*f6dc9357SAndroid Build Coastguard Worker #undef N1
404*f6dc9357SAndroid Build Coastguard Worker #undef C
405*f6dc9357SAndroid Build Coastguard Worker #undef P
406*f6dc9357SAndroid Build Coastguard Worker #undef M
407*f6dc9357SAndroid Build Coastguard Worker #undef H
408*f6dc9357SAndroid Build Coastguard Worker #undef T
409*f6dc9357SAndroid Build Coastguard Worker #undef MY_rev32_for_LE
410*f6dc9357SAndroid Build Coastguard Worker #undef NNN
411*f6dc9357SAndroid Build Coastguard Worker #undef LOAD_128
412*f6dc9357SAndroid Build Coastguard Worker #undef STORE_128
413*f6dc9357SAndroid Build Coastguard Worker #undef LOAD_SHUFFLE
414*f6dc9357SAndroid Build Coastguard Worker #undef SM1
415*f6dc9357SAndroid Build Coastguard Worker #undef SM2
416*f6dc9357SAndroid Build Coastguard Worker #undef SM3
417*f6dc9357SAndroid Build Coastguard Worker #undef NNN
418*f6dc9357SAndroid Build Coastguard Worker #undef R4
419*f6dc9357SAndroid Build Coastguard Worker #undef R16
420*f6dc9357SAndroid Build Coastguard Worker #undef PREPARE_STATE
421*f6dc9357SAndroid Build Coastguard Worker #undef USE_HW_SHA
422*f6dc9357SAndroid Build Coastguard Worker #undef ATTRIB_SHA
423*f6dc9357SAndroid Build Coastguard Worker #undef USE_VER_MIN
424*f6dc9357SAndroid Build Coastguard Worker #undef Z7_USE_HW_SHA_STUB
425