diff options
| author | jsing <> | 2025-07-21 10:24:23 +0000 |
|---|---|---|
| committer | jsing <> | 2025-07-21 10:24:23 +0000 |
| commit | b73facdeca098be7e538e556c1a293942db3110c (patch) | |
| tree | ff569faf5125c023700a2783ef5d648c47c81313 /src/lib/libcrypto/aes | |
| parent | 32c75086555dc2a71cc1500a21b0d024fe48ceaf (diff) | |
| download | openbsd-b73facdeca098be7e538e556c1a293942db3110c.tar.gz openbsd-b73facdeca098be7e538e556c1a293942db3110c.tar.bz2 openbsd-b73facdeca098be7e538e556c1a293942db3110c.zip | |
Move AES-NI from EVP to AES for CCM mode.
The mode implementation for CCM has two variants - one takes the block
function, while the other takes a "ccm64" function. The latter is expected
to handle the lower 64 bits of the IV/counter but only for 16 byte blocks.
The AES-NI implementation for CCM currently uses the second variant.
Provide aes_ccm64_encrypt_internal() as a function that can be replaced on
a machine dependent basis, along with an aes_ccm64_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 EVP's
aes_ccm_cipher() to use CRYPTO_ctr128_{en,de}crypt_ccm64() with
aes_ccm64_encrypt_internal()) and remove the various AES-NI specific
EVP_CIPHER methods for CCM.
ok tb@
Diffstat (limited to 'src/lib/libcrypto/aes')
| -rw-r--r-- | src/lib/libcrypto/aes/aes.c | 70 | ||||
| -rw-r--r-- | src/lib/libcrypto/aes/aes_amd64.c | 30 | ||||
| -rw-r--r-- | src/lib/libcrypto/aes/aes_i386.c | 30 | ||||
| -rw-r--r-- | src/lib/libcrypto/aes/aes_local.h | 10 |
4 files changed, 136 insertions, 4 deletions
diff --git a/src/lib/libcrypto/aes/aes.c b/src/lib/libcrypto/aes/aes.c index cbfb548b3b..33e6273268 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.12 2025/07/20 08:55:49 jsing Exp $ */ | 1 | /* $OpenBSD: aes.c,v 1.13 2025/07/21 10:24:23 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 | * |
| @@ -173,6 +173,74 @@ AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, size_t length, | |||
| 173 | LCRYPTO_ALIAS(AES_cfb8_encrypt); | 173 | LCRYPTO_ALIAS(AES_cfb8_encrypt); |
| 174 | 174 | ||
| 175 | void | 175 | void |
| 176 | aes_ccm64_encrypt_generic(const unsigned char *in, unsigned char *out, | ||
| 177 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 178 | unsigned char cmac[16], int encrypt) | ||
| 179 | { | ||
| 180 | uint8_t iv[AES_BLOCK_SIZE], buf[AES_BLOCK_SIZE]; | ||
| 181 | uint8_t in_mask; | ||
| 182 | uint64_t ctr; | ||
| 183 | int i; | ||
| 184 | |||
| 185 | in_mask = 0 - (encrypt != 0); | ||
| 186 | |||
| 187 | memcpy(iv, ivec, sizeof(iv)); | ||
| 188 | |||
| 189 | ctr = crypto_load_be64toh(&iv[8]); | ||
| 190 | |||
| 191 | while (blocks > 0) { | ||
| 192 | crypto_store_htobe64(&iv[8], ctr); | ||
| 193 | aes_encrypt_internal(iv, buf, key); | ||
| 194 | ctr++; | ||
| 195 | |||
| 196 | for (i = 0; i < 16; i++) { | ||
| 197 | out[i] = in[i] ^ buf[i]; | ||
| 198 | cmac[i] ^= (in[i] & in_mask) | (out[i] & ~in_mask); | ||
| 199 | } | ||
| 200 | |||
| 201 | aes_encrypt_internal(cmac, cmac, key); | ||
| 202 | |||
| 203 | in += 16; | ||
| 204 | out += 16; | ||
| 205 | blocks--; | ||
| 206 | } | ||
| 207 | |||
| 208 | explicit_bzero(buf, sizeof(buf)); | ||
| 209 | explicit_bzero(iv, sizeof(iv)); | ||
| 210 | } | ||
| 211 | |||
| 212 | #ifdef HAVE_AES_CCM64_ENCRYPT_INTERNAL | ||
| 213 | void aes_ccm64_encrypt_internal(const unsigned char *in, unsigned char *out, | ||
| 214 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 215 | unsigned char cmac[16], int encrypt); | ||
| 216 | |||
| 217 | #else | ||
| 218 | static inline void | ||
| 219 | aes_ccm64_encrypt_internal(const unsigned char *in, unsigned char *out, | ||
| 220 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 221 | unsigned char cmac[16], int encrypt) | ||
| 222 | { | ||
| 223 | aes_ccm64_encrypt_generic(in, out, blocks, key, ivec, cmac, encrypt); | ||
| 224 | } | ||
| 225 | #endif | ||
| 226 | |||
| 227 | void | ||
| 228 | aes_ccm64_encrypt_ccm128f(const unsigned char *in, unsigned char *out, | ||
| 229 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 230 | unsigned char cmac[16]) | ||
| 231 | { | ||
| 232 | aes_ccm64_encrypt_internal(in, out, blocks, key, ivec, cmac, 1); | ||
| 233 | } | ||
| 234 | |||
| 235 | void | ||
| 236 | aes_ccm64_decrypt_ccm128f(const unsigned char *in, unsigned char *out, | ||
| 237 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 238 | unsigned char cmac[16]) | ||
| 239 | { | ||
| 240 | aes_ccm64_encrypt_internal(in, out, blocks, key, ivec, cmac, 0); | ||
| 241 | } | ||
| 242 | |||
| 243 | void | ||
| 176 | aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out, | 244 | aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out, |
| 177 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]) | 245 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]) |
| 178 | { | 246 | { |
diff --git a/src/lib/libcrypto/aes/aes_amd64.c b/src/lib/libcrypto/aes/aes_amd64.c index 5a40274675..436983d872 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.3 2025/07/13 06:01:33 jsing Exp $ */ | 1 | /* $OpenBSD: aes_amd64.c,v 1.4 2025/07/21 10:24:23 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2025 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2025 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -33,6 +33,10 @@ void aes_decrypt_generic(const unsigned char *in, unsigned char *out, | |||
| 33 | void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, | 33 | void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, |
| 34 | size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); | 34 | size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); |
| 35 | 35 | ||
| 36 | void aes_ccm64_encrypt_generic(const unsigned char *in, unsigned char *out, | ||
| 37 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 38 | unsigned char cmac[16], int encrypt); | ||
| 39 | |||
| 36 | void aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out, | 40 | void aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out, |
| 37 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]); | 41 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]); |
| 38 | 42 | ||
| @@ -53,6 +57,14 @@ void aesni_decrypt(const unsigned char *in, unsigned char *out, | |||
| 53 | void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, | 57 | void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, |
| 54 | size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); | 58 | size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); |
| 55 | 59 | ||
| 60 | void aesni_ccm64_encrypt_blocks(const unsigned char *in, unsigned char *out, | ||
| 61 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 62 | unsigned char cmac[16]); | ||
| 63 | |||
| 64 | void aesni_ccm64_decrypt_blocks(const unsigned char *in, unsigned char *out, | ||
| 65 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 66 | unsigned char cmac[16]); | ||
| 67 | |||
| 56 | void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, | 68 | void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, |
| 57 | size_t blocks, const void *key, const unsigned char *ivec); | 69 | size_t blocks, const void *key, const unsigned char *ivec); |
| 58 | 70 | ||
| @@ -121,6 +133,22 @@ aes_cbc_encrypt_internal(const unsigned char *in, unsigned char *out, | |||
| 121 | } | 133 | } |
| 122 | 134 | ||
| 123 | void | 135 | void |
| 136 | aes_ccm64_encrypt_internal(const unsigned char *in, unsigned char *out, | ||
| 137 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 138 | unsigned char cmac[16], int encrypt) | ||
| 139 | { | ||
| 140 | if ((crypto_cpu_caps_amd64 & CRYPTO_CPU_CAPS_AMD64_AES) != 0) { | ||
| 141 | if (encrypt) | ||
| 142 | aesni_ccm64_encrypt_blocks(in, out, blocks, key, ivec, cmac); | ||
| 143 | else | ||
| 144 | aesni_ccm64_decrypt_blocks(in, out, blocks, key, ivec, cmac); | ||
| 145 | return; | ||
| 146 | } | ||
| 147 | |||
| 148 | aes_ccm64_encrypt_generic(in, out, blocks, key, ivec, cmac, encrypt); | ||
| 149 | } | ||
| 150 | |||
| 151 | void | ||
| 124 | aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out, | 152 | aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out, |
| 125 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]) | 153 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]) |
| 126 | { | 154 | { |
diff --git a/src/lib/libcrypto/aes/aes_i386.c b/src/lib/libcrypto/aes/aes_i386.c index 73b75d28f5..7f2241eaf5 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.3 2025/07/13 06:01:33 jsing Exp $ */ | 1 | /* $OpenBSD: aes_i386.c,v 1.4 2025/07/21 10:24:23 jsing Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2025 Joel Sing <jsing@openbsd.org> | 3 | * Copyright (c) 2025 Joel Sing <jsing@openbsd.org> |
| 4 | * | 4 | * |
| @@ -33,6 +33,10 @@ void aes_decrypt_generic(const unsigned char *in, unsigned char *out, | |||
| 33 | void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, | 33 | void aes_cbc_encrypt_generic(const unsigned char *in, unsigned char *out, |
| 34 | size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); | 34 | size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); |
| 35 | 35 | ||
| 36 | void aes_ccm64_encrypt_generic(const unsigned char *in, unsigned char *out, | ||
| 37 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 38 | unsigned char cmac[16], int encrypt); | ||
| 39 | |||
| 36 | void aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out, | 40 | void aes_ctr32_encrypt_generic(const unsigned char *in, unsigned char *out, |
| 37 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]); | 41 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]); |
| 38 | 42 | ||
| @@ -53,6 +57,14 @@ void aesni_decrypt(const unsigned char *in, unsigned char *out, | |||
| 53 | void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, | 57 | void aesni_cbc_encrypt(const unsigned char *in, unsigned char *out, |
| 54 | size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); | 58 | size_t len, const AES_KEY *key, unsigned char *ivec, const int enc); |
| 55 | 59 | ||
| 60 | void aesni_ccm64_encrypt_blocks(const unsigned char *in, unsigned char *out, | ||
| 61 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 62 | unsigned char cmac[16]); | ||
| 63 | |||
| 64 | void aesni_ccm64_decrypt_blocks(const unsigned char *in, unsigned char *out, | ||
| 65 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 66 | unsigned char cmac[16]); | ||
| 67 | |||
| 56 | void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, | 68 | void aesni_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, |
| 57 | size_t blocks, const void *key, const unsigned char *ivec); | 69 | size_t blocks, const void *key, const unsigned char *ivec); |
| 58 | 70 | ||
| @@ -121,6 +133,22 @@ aes_cbc_encrypt_internal(const unsigned char *in, unsigned char *out, | |||
| 121 | } | 133 | } |
| 122 | 134 | ||
| 123 | void | 135 | void |
| 136 | aes_ccm64_encrypt_internal(const unsigned char *in, unsigned char *out, | ||
| 137 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 138 | unsigned char cmac[16], int encrypt) | ||
| 139 | { | ||
| 140 | if ((crypto_cpu_caps_i386 & CRYPTO_CPU_CAPS_I386_AES) != 0) { | ||
| 141 | if (encrypt) | ||
| 142 | aesni_ccm64_encrypt_blocks(in, out, blocks, key, ivec, cmac); | ||
| 143 | else | ||
| 144 | aesni_ccm64_decrypt_blocks(in, out, blocks, key, ivec, cmac); | ||
| 145 | return; | ||
| 146 | } | ||
| 147 | |||
| 148 | aes_ccm64_encrypt_generic(in, out, blocks, key, ivec, cmac, encrypt); | ||
| 149 | } | ||
| 150 | |||
| 151 | void | ||
| 124 | aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out, | 152 | aes_ctr32_encrypt_internal(const unsigned char *in, unsigned char *out, |
| 125 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]) | 153 | size_t blocks, const AES_KEY *key, const unsigned char ivec[AES_BLOCK_SIZE]) |
| 126 | { | 154 | { |
diff --git a/src/lib/libcrypto/aes/aes_local.h b/src/lib/libcrypto/aes/aes_local.h index f68d4624e7..539373ea06 100644 --- a/src/lib/libcrypto/aes/aes_local.h +++ b/src/lib/libcrypto/aes/aes_local.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $OpenBSD: aes_local.h,v 1.9 2025/07/13 06:01:33 jsing Exp $ */ | 1 | /* $OpenBSD: aes_local.h,v 1.10 2025/07/21 10:24:23 jsing Exp $ */ |
| 2 | /* ==================================================================== | 2 | /* ==================================================================== |
| 3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. | 3 | * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. |
| 4 | * | 4 | * |
| @@ -66,6 +66,14 @@ __BEGIN_HIDDEN_DECLS | |||
| 66 | void aes_ctr32_encrypt_ctr128f(const unsigned char *in, unsigned char *out, | 66 | void aes_ctr32_encrypt_ctr128f(const unsigned char *in, unsigned char *out, |
| 67 | size_t blocks, const void *key, const unsigned char ivec[AES_BLOCK_SIZE]); | 67 | size_t blocks, const void *key, const unsigned char ivec[AES_BLOCK_SIZE]); |
| 68 | 68 | ||
| 69 | void aes_ccm64_encrypt_ccm128f(const unsigned char *in, unsigned char *out, | ||
| 70 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 71 | unsigned char cmac[16]); | ||
| 72 | |||
| 73 | void aes_ccm64_decrypt_ccm128f(const unsigned char *in, unsigned char *out, | ||
| 74 | size_t blocks, const void *key, const unsigned char ivec[16], | ||
| 75 | unsigned char cmac[16]); | ||
| 76 | |||
| 69 | void aes_ecb_encrypt_internal(const unsigned char *in, unsigned char *out, | 77 | void aes_ecb_encrypt_internal(const unsigned char *in, unsigned char *out, |
| 70 | size_t len, const AES_KEY *key, int encrypt); | 78 | size_t len, const AES_KEY *key, int encrypt); |
| 71 | 79 | ||
