1 // Copyright 2018 The BoringSSL Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_SHA_INTERNAL_H
16 #define OPENSSL_HEADER_CRYPTO_FIPSMODULE_SHA_INTERNAL_H
17
18 #include <openssl/base.h>
19
20 #include "../../internal.h"
21
22 #if defined(__cplusplus)
23 extern "C" {
24 #endif
25
26 // Define SHA{n}[_{variant}]_ASM if sha{n}_block_data_order[_{variant}] is
27 // defined in assembly.
28
29 #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_ARM)
30
31 #define SHA1_ASM_NOHW
32 #define SHA256_ASM_NOHW
33 #define SHA512_ASM_NOHW
34
35 #define SHA1_ASM_HW
sha1_hw_capable(void)36 inline int sha1_hw_capable(void) { return CRYPTO_is_ARMv8_SHA1_capable(); }
37
38 #define SHA1_ASM_NEON
39 void sha1_block_data_order_neon(uint32_t state[5], const uint8_t *data,
40 size_t num);
41
42 #define SHA256_ASM_HW
sha256_hw_capable(void)43 inline int sha256_hw_capable(void) { return CRYPTO_is_ARMv8_SHA256_capable(); }
44
45 #define SHA256_ASM_NEON
46 void sha256_block_data_order_neon(uint32_t state[8], const uint8_t *data,
47 size_t num);
48
49 // Armv8.2 SHA-512 instructions are not available in 32-bit.
50 #define SHA512_ASM_NEON
51 void sha512_block_data_order_neon(uint64_t state[8], const uint8_t *data,
52 size_t num);
53
54 #elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64)
55
56 #define SHA1_ASM_NOHW
57 #define SHA256_ASM_NOHW
58 #define SHA512_ASM_NOHW
59
60 #define SHA1_ASM_HW
61 inline int sha1_hw_capable(void) { return CRYPTO_is_ARMv8_SHA1_capable(); }
62
63 #define SHA256_ASM_HW
64 inline int sha256_hw_capable(void) { return CRYPTO_is_ARMv8_SHA256_capable(); }
65
66 #define SHA512_ASM_HW
67 inline int sha512_hw_capable(void) { return CRYPTO_is_ARMv8_SHA512_capable(); }
68
69 #elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86)
70
71 #define SHA1_ASM_NOHW
72 #define SHA256_ASM_NOHW
73 #define SHA512_ASM_NOHW
74
75 #define SHA1_ASM_SSSE3
76 inline int sha1_ssse3_capable(void) {
77 return CRYPTO_is_SSSE3_capable();
78 }
79 void sha1_block_data_order_ssse3(uint32_t state[5], const uint8_t *data,
80 size_t num);
81
82 #define SHA1_ASM_AVX
83 inline int sha1_avx_capable(void) {
84 // AMD CPUs have slow SHLD/SHRD. See also the discussion in sha1-586.pl.
85 //
86 // TODO(crbug.com/42290564): Should we enable SHAEXT on 32-bit x86?
87 return CRYPTO_is_AVX_capable() && CRYPTO_is_intel_cpu();
88 }
89 void sha1_block_data_order_avx(uint32_t state[5], const uint8_t *data,
90 size_t num);
91
92 #define SHA256_ASM_SSSE3
93 inline int sha256_ssse3_capable(void) {
94 return CRYPTO_is_SSSE3_capable();
95 }
96 void sha256_block_data_order_ssse3(uint32_t state[8], const uint8_t *data,
97 size_t num);
98
99 #define SHA256_ASM_AVX
100 inline int sha256_avx_capable(void) {
101 // AMD CPUs have slow SHLD/SHRD. See also the discussion in sha1-586.pl.
102 //
103 // TODO(crbug.com/42290564): Should we enable SHAEXT on 32-bit x86?
104 return CRYPTO_is_AVX_capable() && CRYPTO_is_intel_cpu();
105 }
106 void sha256_block_data_order_avx(uint32_t state[8], const uint8_t *data,
107 size_t num);
108
109 #define SHA512_ASM_SSSE3
110 inline int sha512_ssse3_capable(void) {
111 return CRYPTO_is_SSSE3_capable();
112 }
113 void sha512_block_data_order_ssse3(uint64_t state[8], const uint8_t *data,
114 size_t num);
115
116 #elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64)
117
118 #define SHA1_ASM_NOHW
119 #define SHA256_ASM_NOHW
120 #define SHA512_ASM_NOHW
121
122 #define SHA1_ASM_HW
123 inline int sha1_hw_capable(void) {
124 return CRYPTO_is_x86_SHA_capable() && CRYPTO_is_SSSE3_capable();
125 }
126
127 #define SHA1_ASM_AVX2
128 inline int sha1_avx2_capable(void) {
129 return CRYPTO_is_AVX2_capable() && CRYPTO_is_BMI2_capable() &&
130 CRYPTO_is_BMI1_capable();
131 }
132 void sha1_block_data_order_avx2(uint32_t state[5], const uint8_t *data,
133 size_t num);
134
135 #define SHA1_ASM_AVX
136 inline int sha1_avx_capable(void) {
137 // AMD CPUs have slow SHLD/SHRD. See also the discussion in sha1-586.pl. Zen
138 // added the SHA extension, so this is moot on newer AMD CPUs.
139 return CRYPTO_is_AVX_capable() && CRYPTO_is_intel_cpu();
140 }
141 void sha1_block_data_order_avx(uint32_t state[5], const uint8_t *data,
142 size_t num);
143
144 #define SHA1_ASM_SSSE3
145 inline int sha1_ssse3_capable(void) { return CRYPTO_is_SSSE3_capable(); }
146 void sha1_block_data_order_ssse3(uint32_t state[5], const uint8_t *data,
147 size_t num);
148
149 #define SHA256_ASM_HW
150 inline int sha256_hw_capable(void) {
151 // Note that the original assembly did not check SSSE3.
152 return CRYPTO_is_x86_SHA_capable() && CRYPTO_is_SSSE3_capable();
153 }
154
155 #define SHA256_ASM_AVX
156 inline int sha256_avx_capable(void) {
157 // AMD CPUs have slow SHLD/SHRD. See also the discussion in sha1-586.pl. Zen
158 // added the SHA extension, so this is moot on newer AMD CPUs.
159 return CRYPTO_is_AVX_capable() && CRYPTO_is_intel_cpu();
160 }
161 void sha256_block_data_order_avx(uint32_t state[8], const uint8_t *data,
162 size_t num);
163
164 #define SHA256_ASM_SSSE3
165 inline int sha256_ssse3_capable(void) { return CRYPTO_is_SSSE3_capable(); }
166 void sha256_block_data_order_ssse3(uint32_t state[8], const uint8_t *data,
167 size_t num);
168
169 #define SHA512_ASM_AVX
170 inline int sha512_avx_capable(void) {
171 // AMD CPUs have slow SHLD/SHRD. See also the discussion in sha1-586.pl.
172 //
173 // TODO(crbug.com/42290564): Fixing and enabling the AVX2 implementation would
174 // mitigate this on newer AMD CPUs.
175 return CRYPTO_is_AVX_capable() && CRYPTO_is_intel_cpu();
176 }
177 void sha512_block_data_order_avx(uint64_t state[8], const uint8_t *data,
178 size_t num);
179
180 #endif
181
182 #if defined(SHA1_ASM_HW)
183 void sha1_block_data_order_hw(uint32_t state[5], const uint8_t *data,
184 size_t num);
185 #endif
186 #if defined(SHA1_ASM_NOHW)
187 void sha1_block_data_order_nohw(uint32_t state[5], const uint8_t *data,
188 size_t num);
189 #endif
190
191 #if defined(SHA256_ASM_HW)
192 void sha256_block_data_order_hw(uint32_t state[8], const uint8_t *data,
193 size_t num);
194 #endif
195 #if defined(SHA256_ASM_NOHW)
196 void sha256_block_data_order_nohw(uint32_t state[8], const uint8_t *data,
197 size_t num);
198 #endif
199
200 #if defined(SHA512_ASM_HW)
201 void sha512_block_data_order_hw(uint64_t state[8], const uint8_t *data,
202 size_t num);
203 #endif
204
205 #if defined(SHA512_ASM_NOHW)
206 void sha512_block_data_order_nohw(uint64_t state[8], const uint8_t *data,
207 size_t num);
208 #endif
209
210 #if defined(__cplusplus)
211 } // extern "C"
212 #endif
213
214 #endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_SHA_INTERNAL_H
215