summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/eng_aesni.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/engine/eng_aesni.c')
-rw-r--r--src/lib/libcrypto/engine/eng_aesni.c331
1 files changed, 169 insertions, 162 deletions
diff --git a/src/lib/libcrypto/engine/eng_aesni.c b/src/lib/libcrypto/engine/eng_aesni.c
index d547d7f465..b1eade2d63 100644
--- a/src/lib/libcrypto/engine/eng_aesni.c
+++ b/src/lib/libcrypto/engine/eng_aesni.c
@@ -102,7 +102,8 @@ void ENGINE_load_aesni (void)
102/* On non-x86 CPUs it just returns. */ 102/* On non-x86 CPUs it just returns. */
103#ifdef COMPILE_HW_AESNI 103#ifdef COMPILE_HW_AESNI
104 ENGINE *toadd = ENGINE_aesni(); 104 ENGINE *toadd = ENGINE_aesni();
105 if (!toadd) return; 105 if (!toadd)
106 return;
106 ENGINE_add (toadd); 107 ENGINE_add (toadd);
107 ENGINE_register_complete (toadd); 108 ENGINE_register_complete (toadd);
108 ENGINE_free (toadd); 109 ENGINE_free (toadd);
@@ -112,32 +113,26 @@ void ENGINE_load_aesni (void)
112 113
113#ifdef COMPILE_HW_AESNI 114#ifdef COMPILE_HW_AESNI
114int aesni_set_encrypt_key(const unsigned char *userKey, int bits, 115int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
115 AES_KEY *key); 116 AES_KEY *key);
116int aesni_set_decrypt_key(const unsigned char *userKey, int bits, 117int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
117 AES_KEY *key); 118 AES_KEY *key);
118 119
119void aesni_encrypt(const unsigned char *in, unsigned char *out, 120void aesni_encrypt(const unsigned char *in, unsigned char *out,
120 const AES_KEY *key); 121 const AES_KEY *key);
121void aesni_decrypt(const unsigned char *in, unsigned char *out, 122void aesni_decrypt(const unsigned char *in, unsigned char *out,
122 const AES_KEY *key); 123 const AES_KEY *key);
123 124
124void aesni_ecb_encrypt(const unsigned char *in, 125void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
125 unsigned char *out, 126 size_t length, const AES_KEY *key, int enc);
126 size_t length, 127void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
127 const AES_KEY *key, 128 size_t length, const AES_KEY *key, unsigned char *ivec, int enc);
128 int enc);
129void aesni_cbc_encrypt(const unsigned char *in,
130 unsigned char *out,
131 size_t length,
132 const AES_KEY *key,
133 unsigned char *ivec, int enc);
134 129
135/* Function for ENGINE detection and control */ 130/* Function for ENGINE detection and control */
136static int aesni_init(ENGINE *e); 131static int aesni_init(ENGINE *e);
137 132
138/* Cipher Stuff */ 133/* Cipher Stuff */
139static int aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher, 134static int aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
140 const int **nids, int nid); 135 const int **nids, int nid);
141 136
142#define AESNI_MIN_ALIGN 16 137#define AESNI_MIN_ALIGN 16
143#define AESNI_ALIGN(x) \ 138#define AESNI_ALIGN(x) \
@@ -145,143 +140,146 @@ static int aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
145 140
146/* Engine names */ 141/* Engine names */
147static const char aesni_id[] = "aesni", 142static const char aesni_id[] = "aesni",
148 aesni_name[] = "Intel AES-NI engine", 143 aesni_name[] = "Intel AES-NI engine",
149 no_aesni_name[] = "Intel AES-NI engine (no-aesni)"; 144 no_aesni_name[] = "Intel AES-NI engine (no-aesni)";
150 145
151 146
152/* The input and output encrypted as though 128bit cfb mode is being 147/* The input and output encrypted as though 128bit cfb mode is being
153 * used. The extra state information to record how much of the 148 * used. The extra state information to record how much of the
154 * 128bit block we have used is contained in *num; 149 * 128bit block we have used is contained in *num;
155 */ 150 */
156static void aesni_cfb128_encrypt(const unsigned char *in, unsigned char *out, 151static void
157 unsigned int len, const void *key, 152aesni_cfb128_encrypt(const unsigned char *in, unsigned char *out,
158 unsigned char ivec[16], int *num, 153 unsigned int len, const void *key, unsigned char ivec[16], int *num,
159 int enc) 154 int enc)
160{ 155{
161 unsigned int n; 156 unsigned int n;
162 size_t l = 0; 157 size_t l = 0;
163 158
164 assert(in && out && key && ivec && num); 159 assert(in && out && key && ivec && num);
165 160
166 n = *num; 161 n = *num;
167 162
168 if (enc) { 163 if (enc) {
169#if !defined(OPENSSL_SMALL_FOOTPRINT) 164#if !defined(OPENSSL_SMALL_FOOTPRINT)
170 if (16%sizeof(size_t) == 0) do { /* always true actually */ 165 if (16%sizeof(size_t) == 0) do { /* always true actually */
171 while (n && len) { 166 while (n && len) {
172 *(out++) = ivec[n] ^= *(in++); 167 *(out++) = ivec[n] ^= *(in++);
173 --len; 168 --len;
174 n = (n+1) % 16; 169 n = (n + 1) % 16;
175 }
176 while (len>=16) {
177 aesni_encrypt(ivec, ivec, key);
178 for (n=0; n<16; n+=sizeof(size_t)) {
179 *(size_t*)(out+n) =
180 *(size_t*)(ivec+n) ^= *(size_t*)(in+n);
181 } 170 }
182 len -= 16; 171 while (len >= 16) {
183 out += 16; 172 aesni_encrypt(ivec, ivec, key);
184 in += 16; 173 for (n = 0; n < 16; n += sizeof(size_t)) {
185 } 174 *(size_t*)(out + n) =
186 n = 0; 175 *(size_t*)(ivec + n) ^= *(size_t*)(in + n);
187 if (len) { 176 }
188 aesni_encrypt(ivec, ivec, key); 177 len -= 16;
189 while (len--) { 178 out += 16;
190 out[n] = ivec[n] ^= in[n]; 179 in += 16;
191 ++n;
192 } 180 }
193 } 181 n = 0;
194 *num = n; 182 if (len) {
195 return; 183 aesni_encrypt(ivec, ivec, key);
196 } while (0); 184 while (len--) {
197 /* the rest would be commonly eliminated by x86* compiler */ 185 out[n] = ivec[n] ^= in[n];
186 ++n;
187 }
188 }
189 *num = n;
190 return;
191 } while (0);
192 /* the rest would be commonly eliminated by x86* compiler */
198#endif 193#endif
199 while (l<len) { 194 while (l < len) {
200 if (n == 0) { 195 if (n == 0) {
201 aesni_encrypt(ivec, ivec, key); 196 aesni_encrypt(ivec, ivec, key);
202 }
203 out[l] = ivec[n] ^= in[l];
204 ++l;
205 n = (n+1) % 16;
206 }
207 *num = n;
208 } else {
209#if !defined(OPENSSL_SMALL_FOOTPRINT)
210 if (16%sizeof(size_t) == 0) do { /* always true actually */
211 while (n && len) {
212 unsigned char c;
213 *(out++) = ivec[n] ^ (c = *(in++)); ivec[n] = c;
214 --len;
215 n = (n+1) % 16;
216 }
217 while (len>=16) {
218 aesni_encrypt(ivec, ivec, key);
219 for (n=0; n<16; n+=sizeof(size_t)) {
220 size_t t = *(size_t*)(in+n);
221 *(size_t*)(out+n) = *(size_t*)(ivec+n) ^ t;
222 *(size_t*)(ivec+n) = t;
223 } 197 }
224 len -= 16; 198 out[l] = ivec[n] ^= in[l];
225 out += 16; 199 ++l;
226 in += 16; 200 n = (n + 1) % 16;
227 } 201 }
228 n = 0; 202 *num = n;
229 if (len) { 203 } else {
230 aesni_encrypt(ivec, ivec, key); 204#if !defined(OPENSSL_SMALL_FOOTPRINT)
231 while (len--) { 205 if (16%sizeof(size_t) == 0) do { /* always true actually */
206 while (n && len) {
232 unsigned char c; 207 unsigned char c;
233 out[n] = ivec[n] ^ (c = in[n]); ivec[n] = c; 208 *(out++) = ivec[n] ^ (c = *(in++));
234 ++n; 209 ivec[n] = c;
210 --len;
211 n = (n + 1) % 16;
235 } 212 }
236 } 213 while (len >= 16) {
237 *num = n; 214 aesni_encrypt(ivec, ivec, key);
238 return; 215 for (n = 0; n < 16; n += sizeof(size_t)) {
239 } while (0); 216 size_t t = *(size_t*)(in + n);
240 /* the rest would be commonly eliminated by x86* compiler */ 217 *(size_t*)(out + n) = *(size_t*)(ivec + n) ^ t;
218 *(size_t*)(ivec + n) = t;
219 }
220 len -= 16;
221 out += 16;
222 in += 16;
223 }
224 n = 0;
225 if (len) {
226 aesni_encrypt(ivec, ivec, key);
227 while (len--) {
228 unsigned char c;
229 out[n] = ivec[n] ^ (c = in[n]);
230 ivec[n] = c;
231 ++n;
232 }
233 }
234 *num = n;
235 return;
236 } while (0);
237 /* the rest would be commonly eliminated by x86* compiler */
241#endif 238#endif
242 while (l<len) { 239 while (l < len) {
243 unsigned char c; 240 unsigned char c;
244 if (n == 0) { 241 if (n == 0) {
245 aesni_encrypt(ivec, ivec, key); 242 aesni_encrypt(ivec, ivec, key);
243 }
244 out[l] = ivec[n] ^ (c = in[l]);
245 ivec[n] = c;
246 ++l;
247 n = (n + 1) % 16;
246 } 248 }
247 out[l] = ivec[n] ^ (c = in[l]); ivec[n] = c; 249 *num = n;
248 ++l;
249 n = (n+1) % 16;
250 } 250 }
251 *num=n;
252 }
253} 251}
254 252
255/* The input and output encrypted as though 128bit ofb mode is being 253/* The input and output encrypted as though 128bit ofb mode is being
256 * used. The extra state information to record how much of the 254 * used. The extra state information to record how much of the
257 * 128bit block we have used is contained in *num; 255 * 128bit block we have used is contained in *num;
258 */ 256 */
259static void aesni_ofb128_encrypt(const unsigned char *in, unsigned char *out, 257static void
260 unsigned int len, const void *key, 258aesni_ofb128_encrypt(const unsigned char *in, unsigned char *out,
261 unsigned char ivec[16], int *num) 259 unsigned int len, const void *key, unsigned char ivec[16], int *num)
262{ 260{
263 unsigned int n; 261 unsigned int n;
264 size_t l=0; 262 size_t l = 0;
265 263
266 assert(in && out && key && ivec && num); 264 assert(in && out && key && ivec && num);
267 265
268 n = *num; 266 n = *num;
269 267
270#if !defined(OPENSSL_SMALL_FOOTPRINT) 268#if !defined(OPENSSL_SMALL_FOOTPRINT)
271 if (16%sizeof(size_t) == 0) do { /* always true actually */ 269 if (16%sizeof(size_t) == 0) do { /* always true actually */
272 while (n && len) { 270 while (n && len) {
273 *(out++) = *(in++) ^ ivec[n]; 271 *(out++) = *(in++) ^ ivec[n];
274 --len; 272 --len;
275 n = (n+1) % 16; 273 n = (n + 1) % 16;
276 } 274 }
277 while (len>=16) { 275 while (len >= 16) {
278 aesni_encrypt(ivec, ivec, key); 276 aesni_encrypt(ivec, ivec, key);
279 for (n=0; n<16; n+=sizeof(size_t)) 277 for (n = 0; n < 16; n += sizeof(size_t))
280 *(size_t*)(out+n) = 278 *(size_t*)(out + n) =
281 *(size_t*)(in+n) ^ *(size_t*)(ivec+n); 279 *(size_t*)(in + n) ^ *(size_t*)(ivec + n);
282 len -= 16; 280 len -= 16;
283 out += 16; 281 out += 16;
284 in += 16; 282 in += 16;
285 } 283 }
286 n = 0; 284 n = 0;
287 if (len) { 285 if (len) {
@@ -293,19 +291,19 @@ static void aesni_ofb128_encrypt(const unsigned char *in, unsigned char *out,
293 } 291 }
294 *num = n; 292 *num = n;
295 return; 293 return;
296 } while(0); 294 } while (0);
297 /* the rest would be commonly eliminated by x86* compiler */ 295 /* the rest would be commonly eliminated by x86* compiler */
298#endif 296#endif
299 while (l<len) { 297 while (l < len) {
300 if (n==0) { 298 if (n == 0) {
301 aesni_encrypt(ivec, ivec, key); 299 aesni_encrypt(ivec, ivec, key);
302 } 300 }
303 out[l] = in[l] ^ ivec[n]; 301 out[l] = in[l] ^ ivec[n];
304 ++l; 302 ++l;
305 n = (n+1) % 16; 303 n = (n + 1) % 16;
306 } 304 }
307 305
308 *num=n; 306 *num = n;
309} 307}
310/* ===== Engine "management" functions ===== */ 308/* ===== Engine "management" functions ===== */
311 309
@@ -316,6 +314,7 @@ static int
316aesni_bind_helper(ENGINE *e) 314aesni_bind_helper(ENGINE *e)
317{ 315{
318 int engage; 316 int engage;
317
319 if (sizeof(OPENSSL_ia32cap_P) > 4) { 318 if (sizeof(OPENSSL_ia32cap_P) > 4) {
320 engage = ((IA32CAP)OPENSSL_ia32cap_P >> 57) & 1; 319 engage = ((IA32CAP)OPENSSL_ia32cap_P >> 57) & 1;
321 } else { 320 } else {
@@ -326,10 +325,8 @@ aesni_bind_helper(ENGINE *e)
326 /* Register everything or return with an error */ 325 /* Register everything or return with an error */
327 if (!ENGINE_set_id(e, aesni_id) || 326 if (!ENGINE_set_id(e, aesni_id) ||
328 !ENGINE_set_name(e, engage ? aesni_name : no_aesni_name) || 327 !ENGINE_set_name(e, engage ? aesni_name : no_aesni_name) ||
329
330 !ENGINE_set_init_function(e, aesni_init) || 328 !ENGINE_set_init_function(e, aesni_init) ||
331 (engage && !ENGINE_set_ciphers (e, aesni_ciphers)) 329 (engage && !ENGINE_set_ciphers (e, aesni_ciphers)))
332 )
333 return 0; 330 return 0;
334 331
335 /* Everything looks good */ 332 /* Everything looks good */
@@ -403,60 +400,72 @@ static int aesni_cipher_nids[] = {
403 NID_aes_256_ofb, 400 NID_aes_256_ofb,
404}; 401};
405static int aesni_cipher_nids_num = 402static int aesni_cipher_nids_num =
406 (sizeof(aesni_cipher_nids)/sizeof(aesni_cipher_nids[0])); 403 (sizeof(aesni_cipher_nids) / sizeof(aesni_cipher_nids[0]));
407 404
408typedef struct 405typedef struct {
409{
410 AES_KEY ks; 406 AES_KEY ks;
411 unsigned int _pad1[3]; 407 unsigned int _pad1[3];
412} AESNI_KEY; 408} AESNI_KEY;
413 409
414static int 410static int
415aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *user_key, 411aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *user_key,
416 const unsigned char *iv, int enc) 412 const unsigned char *iv, int enc)
417{ 413{
418 int ret; 414 int ret;
419 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data); 415 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
420 416
421 if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE 417 if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE ||
422 || (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE 418 (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE ||
423 || enc) 419 enc)
424 ret=aesni_set_encrypt_key(user_key, ctx->key_len * 8, key); 420 ret = aesni_set_encrypt_key(user_key, ctx->key_len * 8, key);
425 else 421 else
426 ret=aesni_set_decrypt_key(user_key, ctx->key_len * 8, key); 422 ret = aesni_set_decrypt_key(user_key, ctx->key_len * 8, key);
427 423
428 if(ret < 0) { 424 if (ret < 0) {
429 EVPerr(EVP_F_AESNI_INIT_KEY,EVP_R_AES_KEY_SETUP_FAILED); 425 EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED);
430 return 0; 426 return 0;
431 } 427 }
432 428
433 return 1; 429 return 1;
434} 430}
435 431
436static int aesni_cipher_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out, 432static int
437 const unsigned char *in, size_t inl) 433aesni_cipher_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
438{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data); 434 const unsigned char *in, size_t inl)
435{
436 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
437
439 aesni_ecb_encrypt(in, out, inl, key, ctx->encrypt); 438 aesni_ecb_encrypt(in, out, inl, key, ctx->encrypt);
440 return 1; 439 return 1;
441} 440}
442static int aesni_cipher_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out, 441
443 const unsigned char *in, size_t inl) 442static int
444{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data); 443aesni_cipher_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
445 aesni_cbc_encrypt(in, out, inl, key, 444 const unsigned char *in, size_t inl)
446 ctx->iv, ctx->encrypt); 445{
446 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
447
448 aesni_cbc_encrypt(in, out, inl, key, ctx->iv, ctx->encrypt);
447 return 1; 449 return 1;
448} 450}
449static int aesni_cipher_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
450 const unsigned char *in, size_t inl)
451{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
452 451
453 aesni_cfb128_encrypt(in, out, inl, key, ctx->iv, 452static int
454 &ctx->num, ctx->encrypt); 453aesni_cipher_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
454 const unsigned char *in, size_t inl)
455{
456 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
457
458 aesni_cfb128_encrypt(in, out, inl, key, ctx->iv, &ctx->num,
459 ctx->encrypt);
455 return 1; 460 return 1;
456} 461}
457static int aesni_cipher_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out, 462
458 const unsigned char *in, size_t inl) 463static int
459{ AES_KEY *key = AESNI_ALIGN(ctx->cipher_data); 464aesni_cipher_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
465 const unsigned char *in, size_t inl)
466{
467 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
468
460 aesni_ofb128_encrypt(in, out, inl, key, ctx->iv, &ctx->num); 469 aesni_ofb128_encrypt(in, out, inl, key, ctx->iv, &ctx->num);
461 return 1; 470 return 1;
462} 471}
@@ -487,24 +496,23 @@ static const EVP_CIPHER aesni_##ksize##_##lmode = { \
487 NULL \ 496 NULL \
488} 497}
489 498
490DECLARE_AES_EVP(128,ecb,ECB); 499DECLARE_AES_EVP(128, ecb, ECB);
491DECLARE_AES_EVP(128,cbc,CBC); 500DECLARE_AES_EVP(128, cbc, CBC);
492DECLARE_AES_EVP(128,cfb,CFB); 501DECLARE_AES_EVP(128, cfb, CFB);
493DECLARE_AES_EVP(128,ofb,OFB); 502DECLARE_AES_EVP(128, ofb, OFB);
494 503
495DECLARE_AES_EVP(192,ecb,ECB); 504DECLARE_AES_EVP(192, ecb, ECB);
496DECLARE_AES_EVP(192,cbc,CBC); 505DECLARE_AES_EVP(192, cbc, CBC);
497DECLARE_AES_EVP(192,cfb,CFB); 506DECLARE_AES_EVP(192, cfb, CFB);
498DECLARE_AES_EVP(192,ofb,OFB); 507DECLARE_AES_EVP(192, ofb, OFB);
499 508
500DECLARE_AES_EVP(256,ecb,ECB); 509DECLARE_AES_EVP(256, ecb, ECB);
501DECLARE_AES_EVP(256,cbc,CBC); 510DECLARE_AES_EVP(256, cbc, CBC);
502DECLARE_AES_EVP(256,cfb,CFB); 511DECLARE_AES_EVP(256, cfb, CFB);
503DECLARE_AES_EVP(256,ofb,OFB); 512DECLARE_AES_EVP(256, ofb, OFB);
504 513
505static int 514static int
506aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher, 515aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
507 const int **nids, int nid)
508{ 516{
509 /* No specific cipher => return a list of supported nids ... */ 517 /* No specific cipher => return a list of supported nids ... */
510 if (!cipher) { 518 if (!cipher) {
@@ -563,4 +571,3 @@ aesni_ciphers (ENGINE *e, const EVP_CIPHER **cipher,
563 571
564#endif /* COMPILE_HW_AESNI */ 572#endif /* COMPILE_HW_AESNI */
565#endif /* !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI) && !defined(OPENSSL_NO_AES) */ 573#endif /* !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI) && !defined(OPENSSL_NO_AES) */
566