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 "../../internal.h"
21
22 #if defined(__cplusplus)
23 extern "C" {
24 #endif
25
26
27 #if !defined(OPENSSL_NO_ASM)
28
29 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
30 #define HWAES
31 #define HWAES_ECB
32
hwaes_capable(void)33 OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_AESNI_capable(); }
34
35 #define VPAES
36 #if defined(OPENSSL_X86_64)
37 #define VPAES_CTR32
38 #endif
39 #define VPAES_CBC
vpaes_capable(void)40 OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_SSSE3_capable(); }
41
42 #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
43 #define HWAES
44
45 OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_ARMv8_AES_capable(); }
46
47 #if defined(OPENSSL_ARM)
48 #define BSAES
49 #define VPAES
50 #define VPAES_CTR32
51 OPENSSL_INLINE int bsaes_capable(void) { return CRYPTO_is_NEON_capable(); }
52 OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); }
53 #endif
54
55 #if defined(OPENSSL_AARCH64)
56 #define VPAES
57 #define VPAES_CBC
58 #define VPAES_CTR32
59 OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); }
60 #endif
61
62 #endif
63
64 #endif // !NO_ASM
65
66
67 #if defined(HWAES)
68
69 int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits, AES_KEY *key);
70 int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits, AES_KEY *key);
71 void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
72 void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
73 void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
74 const AES_KEY *key, uint8_t *ivec, int enc);
75 void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
76 const AES_KEY *key, const uint8_t ivec[16]);
77
78 #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
79 // On x86 and x86_64, |aes_hw_set_decrypt_key| is implemented in terms of
80 // |aes_hw_set_encrypt_key| and a conversion function.
81 void aes_hw_encrypt_key_to_decrypt_key(AES_KEY *key);
82
83 // There are two variants of this function, one which uses aeskeygenassist
84 // ("base") and one which uses aesenclast + pshufb ("alt"). aesenclast is
85 // overall faster but is slower on some older processors. It doesn't use AVX,
86 // but AVX is used as a proxy to detecting this. See
87 // https://groups.google.com/g/mailing.openssl.dev/c/OuFXwW4NfO8/m/7d2ZXVjkxVkJ
88 //
89 // TODO(davidben): It is unclear if the aeskeygenassist version is still
90 // worthwhile. However, the aesenclast version requires SSSE3. SSSE3 long
91 // predates AES-NI, but it's not clear if AES-NI implies SSSE3. In OpenSSL, the
92 // CCM AES-NI assembly seems to assume it does.
aes_hw_set_encrypt_key_alt_capable(void)93 OPENSSL_INLINE int aes_hw_set_encrypt_key_alt_capable(void) {
94 return hwaes_capable() && CRYPTO_is_SSSE3_capable();
95 }
aes_hw_set_encrypt_key_alt_preferred(void)96 OPENSSL_INLINE int aes_hw_set_encrypt_key_alt_preferred(void) {
97 return hwaes_capable() && CRYPTO_is_AVX_capable();
98 }
99 int aes_hw_set_encrypt_key_base(const uint8_t *user_key, int bits,
100 AES_KEY *key);
101 int aes_hw_set_encrypt_key_alt(const uint8_t *user_key, int bits, AES_KEY *key);
102 #endif // OPENSSL_X86 || OPENSSL_X86_64
103
104 #else
105
106 // If HWAES isn't defined then we provide dummy functions for each of the hwaes
107 // functions.
hwaes_capable(void)108 OPENSSL_INLINE int hwaes_capable(void) { return 0; }
109
aes_hw_set_encrypt_key(const uint8_t * user_key,int bits,AES_KEY * key)110 OPENSSL_INLINE int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits,
111 AES_KEY *key) {
112 abort();
113 }
114
aes_hw_set_decrypt_key(const uint8_t * user_key,int bits,AES_KEY * key)115 OPENSSL_INLINE int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits,
116 AES_KEY *key) {
117 abort();
118 }
119
aes_hw_encrypt(const uint8_t * in,uint8_t * out,const AES_KEY * key)120 OPENSSL_INLINE void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
121 const AES_KEY *key) {
122 abort();
123 }
124
aes_hw_decrypt(const uint8_t * in,uint8_t * out,const AES_KEY * key)125 OPENSSL_INLINE void aes_hw_decrypt(const uint8_t *in, uint8_t *out,
126 const AES_KEY *key) {
127 abort();
128 }
129
aes_hw_cbc_encrypt(const uint8_t * in,uint8_t * out,size_t length,const AES_KEY * key,uint8_t * ivec,int enc)130 OPENSSL_INLINE void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out,
131 size_t length, const AES_KEY *key,
132 uint8_t *ivec, int enc) {
133 abort();
134 }
135
aes_hw_ctr32_encrypt_blocks(const uint8_t * in,uint8_t * out,size_t len,const AES_KEY * key,const uint8_t ivec[16])136 OPENSSL_INLINE void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
137 size_t len, const AES_KEY *key,
138 const uint8_t ivec[16]) {
139 abort();
140 }
141
142 #endif // !HWAES
143
144
145 #if defined(HWAES_ECB)
146 void aes_hw_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
147 const AES_KEY *key, int enc);
148 #endif // HWAES_ECB
149
150
151 #if defined(BSAES)
152 // Note |bsaes_cbc_encrypt| requires |enc| to be zero.
153 void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
154 const AES_KEY *key, uint8_t ivec[16], int enc);
155 void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
156 const AES_KEY *key, const uint8_t ivec[16]);
157 // VPAES to BSAES conversions are available on all BSAES platforms.
158 void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes);
159 void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes);
160 #else
bsaes_capable(void)161 OPENSSL_INLINE char bsaes_capable(void) { return 0; }
162
163 // On other platforms, bsaes_capable() will always return false and so the
164 // following will never be called.
bsaes_cbc_encrypt(const uint8_t * in,uint8_t * out,size_t length,const AES_KEY * key,uint8_t ivec[16],int enc)165 OPENSSL_INLINE void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
166 size_t length, const AES_KEY *key,
167 uint8_t ivec[16], int enc) {
168 abort();
169 }
170
bsaes_ctr32_encrypt_blocks(const uint8_t * in,uint8_t * out,size_t len,const AES_KEY * key,const uint8_t ivec[16])171 OPENSSL_INLINE void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
172 size_t len, const AES_KEY *key,
173 const uint8_t ivec[16]) {
174 abort();
175 }
176
vpaes_encrypt_key_to_bsaes(AES_KEY * out_bsaes,const AES_KEY * vpaes)177 OPENSSL_INLINE void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes,
178 const AES_KEY *vpaes) {
179 abort();
180 }
181
vpaes_decrypt_key_to_bsaes(AES_KEY * out_bsaes,const AES_KEY * vpaes)182 OPENSSL_INLINE void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes,
183 const AES_KEY *vpaes) {
184 abort();
185 }
186 #endif // !BSAES
187
188
189 #if defined(VPAES)
190 // On platforms where VPAES gets defined (just above), then these functions are
191 // provided by asm.
192 int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
193 int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
194
195 void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
196 void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
197
198 #if defined(VPAES_CBC)
199 void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
200 const AES_KEY *key, uint8_t *ivec, int enc);
201 #endif
202 #if defined(VPAES_CTR32)
203 void vpaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
204 const AES_KEY *key, const uint8_t ivec[16]);
205 #endif
206 #else
vpaes_capable(void)207 OPENSSL_INLINE char vpaes_capable(void) { return 0; }
208
209 // On other platforms, vpaes_capable() will always return false and so the
210 // following will never be called.
vpaes_set_encrypt_key(const uint8_t * userKey,int bits,AES_KEY * key)211 OPENSSL_INLINE int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
212 AES_KEY *key) {
213 abort();
214 }
vpaes_set_decrypt_key(const uint8_t * userKey,int bits,AES_KEY * key)215 OPENSSL_INLINE int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
216 AES_KEY *key) {
217 abort();
218 }
vpaes_encrypt(const uint8_t * in,uint8_t * out,const AES_KEY * key)219 OPENSSL_INLINE void vpaes_encrypt(const uint8_t *in, uint8_t *out,
220 const AES_KEY *key) {
221 abort();
222 }
vpaes_decrypt(const uint8_t * in,uint8_t * out,const AES_KEY * key)223 OPENSSL_INLINE void vpaes_decrypt(const uint8_t *in, uint8_t *out,
224 const AES_KEY *key) {
225 abort();
226 }
vpaes_cbc_encrypt(const uint8_t * in,uint8_t * out,size_t length,const AES_KEY * key,uint8_t * ivec,int enc)227 OPENSSL_INLINE void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
228 size_t length, const AES_KEY *key,
229 uint8_t *ivec, int enc) {
230 abort();
231 }
232 #endif // !VPAES
233
234
235 int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
236 AES_KEY *aeskey);
237 int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
238 AES_KEY *aeskey);
239 void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
240 void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
241 void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
242 size_t blocks, const AES_KEY *key,
243 const uint8_t ivec[16]);
244 void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
245 const AES_KEY *key, uint8_t *ivec, int enc);
246
247
248 #if defined(__cplusplus)
249 } // extern C
250 #endif
251
252 #endif // OPENSSL_HEADER_AES_INTERNAL_H
253