summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/aes
diff options
context:
space:
mode:
authorjsing <>2025-06-27 17:10:45 +0000
committerjsing <>2025-06-27 17:10:45 +0000
commitabb03e21a8d0fc7f97a871f5aee5a8084176540f (patch)
tree8acdb3ab7caf1e6f49b7bf3d7e6a066ca52920a2 /src/lib/libcrypto/aes
parentc5c4895f860c5e071b09ef5f94bcfae0a51b148e (diff)
downloadopenbsd-abb03e21a8d0fc7f97a871f5aee5a8084176540f.tar.gz
openbsd-abb03e21a8d0fc7f97a871f5aee5a8084176540f.tar.bz2
openbsd-abb03e21a8d0fc7f97a871f5aee5a8084176540f.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/lib/libcrypto/aes')
-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
3 files changed, 88 insertions, 5 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}