xref: /aosp_15_r20/external/boringssl/src/crypto/fipsmodule/aes/internal.h (revision 8fb009dc861624b67b6cdb62ea21f0f22d0c584b)
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