/src/boringssl/crypto/fipsmodule/aes/internal.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (c) 2017, Google Inc. |
2 | | * |
3 | | * Permission to use, copy, modify, and/or distribute this software for any |
4 | | * purpose with or without fee is hereby granted, provided that the above |
5 | | * copyright notice and this permission notice appear in all copies. |
6 | | * |
7 | | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
8 | | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
9 | | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY |
10 | | * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
11 | | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION |
12 | | * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
13 | | * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ |
14 | | |
15 | | #ifndef OPENSSL_HEADER_AES_INTERNAL_H |
16 | | #define OPENSSL_HEADER_AES_INTERNAL_H |
17 | | |
18 | | #include <stdlib.h> |
19 | | |
20 | | #include <openssl/aes.h> |
21 | | |
22 | | #include "../../internal.h" |
23 | | |
24 | | #if defined(__cplusplus) |
25 | | extern "C" { |
26 | | #endif |
27 | | |
28 | | |
29 | | #if !defined(OPENSSL_NO_ASM) |
30 | | |
31 | | #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) |
32 | | #define HWAES |
33 | | #define HWAES_ECB |
34 | | |
35 | | OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_AESNI_capable(); } |
36 | | |
37 | | #define VPAES |
38 | | #if defined(OPENSSL_X86_64) |
39 | | #define VPAES_CTR32 |
40 | | #endif |
41 | | #define VPAES_CBC |
42 | | OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_SSSE3_capable(); } |
43 | | |
44 | | #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) |
45 | | #define HWAES |
46 | | |
47 | | OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_ARMv8_AES_capable(); } |
48 | | |
49 | | #if defined(OPENSSL_ARM) |
50 | | #define BSAES |
51 | | #define VPAES |
52 | | #define VPAES_CTR32 |
53 | | OPENSSL_INLINE int bsaes_capable(void) { return CRYPTO_is_NEON_capable(); } |
54 | | OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); } |
55 | | #endif |
56 | | |
57 | | #if defined(OPENSSL_AARCH64) |
58 | | #define VPAES |
59 | | #define VPAES_CBC |
60 | | #define VPAES_CTR32 |
61 | | OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); } |
62 | | #endif |
63 | | |
64 | | #endif |
65 | | |
66 | | #endif // !NO_ASM |
67 | | |
68 | | |
69 | | #if defined(HWAES) |
70 | | |
71 | | int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key); |
72 | | int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key); |
73 | | void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); |
74 | | void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); |
75 | | void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, |
76 | | const AES_KEY *key, uint8_t *ivec, int enc); |
77 | | void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, |
78 | | const AES_KEY *key, const uint8_t ivec[16]); |
79 | | |
80 | | #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) |
81 | | // On x86 and x86_64, |aes_hw_set_decrypt_key| is implemented in terms of |
82 | | // |aes_hw_set_encrypt_key| and a conversion function. |
83 | | void aes_hw_encrypt_key_to_decrypt_key(AES_KEY *key); |
84 | | |
85 | | // There are two variants of this function, one which uses aeskeygenassist |
86 | | // ("base") and one which uses aesenclast + pshufb ("alt"). aesenclast is |
87 | | // overall faster but is slower on some older processors. It doesn't use AVX, |
88 | | // but AVX is used as a proxy to detecting this. See |
89 | | // https://groups.google.com/g/mailing.openssl.dev/c/OuFXwW4NfO8/m/7d2ZXVjkxVkJ |
90 | | // |
91 | | // TODO(davidben): It is unclear if the aeskeygenassist version is still |
92 | | // worthwhile. However, the aesenclast version requires SSSE3. SSSE3 long |
93 | | // predates AES-NI, but it's not clear if AES-NI implies SSSE3. In OpenSSL, the |
94 | | // CCM AES-NI assembly seems to assume it does. |
95 | 0 | OPENSSL_INLINE int aes_hw_set_encrypt_key_alt_capable(void) { |
96 | 0 | return hwaes_capable() && CRYPTO_is_SSSE3_capable(); |
97 | 0 | } |
98 | 2.20k | OPENSSL_INLINE int aes_hw_set_encrypt_key_alt_preferred(void) { |
99 | 2.20k | return hwaes_capable() && CRYPTO_is_AVX_capable(); |
100 | 2.20k | } |
101 | | int aes_hw_set_encrypt_key_base(const uint8_t *user_key, int bits, |
102 | | AES_KEY *key); |
103 | | int aes_hw_set_encrypt_key_alt(const uint8_t *user_key, int bits, AES_KEY *key); |
104 | | #endif // OPENSSL_X86 || OPENSSL_X86_64 |
105 | | |
106 | | #else |
107 | | |
108 | | // If HWAES isn't defined then we provide dummy functions for each of the hwaes |
109 | | // functions. |
110 | 12.3k | OPENSSL_INLINE int hwaes_capable(void) { return 0; } |
111 | | |
112 | | OPENSSL_INLINE int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits, |
113 | 0 | AES_KEY *key) { |
114 | 0 | abort(); |
115 | 0 | } |
116 | | |
117 | | OPENSSL_INLINE int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits, |
118 | 0 | AES_KEY *key) { |
119 | 0 | abort(); |
120 | 0 | } |
121 | | |
122 | | OPENSSL_INLINE void aes_hw_encrypt(const uint8_t *in, uint8_t *out, |
123 | 0 | const AES_KEY *key) { |
124 | 0 | abort(); |
125 | 0 | } |
126 | | |
127 | | OPENSSL_INLINE void aes_hw_decrypt(const uint8_t *in, uint8_t *out, |
128 | 0 | const AES_KEY *key) { |
129 | 0 | abort(); |
130 | 0 | } |
131 | | |
132 | | OPENSSL_INLINE void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, |
133 | | size_t length, const AES_KEY *key, |
134 | 0 | uint8_t *ivec, int enc) { |
135 | 0 | abort(); |
136 | 0 | } |
137 | | |
138 | | OPENSSL_INLINE void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, |
139 | | size_t len, const AES_KEY *key, |
140 | 0 | const uint8_t ivec[16]) { |
141 | 0 | abort(); |
142 | 0 | } |
143 | | |
144 | | #endif // !HWAES |
145 | | |
146 | | |
147 | | #if defined(HWAES_ECB) |
148 | | void aes_hw_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length, |
149 | | const AES_KEY *key, int enc); |
150 | | #endif // HWAES_ECB |
151 | | |
152 | | |
153 | | #if defined(BSAES) |
154 | | // Note |bsaes_cbc_encrypt| requires |enc| to be zero. |
155 | | void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, |
156 | | const AES_KEY *key, uint8_t ivec[16], int enc); |
157 | | void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, |
158 | | const AES_KEY *key, const uint8_t ivec[16]); |
159 | | // VPAES to BSAES conversions are available on all BSAES platforms. |
160 | | void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes); |
161 | | void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes); |
162 | | #else |
163 | 120 | OPENSSL_INLINE char bsaes_capable(void) { return 0; } |
164 | | |
165 | | // On other platforms, bsaes_capable() will always return false and so the |
166 | | // following will never be called. |
167 | | OPENSSL_INLINE void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, |
168 | | size_t length, const AES_KEY *key, |
169 | 0 | uint8_t ivec[16], int enc) { |
170 | 0 | abort(); |
171 | 0 | } |
172 | | |
173 | | OPENSSL_INLINE void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, |
174 | | size_t len, const AES_KEY *key, |
175 | 0 | const uint8_t ivec[16]) { |
176 | 0 | abort(); |
177 | 0 | } |
178 | | |
179 | | OPENSSL_INLINE void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, |
180 | 0 | const AES_KEY *vpaes) { |
181 | 0 | abort(); |
182 | 0 | } |
183 | | |
184 | | OPENSSL_INLINE void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, |
185 | 0 | const AES_KEY *vpaes) { |
186 | 0 | abort(); |
187 | 0 | } |
188 | | #endif // !BSAES |
189 | | |
190 | | |
191 | | #if defined(VPAES) |
192 | | // On platforms where VPAES gets defined (just above), then these functions are |
193 | | // provided by asm. |
194 | | int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); |
195 | | int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); |
196 | | |
197 | | void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); |
198 | | void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); |
199 | | |
200 | | #if defined(VPAES_CBC) |
201 | | void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, |
202 | | const AES_KEY *key, uint8_t *ivec, int enc); |
203 | | #endif |
204 | | #if defined(VPAES_CTR32) |
205 | | void vpaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, |
206 | | const AES_KEY *key, const uint8_t ivec[16]); |
207 | | #endif |
208 | | #else |
209 | 7.89k | OPENSSL_INLINE char vpaes_capable(void) { return 0; } |
210 | | |
211 | | // On other platforms, vpaes_capable() will always return false and so the |
212 | | // following will never be called. |
213 | | OPENSSL_INLINE int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, |
214 | 0 | AES_KEY *key) { |
215 | 0 | abort(); |
216 | 0 | } |
217 | | OPENSSL_INLINE int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, |
218 | 0 | AES_KEY *key) { |
219 | 0 | abort(); |
220 | 0 | } |
221 | | OPENSSL_INLINE void vpaes_encrypt(const uint8_t *in, uint8_t *out, |
222 | 0 | const AES_KEY *key) { |
223 | 0 | abort(); |
224 | 0 | } |
225 | | OPENSSL_INLINE void vpaes_decrypt(const uint8_t *in, uint8_t *out, |
226 | 0 | const AES_KEY *key) { |
227 | 0 | abort(); |
228 | 0 | } |
229 | | OPENSSL_INLINE void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, |
230 | | size_t length, const AES_KEY *key, |
231 | 0 | uint8_t *ivec, int enc) { |
232 | 0 | abort(); |
233 | 0 | } |
234 | | #endif // !VPAES |
235 | | |
236 | | |
237 | | int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits, |
238 | | AES_KEY *aeskey); |
239 | | int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits, |
240 | | AES_KEY *aeskey); |
241 | | void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); |
242 | | void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); |
243 | | void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, |
244 | | size_t blocks, const AES_KEY *key, |
245 | | const uint8_t ivec[16]); |
246 | | void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, |
247 | | const AES_KEY *key, uint8_t *ivec, int enc); |
248 | | |
249 | | |
250 | | #if defined(__cplusplus) |
251 | | } // extern C |
252 | | #endif |
253 | | |
254 | | #endif // OPENSSL_HEADER_AES_INTERNAL_H |