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