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/cpu.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) {
34 return (OPENSSL_ia32cap_get()[1] & (1 << (57 - 32))) != 0;
35 }
36
37 #define VPAES
38 #if defined(OPENSSL_X86_64)
39 #define VPAES_CTR32
40 #endif
41 #define VPAES_CBC
vpaes_capable(void)42 OPENSSL_INLINE int vpaes_capable(void) {
43 return (OPENSSL_ia32cap_get()[1] & (1 << (41 - 32))) != 0;
44 }
45
46 #elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
47 #define HWAES
48
49 OPENSSL_INLINE int hwaes_capable(void) { return CRYPTO_is_ARMv8_AES_capable(); }
50
51 #if defined(OPENSSL_ARM)
52 #define BSAES
53 #define VPAES
54 #define VPAES_CTR32
55 OPENSSL_INLINE int bsaes_capable(void) { return CRYPTO_is_NEON_capable(); }
56 OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); }
57 #endif
58
59 #if defined(OPENSSL_AARCH64)
60 #define VPAES
61 #define VPAES_CBC
62 #define VPAES_CTR32
63 OPENSSL_INLINE int vpaes_capable(void) { return CRYPTO_is_NEON_capable(); }
64 #endif
65
66 #elif defined(OPENSSL_PPC64LE)
67 #define HWAES
68
69 OPENSSL_INLINE int hwaes_capable(void) {
70 return CRYPTO_is_PPC64LE_vcrypto_capable();
71 }
72 #endif
73
74 #endif // !NO_ASM
75
76
77 #if defined(HWAES)
78
79 int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits,
80 AES_KEY *key);
81 int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits,
82 AES_KEY *key);
83 void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
84 void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
85 void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
86 const AES_KEY *key, uint8_t *ivec, const int enc);
87 void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
88 const AES_KEY *key, const uint8_t ivec[16]);
89
90 #else
91
92 // If HWAES isn't defined then we provide dummy functions for each of the hwaes
93 // functions.
hwaes_capable(void)94 OPENSSL_INLINE int hwaes_capable(void) { return 0; }
95
aes_hw_set_encrypt_key(const uint8_t * user_key,int bits,AES_KEY * key)96 OPENSSL_INLINE int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits,
97 AES_KEY *key) {
98 abort();
99 }
100
aes_hw_set_decrypt_key(const uint8_t * user_key,int bits,AES_KEY * key)101 OPENSSL_INLINE int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits,
102 AES_KEY *key) {
103 abort();
104 }
105
aes_hw_encrypt(const uint8_t * in,uint8_t * out,const AES_KEY * key)106 OPENSSL_INLINE void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
107 const AES_KEY *key) {
108 abort();
109 }
110
aes_hw_decrypt(const uint8_t * in,uint8_t * out,const AES_KEY * key)111 OPENSSL_INLINE void aes_hw_decrypt(const uint8_t *in, uint8_t *out,
112 const AES_KEY *key) {
113 abort();
114 }
115
aes_hw_cbc_encrypt(const uint8_t * in,uint8_t * out,size_t length,const AES_KEY * key,uint8_t * ivec,int enc)116 OPENSSL_INLINE void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out,
117 size_t length, const AES_KEY *key,
118 uint8_t *ivec, int enc) {
119 abort();
120 }
121
aes_hw_ctr32_encrypt_blocks(const uint8_t * in,uint8_t * out,size_t len,const AES_KEY * key,const uint8_t ivec[16])122 OPENSSL_INLINE void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
123 size_t len, const AES_KEY *key,
124 const uint8_t ivec[16]) {
125 abort();
126 }
127
128 #endif // !HWAES
129
130
131 #if defined(HWAES_ECB)
132 void aes_hw_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
133 const AES_KEY *key, const int enc);
134 #endif // HWAES_ECB
135
136
137 #if defined(BSAES)
138 // Note |bsaes_cbc_encrypt| requires |enc| to be zero.
139 void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
140 const AES_KEY *key, uint8_t ivec[16], int enc);
141 void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
142 const AES_KEY *key, const uint8_t ivec[16]);
143 // VPAES to BSAES conversions are available on all BSAES platforms.
144 void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes);
145 void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes);
146 #else
bsaes_capable(void)147 OPENSSL_INLINE char bsaes_capable(void) { return 0; }
148
149 // On other platforms, bsaes_capable() will always return false and so the
150 // 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)151 OPENSSL_INLINE void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
152 size_t length, const AES_KEY *key,
153 uint8_t ivec[16], int enc) {
154 abort();
155 }
156
bsaes_ctr32_encrypt_blocks(const uint8_t * in,uint8_t * out,size_t len,const AES_KEY * key,const uint8_t ivec[16])157 OPENSSL_INLINE void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
158 size_t len, const AES_KEY *key,
159 const uint8_t ivec[16]) {
160 abort();
161 }
162
vpaes_encrypt_key_to_bsaes(AES_KEY * out_bsaes,const AES_KEY * vpaes)163 OPENSSL_INLINE void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes,
164 const AES_KEY *vpaes) {
165 abort();
166 }
167
vpaes_decrypt_key_to_bsaes(AES_KEY * out_bsaes,const AES_KEY * vpaes)168 OPENSSL_INLINE void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes,
169 const AES_KEY *vpaes) {
170 abort();
171 }
172 #endif // !BSAES
173
174
175 #if defined(VPAES)
176 // On platforms where VPAES gets defined (just above), then these functions are
177 // provided by asm.
178 int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
179 int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
180
181 void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
182 void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
183
184 #if defined(VPAES_CBC)
185 void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
186 const AES_KEY *key, uint8_t *ivec, int enc);
187 #endif
188 #if defined(VPAES_CTR32)
189 void vpaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
190 const AES_KEY *key, const uint8_t ivec[16]);
191 #endif
192 #else
vpaes_capable(void)193 OPENSSL_INLINE char vpaes_capable(void) { return 0; }
194
195 // On other platforms, vpaes_capable() will always return false and so the
196 // following will never be called.
vpaes_set_encrypt_key(const uint8_t * userKey,int bits,AES_KEY * key)197 OPENSSL_INLINE int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
198 AES_KEY *key) {
199 abort();
200 }
vpaes_set_decrypt_key(const uint8_t * userKey,int bits,AES_KEY * key)201 OPENSSL_INLINE int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
202 AES_KEY *key) {
203 abort();
204 }
vpaes_encrypt(const uint8_t * in,uint8_t * out,const AES_KEY * key)205 OPENSSL_INLINE void vpaes_encrypt(const uint8_t *in, uint8_t *out,
206 const AES_KEY *key) {
207 abort();
208 }
vpaes_decrypt(const uint8_t * in,uint8_t * out,const AES_KEY * key)209 OPENSSL_INLINE void vpaes_decrypt(const uint8_t *in, uint8_t *out,
210 const AES_KEY *key) {
211 abort();
212 }
vpaes_cbc_encrypt(const uint8_t * in,uint8_t * out,size_t length,const AES_KEY * key,uint8_t * ivec,int enc)213 OPENSSL_INLINE void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out,
214 size_t length, const AES_KEY *key,
215 uint8_t *ivec, int enc) {
216 abort();
217 }
218 #endif // !VPAES
219
220
221 int aes_nohw_set_encrypt_key(const uint8_t *key, unsigned bits,
222 AES_KEY *aeskey);
223 int aes_nohw_set_decrypt_key(const uint8_t *key, unsigned bits,
224 AES_KEY *aeskey);
225 void aes_nohw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
226 void aes_nohw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
227 void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
228 size_t blocks, const AES_KEY *key,
229 const uint8_t ivec[16]);
230 void aes_nohw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
231 const AES_KEY *key, uint8_t *ivec, const int enc);
232
233
234 #if defined(__cplusplus)
235 } // extern C
236 #endif
237
238 #endif // OPENSSL_HEADER_AES_INTERNAL_H
239