diff options
| author | jsing <> | 2025-06-27 17:10:45 +0000 |
|---|---|---|
| committer | jsing <> | 2025-06-27 17:10:45 +0000 |
| commit | abb03e21a8d0fc7f97a871f5aee5a8084176540f (patch) | |
| tree | 8acdb3ab7caf1e6f49b7bf3d7e6a066ca52920a2 /src/lib/libcrypto/aes | |
| parent | c5c4895f860c5e071b09ef5f94bcfae0a51b148e (diff) | |
| download | openbsd-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.c | 53 | ||||
| -rw-r--r-- | src/lib/libcrypto/aes/aes_amd64.c | 20 | ||||
| -rw-r--r-- | src/lib/libcrypto/aes/aes_i386.c | 20 |
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 | ||
| 60 | static const unsigned char aes_wrap_default_iv[] = { | 61 | static 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, | |||
| 171 | LCRYPTO_ALIAS(AES_cfb8_encrypt); | 172 | LCRYPTO_ALIAS(AES_cfb8_encrypt); |
| 172 | 173 | ||
| 173 | void | 174 | void |
| 175 | aes_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 | ||
| 201 | void 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 | ||
| 205 | static inline void | ||
| 206 | aes_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 | |||
| 213 | void | ||
| 214 | aes_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 | |||
| 220 | void | ||
| 174 | AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, | 221 | AES_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 | } |
| 181 | LCRYPTO_ALIAS(AES_ctr128_encrypt); | 228 | LCRYPTO_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, | |||
| 32 | void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, | 32 | void 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 | ||
| 35 | void 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 | |||
| 35 | int aesni_set_encrypt_key(const unsigned char *userKey, int bits, | 38 | int aesni_set_encrypt_key(const unsigned char *userKey, int bits, |
| 36 | AES_KEY *key); | 39 | AES_KEY *key); |
| 37 | int aesni_set_decrypt_key(const unsigned char *userKey, int bits, | 40 | int aesni_set_decrypt_key(const unsigned char *userKey, int bits, |
| @@ -45,6 +48,9 @@ void aesni_decrypt(const unsigned char *in, unsigned char *out, | |||
| 45 | void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, | 48 | void 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 | ||
| 51 | void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, | ||
| 52 | size_t blocks, const void *key, const unsigned char *ivec); | ||
| 53 | |||
| 48 | int | 54 | int |
| 49 | aes_set_encrypt_key_internal(const unsigned char *userKey, const int bits, | 55 | aes_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 | |||
| 110 | void | ||
| 111 | aes_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, | |||
| 32 | void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, | 32 | void 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 | ||
| 35 | void 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 | |||
| 35 | int aesni_set_encrypt_key(const unsigned char *userKey, int bits, | 38 | int aesni_set_encrypt_key(const unsigned char *userKey, int bits, |
| 36 | AES_KEY *key); | 39 | AES_KEY *key); |
| 37 | int aesni_set_decrypt_key(const unsigned char *userKey, int bits, | 40 | int aesni_set_decrypt_key(const unsigned char *userKey, int bits, |
| @@ -45,6 +48,9 @@ void aesni_decrypt(const unsigned char *in, unsigned char *out, | |||
| 45 | void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, | 48 | void 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 | ||
| 51 | void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, | ||
| 52 | size_t blocks, const void *key, const unsigned char *ivec); | ||
| 53 | |||
| 48 | int | 54 | int |
| 49 | aes_set_encrypt_key_internal(const unsigned char *userKey, const int bits, | 55 | aes_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 | |||
| 110 | void | ||
| 111 | aes_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 | } | ||
