summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2025-06-27 17:10:45 +0000
committerjsing <>2025-06-27 17:10:45 +0000
commit5cdc980054fcaa7078e29884d57b6a7e9e3e6731 (patch)
tree8acdb3ab7caf1e6f49b7bf3d7e6a066ca52920a2 /src
parentb056e8cf614fa516bdb0e53896cad019b9d462d9 (diff)
downloadopenbsd-5cdc980054fcaa7078e29884d57b6a7e9e3e6731.tar.gz
openbsd-5cdc980054fcaa7078e29884d57b6a7e9e3e6731.tar.bz2
openbsd-5cdc980054fcaa7078e29884d57b6a7e9e3e6731.zip
Move AES-NI from EVP to AES for CTR mode.
The mode implementation for CTR has two variants - one takes the block function, while the other takes a "ctr32" function. The latter is expected to handle the lower 32 bits of the IV/counter, but is not expected to handle overflow. The AES-NI implementation for CTR currently uses the second variant. Provide aes_ctr32_encrypt_internal() as a function that can be replaced on a machine dependent basis, along with an aes_ctr32_encrypt_generic() function that provides the default implementation and can be used as a fallback. Wire up the AES-NI version for amd64 and i386, change AES_ctr128_encrypt() to use CRYPTO_ctr128_encrypt_ctr32() (which calls aes_ctr32_encrypt_internal()) and remove the various AES-NI specific EVP_CIPHER methods for CTR. Callers of AES_ctr128_encrypt() will now use AES-NI, if available. ok tb@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/aes/aes.c53
-rw-r--r--src/lib/libcrypto/aes/aes_amd64.c20
-rw-r--r--src/lib/libcrypto/aes/aes_i386.c20
-rw-r--r--src/lib/libcrypto/arch/amd64/crypto_arch.h5
-rw-r--r--src/lib/libcrypto/arch/i386/crypto_arch.h5
-rw-r--r--src/lib/libcrypto/evp/e_aes.c68
6 files changed, 95 insertions, 76 deletions
diff --git a/src/lib/libcrypto/aes/aes.c b/src/lib/libcrypto/aes/aes.c
index e630c3f81a..e9dbe975e3 100644
--- a/src/lib/libcrypto/aes/aes.c
+++ b/src/lib/libcrypto/aes/aes.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: aes.c,v 1.9 2025/06/03 08:42:15 kenjiro Exp $ */ 1/* $OpenBSD: aes.c,v 1.10 2025/06/27 17:10:45 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -56,6 +56,7 @@
56#include <openssl/modes.h> 56#include <openssl/modes.h>
57 57
58#include "crypto_arch.h" 58#include "crypto_arch.h"
59#include "crypto_internal.h"
59 60
60static const unsigned char aes_wrap_default_iv[] = { 61static const unsigned char aes_wrap_default_iv[] = {
61 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 62 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
@@ -171,12 +172,58 @@ AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, size_t length,
171LCRYPTO_ALIAS(AES_cfb8_encrypt); 172LCRYPTO_ALIAS(AES_cfb8_encrypt);
172 173
173void 174void
175aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out,
176 size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE])
177{
178 uint8_t iv[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE];
179 uint32_t ctr;
180 int i;
181
182 memcpy(iv, ivec, sizeof(iv));
183
184 ctr = crypto_load_be32toh(&iv[12]);
185
186 while (blocks > 0) {
187 crypto_store_htobe32(&iv[12], ctr);
188 aes_encrypt_internal(iv, buf, key);
189 ctr++;
190
191 for (i = 0; i < AES_BLOCK_SIZE; i++)
192 out[i] = in[i] ^ buf[i];
193
194 in += 16;
195 out += 16;
196 blocks--;
197 }
198}
199
200#ifdef HAVE_AES_CTR32_ENCRYPT_INTERNAL
201void aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out,
202 size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]);
203
204#else
205static inline void
206aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out,
207 size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE])
208{
209 aes_ctr32_encrypt_generic(in, out, blocks, key, ivec);
210}
211#endif
212
213void
214aes_ctr32_encrypt_ctr128f(const unsigned char *in, unsigned char *out, size_t blocks,
215 const void *key, const unsigned char ivec[AES_BLOCK_SIZE])
216{
217 aes_ctr32_encrypt_internal(in, out, blocks, key, ivec);
218}
219
220void
174AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, 221AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
175 size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE], 222 size_t length, const AES_KEY *key, unsigned char ivec[AES_BLOCK_SIZE],
176 unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num) 223 unsigned char ecount_buf[AES_BLOCK_SIZE], unsigned int *num)
177{ 224{
178 CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, 225 CRYPTO_ctr128_encrypt_ctr32(in, out, length, key, ivec, ecount_buf,
179 aes_encrypt_block128); 226 num, aes_ctr32_encrypt_ctr128f);
180} 227}
181LCRYPTO_ALIAS(AES_ctr128_encrypt); 228LCRYPTO_ALIAS(AES_ctr128_encrypt);
182 229
diff --git a/src/lib/libcrypto/aes/aes_amd64.c b/src/lib/libcrypto/aes/aes_amd64.c
index 302d1ac91d..456409d186 100644
--- a/src/lib/libcrypto/aes/aes_amd64.c
+++ b/src/lib/libcrypto/aes/aes_amd64.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: aes_amd64.c,v 1.1 2025/06/15 15:11:50 jsing Exp $ */ 1/* $OpenBSD: aes_amd64.c,v 1.2 2025/06/27 17:10:45 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2025 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2025 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -32,6 +32,9 @@ void aes_decrypt_generic(const unsigned char *in, unsigned char *out,
32void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, 32void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out,
33 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); 33 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc);
34 34
35void aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out,
36 size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]);
37
35int aesni_set_encrypt_key(const unsigned char *userKey, int bits, 38int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
36 AES_KEY *key); 39 AES_KEY *key);
37int aesni_set_decrypt_key(const unsigned char *userKey, int bits, 40int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
@@ -45,6 +48,9 @@ void aesni_decrypt(const unsigned char *in, unsigned char *out,
45void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, 48void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
46 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); 49 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc);
47 50
51void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
52 size_t blocks, const void *key, const unsigned char *ivec);
53
48int 54int
49aes_set_encrypt_key_internal(const unsigned char *userKey, const int bits, 55aes_set_encrypt_key_internal(const unsigned char *userKey, const int bits,
50 AES_KEY *key) 56 AES_KEY *key)
@@ -100,3 +106,15 @@ aes_cbc_encrypt_internal(const unsigned char *in, unsigned char *out,
100 106
101 aes_cbc_encrypt_generic(in, out, len, key, ivec, enc); 107 aes_cbc_encrypt_generic(in, out, len, key, ivec, enc);
102} 108}
109
110void
111aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out,
112 size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE])
113{
114 if ((crypto_cpu_caps_amd64 & CRYPTO_CPU_CAPS_AMD64_AES) != 0) {
115 aesni_ctr32_encrypt_blocks(in, out, blocks, key, ivec);
116 return;
117 }
118
119 aes_ctr32_encrypt_generic(in, out, blocks, key, ivec);
120}
diff --git a/src/lib/libcrypto/aes/aes_i386.c b/src/lib/libcrypto/aes/aes_i386.c
index 0b5c89af70..2da02a8d35 100644
--- a/src/lib/libcrypto/aes/aes_i386.c
+++ b/src/lib/libcrypto/aes/aes_i386.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: aes_i386.c,v 1.1 2025/06/15 15:11:50 jsing Exp $ */ 1/* $OpenBSD: aes_i386.c,v 1.2 2025/06/27 17:10:45 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2025 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2025 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -32,6 +32,9 @@ void aes_decrypt_generic(const unsigned char *in, unsigned char *out,
32void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, 32void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out,
33 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); 33 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc);
34 34
35void aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out,
36 size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]);
37
35int aesni_set_encrypt_key(const unsigned char *userKey, int bits, 38int aesni_set_encrypt_key(const unsigned char *userKey, int bits,
36 AES_KEY *key); 39 AES_KEY *key);
37int aesni_set_decrypt_key(const unsigned char *userKey, int bits, 40int aesni_set_decrypt_key(const unsigned char *userKey, int bits,
@@ -45,6 +48,9 @@ void aesni_decrypt(const unsigned char *in, unsigned char *out,
45void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, 48void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out,
46 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); 49 size_t len, const AES_KEY *key, unsigned char *ivec, const int enc);
47 50
51void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
52 size_t blocks, const void *key, const unsigned char *ivec);
53
48int 54int
49aes_set_encrypt_key_internal(const unsigned char *userKey, const int bits, 55aes_set_encrypt_key_internal(const unsigned char *userKey, const int bits,
50 AES_KEY *key) 56 AES_KEY *key)
@@ -100,3 +106,15 @@ aes_cbc_encrypt_internal(const unsigned char *in, unsigned char *out,
100 106
101 aes_cbc_encrypt_generic(in, out, len, key, ivec, enc); 107 aes_cbc_encrypt_generic(in, out, len, key, ivec, enc);
102} 108}
109
110void
111aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out,
112 size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE])
113{
114 if ((crypto_cpu_caps_i386 & CRYPTO_CPU_CAPS_I386_AES) != 0) {
115 aesni_ctr32_encrypt_blocks(in, out, blocks, key, ivec);
116 return;
117 }
118
119 aes_ctr32_encrypt_generic(in, out, blocks, key, ivec);
120}
diff --git a/src/lib/libcrypto/arch/amd64/crypto_arch.h b/src/lib/libcrypto/arch/amd64/crypto_arch.h
index da1a22e003..9eb99229d1 100644
--- a/src/lib/libcrypto/arch/amd64/crypto_arch.h
+++ b/src/lib/libcrypto/arch/amd64/crypto_arch.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: crypto_arch.h,v 1.6 2025/06/15 14:16:11 jsing Exp $ */ 1/* $OpenBSD: crypto_arch.h,v 1.7 2025/06/27 17:10:45 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -32,11 +32,12 @@ extern uint64_t crypto_cpu_caps_amd64;
32 32
33#ifndef OPENSSL_NO_ASM 33#ifndef OPENSSL_NO_ASM
34 34
35#define HAVE_AES_CBC_ENCRYPT_INTERNAL
36#define HAVE_AES_SET_ENCRYPT_KEY_INTERNAL 35#define HAVE_AES_SET_ENCRYPT_KEY_INTERNAL
37#define HAVE_AES_SET_DECRYPT_KEY_INTERNAL 36#define HAVE_AES_SET_DECRYPT_KEY_INTERNAL
38#define HAVE_AES_ENCRYPT_INTERNAL 37#define HAVE_AES_ENCRYPT_INTERNAL
39#define HAVE_AES_DECRYPT_INTERNAL 38#define HAVE_AES_DECRYPT_INTERNAL
39#define HAVE_AES_CBC_ENCRYPT_INTERNAL
40#define HAVE_AES_CTR32_ENCRYPT_INTERNAL
40 41
41#define HAVE_RC4_INTERNAL 42#define HAVE_RC4_INTERNAL
42#define HAVE_RC4_SET_KEY_INTERNAL 43#define HAVE_RC4_SET_KEY_INTERNAL
diff --git a/src/lib/libcrypto/arch/i386/crypto_arch.h b/src/lib/libcrypto/arch/i386/crypto_arch.h
index a693bd20d8..e03e6cd765 100644
--- a/src/lib/libcrypto/arch/i386/crypto_arch.h
+++ b/src/lib/libcrypto/arch/i386/crypto_arch.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: crypto_arch.h,v 1.5 2025/06/15 14:18:31 jsing Exp $ */ 1/* $OpenBSD: crypto_arch.h,v 1.6 2025/06/27 17:10:45 jsing Exp $ */
2/* 2/*
3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2024 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -31,11 +31,12 @@ extern uint64_t crypto_cpu_caps_i386;
31 31
32#ifndef OPENSSL_NO_ASM 32#ifndef OPENSSL_NO_ASM
33 33
34#define HAVE_AES_CBC_ENCRYPT_INTERNAL
35#define HAVE_AES_SET_ENCRYPT_KEY_INTERNAL 34#define HAVE_AES_SET_ENCRYPT_KEY_INTERNAL
36#define HAVE_AES_SET_DECRYPT_KEY_INTERNAL 35#define HAVE_AES_SET_DECRYPT_KEY_INTERNAL
37#define HAVE_AES_ENCRYPT_INTERNAL 36#define HAVE_AES_ENCRYPT_INTERNAL
38#define HAVE_AES_DECRYPT_INTERNAL 37#define HAVE_AES_DECRYPT_INTERNAL
38#define HAVE_AES_CBC_ENCRYPT_INTERNAL
39#define HAVE_AES_CTR32_ENCRYPT_INTERNAL
39 40
40#define HAVE_RC4_INTERNAL 41#define HAVE_RC4_INTERNAL
41#define HAVE_RC4_SET_KEY_INTERNAL 42#define HAVE_RC4_SET_KEY_INTERNAL
diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c
index 34f5513300..b00eb048e8 100644
--- a/src/lib/libcrypto/evp/e_aes.c
+++ b/src/lib/libcrypto/evp/e_aes.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: e_aes.c,v 1.75 2025/06/16 14:50:30 jsing Exp $ */ 1/* $OpenBSD: e_aes.c,v 1.76 2025/06/27 17:10:45 jsing Exp $ */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
4 * 4 *
@@ -160,21 +160,6 @@ void aesni_ccm64_decrypt_blocks (const unsigned char *in, unsigned char *out,
160 unsigned char cmac[16]); 160 unsigned char cmac[16]);
161 161
162static int 162static int
163aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
164 const unsigned char *in, size_t len)
165{
166 EVP_AES_KEY *eak = ctx->cipher_data;
167 unsigned int num = ctx->num;
168
169 CRYPTO_ctr128_encrypt_ctr32(in, out, len, &eak->ks, ctx->iv, ctx->buf,
170 &num, aesni_ctr32_encrypt_blocks);
171
172 ctx->num = (size_t)num;
173
174 return 1;
175}
176
177static int
178aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 163aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
179 const unsigned char *in, size_t len) 164 const unsigned char *in, size_t len)
180{ 165{
@@ -562,19 +547,6 @@ EVP_aes_128_cfb8(void)
562} 547}
563LCRYPTO_ALIAS(EVP_aes_128_cfb8); 548LCRYPTO_ALIAS(EVP_aes_128_cfb8);
564 549
565#ifdef AESNI_CAPABLE
566static const EVP_CIPHER aesni_128_ctr = {
567 .nid = NID_aes_128_ctr,
568 .block_size = 1,
569 .key_len = 16,
570 .iv_len = 16,
571 .flags = EVP_CIPH_CTR_MODE,
572 .init = aes_init_key,
573 .do_cipher = aesni_ctr_cipher,
574 .ctx_size = sizeof(EVP_AES_KEY),
575};
576#endif
577
578static const EVP_CIPHER aes_128_ctr = { 550static const EVP_CIPHER aes_128_ctr = {
579 .nid = NID_aes_128_ctr, 551 .nid = NID_aes_128_ctr,
580 .block_size = 1, 552 .block_size = 1,
@@ -589,11 +561,7 @@ static const EVP_CIPHER aes_128_ctr = {
589const EVP_CIPHER * 561const EVP_CIPHER *
590EVP_aes_128_ctr(void) 562EVP_aes_128_ctr(void)
591{ 563{
592#ifdef AESNI_CAPABLE
593 return AESNI_CAPABLE ? &aesni_128_ctr : &aes_128_ctr;
594#else
595 return &aes_128_ctr; 564 return &aes_128_ctr;
596#endif
597} 565}
598LCRYPTO_ALIAS(EVP_aes_128_ctr); 566LCRYPTO_ALIAS(EVP_aes_128_ctr);
599 567
@@ -722,19 +690,6 @@ EVP_aes_192_cfb8(void)
722} 690}
723LCRYPTO_ALIAS(EVP_aes_192_cfb8); 691LCRYPTO_ALIAS(EVP_aes_192_cfb8);
724 692
725#ifdef AESNI_CAPABLE
726static const EVP_CIPHER aesni_192_ctr = {
727 .nid = NID_aes_192_ctr,
728 .block_size = 1,
729 .key_len = 24,
730 .iv_len = 16,
731 .flags = EVP_CIPH_CTR_MODE,
732 .init = aes_init_key,
733 .do_cipher = aesni_ctr_cipher,
734 .ctx_size = sizeof(EVP_AES_KEY),
735};
736#endif
737
738static const EVP_CIPHER aes_192_ctr = { 693static const EVP_CIPHER aes_192_ctr = {
739 .nid = NID_aes_192_ctr, 694 .nid = NID_aes_192_ctr,
740 .block_size = 1, 695 .block_size = 1,
@@ -749,11 +704,7 @@ static const EVP_CIPHER aes_192_ctr = {
749const EVP_CIPHER * 704const EVP_CIPHER *
750EVP_aes_192_ctr(void) 705EVP_aes_192_ctr(void)
751{ 706{
752#ifdef AESNI_CAPABLE
753 return AESNI_CAPABLE ? &aesni_192_ctr : &aes_192_ctr;
754#else
755 return &aes_192_ctr; 707 return &aes_192_ctr;
756#endif
757} 708}
758LCRYPTO_ALIAS(EVP_aes_192_ctr); 709LCRYPTO_ALIAS(EVP_aes_192_ctr);
759 710
@@ -882,19 +833,6 @@ EVP_aes_256_cfb8(void)
882} 833}
883LCRYPTO_ALIAS(EVP_aes_256_cfb8); 834LCRYPTO_ALIAS(EVP_aes_256_cfb8);
884 835
885#ifdef AESNI_CAPABLE
886static const EVP_CIPHER aesni_256_ctr = {
887 .nid = NID_aes_256_ctr,
888 .block_size = 1,
889 .key_len = 32,
890 .iv_len = 16,
891 .flags = EVP_CIPH_CTR_MODE,
892 .init = aes_init_key,
893 .do_cipher = aesni_ctr_cipher,
894 .ctx_size = sizeof(EVP_AES_KEY),
895};
896#endif
897
898static const EVP_CIPHER aes_256_ctr = { 836static const EVP_CIPHER aes_256_ctr = {
899 .nid = NID_aes_256_ctr, 837 .nid = NID_aes_256_ctr,
900 .block_size = 1, 838 .block_size = 1,
@@ -909,11 +847,7 @@ static const EVP_CIPHER aes_256_ctr = {
909const EVP_CIPHER * 847const EVP_CIPHER *
910EVP_aes_256_ctr(void) 848EVP_aes_256_ctr(void)
911{ 849{
912#ifdef AESNI_CAPABLE
913 return AESNI_CAPABLE ? &aesni_256_ctr : &aes_256_ctr;
914#else
915 return &aes_256_ctr; 850 return &aes_256_ctr;
916#endif
917} 851}
918LCRYPTO_ALIAS(EVP_aes_256_ctr); 852LCRYPTO_ALIAS(EVP_aes_256_ctr);
919 853