summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/engine/eng_aesni.c
diff options
context:
space:
mode:
authortb <>2023-07-20 16:36:06 +0000
committertb <>2023-07-20 16:36:06 +0000
commitffc366ad631823ca313e68ca9a54544739bce0c8 (patch)
treedc0fc379632be1703e99e20edee64079a8279ae5 /src/lib/libcrypto/engine/eng_aesni.c
parent7b660744be840ee9a7e28176e6a379962d6e2332 (diff)
downloadopenbsd-ffc366ad631823ca313e68ca9a54544739bce0c8.tar.gz
openbsd-ffc366ad631823ca313e68ca9a54544739bce0c8.tar.bz2
openbsd-ffc366ad631823ca313e68ca9a54544739bce0c8.zip
Remove some ancient cruft that hasn't been used in ages
discussed with jsing
Diffstat (limited to 'src/lib/libcrypto/engine/eng_aesni.c')
-rw-r--r--src/lib/libcrypto/engine/eng_aesni.c563
1 files changed, 0 insertions, 563 deletions
diff --git a/src/lib/libcrypto/engine/eng_aesni.c b/src/lib/libcrypto/engine/eng_aesni.c
deleted file mode 100644
index e08edcf346..0000000000
--- a/src/lib/libcrypto/engine/eng_aesni.c
+++ /dev/null
@@ -1,563 +0,0 @@
1/* $OpenBSD: eng_aesni.c,v 1.14 2023/07/20 15:08:12 tb Exp $ */
2/*
3 * Support for Intel AES-NI instruction set
4 * Author: Huang Ying <ying.huang@intel.com>
5 *
6 * Intel AES-NI is a new set of Single Instruction Multiple Data
7 * (SIMD) instructions that are going to be introduced in the next
8 * generation of Intel processor, as of 2009. These instructions
9 * enable fast and secure data encryption and decryption, using the
10 * Advanced Encryption Standard (AES), defined by FIPS Publication
11 * number 197. The architecture introduces six instructions that
12 * offer full hardware support for AES. Four of them support high
13 * performance data encryption and decryption, and the other two
14 * instructions support the AES key expansion procedure.
15 *
16 * The white paper can be downloaded from:
17 * http://softwarecommunity.intel.com/isn/downloads/intelavx/AES-Instructions-Set_WP.pdf
18 *
19 * This file is based on engines/e_padlock.c
20 */
21
22/* ====================================================================
23 * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved.
24 *
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 *
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 *
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in
34 * the documentation and/or other materials provided with the
35 * distribution.
36 *
37 * 3. All advertising materials mentioning features or use of this
38 * software must display the following acknowledgment:
39 * "This product includes software developed by the OpenSSL Project
40 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
41 *
42 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
43 * endorse or promote products derived from this software without
44 * prior written permission. For written permission, please contact
45 * licensing@OpenSSL.org.
46 *
47 * 5. Products derived from this software may not be called "OpenSSL"
48 * nor may "OpenSSL" appear in their names without prior written
49 * permission of the OpenSSL Project.
50 *
51 * 6. Redistributions of any form whatsoever must retain the following
52 * acknowledgment:
53 * "This product includes software developed by the OpenSSL Project
54 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
55 *
56 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
57 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
59 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
60 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
61 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
62 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
63 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
65 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
66 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
67 * OF THE POSSIBILITY OF SUCH DAMAGE.
68 * ====================================================================
69 *
70 * This product includes cryptographic software written by Eric Young
71 * (eay@cryptsoft.com). This product includes software written by Tim
72 * Hudson (tjh@cryptsoft.com).
73 *
74 */
75
76#include <stdio.h>
77
78#include <openssl/opensslconf.h>
79
80#if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AES_NI) && !defined(OPENSSL_NO_AES)
81
82#include <openssl/aes.h>
83#include <openssl/engine.h>
84#include <openssl/err.h>
85#include <openssl/evp.h>
86
87#include "evp_local.h"
88
89/* AES-NI is available *ONLY* on some x86 CPUs. Not only that it
90 doesn't exist elsewhere, but it even can't be compiled on other
91 platforms! */
92#undef COMPILE_HW_AESNI
93#if (defined(__x86_64) || defined(__x86_64__) || \
94 defined(_M_AMD64) || defined(_M_X64) || \
95 defined(OPENSSL_IA32_SSE2)) && !defined(OPENSSL_NO_ASM) && !defined(__i386__)
96#define COMPILE_HW_AESNI
97#include "x86_arch.h"
98#endif
99static ENGINE *ENGINE_aesni(void);
100
101void ENGINE_load_aesni(void)
102{
103/* On non-x86 CPUs it just returns. */
104#ifdef COMPILE_HW_AESNI
105 ENGINE *toadd = ENGINE_aesni();
106 if (toadd == NULL)
107 return;
108 ENGINE_add(toadd);
109 ENGINE_register_complete(toadd);
110 ENGINE_free(toadd);
111 ERR_clear_error();
112#endif
113}
114
115#ifdef COMPILE_HW_AESNI
116int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
117 AES_KEY *key);
118int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
119 AES_KEY *key);
120
121void aesni_encrypt(const unsigned char *in, unsigned char *out,
122 const AES_KEY *key);
123void aesni_decrypt(const unsigned char *in, unsigned char *out,
124 const AES_KEY *key);
125
126void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out,
127 size_t length, const AES_KEY *key, int enc);
128void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
129 size_t length, const AES_KEY *key, unsigned char *ivec, int enc);
130
131/* Function for ENGINE detection and control */
132static int aesni_init(ENGINE *e);
133
134/* Cipher Stuff */
135static int aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher,
136 const int **nids, int nid);
137
138#define AESNI_MIN_ALIGN 16
139#define AESNI_ALIGN(x) \
140 ((void *)(((unsigned long)(x)+AESNI_MIN_ALIGN-1)&~(AESNI_MIN_ALIGN-1)))
141
142/* Engine names */
143static const char aesni_id[] = "aesni",
144 aesni_name[] = "Intel AES-NI engine",
145 no_aesni_name[] = "Intel AES-NI engine (no-aesni)";
146
147
148/* The input and output encrypted as though 128bit cfb mode is being
149 * used. The extra state information to record how much of the
150 * 128bit block we have used is contained in *num;
151 */
152static void
153aesni_cfb128_encrypt(const unsigned char *in, unsigned char *out,
154 unsigned int len, const void *key, unsigned char ivec[16], int *num,
155 int enc)
156{
157 unsigned int n;
158 size_t l = 0;
159
160 n = *num;
161
162 if (enc) {
163#if !defined(OPENSSL_SMALL_FOOTPRINT)
164 if (16%sizeof(size_t) == 0) do { /* always true actually */
165 while (n && len) {
166 *(out++) = ivec[n] ^= *(in++);
167 --len;
168 n = (n + 1) % 16;
169 }
170 while (len >= 16) {
171 aesni_encrypt(ivec, ivec, key);
172 for (n = 0; n < 16; n += sizeof(size_t)) {
173 *(size_t*)(out + n) =
174 *(size_t*)(ivec + n) ^= *(size_t*)(in + n);
175 }
176 len -= 16;
177 out += 16;
178 in += 16;
179 }
180 n = 0;
181 if (len) {
182 aesni_encrypt(ivec, ivec, key);
183 while (len--) {
184 out[n] = ivec[n] ^= in[n];
185 ++n;
186 }
187 }
188 *num = n;
189 return;
190 } while (0);
191 /* the rest would be commonly eliminated by x86* compiler */
192#endif
193 while (l < len) {
194 if (n == 0) {
195 aesni_encrypt(ivec, ivec, key);
196 }
197 out[l] = ivec[n] ^= in[l];
198 ++l;
199 n = (n + 1) % 16;
200 }
201 *num = n;
202 } else {
203#if !defined(OPENSSL_SMALL_FOOTPRINT)
204 if (16%sizeof(size_t) == 0) do { /* always true actually */
205 while (n && len) {
206 unsigned char c;
207 *(out++) = ivec[n] ^ (c = *(in++));
208 ivec[n] = c;
209 --len;
210 n = (n + 1) % 16;
211 }
212 while (len >= 16) {
213 aesni_encrypt(ivec, ivec, key);
214 for (n = 0; n < 16; n += sizeof(size_t)) {
215 size_t t = *(size_t*)(in + n);
216 *(size_t*)(out + n) = *(size_t*)(ivec + n) ^ t;
217 *(size_t*)(ivec + n) = t;
218 }
219 len -= 16;
220 out += 16;
221 in += 16;
222 }
223 n = 0;
224 if (len) {
225 aesni_encrypt(ivec, ivec, key);
226 while (len--) {
227 unsigned char c;
228 out[n] = ivec[n] ^ (c = in[n]);
229 ivec[n] = c;
230 ++n;
231 }
232 }
233 *num = n;
234 return;
235 } while (0);
236 /* the rest would be commonly eliminated by x86* compiler */
237#endif
238 while (l < len) {
239 unsigned char c;
240 if (n == 0) {
241 aesni_encrypt(ivec, ivec, key);
242 }
243 out[l] = ivec[n] ^ (c = in[l]);
244 ivec[n] = c;
245 ++l;
246 n = (n + 1) % 16;
247 }
248 *num = n;
249 }
250}
251
252/* The input and output encrypted as though 128bit ofb mode is being
253 * used. The extra state information to record how much of the
254 * 128bit block we have used is contained in *num;
255 */
256static void
257aesni_ofb128_encrypt(const unsigned char *in, unsigned char *out,
258 unsigned int len, const void *key, unsigned char ivec[16], int *num)
259{
260 unsigned int n;
261 size_t l = 0;
262
263 n = *num;
264
265#if !defined(OPENSSL_SMALL_FOOTPRINT)
266 if (16%sizeof(size_t) == 0) do { /* always true actually */
267 while (n && len) {
268 *(out++) = *(in++) ^ ivec[n];
269 --len;
270 n = (n + 1) % 16;
271 }
272 while (len >= 16) {
273 aesni_encrypt(ivec, ivec, key);
274 for (n = 0; n < 16; n += sizeof(size_t))
275 *(size_t*)(out + n) =
276 *(size_t*)(in + n) ^ *(size_t*)(ivec + n);
277 len -= 16;
278 out += 16;
279 in += 16;
280 }
281 n = 0;
282 if (len) {
283 aesni_encrypt(ivec, ivec, key);
284 while (len--) {
285 out[n] = in[n] ^ ivec[n];
286 ++n;
287 }
288 }
289 *num = n;
290 return;
291 } while (0);
292 /* the rest would be commonly eliminated by x86* compiler */
293#endif
294 while (l < len) {
295 if (n == 0) {
296 aesni_encrypt(ivec, ivec, key);
297 }
298 out[l] = in[l] ^ ivec[n];
299 ++l;
300 n = (n + 1) % 16;
301 }
302
303 *num = n;
304}
305/* ===== Engine "management" functions ===== */
306
307/* Prepare the ENGINE structure for registration */
308static int
309aesni_bind_helper(ENGINE *e)
310{
311 int engage;
312
313 engage = (OPENSSL_cpu_caps() & CPUCAP_MASK_AESNI) != 0;
314
315 /* Register everything or return with an error */
316 if (!ENGINE_set_id(e, aesni_id) ||
317 !ENGINE_set_name(e, engage ? aesni_name : no_aesni_name) ||
318 !ENGINE_set_init_function(e, aesni_init) ||
319 (engage && !ENGINE_set_ciphers (e, aesni_ciphers)))
320 return 0;
321
322 /* Everything looks good */
323 return 1;
324}
325
326/* Constructor */
327static ENGINE *
328ENGINE_aesni(void)
329{
330 ENGINE *eng = ENGINE_new();
331
332 if (!eng) {
333 return NULL;
334 }
335
336 if (!aesni_bind_helper(eng)) {
337 ENGINE_free(eng);
338 return NULL;
339 }
340
341 return eng;
342}
343
344/* Check availability of the engine */
345static int
346aesni_init(ENGINE *e)
347{
348 return 1;
349}
350
351#if defined(NID_aes_128_cfb128) && ! defined (NID_aes_128_cfb)
352#define NID_aes_128_cfb NID_aes_128_cfb128
353#endif
354
355#if defined(NID_aes_128_ofb128) && ! defined (NID_aes_128_ofb)
356#define NID_aes_128_ofb NID_aes_128_ofb128
357#endif
358
359#if defined(NID_aes_192_cfb128) && ! defined (NID_aes_192_cfb)
360#define NID_aes_192_cfb NID_aes_192_cfb128
361#endif
362
363#if defined(NID_aes_192_ofb128) && ! defined (NID_aes_192_ofb)
364#define NID_aes_192_ofb NID_aes_192_ofb128
365#endif
366
367#if defined(NID_aes_256_cfb128) && ! defined (NID_aes_256_cfb)
368#define NID_aes_256_cfb NID_aes_256_cfb128
369#endif
370
371#if defined(NID_aes_256_ofb128) && ! defined (NID_aes_256_ofb)
372#define NID_aes_256_ofb NID_aes_256_ofb128
373#endif
374
375/* List of supported ciphers. */
376static int aesni_cipher_nids[] = {
377 NID_aes_128_ecb,
378 NID_aes_128_cbc,
379 NID_aes_128_cfb,
380 NID_aes_128_ofb,
381
382 NID_aes_192_ecb,
383 NID_aes_192_cbc,
384 NID_aes_192_cfb,
385 NID_aes_192_ofb,
386
387 NID_aes_256_ecb,
388 NID_aes_256_cbc,
389 NID_aes_256_cfb,
390 NID_aes_256_ofb,
391};
392static int aesni_cipher_nids_num =
393 (sizeof(aesni_cipher_nids) / sizeof(aesni_cipher_nids[0]));
394
395typedef struct {
396 AES_KEY ks;
397 unsigned int _pad1[3];
398} AESNI_KEY;
399
400static int
401aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *user_key,
402 const unsigned char *iv, int enc)
403{
404 int ret;
405 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
406
407 if ((ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_CFB_MODE ||
408 (ctx->cipher->flags & EVP_CIPH_MODE) == EVP_CIPH_OFB_MODE ||
409 enc)
410 ret = aesni_set_encrypt_key(user_key, ctx->key_len * 8, key);
411 else
412 ret = aesni_set_decrypt_key(user_key, ctx->key_len * 8, key);
413
414 if (ret < 0) {
415 EVPerror(EVP_R_AES_KEY_SETUP_FAILED);
416 return 0;
417 }
418
419 return 1;
420}
421
422static int
423aesni_cipher_ecb(EVP_CIPHER_CTX *ctx, unsigned char *out,
424 const unsigned char *in, size_t inl)
425{
426 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
427
428 aesni_ecb_encrypt(in, out, inl, key, ctx->encrypt);
429 return 1;
430}
431
432static int
433aesni_cipher_cbc(EVP_CIPHER_CTX *ctx, unsigned char *out,
434 const unsigned char *in, size_t inl)
435{
436 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
437
438 aesni_cbc_encrypt(in, out, inl, key, ctx->iv, ctx->encrypt);
439 return 1;
440}
441
442static int
443aesni_cipher_cfb(EVP_CIPHER_CTX *ctx, unsigned char *out,
444 const unsigned char *in, size_t inl)
445{
446 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
447
448 aesni_cfb128_encrypt(in, out, inl, key, ctx->iv, &ctx->num,
449 ctx->encrypt);
450 return 1;
451}
452
453static int
454aesni_cipher_ofb(EVP_CIPHER_CTX *ctx, unsigned char *out,
455 const unsigned char *in, size_t inl)
456{
457 AES_KEY *key = AESNI_ALIGN(ctx->cipher_data);
458
459 aesni_ofb128_encrypt(in, out, inl, key, ctx->iv, &ctx->num);
460 return 1;
461}
462
463#define AES_BLOCK_SIZE 16
464
465#define EVP_CIPHER_block_size_ECB AES_BLOCK_SIZE
466#define EVP_CIPHER_block_size_CBC AES_BLOCK_SIZE
467#define EVP_CIPHER_block_size_OFB 1
468#define EVP_CIPHER_block_size_CFB 1
469
470/* Declaring so many ciphers by hand would be a pain.
471 Instead introduce a bit of preprocessor magic :-) */
472#define DECLARE_AES_EVP(ksize,lmode,umode) \
473static const EVP_CIPHER aesni_##ksize##_##lmode = { \
474 NID_aes_##ksize##_##lmode, \
475 EVP_CIPHER_block_size_##umode, \
476 ksize / 8, \
477 AES_BLOCK_SIZE, \
478 0 | EVP_CIPH_##umode##_MODE, \
479 aesni_init_key, \
480 aesni_cipher_##lmode, \
481 NULL, \
482 sizeof(AESNI_KEY), \
483 EVP_CIPHER_set_asn1_iv, \
484 EVP_CIPHER_get_asn1_iv, \
485 NULL, \
486 NULL \
487}
488
489DECLARE_AES_EVP(128, ecb, ECB);
490DECLARE_AES_EVP(128, cbc, CBC);
491DECLARE_AES_EVP(128, cfb, CFB);
492DECLARE_AES_EVP(128, ofb, OFB);
493
494DECLARE_AES_EVP(192, ecb, ECB);
495DECLARE_AES_EVP(192, cbc, CBC);
496DECLARE_AES_EVP(192, cfb, CFB);
497DECLARE_AES_EVP(192, ofb, OFB);
498
499DECLARE_AES_EVP(256, ecb, ECB);
500DECLARE_AES_EVP(256, cbc, CBC);
501DECLARE_AES_EVP(256, cfb, CFB);
502DECLARE_AES_EVP(256, ofb, OFB);
503
504static int
505aesni_ciphers(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid)
506{
507 /* No specific cipher => return a list of supported nids ... */
508 if (!cipher) {
509 *nids = aesni_cipher_nids;
510 return aesni_cipher_nids_num;
511 }
512
513 /* ... or the requested "cipher" otherwise */
514 switch (nid) {
515 case NID_aes_128_ecb:
516 *cipher = &aesni_128_ecb;
517 break;
518 case NID_aes_128_cbc:
519 *cipher = &aesni_128_cbc;
520 break;
521 case NID_aes_128_cfb:
522 *cipher = &aesni_128_cfb;
523 break;
524 case NID_aes_128_ofb:
525 *cipher = &aesni_128_ofb;
526 break;
527
528 case NID_aes_192_ecb:
529 *cipher = &aesni_192_ecb;
530 break;
531 case NID_aes_192_cbc:
532 *cipher = &aesni_192_cbc;
533 break;
534 case NID_aes_192_cfb:
535 *cipher = &aesni_192_cfb;
536 break;
537 case NID_aes_192_ofb:
538 *cipher = &aesni_192_ofb;
539 break;
540
541 case NID_aes_256_ecb:
542 *cipher = &aesni_256_ecb;
543 break;
544 case NID_aes_256_cbc:
545 *cipher = &aesni_256_cbc;
546 break;
547 case NID_aes_256_cfb:
548 *cipher = &aesni_256_cfb;
549 break;
550 case NID_aes_256_ofb:
551 *cipher = &aesni_256_ofb;
552 break;
553
554 default:
555 /* Sorry, we don't support this NID */
556 *cipher = NULL;
557 return 0;
558 }
559 return 1;
560}
561
562#endif /* COMPILE_HW_AESNI */
563#endif /* !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_AESNI) && !defined(OPENSSL_NO_AES) */