AES library improvements
Subsystems (26)
Eric Biggers
maintainercover AES library improvements
This series applies to libcrypto-next. It can also be retrieved from:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git aes-lib-v1
This series makes three main improvements to the kernel's AES library:
1. Make it use the kernel's existing architecture-optimized AES code, including AES instructions, when available. Previously, only the traditional crypto API gave access to the optimized AES code. (As a reminder, AES instructions typically make AES over 10 times as fast as the generic code. They also make it constant-time.)
2. Support preparing an AES key for only the forward direction of the block cipher, using about half as much memory. This is a helpful optimization for many common AES modes of operation. It also helps keep structs small enough to be allocated on the stack, especially considering potential future library APIs for AES modes.
3. Replace the library's generic AES implementation with a much faster one that is almost as fast as "aes-generic", while still keeping the table size reasonably small and maintaining some constant-time hardening. This allows removing "aes-generic", unifying the current two generic AES implementations in the kernel tree.
(1) and (2) end up being interrelated: the existing 'struct crypto_aes_ctx' does not work for either one (in general). Thus, this series reworks the AES library to be based around new data types 'struct aes_key' and 'struct aes_enckey'.
As has been the case for other algorithms, to achieve (1) without duplicating the architecture-optimized code, it had to be moved into lib/crypto/ rather than copied. To allow actually removing the arch-specific crypto_cipher "aes" algorithms, a consolidated "aes-lib" crypto_cipher algorithm which simply wraps the library is also added. That's most easily done with it replacing "aes-generic" too, so that is done too. (That's another reason for doing (3) at the same time.)
As usual, care is taken to support all the existing arch-optimized code. This makes it possible for users of the traditional crypto API to switch to the library API, which is generally much easier to use, without being concerned about performance regressions.
That being said, this series only deals with the bare (single-block) AES library. Future patchsets are expected to build on this work to provide architecture-optimized library APIs for specific AES modes of operation.
Eric Biggers (36):
crypto: powerpc/aes - Rename struct aes_key
lib/crypto: aes: Introduce improved AES library
crypto: arm/aes-neonbs - Use AES library for single blocks
crypto: arm/aes - Switch to aes_enc_tab[] and aes_dec_tab[]
crypto: arm64/aes - Switch to aes_enc_tab[] and aes_dec_tab[]
crypto: arm64/aes - Select CRYPTO_LIB_SHA256 from correct places
crypto: aegis - Switch from crypto_ft_tab[] to aes_enc_tab[]
crypto: aes - Remove aes-fixed-time / CONFIG_CRYPTO_AES_TI
crypto: aes - Replace aes-generic with wrapper around lib lib/crypto: arm/aes: Migrate optimized code into library lib/crypto: arm64/aes: Migrate optimized code into library lib/crypto: powerpc/aes: Migrate SPE optimized code into library lib/crypto: powerpc/aes: Migrate POWER8 optimized code into library lib/crypto: riscv/aes: Migrate optimized code into library lib/crypto: s390/aes: Migrate optimized code into library lib/crypto: sparc/aes: Migrate optimized code into library lib/crypto: x86/aes: Add AES-NI optimization
crypto: x86/aes - Remove the superseded AES-NI crypto_cipher
Bluetooth: SMP: Use new AES library API
chelsio: Use new AES library API
net: phy: mscc: macsec: Use new AES library API
staging: rtl8723bs: core: Use new AES library API
crypto: arm/ghash - Use new AES library API
crypto: arm64/ghash - Use new AES library API
crypto: x86/aes-gcm - Use new AES library API
crypto: ccp - Use new AES library API
crypto: chelsio - Use new AES library API
crypto: crypto4xx - Use new AES library API
crypto: drbg - Use new AES library API
crypto: inside-secure - Use new AES library API
crypto: omap - Use new AES library API
lib/crypto: aescfb: Use new AES library API
lib/crypto: aesgcm: Use new AES library API
lib/crypto: aes: Remove old AES en/decryption functions lib/crypto: aes: Drop "_new" suffix from en/decryption functions lib/crypto: aes: Drop 'volatile' from aes_sbox and aes_inv_sbox
arch/arm/configs/milbeaut_m10v_defconfig | 1 -
arch/arm/configs/multi_v7_defconfig | 2 +-
arch/arm/configs/omap2plus_defconfig | 2 +-
arch/arm/configs/pxa_defconfig | 2 +-
arch/arm/crypto/Kconfig | 19 -
arch/arm/crypto/Makefile | 2 -
arch/arm/crypto/aes-cipher-glue.c | 69 -
arch/arm/crypto/aes-cipher.h | 13 -
arch/arm/crypto/aes-neonbs-glue.c | 29 +-
arch/arm/crypto/ghash-ce-glue.c | 14 +-
arch/arm64/crypto/Kconfig | 29 +-
arch/arm64/crypto/Makefile | 6 -
arch/arm64/crypto/aes-ce-ccm-glue.c | 2 -
arch/arm64/crypto/aes-ce-glue.c | 178 ---
arch/arm64/crypto/aes-ce-setkey.h | 6 -
arch/arm64/crypto/aes-cipher-glue.c | 63 -
arch/arm64/crypto/aes-glue.c | 2 -
arch/arm64/crypto/ghash-ce-glue.c | 27 +-
arch/m68k/configs/amiga_defconfig | 1 -
arch/m68k/configs/apollo_defconfig | 1 -
arch/m68k/configs/atari_defconfig | 1 -
arch/m68k/configs/bvme6000_defconfig | 1 -
arch/m68k/configs/hp300_defconfig | 1 -
arch/m68k/configs/mac_defconfig | 1 -
arch/m68k/configs/multi_defconfig | 1 -
arch/m68k/configs/mvme147_defconfig | 1 -
arch/m68k/configs/mvme16x_defconfig | 1 -
arch/m68k/configs/q40_defconfig | 1 -
arch/m68k/configs/sun3_defconfig | 1 -
arch/m68k/configs/sun3x_defconfig | 1 -
arch/powerpc/crypto/Kconfig | 2 +-
arch/powerpc/crypto/Makefile | 9 +-
arch/powerpc/crypto/aes-gcm-p10-glue.c | 4 +-
arch/powerpc/crypto/aes-spe-glue.c | 88 +-
arch/powerpc/crypto/aes.c | 134 --
arch/powerpc/crypto/aes_cbc.c | 4 +-
arch/powerpc/crypto/aes_ctr.c | 2 +-
arch/powerpc/crypto/aes_xts.c | 6 +-
arch/powerpc/crypto/aesp8-ppc.h | 22 -
arch/powerpc/crypto/vmx.c | 10 +-
arch/riscv/crypto/Kconfig | 2 -
arch/riscv/crypto/aes-macros.S | 12 +-
arch/riscv/crypto/aes-riscv64-glue.c | 78 +-
arch/riscv/crypto/aes-riscv64-zvkned.S | 27 -
arch/s390/configs/debug_defconfig | 2 +-
arch/s390/configs/defconfig | 2 +-
arch/s390/crypto/Kconfig | 2 -
arch/s390/crypto/aes_s390.c | 113 --
arch/sparc/crypto/Kconfig | 2 +-
arch/sparc/crypto/Makefile | 2 +-
arch/sparc/crypto/aes_glue.c | 140 +-
arch/x86/crypto/Kconfig | 2 -
arch/x86/crypto/aes-gcm-aesni-x86_64.S | 33 +-
arch/x86/crypto/aes-gcm-vaes-avx2.S | 21 +-
arch/x86/crypto/aes-gcm-vaes-avx512.S | 25 +-
arch/x86/crypto/aesni-intel_asm.S | 25 -
arch/x86/crypto/aesni-intel_glue.c | 119 +-
crypto/Kconfig | 23 +-
crypto/Makefile | 4 +-
crypto/aegis.h | 2 +-
crypto/aes.c | 66 +
crypto/aes_generic.c | 1320 -----------------
crypto/aes_ti.c | 83 --
crypto/crypto_user.c | 2 +-
crypto/df_sp80090a.c | 30 +-
crypto/drbg.c | 12 +-
crypto/testmgr.c | 43 +-
drivers/char/tpm/tpm2-sessions.c | 10 +-
drivers/crypto/amcc/crypto4xx_alg.c | 10 +-
drivers/crypto/ccp/ccp-crypto-aes-cmac.c | 4 +-
drivers/crypto/chelsio/chcr_algo.c | 10 +-
.../crypto/inside-secure/safexcel_cipher.c | 12 +-
drivers/crypto/inside-secure/safexcel_hash.c | 14 +-
drivers/crypto/omap-aes-gcm.c | 6 +-
drivers/crypto/omap-aes.h | 2 +-
drivers/crypto/starfive/jh7110-aes.c | 10 +-
drivers/crypto/xilinx/xilinx-trng.c | 8 +-
.../inline_crypto/ch_ipsec/chcr_ipsec.c | 4 +-
.../chelsio/inline_crypto/ch_ktls/chcr_ktls.c | 8 +-
.../chelsio/inline_crypto/chtls/chtls_hw.c | 4 +-
drivers/net/phy/mscc/mscc_macsec.c | 8 +-
drivers/staging/rtl8723bs/core/rtw_security.c | 20 +-
include/crypto/aes.h | 279 +++-
include/crypto/df_sp80090a.h | 2 +-
include/crypto/gcm.h | 2 +-
lib/crypto/Kconfig | 12 +
lib/crypto/Makefile | 43 +-
lib/crypto/aes.c | 473 ++++--
lib/crypto/aescfb.c | 30 +-
lib/crypto/aesgcm.c | 12 +-
.../crypto/arm}/aes-cipher-core.S | 4 +-
lib/crypto/arm/aes.h | 56 +
.../crypto => lib/crypto/arm64}/aes-ce-core.S | 0
.../crypto/arm64}/aes-cipher-core.S | 4 +-
lib/crypto/arm64/aes.h | 164 ++
lib/crypto/powerpc/.gitignore | 2 +
.../crypto/powerpc}/aes-spe-core.S | 0
.../crypto/powerpc}/aes-spe-keys.S | 0
.../crypto/powerpc}/aes-spe-modes.S | 0
.../crypto/powerpc}/aes-spe-regs.h | 0
.../crypto/powerpc}/aes-tab-4k.S | 0
lib/crypto/powerpc/aes.h | 238 +++
.../crypto/powerpc}/aesp8-ppc.pl | 1 +
lib/crypto/riscv/aes-riscv64-zvkned.S | 84 ++
lib/crypto/riscv/aes.h | 63 +
lib/crypto/s390/aes.h | 106 ++
lib/crypto/sparc/aes.h | 149 ++
.../crypto => lib/crypto/sparc}/aes_asm.S | 0
lib/crypto/x86/aes-aesni.S | 261 ++++
lib/crypto/x86/aes.h | 85 ++
net/bluetooth/smp.c | 8 +-
111 files changed, 2202 insertions(+), 2957 deletions(-)
delete mode 100644 arch/arm/crypto/aes-cipher-glue.c
delete mode 100644 arch/arm/crypto/aes-cipher.h
delete mode 100644 arch/arm64/crypto/aes-ce-glue.c
delete mode 100644 arch/arm64/crypto/aes-ce-setkey.h
delete mode 100644 arch/arm64/crypto/aes-cipher-glue.c
delete mode 100644 arch/powerpc/crypto/aes.c
create mode 100644 crypto/aes.c
delete mode 100644 crypto/aes_generic.c
delete mode 100644 crypto/aes_ti.c
rename {arch/arm/crypto => lib/crypto/arm}/aes-cipher-core.S (97%)
create mode 100644 lib/crypto/arm/aes.h
rename {arch/arm64/crypto => lib/crypto/arm64}/aes-ce-core.S (100%)
rename {arch/arm64/crypto => lib/crypto/arm64}/aes-cipher-core.S (96%)
create mode 100644 lib/crypto/arm64/aes.h
create mode 100644 lib/crypto/powerpc/.gitignore
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-spe-core.S (100%)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-spe-keys.S (100%)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-spe-modes.S (100%)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-spe-regs.h (100%)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-tab-4k.S (100%)
create mode 100644 lib/crypto/powerpc/aes.h
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aesp8-ppc.pl (99%)
create mode 100644 lib/crypto/riscv/aes-riscv64-zvkned.S
create mode 100644 lib/crypto/riscv/aes.h
create mode 100644 lib/crypto/s390/aes.h
create mode 100644 lib/crypto/sparc/aes.h
rename {arch/sparc/crypto => lib/crypto/sparc}/aes_asm.S (100%)
create mode 100644 lib/crypto/x86/aes-aesni.S
create mode 100644 lib/crypto/x86/aes.hbase-commit: e78a3142fa5875126e477fdfe329b0aeb1b0693f
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 1/36 crypto: powerpc/aes - Rename struct aes_key
Rename struct aes_key in aesp8-ppc.h and aes-gcm-p10-glue.c to p8_aes_key and p10_aes_key, respectively. This frees up the name to use in the library API in <crypto/aes.h>.
--- arch/powerpc/crypto/aes-gcm-p10-glue.c | 4 ++-- arch/powerpc/crypto/aes.c | 4 ++-- arch/powerpc/crypto/aes_cbc.c | 4 ++-- arch/powerpc/crypto/aes_ctr.c | 2 +- arch/powerpc/crypto/aes_xts.c | 6 +++--- arch/powerpc/crypto/aesp8-ppc.h | 23 ++++++++++++----------- 6 files changed, 22 insertions(+), 21 deletions(-)
arch/powerpc/crypto/aes-gcm-p10-glue.c +2 -2
@@ -42,11 +42,11 @@ asmlinkage void aes_p10_gcm_decrypt(const u8 *in, u8 *out, size_t len, asmlinkage void gcm_init_htable(unsigned char htable[], unsigned char Xi[]); asmlinkage void gcm_ghash_p10(unsigned char *Xi, unsigned char *Htable,unsigned char *aad,unsigned int alen); asmlinkage void gcm_update(u8 *iv, void *Xi); -struct aes_key { +struct p10_aes_key {u8 key[AES_MAX_KEYLENGTH ];u64 rounds; };struct gcm_ctx {
@@ -61,11 +61,11 @@ struct Hash_ctx {u8 H [16 ];/* subkey */ u8 Htable[256 ];/* Xi, Hash table(offset 32) */ };struct p10_aes_gcm_ctx { -struct aes_key enc_key; +struct p10_aes_key enc_key;u8 nonce[RFC4106_NONCE_SIZE ]; };static void vsx_begin (void ) {
arch/powerpc/crypto/aes.c +2 -2
@@ -19,12 +19,12 @@#include "aesp8-ppc.h" struct p8_aes_ctx {struct crypto_cipher *fallback; -struct aes_key enc_key; -struct aes_key dec_key; +struct p8_aes_key enc_key; +struct p8_aes_key dec_key; };static int p8_aes_init (struct crypto_tfm *tfm) {const char *alg =crypto_tfm_alg_name (tfm);
arch/powerpc/crypto/aes_cbc.c +2 -2
@@ -19,12 +19,12 @@#include "aesp8-ppc.h" struct p8_aes_cbc_ctx {struct crypto_skcipher *fallback; -struct aes_key enc_key; -struct aes_key dec_key; +struct p8_aes_key enc_key; +struct p8_aes_key dec_key; };static int p8_aes_cbc_init (struct crypto_skcipher *tfm) {struct p8_aes_cbc_ctx *ctx =crypto_skcipher_ctx (tfm);
arch/powerpc/crypto/aes_ctr.c +1 -1
@@ -19,11 +19,11 @@#include "aesp8-ppc.h" struct p8_aes_ctr_ctx {struct crypto_skcipher *fallback; -struct aes_key enc_key; +struct p8_aes_key enc_key; };static int p8_aes_ctr_init (struct crypto_skcipher *tfm) {struct p8_aes_ctr_ctx *ctx =crypto_skcipher_ctx (tfm);
arch/powerpc/crypto/aes_xts.c +3 -3
@@ -20,13 +20,13 @@#include "aesp8-ppc.h" struct p8_aes_xts_ctx {struct crypto_skcipher *fallback; -struct aes_key enc_key; -struct aes_key dec_key; -struct aes_key tweak_key; +struct p8_aes_key enc_key; +struct p8_aes_key dec_key; +struct p8_aes_key tweak_key; };static int p8_aes_xts_init (struct crypto_skcipher *tfm) {struct p8_aes_xts_ctx *ctx =crypto_skcipher_ctx (tfm);
arch/powerpc/crypto/aesp8-ppc.h +12 -11
@@ -1,10 +1,10 @@/* SPDX-License-Identifier: GPL-2.0 */ #include <linux/types.h> #include <crypto/aes.h> -struct aes_key { +struct p8_aes_key {u8 key[AES_MAX_KEYLENGTH ];int rounds; };extern struct shash_alg p8_ghash_alg;
@@ -12,19 +12,20 @@ extern struct crypto_alg p8_aes_alg;extern struct skcipher_alg p8_aes_cbc_alg;extern struct skcipher_alg p8_aes_ctr_alg;extern struct skcipher_alg p8_aes_xts_alg;int aes_p8_set_encrypt_key (const u8 *userKey,const int bits, -struct aes_key *key); +struct p8_aes_key *key);int aes_p8_set_decrypt_key (const u8 *userKey,const int bits, -struct aes_key *key); -void aes_p8_encrypt (const u8 *in,u8 *out,const struct aes_key *key); -void aes_p8_decrypt (const u8 *in,u8 *out,const struct aes_key *key); +struct p8_aes_key *key); +void aes_p8_encrypt (const u8 *in,u8 *out,const struct p8_aes_key *key); +void aes_p8_decrypt (const u8 *in,u8 *out,const struct p8_aes_key *key);void aes_p8_cbc_encrypt (const u8 *in,u8 *out,size_t len, -const struct aes_key *key,u8 *iv,const int enc); -void aes_p8_ctr32_encrypt_blocks (const u8 *in,u8 *out, -size_t len,const struct aes_key *key, -const u8 *iv); +const struct p8_aes_key *key,u8 *iv,const int enc); +void aes_p8_ctr32_encrypt_blocks (const u8 *in,u8 *out,size_t len, +const struct p8_aes_key *key,const u8 *iv);void aes_p8_xts_encrypt (const u8 *in,u8 *out,size_t len, -const struct aes_key *key1,const struct aes_key *key2,u8 *iv); +const struct p8_aes_key *key1, +const struct p8_aes_key *key2,u8 *iv);void aes_p8_xts_decrypt (const u8 *in,u8 *out,size_t len, -const struct aes_key *key1,const struct aes_key *key2,u8 *iv); +const struct p8_aes_key *key1, +const struct p8_aes_key *key2,u8 *iv);
base-commit: e78a3142fa5875126e477fdfe329b0aeb1b0693f
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 2/36 lib/crypto: aes: Introduce improved AES library
In reply to Eric BiggersThe kernel's AES library currently has the following issues:
- It doesn't take advantage of the architecture-optimized AES code, including the implementations using AES instructions.
- It's much slower than even the other software AES implementations: 2-4 times slower than "aes-generic", "aes-arm", and "aes-arm64".
- It requires that both the encryption and decryption round keys be computed and cached. This is wasteful for users that need only the forward (encryption) direction of the cipher: the key struct is 484 bytes when only 244 are actually needed. This missed optimization is very common, as many AES modes (e.g. GCM, CFB, CTR, CMAC, and even the tweak key in XTS) use the cipher only in the forward (encryption) direction even when doing decryption.
- It doesn't provide the flexibility to customize the prepared key format. The API is defined to do key expansion, and several callers in drivers/crypto/ use it specifically to expand the key. This is an issue when integrating the existing powerpc, s390, and sparc code, which is necessary to provide full parity with the traditional API.
To resolve these issues, I'm proposing the following changes:
1. New structs 'aes_key' and 'aes_enckey' are introduced, with corresponding functions aes_preparekey() and aes_prepareenckey().
Generally these structs will include the encryption+decryption round keys and the encryption round keys, respectively. However, the exact format will be under control of the architecture-specific AES code.
(The verb "prepare" is chosen over "expand" since key expansion isn't necessarily done. It's also consistent with hmac*_preparekey().)
2. aes_encrypt() and aes_decrypt() will be changed to operate on the new structs instead of struct crypto_aes_ctx.
3. aes_encrypt() and aes_decrypt() will use architecture-optimized code when available, or else fall back to a new generic AES implementation that unifies the existing two fragmented generic AES implementations.
The new generic AES implementation uses tables for both SubBytes and MixColumns, making it almost as fast as "aes-generic". However, instead of aes-generic's huge 8192-byte tables per direction, it uses only 1024 bytes for encryption and 1280 bytes for decryption (similar to "aes-arm"). The cost is just some extra rotations.
The new generic AES implementation also includes table prefetching, making it have some "constant-time hardening". That's an improvement from aes-generic which has no constant-time hardening.
It does slightly regress in constant-time hardening vs. the old lib/crypto/aes.c which had smaller tables, and from aes-fixed-time which disabled IRQs on top of that. But I think this is tolerable. The real solutions for constant-time AES are AES instructions or bit-slicing. The table-based code remains a best-effort fallback for the increasingly-rare case where a real solution is unavailable.
4. crypto_aes_ctx and aes_expandkey() will remain for now, but only for callers that are using them specifically for the AES key expansion (as opposed to en/decrypting data with the AES library).
This commit begins the migration process by introducing the new structs and functions, backed by the new generic AES implementation.
To allow callers to be incrementally converted, the new en/decryption functions are introduced alongside the existing ones and under new
names: aes_encrypt_new() and aes_decrypt_new(). Of course, after all callers have been updated, the original aes_encrypt() and aes_decrypt() will be removed and the new functions will take their names.
--- include/crypto/aes.h | 138 +++++++++++++++- lib/crypto/Kconfig | 4 + lib/crypto/Makefile | 11 +- lib/crypto/aes.c | 379 ++++++++++++++++++++++++++++++++++++++----- 4 files changed, 488 insertions(+), 44 deletions(-)
include/crypto/aes.h +137 -1
@@ -16,10 +16,64 @@#define AES_KEYSIZE_256 32#define AES_BLOCK_SIZE 16#define AES_MAX_KEYLENGTH (15 * 16)#define AES_MAX_KEYLENGTH_U32 (AES_MAX_KEYLENGTH / sizeof(u32)) +union aes_enckey_arch { +u32 rndkeys[AES_MAX_KEYLENGTH_U32 ]; +}; + +union aes_invkey_arch { +u32 inv_rndkeys[AES_MAX_KEYLENGTH_U32 ]; +}; + +/** +* struct aes_enckey - An AES key prepared for encryption +* @len: Key length in bytes: 16 for AES-128, 24 for AES-192, 32 for AES-256. +* @nrounds: Number of rounds: 10 for AES-128, 12 for AES-192, 14 for AES-256. +* This is '6 + @len / 4' and is cached so that AES implementations +* that need it don't have to recompute it for each en/decryption. +* @padding: Padding to make offsetof(@k) be a multiple of 16, so that aligning +* this struct to a 16-byte boundary results in @k also being 16-byte +* aligned. Users aren't required to align this struct to 16 bytes, +* but it may slightly improve performance. +* @k: This typically contains the AES round keys as an array of '@nrounds + 1' +* groups of four u32 words. However, architecture-specific implementations +* of AES may store something else here, e.g. just the raw key if it's all +* they need. +* +* Note that this struct is about half the size of struct aes_key. This is +* separate from struct aes_key so that modes that need only AES encryption +* (e.g. AES-GCM, AES-CTR, AES-CMAC, tweak key in AES-XTS) don't incur the time +* and space overhead of computing and caching the decryption round keys. +* +* Note that there's no decryption-only equivalent (i.e. "struct aes_deckey"), +* since (a) it's rare that modes need decryption-only, and (b) some AES +* implementations use the same @k for both encryption and decryption, either +* always or conditionally; in the latter case both @k and @inv_k are needed. +*/ +struct aes_enckey { +u32 len; +u32 nrounds; +u32 padding[2 ]; +union aes_enckey_arch k; +}; + +/** +* struct aes_key - An AES key prepared for encryption and decryption +* @aes_enckey: Common fields and the key prepared for encryption +* @inv_k: This generally contains the round keys for the AES Equivalent +* Inverse Cipher, as an array of '@nrounds + 1' groups of four u32 +* words. However, architecture-specific implementations of AES may +* store something else here. For example, they may leave this field +* uninitialized if they use @k for both encryption and decryption. +*/ +struct aes_key { +struct aes_enckey ;/* Include all fields of aes_enckey. */ +union aes_invkey_arch inv_k; +}; +/* * Please ensure that the first two fields are 16-byte aligned * relative to the start of the structure, i.e., don't move them! */ struct crypto_aes_ctx {
@@ -32,11 +86,11 @@ extern const u32 crypto_ft_tab[4][256] ____cacheline_aligned;extern const u32 crypto_it_tab[4 ][256 ]____cacheline_aligned ;/* * validate key length for AES algorithms */ -static inline int aes_check_keylen (unsigned int keylen) +static inline int aes_check_keylen (size_t keylen) {switch (keylen) {case AES_KEYSIZE_128 :case AES_KEYSIZE_192 :case AES_KEYSIZE_256 :
@@ -66,10 +120,62 @@ int crypto_aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,* for the initial combination, the second slot for the first round and so on. */ int aes_expandkey (struct crypto_aes_ctx *ctx,const u8 *in_key,unsigned int key_len); +/** +* aes_preparekey() - Prepare an AES key for encryption and decryption +* @key: (output) The key structure to initialize +* @in_key: The raw AES key +* @key_len: Length of the raw key in bytes. Should be either AES_KEYSIZE_128, +* AES_KEYSIZE_192, or AES_KEYSIZE_256. +* +* This prepares an AES key for both the encryption and decryption directions of +* the block cipher. Typically this involves expanding the raw key into both +* the standard round keys and the Equivalent Inverse Cipher round keys, but +* some architecture-specific implementations don't do the full expansion here. +* +* The caller is responsible for zeroizing both the struct aes_key and the raw +* key once they are no longer needed. +* +* If you don't need decryption support, use aes_prepareenckey() instead. +* +* Return: 0 on success or -EINVAL if the given key length is invalid. No other +* errors are possible, so callers that always pass a valid key length +* don't need to check for errors. +* +* Context: Any context. +*/ +int aes_preparekey (struct aes_key *key,const u8 *in_key,size_t key_len); + +/** +* aes_prepareenckey() - Prepare an AES key for encryption-only +* @enc_key: (output) The key structure to initialize +* @in_key: The raw AES key +* @key_len: Length of the raw key in bytes. Should be either AES_KEYSIZE_128, +* AES_KEYSIZE_192, or AES_KEYSIZE_256. +* +* This prepares an AES key for only the encryption direction of the block +* cipher. Typically this involves expanding the raw key into only the standard +* round keys, resulting in a struct about half the size of struct aes_key. +* +* The caller is responsible for zeroizing both the struct aes_enckey and the +* raw key once they are no longer needed. +* +* Note that while the resulting prepared key supports only AES encryption, it +* can still be used for decrypting in a mode of operation that uses AES in only +* the encryption (forward) direction, for example counter mode. +* +* Return: 0 on success or -EINVAL if the given key length is invalid. No other +* errors are possible, so callers that always pass a valid key length +* don't need to check for errors. +* +* Context: Any context. +*/ +int aes_prepareenckey (struct aes_enckey *enc_key, +const u8 *in_key,size_t key_len); +/** * aes_encrypt - Encrypt a single AES block * @ctx: Context struct containing the key schedule * @out: Buffer to store the ciphertext * @in: Buffer containing the plaintext
@@ -82,12 +188,42 @@ void aes_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in);* @out: Buffer to store the plaintext * @in: Buffer containing the ciphertext */ void aes_decrypt (const struct crypto_aes_ctx *ctx,u8 *out,const u8 *in); +typedef union { +const struct aes_enckey *enc_key; +const struct aes_key *full_key; +}aes_encrypt_arg __attribute__ ((__transparent_union__)); + +/** +* aes_encrypt_new() - Encrypt a single AES block +* @key: The AES key, as a pointer to either an encryption-only key +* (struct aes_enckey) or a full, bidirectional key (struct aes_key). +* @out: Buffer to store the ciphertext block +* @in: Buffer containing the plaintext block +* +* Context: Any context. +*/ +void aes_encrypt_new(aes_encrypt_arg key, u8 out[at_least AES_BLOCK_SIZE], + const u8 in[at_least AES_BLOCK_SIZE]); + +/** +* aes_decrypt_new() - Decrypt a single AES block +* @key: The AES key, previously initialized by aes_preparekey() +* @out: Buffer to store the plaintext block +* @in: Buffer containing the ciphertext block +* +* Context: Any context. +*/ +void aes_decrypt_new(const struct aes_key *key, u8 out[at_least AES_BLOCK_SIZE], + const u8 in[at_least AES_BLOCK_SIZE]); +extern const u8 crypto_aes_sbox[];extern const u8 crypto_aes_inv_sbox[]; +extern const u32 __cacheline_aligned aes_enc_tab[256]; +extern const u32 __cacheline_aligned aes_dec_tab[256];void aescfb_encrypt (const struct crypto_aes_ctx *ctx,u8 *dst,const u8 *src,int len,const u8 iv[AES_BLOCK_SIZE ]);void aescfb_decrypt (const struct crypto_aes_ctx *ctx,u8 *dst,const u8 *src,int len,const u8 iv[AES_BLOCK_SIZE ]);
lib/crypto/Kconfig +4 -0
@@ -9,10 +9,14 @@ config CRYPTO_LIB_UTILS tristate config CRYPTO_LIB_AES tristate +config CRYPTO_LIB_AES_ARCH + bool + depends on CRYPTO_LIB_AES && !UML && !KMSAN + config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/Makefile +9 -2
@@ -13,12 +13,19 @@ obj-$(CONFIG_KUNIT) += tests/ obj-$(CONFIG_CRYPTO_HASH_INFO) += hash_info.o obj-$(CONFIG_CRYPTO_LIB_UTILS) += libcryptoutils.o libcryptoutils-y := memneq.o utils.o -obj-$(CONFIG_CRYPTO_LIB_AES) += libaes.o -libaes-y := aes.o +################################################################################ + +obj-$(CONFIG_CRYPTO_LIB_AES) += libaes.o +libaes-y := aes.o +ifeq ($(CONFIG_CRYPTO_LIB_AES_ARCH),y) +CFLAGS_aes.o += -I$(src)/$(SRCARCH) +endif # CONFIG_CRYPTO_LIB_AES_ARCH + +################################################################################ obj-$(CONFIG_CRYPTO_LIB_AESCFB) += libaescfb.o libaescfb-y := aescfb.o obj-$(CONFIG_CRYPTO_LIB_AESGCM) += libaesgcm.o
lib/crypto/aes.c +338 -41
446 lines not on this page · raw message
Signature · 1 line
2.52.0
Re: [PATCH 02/36] lib/crypto: aes: Introduce improved AES library
include/crypto/aes.h void aes_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); · line 224
Quoted 4 lines · Eric Biggers
extern const u8 crypto_aes_sbox[];
extern const u8 crypto_aes_inv_sbox[];include/crypto/aes.h +2
-0+extern const u32 __cacheline_aligned aes_enc_tab[256]; +extern const u32 __cacheline_aligned aes_dec_tab[256];
__cacheline_aligned puts the array in ".data..cacheline_aligned" section. As a const array, it should be in ".rodata" section, so ____cacheline_aligned (note the extra underscores) should be used instead.
You can also apply the same to crypto_aes_sbox and crypto_aes_inv_sbox while at it.
Regards,
Qingfang
Eric Biggers
maintainerRe: [PATCH 02/36] lib/crypto: aes: Introduce improved AES library
Quoted 13 lines · Qingfang Deng
include/crypto/aes.h void aes_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); · line 224
Quoted 4 lines · Eric Biggers
extern const u8 crypto_aes_sbox[];
extern const u8 crypto_aes_inv_sbox[];include/crypto/aes.h +2
-0+extern const u32 __cacheline_aligned aes_enc_tab[256]; +extern const u32 __cacheline_aligned aes_dec_tab[256];
__cacheline_alignedputs the array in ".data..cacheline_aligned" section. As a const array, it should be in ".rodata" section, so____cacheline_aligned(note the extra underscores) should be used instead.
You can also apply the same tocrypto_aes_sboxandcrypto_aes_inv_sboxwhile at it.
Quoted 2 lines
Regards,
Qingfang
Good catch! So the result is that MMU protection isn't applied to the const data as intended.
I guess I'll change these to the four-underscore ____cacheline_aligned.
Though, I'm tempted to instead just do __aligned(SMP_CACHE_BYTES), to stay well away from this footgun.
- Eric
Eric Biggers
maintainerPATCH 3/36 crypto: arm/aes-neonbs - Use AES library for single blocks
In reply to Eric Biggersaes-neonbs-glue.c calls __aes_arm_encrypt() and __aes_arm_decrypt() to en/decrypt single blocks for CBC encryption, XTS tweak encryption, and XTS ciphertext stealing. In preparation for making the AES library use this same ARM-optimized single-block AES en/decryption code and making it an internal implementation detail of the AES library, replace the calls to these functions with calls to the AES library.
Note that this reduces the size of the aesbs_cbc_ctx and aesbs_xts_ctx structs, since unnecessary decryption round keys are no longer included.
--- arch/arm/crypto/Kconfig | 1 - arch/arm/crypto/aes-neonbs-glue.c | 29 ++++++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-)
arch/arm/crypto/Kconfig +0 -1
@@ -42,11 +42,10 @@ config CRYPTO_AES_ARM such attacks very difficult. config CRYPTO_AES_ARM_BS tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (bit-sliced NEON)" depends on KERNEL_MODE_NEON - select CRYPTO_AES_ARM select CRYPTO_SKCIPHER select CRYPTO_LIB_AES help Length-preserving ciphers: AES cipher algorithms (FIPS-197) with block cipher modes:
arch/arm/crypto/aes-neonbs-glue.c +16 -13
@@ -10,11 +10,10 @@#include <crypto/aes.h> #include <crypto/internal/skcipher.h> #include <crypto/scatterwalk.h> #include <crypto/xts.h> #include <linux/module.h> -#include "aes-cipher.h" MODULE_AUTHOR ("Ard Biesheuvel <[email protected]>" );MODULE_DESCRIPTION ("Bit sliced AES using NEON instructions" );MODULE_LICENSE ("GPL v2" );
@@ -46,17 +45,17 @@ struct aesbs_ctx {u8 rk[13 * (8 *AES_BLOCK_SIZE ) +32 ]__aligned(AES_BLOCK_SIZE) ; };struct aesbs_cbc_ctx {struct aesbs_ctx key; -struct crypto_aes_ctx fallback; +struct aes_enckey fallback; };struct aesbs_xts_ctx {struct aesbs_ctx key; -struct crypto_aes_ctx fallback; -struct crypto_aes_ctx tweak_key; +struct aes_key fallback; +struct aes_enckey tweak_key; };static int aesbs_setkey (struct crypto_skcipher *tfm,const u8 *in_key,unsigned int key_len) {
@@ -120,18 +119,23 @@ static int aesbs_cbc_setkey(struct crypto_skcipher *tfm, const u8 *in_key, unsigned int key_len) {struct aesbs_cbc_ctx *ctx =crypto_skcipher_ctx (tfm);int err; - err =aes_expandkey (&ctx->fallback, in_key, key_len); + err =aes_prepareenckey (&ctx->fallback, in_key, key_len);if (err)return err; ctx->key.rounds =6 + key_len /4 ; +/* +* Note: this assumes that the arm implementation of the AES library +* stores the standard round keys in k.rndkeys. +*/ kernel_neon_begin (); -aesbs_convert_key (ctx->key.rk, ctx->fallback.key_enc, ctx->key.rounds); +aesbs_convert_key (ctx->key.rk, ctx->fallback.k.rndkeys, + ctx->key.rounds);kernel_neon_end ();return 0 ; }
@@ -150,12 +154,11 @@ static int cbc_encrypt(struct skcipher_request *req)u8 *dst = walk.dst.virt.addr;u8 *prev = walk.iv;do {crypto_xor_cpy (dst, src, prev,AES_BLOCK_SIZE ); -__aes_arm_encrypt (ctx->fallback.key_enc, - ctx->key.rounds, dst, dst); +aes_encrypt_new (&ctx->fallback, dst, dst); prev = dst; src +=AES_BLOCK_SIZE ; dst +=AES_BLOCK_SIZE ; nbytes -=AES_BLOCK_SIZE ; }while (nbytes >=AES_BLOCK_SIZE );
@@ -237,14 +240,14 @@ static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key, err =xts_verify_key (tfm, in_key, key_len);if (err)return err; key_len /=2 ; - err =aes_expandkey (&ctx->fallback, in_key, key_len); + err =aes_preparekey (&ctx->fallback, in_key, key_len);if (err)return err; - err =aes_expandkey (&ctx->tweak_key, in_key + key_len, key_len); + err =aes_prepareenckey (&ctx->tweak_key, in_key + key_len, key_len);if (err)return err;return aesbs_setkey (tfm, in_key, key_len); }
@@ -277,11 +280,11 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt, err =skcipher_walk_virt (&walk, req, true);if (err)return err; -__aes_arm_encrypt (ctx->tweak_key.key_enc, rounds, walk.iv, walk.iv); +aes_encrypt_new (&ctx->tweak_key, walk.iv, walk.iv);while (walk.nbytes >=AES_BLOCK_SIZE ) {unsigned int blocks = walk.nbytes /AES_BLOCK_SIZE ;int reorder_last_tweak = !encrypt && tail >0 ;
@@ -309,13 +312,13 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt,scatterwalk_map_and_copy (buf, req->src, req->cryptlen, tail,0 );crypto_xor (buf, req->iv,AES_BLOCK_SIZE );if (encrypt) -__aes_arm_encrypt (ctx->fallback.key_enc, rounds, buf, buf); +aes_encrypt_new (&ctx->fallback, buf, buf);else -__aes_arm_decrypt (ctx->fallback.key_dec, rounds, buf, buf); +aes_decrypt_new (&ctx->fallback, buf, buf);crypto_xor (buf, req->iv,AES_BLOCK_SIZE );scatterwalk_map_and_copy (buf, req->dst, req->cryptlen -AES_BLOCK_SIZE ,AES_BLOCK_SIZE + tail,1 );
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 4/36 crypto: arm/aes - Switch to aes_enc_tab[] and aes_dec_tab[]
In reply to Eric BiggersInstead of crypto_ft_tab and crypto_it_tab from aes_generic.c, use aes_enc_tab and aes_dec_tab from lib/crypto/aes.c. These contain the same data in the first 1024 bytes (which is the part that this code uses), so the result is the same. This will allow aes_generic.c to eventually be removed.
--- arch/arm/crypto/aes-cipher-core.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm/crypto/aes-cipher-core.S +2 -2
@@ -190,12 +190,12 @@ .align 3 .ltorg .endm ENTRY(__aes_arm_encrypt) - do_crypt fround, crypto_ft_tab,, 2 + do_crypt fround, aes_enc_tab,, 2 ENDPROC(__aes_arm_encrypt) .align 5 ENTRY(__aes_arm_decrypt) - do_crypt iround, crypto_it_tab, crypto_aes_inv_sbox, 0 + do_crypt iround, aes_dec_tab, crypto_aes_inv_sbox, 0 ENDPROC(__aes_arm_decrypt)
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 5/36 crypto: arm64/aes - Switch to aes_enc_tab[] and aes_dec_tab[]
In reply to Eric BiggersInstead of crypto_ft_tab and crypto_it_tab from aes_generic.c, use aes_enc_tab and aes_dec_tab from lib/crypto/aes.c. These contain the same data in the first 1024 bytes (which is the part that this code uses), so the result is the same. This will allow aes_generic.c to eventually be removed.
--- arch/arm64/crypto/aes-cipher-core.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/crypto/aes-cipher-core.S +2 -2
@@ -121,12 +121,12 @@ CPU_BE( rev w7, w7 ) stp w6, w7, [out, #8] ret .endm SYM_FUNC_START(__aes_arm64_encrypt) - do_crypt fround, crypto_ft_tab, crypto_ft_tab + 1, 2 + do_crypt fround, aes_enc_tab, aes_enc_tab + 1, 2 SYM_FUNC_END(__aes_arm64_encrypt) .align 5 SYM_FUNC_START(__aes_arm64_decrypt) - do_crypt iround, crypto_it_tab, crypto_aes_inv_sbox, 0 + do_crypt iround, aes_dec_tab, crypto_aes_inv_sbox, 0 SYM_FUNC_END(__aes_arm64_decrypt)
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 6/36 crypto: arm64/aes - Select CRYPTO_LIB_SHA256 from correct places
In reply to Eric BiggersThe call to sha256() occurs in code that is built when either CRYPTO_AES_ARM64_CE_BLK or CRYPTO_AES_ARM64_NEON_BLK. The option CRYPTO_AES_ARM64 is unrelated, notwithstanding its documentation. I'll be removing CRYPTO_AES_ARM64 soon anyway, but before doing that, fix where CRYPTO_LIB_SHA256 is selected from.
--- arch/arm64/crypto/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/crypto/Kconfig +2 -1
@@ -38,11 +38,10 @@ config CRYPTO_SM3_ARM64_CE - ARMv8.2 Crypto Extensions config CRYPTO_AES_ARM64 tristate "Ciphers: AES, modes: ECB, CBC, CTR, CTS, XCTR, XTS" select CRYPTO_AES - select CRYPTO_LIB_SHA256 help Block ciphers: AES cipher algorithms (FIPS-197) Length-preserving ciphers: AES with ECB, CBC, CTR, CTS, XCTR, and XTS modes AEAD cipher: AES with CBC, ESSIV, and SHA-256
@@ -64,10 +63,11 @@ config CRYPTO_AES_ARM64_CE config CRYPTO_AES_ARM64_CE_BLK tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (ARMv8 Crypto Extensions)" depends on KERNEL_MODE_NEON select CRYPTO_SKCIPHER select CRYPTO_AES_ARM64_CE + select CRYPTO_LIB_SHA256 help Length-preserving ciphers: AES cipher algorithms (FIPS-197) with block cipher modes: - ECB (Electronic Codebook) mode (NIST SP800-38A) - CBC (Cipher Block Chaining) mode (NIST SP800-38A)
@@ -81,10 +81,11 @@ config CRYPTO_AES_ARM64_CE_BLK config CRYPTO_AES_ARM64_NEON_BLK tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (NEON)" depends on KERNEL_MODE_NEON select CRYPTO_SKCIPHER select CRYPTO_LIB_AES + select CRYPTO_LIB_SHA256 help Length-preserving ciphers: AES cipher algorithms (FIPS-197) with block cipher modes: - ECB (Electronic Codebook) mode (NIST SP800-38A) - CBC (Cipher Block Chaining) mode (NIST SP800-38A)
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 7/36 crypto: aegis - Switch from crypto_ft_tab[] to aes_enc_tab[]
In reply to Eric BiggersInstead of crypto_ft_tab[0] from aes_generic.c, use aes_enc_tab from lib/crypto/aes.c. These contain the same data, so the result is the same. This will allow aes_generic.c to eventually be removed.
--- crypto/Kconfig | 2 +- crypto/aegis.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
crypto/Kconfig +1 -1
@@ -764,11 +764,11 @@ endmenu menu "AEAD (authenticated encryption with associated data) ciphers" config CRYPTO_AEGIS128 tristate "AEGIS-128" select CRYPTO_AEAD - select CRYPTO_AES # for AES S-box tables + select CRYPTO_LIB_AES # for AES S-box tables help AEGIS-128 AEAD algorithm config CRYPTO_AEGIS128_SIMD bool "AEGIS-128 (arm NEON, arm64 NEON)"
crypto/aegis.h +1 -1
@@ -60,11 +60,11 @@ static __always_inline void crypto_aegis_block_and(union aegis_block *dst, static __always_inline void crypto_aegis_aesenc(union aegis_block *dst,const union aegis_block *src,const union aegis_block *key) {const u8 *s = src->bytes; -const u32 *t = crypto_ft_tab[0 ]; +const u32 *t = aes_enc_tab;u32 d0, d1, d2, d3; d0 = t[s[0 ]] ^rol32 (t[s[5 ]],8 ) ^rol32 (t[s[10 ]],16 ) ^rol32 (t[s[15 ]],24 ); d1 = t[s[4 ]] ^rol32 (t[s[9 ]],8 ) ^rol32 (t[s[14 ]],16 ) ^rol32 (t[s[3 ]],24 ); d2 = t[s[8 ]] ^rol32 (t[s[13 ]],8 ) ^rol32 (t[s[2 ]],16 ) ^rol32 (t[s[7 ]],24 );
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 8/36 crypto: aes - Remove aes-fixed-time / CONFIG_CRYPTO_AES_TI
In reply to Eric BiggersRemove aes-fixed-time, i.e. CONFIG_CRYPTO_AES_TI. This was a wrapper around the 256-byte-table-based AES implementation in lib/crypto/aes.c, with extra code to enable and disable IRQs for constant-time hardening.
While nice in theory, in practice this had the following issues:
- For bulk en/decryption it was 2-4 times slower than aes-generic. This resulted in aes-generic still being needed, creating fragmentation.
- Having both aes-generic and aes-fixed-time punted an AES implementation decision to distros and users who are generally unprepared to handle it. In practice, whether aes-fixed-time gets used tends to be incidental and not match an explicit distro or user intent. (While aes-fixed-time has a higher priority than aes-generic, whether it actually gets enabled, loaded, and used depends on the kconfig and whether a modprobe of "aes" happens to be done. It also has a lower priority than aes-arm and aes-arm64.)
- My changes to the generic AES code (in other commits) significantly close the gap with aes-fixed-time anyway. The table size is reduced from 8192 bytes to 1024 bytes, and prefetching is added.
- While AES code *should* be constant-time, the real solutions for that are AES instructions (which most CPUs have now) or bit-slicing. arm and arm64 already have bit-sliced AES code for many modes; generic bit-sliced code could be written but would be very slow for single blocks. Overall, I suggest that trying to write constant-time table-based AES code is a bit futile anyway, and in the rare cases where a proper AES implementation is still unavailable it's reasonable to compromise with an implementation that simply prefetches the table.
Thus, this commit removes aes-fixed-time and CONFIG_CRYPTO_AES_TI. The replacement is just the existing CONFIG_CRYPTO_AES, which for now maps to the existing aes-generic code, but I'll soon be changing to use the improved AES library code instead.
--- arch/m68k/configs/amiga_defconfig | 1 - arch/m68k/configs/apollo_defconfig | 1 - arch/m68k/configs/atari_defconfig | 1 - arch/m68k/configs/bvme6000_defconfig | 1 - arch/m68k/configs/hp300_defconfig | 1 - arch/m68k/configs/mac_defconfig | 1 - arch/m68k/configs/multi_defconfig | 1 - arch/m68k/configs/mvme147_defconfig | 1 - arch/m68k/configs/mvme16x_defconfig | 1 - arch/m68k/configs/q40_defconfig | 1 - arch/m68k/configs/sun3_defconfig | 1 - arch/m68k/configs/sun3x_defconfig | 1 - arch/s390/configs/debug_defconfig | 2 +- arch/s390/configs/defconfig | 2 +- crypto/Kconfig | 21 ------- crypto/Makefile | 1 - crypto/aes_ti.c | 83 ---------------------------- 17 files changed, 2 insertions(+), 119 deletions(-) delete mode 100644 crypto/aes_ti.c
arch/m68k/configs/amiga_defconfig +0 -1
@@ -553,11 +553,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/apollo_defconfig +0 -1
@@ -510,11 +510,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/atari_defconfig +0 -1
@@ -530,11 +530,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/bvme6000_defconfig +0 -1
@@ -502,11 +502,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/hp300_defconfig +0 -1
@@ -512,11 +512,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/mac_defconfig +0 -1
@@ -529,11 +529,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/multi_defconfig +0 -1
@@ -616,11 +616,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/mvme147_defconfig +0 -1
@@ -502,11 +502,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/mvme16x_defconfig +0 -1
@@ -503,11 +503,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/q40_defconfig +0 -1
@@ -519,11 +519,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/sun3_defconfig +0 -1
@@ -500,11 +500,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/m68k/configs/sun3x_defconfig +0 -1
@@ -500,11 +500,10 @@ CONFIG_CRYPTO_RSA=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_AES=y -CONFIG_CRYPTO_AES_TI=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAMELLIA=m CONFIG_CRYPTO_CAST5=m
arch/s390/configs/debug_defconfig +1 -1
@@ -768,11 +768,11 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_BENCHMARK=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m
arch/s390/configs/defconfig +1 -1
@@ -752,11 +752,11 @@ CONFIG_CRYPTO_CRYPTD=m CONFIG_CRYPTO_BENCHMARK=m CONFIG_CRYPTO_DH=m CONFIG_CRYPTO_ECDH=m CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m -CONFIG_CRYPTO_AES_TI=m +CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_ARIA=m CONFIG_CRYPTO_BLOWFISH=m CONFIG_CRYPTO_CAST5=m CONFIG_CRYPTO_CAST6=m
crypto/Kconfig +0 -21
@@ -364,31 +364,10 @@ config CRYPTO_AES demonstrates excellent performance. Rijndael's operations are among the easiest to defend against power and timing attacks. The AES specifies three key sizes: 128, 192 and 256 bits -config CRYPTO_AES_TI - tristate "AES (Advanced Encryption Standard) (fixed time)" - select CRYPTO_ALGAPI - select CRYPTO_LIB_AES - help - AES cipher algorithms (Rijndael)(FIPS-197, ISO/IEC 18033-3) - - This is a generic implementation of AES that attempts to eliminate - data dependent latencies as much as possible without affecting - performance too much. It is intended for use by the generic CCM - and GCM drivers, and other CTR or CMAC/XCBC based modes that rely - solely on encryption (although decryption is supported as well, but - with a more dramatic performance hit) - - Instead of using 16 lookup tables of 1 KB each, (8 for encryption and - 8 for decryption), this implementation only uses just two S-boxes of - 256 bytes each, and attempts to eliminate data dependent latencies by - prefetching the entire table into the cache at the start of each - block. Interrupts are also disabled to avoid races where cachelines - are evicted when the CPU is interrupted to do something else. - config CRYPTO_ANUBIS tristate "Anubis" depends on CRYPTO_USER_API_ENABLE_OBSOLETE select CRYPTO_ALGAPI help
crypto/Makefile +0 -1
@@ -132,11 +132,10 @@ obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o CFLAGS_serpent_generic.o := $(call cc-option,-fsched-pressure) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149 obj-$(CONFIG_CRYPTO_AES) += aes_generic.o CFLAGS_aes_generic.o := $(call cc-option,-fno-code-hoisting) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83356 obj-$(CONFIG_CRYPTO_SM4) += sm4.o obj-$(CONFIG_CRYPTO_SM4_GENERIC) += sm4_generic.o -obj-$(CONFIG_CRYPTO_AES_TI) += aes_ti.o obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o obj-$(CONFIG_CRYPTO_CAST_COMMON) += cast_common.o obj-$(CONFIG_CRYPTO_CAST5) += cast5_generic.o obj-$(CONFIG_CRYPTO_CAST6) += cast6_generic.o obj-$(CONFIG_CRYPTO_ARC4) += arc4.o
crypto/aes_ti.c deleted +0 -83
83 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 9/36 crypto: aes - Replace aes-generic with wrapper around lib
In reply to Eric BiggersNow that the AES library's performance has been improved, replace aes_generic.c with a new file aes.c which wraps the AES library.
In preparation for making the AES library actually utilize the kernel's existing architecture-optimized AES code including AES instructions, set the driver name to "aes-lib" instead of "aes-generic". This mirrors what's been done for the hash algorithms. Update testmgr.c accordingly.
Since this removes the crypto_aes_set_key() helper function, add temporary replacements for it to arch/arm/crypto/aes-cipher-glue.c and arch/arm64/crypto/aes-cipher-glue.c. This is temporary, as that code will be migrated into lib/crypto/ in later commits.
--- arch/arm/crypto/aes-cipher-glue.c | 10 +- arch/arm64/crypto/aes-cipher-glue.c | 10 +- crypto/Makefile | 3 +- crypto/aes.c | 66 ++ crypto/aes_generic.c | 1320 -------------------------- crypto/crypto_user.c | 2 +- crypto/testmgr.c | 43 +- drivers/crypto/starfive/jh7110-aes.c | 10 +- include/crypto/aes.h | 6 - 9 files changed, 117 insertions(+), 1353 deletions(-) create mode 100644 crypto/aes.c delete mode 100644 crypto/aes_generic.c
arch/arm/crypto/aes-cipher-glue.c +9 -1
@@ -12,10 +12,18 @@#include "aes-cipher.h" EXPORT_SYMBOL_GPL (__aes_arm_encrypt);EXPORT_SYMBOL_GPL (__aes_arm_decrypt); +static int aes_arm_setkey (struct crypto_tfm *tfm,const u8 *in_key, +unsigned int key_len) +{ +struct crypto_aes_ctx *ctx =crypto_tfm_ctx (tfm); + +return aes_expandkey (ctx, in_key, key_len); +} +static void aes_arm_encrypt (struct crypto_tfm *tfm,u8 *out,const u8 *in) {struct crypto_aes_ctx *ctx =crypto_tfm_ctx (tfm);int rounds =6 + ctx->key_length /4 ;
@@ -39,11 +47,11 @@ static struct crypto_alg aes_alg = { .cra_ctxsize = sizeof(struct crypto_aes_ctx), .cra_module = THIS_MODULE, .cra_cipher.cia_min_keysize = AES_MIN_KEY_SIZE, .cra_cipher.cia_max_keysize = AES_MAX_KEY_SIZE, - .cra_cipher.cia_setkey = crypto_aes_set_key, + .cra_cipher.cia_setkey = aes_arm_setkey, .cra_cipher.cia_encrypt = aes_arm_encrypt, .cra_cipher.cia_decrypt = aes_arm_decrypt, #ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS .cra_alignmask = 3,
arch/arm64/crypto/aes-cipher-glue.c +9 -1
@@ -10,10 +10,18 @@#include <linux/module.h> asmlinkage void __aes_arm64_encrypt(u32 *rk, u8 *out, const u8 *in, int rounds); asmlinkage void __aes_arm64_decrypt(u32 *rk, u8 *out, const u8 *in, int rounds); +static int aes_arm64_setkey (struct crypto_tfm *tfm,const u8 *in_key, +unsigned int key_len) +{ +struct crypto_aes_ctx *ctx =crypto_tfm_ctx (tfm); + +return aes_expandkey (ctx, in_key, key_len); +} +static void aes_arm64_encrypt (struct crypto_tfm *tfm,u8 *out,const u8 *in) {struct crypto_aes_ctx *ctx =crypto_tfm_ctx (tfm);int rounds =6 + ctx->key_length /4 ;
@@ -37,11 +45,11 @@ static struct crypto_alg aes_alg = { .cra_ctxsize = sizeof(struct crypto_aes_ctx), .cra_module = THIS_MODULE, .cra_cipher.cia_min_keysize = AES_MIN_KEY_SIZE, .cra_cipher.cia_max_keysize = AES_MAX_KEY_SIZE, - .cra_cipher.cia_setkey = crypto_aes_set_key, + .cra_cipher.cia_setkey = aes_arm64_setkey, .cra_cipher.cia_encrypt = aes_arm64_encrypt, .cra_cipher.cia_decrypt = aes_arm64_decrypt };static int __init aes_init (void )
crypto/Makefile +1 -2
@@ -128,12 +128,11 @@ obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish_generic.o obj-$(CONFIG_CRYPTO_BLOWFISH_COMMON) += blowfish_common.o obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o obj-$(CONFIG_CRYPTO_SERPENT) += serpent_generic.o CFLAGS_serpent_generic.o := $(call cc-option,-fsched-pressure) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79149 -obj-$(CONFIG_CRYPTO_AES) += aes_generic.o -CFLAGS_aes_generic.o := $(call cc-option,-fno-code-hoisting) # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=83356 +obj-$(CONFIG_CRYPTO_AES) += aes.o obj-$(CONFIG_CRYPTO_SM4) += sm4.o obj-$(CONFIG_CRYPTO_SM4_GENERIC) += sm4_generic.o obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia_generic.o obj-$(CONFIG_CRYPTO_CAST_COMMON) += cast_common.o obj-$(CONFIG_CRYPTO_CAST5) += cast5_generic.o
crypto/aes.c new file +66 -0
66 lines not on this page · raw message
crypto/aes_generic.c deleted +0 -1320
1,320 lines not on this page · raw message
crypto/crypto_user.c +1 -1
@@ -291,11 +291,11 @@ static int crypto_del_alg(struct sk_buff *skb, struct nlmsghdr *nlh, alg =crypto_alg_match (p,1 );if (!alg)return -ENOENT ; -/* We can not unregister core algorithms such as aes-generic. +/* We can not unregister core algorithms such as aes. * We would loose the reference in the crypto_alg_list to this algorithm * if we try to unregister. Unregistering such an algorithm without * removing the module is not possible, so we restrict to crypto * instances that are build from templates. */ err = -EINVAL ;
crypto/testmgr.c +26 -17
292 lines not on this page · raw message
drivers/crypto/starfive/jh7110-aes.c +5 -5
@@ -981,31 +981,31 @@ static int starfive_aes_ccm_decrypt(struct aead_request *req)return starfive_aes_aead_crypt (req,STARFIVE_AES_MODE_CCM ); }static int starfive_aes_ecb_init_tfm (struct crypto_skcipher *tfm) { -return starfive_aes_init_tfm (tfm,"ecb(aes-generic)" ); +return starfive_aes_init_tfm (tfm,"ecb(aes-lib)" ); }static int starfive_aes_cbc_init_tfm (struct crypto_skcipher *tfm) { -return starfive_aes_init_tfm (tfm,"cbc(aes-generic)" ); +return starfive_aes_init_tfm (tfm,"cbc(aes-lib)" ); }static int starfive_aes_ctr_init_tfm (struct crypto_skcipher *tfm) { -return starfive_aes_init_tfm (tfm,"ctr(aes-generic)" ); +return starfive_aes_init_tfm (tfm,"ctr(aes-lib)" ); }static int starfive_aes_ccm_init_tfm (struct crypto_aead *tfm) { -return starfive_aes_aead_init_tfm (tfm,"ccm_base(ctr(aes-generic),cbcmac(aes-generic))" ); +return starfive_aes_aead_init_tfm (tfm,"ccm_base(ctr(aes-lib),cbcmac(aes-lib))" ); }static int starfive_aes_gcm_init_tfm (struct crypto_aead *tfm) { -return starfive_aes_aead_init_tfm (tfm,"gcm_base(ctr(aes-generic),ghash-generic)" ); +return starfive_aes_aead_init_tfm (tfm,"gcm_base(ctr(aes-lib),ghash-generic)" ); }static struct skcipher_engine_alg skcipher_algs[] = { { .base.init = starfive_aes_ecb_init_tfm,
include/crypto/aes.h +0 -6
@@ -80,13 +80,10 @@ struct crypto_aes_ctx {u32 key_enc[AES_MAX_KEYLENGTH_U32 ];u32 key_dec[AES_MAX_KEYLENGTH_U32 ];u32 key_length; }; -extern const u32 crypto_ft_tab[4 ][256 ]____cacheline_aligned ; -extern const u32 crypto_it_tab[4 ][256 ]____cacheline_aligned ; -/* * validate key length for AES algorithms */ static inline int aes_check_keylen (size_t keylen) {
@@ -100,13 +97,10 @@ static inline int aes_check_keylen(size_t keylen) }return 0 ; } -int crypto_aes_set_key (struct crypto_tfm *tfm,const u8 *in_key, -unsigned int key_len); -/** * aes_expandkey - Expands the AES key as described in FIPS-197 * @ctx: The location where the computed key will be stored. * @in_key: The supplied key. * @key_len: The length of the supplied key.
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 10/36 lib/crypto: arm/aes: Migrate optimized code into library
In reply to Eric BiggersMove the ARM optimized single-block AES en/decryption code into lib/crypto/, wire it up to the AES library API, and remove the superseded "aes-arm" crypto_cipher algorithm.
The result is that both the AES library and crypto_cipher APIs are now optimized for ARM, whereas previously only crypto_cipher was (and the optimizations weren't enabled by default, which this fixes as well).
---
arch/arm/configs/milbeaut_m10v_defconfig | 1 -
arch/arm/configs/multi_v7_defconfig | 2 +-
arch/arm/configs/omap2plus_defconfig | 2 +-
arch/arm/configs/pxa_defconfig | 2 +-
arch/arm/crypto/Kconfig | 18 -----
arch/arm/crypto/Makefile | 2 -
arch/arm/crypto/aes-cipher-glue.c | 77 -------------------
arch/arm/crypto/aes-cipher.h | 13 ----
lib/crypto/Kconfig | 1 +
lib/crypto/Makefile | 3 +
.../crypto/arm}/aes-cipher-core.S | 0
lib/crypto/arm/aes.h | 56 ++++++++++++++
12 files changed, 63 insertions(+), 114 deletions(-)
delete mode 100644 arch/arm/crypto/aes-cipher-glue.c
delete mode 100644 arch/arm/crypto/aes-cipher.h
rename {arch/arm/crypto => lib/crypto/arm}/aes-cipher-core.S (100%)
create mode 100644 lib/crypto/arm/aes.harch/arm/configs/milbeaut_m10v_defconfig +0 -1
@@ -96,11 +96,10 @@ CONFIG_KEYS=y CONFIG_CRYPTO_SELFTESTS=y # CONFIG_CRYPTO_ECHAINIV is not set CONFIG_CRYPTO_AES=y CONFIG_CRYPTO_SEQIV=m CONFIG_CRYPTO_GHASH_ARM_CE=m -CONFIG_CRYPTO_AES_ARM=m CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRYPTO_AES_ARM_CE=m # CONFIG_CRYPTO_HW is not set CONFIG_DMA_CMA=y CONFIG_CMA_SIZE_MBYTES=64
arch/arm/configs/multi_v7_defconfig +1 -1
@@ -1284,11 +1284,11 @@ CONFIG_CRYPTO_USER=m CONFIG_CRYPTO_USER_API_HASH=m CONFIG_CRYPTO_USER_API_SKCIPHER=m CONFIG_CRYPTO_USER_API_RNG=m CONFIG_CRYPTO_USER_API_AEAD=m CONFIG_CRYPTO_GHASH_ARM_CE=m -CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRYPTO_AES_ARM_CE=m CONFIG_CRYPTO_DEV_SUN4I_SS=m CONFIG_CRYPTO_DEV_FSL_CAAM=m CONFIG_CRYPTO_DEV_EXYNOS_RNG=m
arch/arm/configs/omap2plus_defconfig +1 -1
@@ -704,11 +704,11 @@ CONFIG_ROOT_NFS=y CONFIG_NLS_CODEPAGE_437=y CONFIG_NLS_ISO8859_1=y CONFIG_SECURITY=y CONFIG_CRYPTO_MICHAEL_MIC=y CONFIG_CRYPTO_GHASH_ARM_CE=m -CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES=m CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRYPTO_DEV_OMAP=m CONFIG_CRYPTO_DEV_OMAP_SHAM=m CONFIG_CRYPTO_DEV_OMAP_AES=m CONFIG_CRYPTO_DEV_OMAP_DES=m
arch/arm/configs/pxa_defconfig +1 -1
@@ -655,11 +655,11 @@ CONFIG_CRYPTO_TGR192=m CONFIG_CRYPTO_WP512=m CONFIG_CRYPTO_ANUBIS=m CONFIG_CRYPTO_XCBC=m CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_AES_ARM=m +CONFIG_CRYPTO_AES=m CONFIG_FONTS=y CONFIG_FONT_8x8=y CONFIG_FONT_8x16=y CONFIG_FONT_6x11=y CONFIG_FONT_MINI_4x6=y
arch/arm/crypto/Kconfig +0 -18
@@ -21,28 +21,10 @@ config CRYPTO_GHASH_ARM_CE Use an implementation of GHASH (used by the GCM AEAD chaining mode) that uses the 64x64 to 128 bit polynomial multiplication (vmull.p64) that is part of the ARMv8 Crypto Extensions, or a slower variant that uses the vmull.p8 instruction that is part of the basic NEON ISA. -config CRYPTO_AES_ARM - tristate "Ciphers: AES" - select CRYPTO_ALGAPI - select CRYPTO_AES - help - Block ciphers: AES cipher algorithms (FIPS-197) - - Architecture: arm - - On ARM processors without the Crypto Extensions, this is the - fastest AES implementation for single blocks. For multiple - blocks, the NEON bit-sliced implementation is usually faster. - - This implementation may be vulnerable to cache timing attacks, - since it uses lookup tables. However, as countermeasures it - disables IRQs and preloads the tables; it is hoped this makes - such attacks very difficult. - config CRYPTO_AES_ARM_BS tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (bit-sliced NEON)" depends on KERNEL_MODE_NEON select CRYPTO_SKCIPHER select CRYPTO_LIB_AES
arch/arm/crypto/Makefile +0 -2
@@ -1,15 +1,13 @@ # SPDX-License-Identifier: GPL-2.0 # # Arch-specific CryptoAPI modules. # -obj-$(CONFIG_CRYPTO_AES_ARM) += aes-arm.o obj-$(CONFIG_CRYPTO_AES_ARM_BS) += aes-arm-bs.o obj-$(CONFIG_CRYPTO_AES_ARM_CE) += aes-arm-ce.o obj-$(CONFIG_CRYPTO_GHASH_ARM_CE) += ghash-arm-ce.o -aes-arm-y := aes-cipher-core.o aes-cipher-glue.o aes-arm-bs-y := aes-neonbs-core.o aes-neonbs-glue.o aes-arm-ce-y := aes-ce-core.o aes-ce-glue.o ghash-arm-ce-y := ghash-ce-core.o ghash-ce-glue.o
arch/arm/crypto/aes-cipher-glue.c deleted +0 -77
77 lines not on this page · raw message
arch/arm/crypto/aes-cipher.h deleted +0 -13
@@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef ARM_CRYPTO_AES_CIPHER_H -#define ARM_CRYPTO_AES_CIPHER_H - -#include <linux/linkage.h> -#include <linux/types.h> - -asmlinkage void __aes_arm_encrypt(const u32 rk[], int rounds, -const u8 *in,u8 *out); -asmlinkage void __aes_arm_decrypt(const u32 rk[], int rounds, -const u8 *in,u8 *out); - -#endif /* ARM_CRYPTO_AES_CIPHER_H */
lib/crypto/Kconfig +1 -0
@@ -12,10 +12,11 @@ config CRYPTO_LIB_AES tristate config CRYPTO_LIB_AES_ARCH bool depends on CRYPTO_LIB_AES && !UML && !KMSAN + default y if ARM config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/Makefile +3 -0
@@ -19,10 +19,13 @@ libcryptoutils-y := memneq.o utils.o obj-$(CONFIG_CRYPTO_LIB_AES) += libaes.o libaes-y := aes.o ifeq ($(CONFIG_CRYPTO_LIB_AES_ARCH),y) CFLAGS_aes.o += -I$(src)/$(SRCARCH) + +libaes-$(CONFIG_ARM) += arm/aes-cipher-core.o + endif # CONFIG_CRYPTO_LIB_AES_ARCH ################################################################################ obj-$(CONFIG_CRYPTO_LIB_AESCFB) += libaescfb.o
lib/crypto/arm/aes-cipher-core.S renamed from arch/arm/crypto/aes-cipher-core.S +0 -0
lib/crypto/arm/aes.h new file +56 -0
56 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 11/36 lib/crypto: arm64/aes: Migrate optimized code into library
In reply to Eric BiggersMove the ARM64 optimized AES key expansion and single-block AES en/decryption code into lib/crypto/, wire it up to the AES library API, and remove the superseded crypto_cipher algorithms.
The result is that both the AES library and crypto_cipher APIs are now optimized for ARM64, whereas previously only crypto_cipher was (and the optimizations weren't enabled by default, which this fixes as well).
Note: to see the diff from arch/arm64/crypto/aes-ce-glue.c to lib/crypto/arm64/aes.h, view this commit with 'git show -M10'.
---
arch/arm64/crypto/Kconfig | 26 +--
arch/arm64/crypto/Makefile | 6 -
arch/arm64/crypto/aes-ce-ccm-glue.c | 2 -
arch/arm64/crypto/aes-ce-glue.c | 178 ------------------
arch/arm64/crypto/aes-ce-setkey.h | 6 -
arch/arm64/crypto/aes-cipher-glue.c | 71 -------
arch/arm64/crypto/aes-glue.c | 2 -
include/crypto/aes.h | 10 +
lib/crypto/Kconfig | 1 +
lib/crypto/Makefile | 5 +
.../crypto => lib/crypto/arm64}/aes-ce-core.S | 0
.../crypto/arm64}/aes-cipher-core.S | 0
lib/crypto/arm64/aes.h | 164 ++++++++++++++++
13 files changed, 181 insertions(+), 290 deletions(-)
delete mode 100644 arch/arm64/crypto/aes-ce-glue.c
delete mode 100644 arch/arm64/crypto/aes-ce-setkey.h
delete mode 100644 arch/arm64/crypto/aes-cipher-glue.c
rename {arch/arm64/crypto => lib/crypto/arm64}/aes-ce-core.S (100%)
rename {arch/arm64/crypto => lib/crypto/arm64}/aes-cipher-core.S (100%)
create mode 100644 lib/crypto/arm64/aes.harch/arm64/crypto/Kconfig +1 -25
@@ -35,38 +35,15 @@ config CRYPTO_SM3_ARM64_CE SM3 (ShangMi 3) secure hash function (OSCCA GM/T 0004-2012) Architecture: arm64 using: - ARMv8.2 Crypto Extensions -config CRYPTO_AES_ARM64 - tristate "Ciphers: AES, modes: ECB, CBC, CTR, CTS, XCTR, XTS" - select CRYPTO_AES - help - Block ciphers: AES cipher algorithms (FIPS-197) - Length-preserving ciphers: AES with ECB, CBC, CTR, CTS, - XCTR, and XTS modes - AEAD cipher: AES with CBC, ESSIV, and SHA-256 - for fscrypt and dm-crypt - - Architecture: arm64 - -config CRYPTO_AES_ARM64_CE - tristate "Ciphers: AES (ARMv8 Crypto Extensions)" - depends on KERNEL_MODE_NEON - select CRYPTO_ALGAPI - select CRYPTO_LIB_AES - help - Block ciphers: AES cipher algorithms (FIPS-197) - - Architecture: arm64 using: - - ARMv8 Crypto Extensions - config CRYPTO_AES_ARM64_CE_BLK tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (ARMv8 Crypto Extensions)" depends on KERNEL_MODE_NEON select CRYPTO_SKCIPHER - select CRYPTO_AES_ARM64_CE + select CRYPTO_LIB_AES select CRYPTO_LIB_SHA256 help Length-preserving ciphers: AES cipher algorithms (FIPS-197) with block cipher modes: - ECB (Electronic Codebook) mode (NIST SP800-38A)
@@ -163,11 +140,10 @@ config CRYPTO_SM4_ARM64_NEON_BLK config CRYPTO_AES_ARM64_CE_CCM tristate "AEAD cipher: AES in CCM mode (ARMv8 Crypto Extensions)" depends on KERNEL_MODE_NEON select CRYPTO_ALGAPI - select CRYPTO_AES_ARM64_CE select CRYPTO_AES_ARM64_CE_BLK select CRYPTO_AEAD select CRYPTO_LIB_AES help AEAD cipher: AES cipher algorithms (FIPS-197) with
arch/arm64/crypto/Makefile +0 -6
@@ -27,22 +27,16 @@ obj-$(CONFIG_CRYPTO_SM4_ARM64_NEON_BLK) += sm4-neon.o sm4-neon-y := sm4-neon-glue.o sm4-neon-core.o obj-$(CONFIG_CRYPTO_GHASH_ARM64_CE) += ghash-ce.o ghash-ce-y := ghash-ce-glue.o ghash-ce-core.o -obj-$(CONFIG_CRYPTO_AES_ARM64_CE) += aes-ce-cipher.o -aes-ce-cipher-y := aes-ce-core.o aes-ce-glue.o - obj-$(CONFIG_CRYPTO_AES_ARM64_CE_CCM) += aes-ce-ccm.o aes-ce-ccm-y := aes-ce-ccm-glue.o aes-ce-ccm-core.o obj-$(CONFIG_CRYPTO_AES_ARM64_CE_BLK) += aes-ce-blk.o aes-ce-blk-y := aes-glue-ce.o aes-ce.o obj-$(CONFIG_CRYPTO_AES_ARM64_NEON_BLK) += aes-neon-blk.o aes-neon-blk-y := aes-glue-neon.o aes-neon.o -obj-$(CONFIG_CRYPTO_AES_ARM64) += aes-arm64.o -aes-arm64-y := aes-cipher-core.o aes-cipher-glue.o - obj-$(CONFIG_CRYPTO_AES_ARM64_BS) += aes-neon-bs.o aes-neon-bs-y := aes-neonbs-core.o aes-neonbs-glue.o
arch/arm64/crypto/aes-ce-ccm-glue.c +0 -2
@@ -15,12 +15,10 @@#include <crypto/internal/skcipher.h> #include <linux/module.h> #include <asm/simd.h> -#include "aes-ce-setkey.h" -MODULE_IMPORT_NS ("CRYPTO_INTERNAL" );static int num_rounds (struct crypto_aes_ctx *ctx) {/*
arch/arm64/crypto/aes-ce-glue.c deleted +0 -178
178 lines not on this page · raw message
arch/arm64/crypto/aes-ce-setkey.h deleted +0 -6
@@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ - -int ce_aes_setkey (struct crypto_tfm *tfm,const u8 *in_key, -unsigned int key_len); -int ce_aes_expandkey (struct crypto_aes_ctx *ctx,const u8 *in_key, -unsigned int key_len);
arch/arm64/crypto/aes-cipher-glue.c deleted +0 -71
71 lines not on this page · raw message
arch/arm64/crypto/aes-glue.c +0 -2
@@ -19,12 +19,10 @@#include <linux/string.h> #include <asm/hwcap.h> #include <asm/simd.h> -#include "aes-ce-setkey.h" -#ifdef USE_V8_CRYPTO_EXTENSIONS #define MODE "ce"#define PRIO 300#define aes_expandkey ce_aes_expandkey#define aes_ecb_encrypt ce_aes_ecb_encrypt
include/crypto/aes.h +10 -0
@@ -114,10 +114,20 @@ static inline int aes_check_keylen(size_t keylen)* for the initial combination, the second slot for the first round and so on. */ int aes_expandkey (struct crypto_aes_ctx *ctx,const u8 *in_key,unsigned int key_len); +/* +* The following functions are temporarily exported for use by the AES mode +* implementations in arch/$(SRCARCH)/crypto/. These exports will go away when +* that code is migrated into lib/crypto/. +*/ +#ifdef CONFIG_ARM64 +int ce_aes_expandkey (struct crypto_aes_ctx *ctx,const u8 *in_key, +unsigned int key_len); +#endif +/** * aes_preparekey() - Prepare an AES key for encryption and decryption * @key: (output) The key structure to initialize * @in_key: The raw AES key * @key_len: Length of the raw key in bytes. Should be either AES_KEYSIZE_128,
lib/crypto/Kconfig +1 -0
@@ -13,10 +13,11 @@ config CRYPTO_LIB_AES config CRYPTO_LIB_AES_ARCH bool depends on CRYPTO_LIB_AES && !UML && !KMSAN default y if ARM + default y if ARM64 config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/Makefile +5 -0
@@ -22,10 +22,15 @@ libaes-y := aes.o ifeq ($(CONFIG_CRYPTO_LIB_AES_ARCH),y) CFLAGS_aes.o += -I$(src)/$(SRCARCH) libaes-$(CONFIG_ARM) += arm/aes-cipher-core.o +ifeq ($(CONFIG_ARM64),y) +libaes-y += arm64/aes-cipher-core.o +libaes-$(CONFIG_KERNEL_MODE_NEON) += arm64/aes-ce-core.o +endif + endif # CONFIG_CRYPTO_LIB_AES_ARCH ################################################################################ obj-$(CONFIG_CRYPTO_LIB_AESCFB) += libaescfb.o
lib/crypto/arm64/aes-ce-core.S renamed from arch/arm64/crypto/aes-ce-core.S +0 -0
lib/crypto/arm64/aes-cipher-core.S renamed from arch/arm64/crypto/aes-cipher-core.S +0 -0
lib/crypto/arm64/aes.h new file +164 -0
164 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 12/36 lib/crypto: powerpc/aes: Migrate SPE optimized code into library
In reply to Eric BiggersMove the PowerPC SPE AES assembly code into lib/crypto/, wire the key expansion and single-block en/decryption functions up to the AES library API, and remove the superseded "aes-ppc-spe" crypto_cipher algorithm.
The result is that both the AES library and crypto_cipher APIs are now optimized with SPE, whereas previously only crypto_cipher was (and optimizations weren't enabled by default, which this commit fixes too).
Note that many of the functions in the PowerPC SPE assembly code are still used by the AES mode implementations in arch/powerpc/crypto/. For now, just export these functions. These exports will go away once the AES modes are migrated to the library as well. (Trying to split up the assembly files seemed like much more trouble than it would be worth.)
---
arch/powerpc/crypto/Kconfig | 2 +-
arch/powerpc/crypto/Makefile | 2 +-
arch/powerpc/crypto/aes-spe-glue.c | 88 ++-----------------
include/crypto/aes.h | 31 +++++++
lib/crypto/Kconfig | 1 +
lib/crypto/Makefile | 9 ++
.../crypto/powerpc}/aes-spe-core.S | 0
.../crypto/powerpc}/aes-spe-keys.S | 0
.../crypto/powerpc}/aes-spe-modes.S | 0
.../crypto/powerpc}/aes-spe-regs.h | 0
.../crypto/powerpc}/aes-tab-4k.S | 0
lib/crypto/powerpc/aes.h | 74 ++++++++++++++++
12 files changed, 122 insertions(+), 85 deletions(-)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-spe-core.S (100%)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-spe-keys.S (100%)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-spe-modes.S (100%)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-spe-regs.h (100%)
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aes-tab-4k.S (100%)
create mode 100644 lib/crypto/powerpc/aes.harch/powerpc/crypto/Kconfig +1 -1
@@ -3,13 +3,13 @@ menu "Accelerated Cryptographic Algorithms for CPU (powerpc)" config CRYPTO_AES_PPC_SPE tristate "Ciphers: AES, modes: ECB/CBC/CTR/XTS (SPE)" depends on SPE + select CRYPTO_LIB_AES select CRYPTO_SKCIPHER help - Block ciphers: AES cipher algorithms (FIPS-197) Length-preserving ciphers: AES with ECB, CBC, CTR, and XTS modes Architecture: powerpc using: - SPE (Signal Processing Engine) extensions
arch/powerpc/crypto/Makefile +1 -1
@@ -7,11 +7,11 @@ obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o -aes-ppc-spe-y := aes-spe-core.o aes-spe-keys.o aes-tab-4k.o aes-spe-modes.o aes-spe-glue.o +aes-ppc-spe-y := aes-spe-glue.o aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-ppc.o vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) override flavour := linux-ppc64le
arch/powerpc/crypto/aes-spe-glue.c +5 -83
153 lines not on this page · raw message
include/crypto/aes.h +31 -0
@@ -18,14 +18,26 @@#define AES_MAX_KEYLENGTH (15 * 16)#define AES_MAX_KEYLENGTH_U32 (AES_MAX_KEYLENGTH / sizeof(u32))union aes_enckey_arch {u32 rndkeys[AES_MAX_KEYLENGTH_U32 ]; +#ifdef CONFIG_CRYPTO_LIB_AES_ARCH +#if defined(CONFIG_PPC ) && defined(CONFIG_SPE ) +/* Used unconditionally (when SPE AES code is enabled in kconfig) */ +u32 spe_enc_key[AES_MAX_KEYLENGTH_U32 ]__aligned(8) ; +#endif +#endif /* CONFIG_CRYPTO_LIB_AES_ARCH */ };union aes_invkey_arch {u32 inv_rndkeys[AES_MAX_KEYLENGTH_U32 ]; +#ifdef CONFIG_CRYPTO_LIB_AES_ARCH +#if defined(CONFIG_PPC ) && defined(CONFIG_SPE ) +/* Used unconditionally (when SPE AES code is enabled in kconfig) */ +u32 spe_dec_key[AES_MAX_KEYLENGTH_U32 ]__aligned(8) ; +#endif +#endif /* CONFIG_CRYPTO_LIB_AES_ARCH */ };/** * struct aes_enckey - An AES key prepared for encryption * @len: Key length in bytes: 16 for AES-128, 24 for AES-192, 32 for AES-256.
@@ -122,10 +134,29 @@ int aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key,* that code is migrated into lib/crypto/. */ #ifdef CONFIG_ARM64 int ce_aes_expandkey (struct crypto_aes_ctx *ctx,const u8 *in_key,unsigned int key_len); +#elif defined(CONFIG_PPC ) +void ppc_expand_key_128 (u32 *key_enc,const u8 *key); +void ppc_expand_key_192 (u32 *key_enc,const u8 *key); +void ppc_expand_key_256 (u32 *key_enc,const u8 *key); +void ppc_generate_decrypt_key (u32 *key_dec,u32 *key_enc,unsigned int key_len); +void ppc_encrypt_ecb (u8 *out,const u8 *in,u32 *key_enc,u32 rounds, +u32 bytes); +void ppc_decrypt_ecb (u8 *out,const u8 *in,u32 *key_dec,u32 rounds, +u32 bytes); +void ppc_encrypt_cbc (u8 *out,const u8 *in,u32 *key_enc,u32 rounds,u32 bytes, +u8 *iv); +void ppc_decrypt_cbc (u8 *out,const u8 *in,u32 *key_dec,u32 rounds,u32 bytes, +u8 *iv); +void ppc_crypt_ctr (u8 *out,const u8 *in,u32 *key_enc,u32 rounds,u32 bytes, +u8 *iv); +void ppc_encrypt_xts (u8 *out,const u8 *in,u32 *key_enc,u32 rounds,u32 bytes, +u8 *iv,u32 *key_twk); +void ppc_decrypt_xts (u8 *out,const u8 *in,u32 *key_dec,u32 rounds,u32 bytes, +u8 *iv,u32 *key_twk);#endif /** * aes_preparekey() - Prepare an AES key for encryption and decryption * @key: (output) The key structure to initialize
lib/crypto/Kconfig +1 -0
@@ -14,10 +14,11 @@ config CRYPTO_LIB_AES config CRYPTO_LIB_AES_ARCH bool depends on CRYPTO_LIB_AES && !UML && !KMSAN default y if ARM default y if ARM64 + default y if PPC && SPE config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/Makefile +9 -0
@@ -27,10 +27,19 @@ libaes-$(CONFIG_ARM) += arm/aes-cipher-core.o ifeq ($(CONFIG_ARM64),y) libaes-y += arm64/aes-cipher-core.o libaes-$(CONFIG_KERNEL_MODE_NEON) += arm64/aes-ce-core.o endif +ifeq ($(CONFIG_PPC),y) +ifeq ($(CONFIG_SPE),y) +libaes-y += powerpc/aes-spe-core.o \ + powerpc/aes-spe-keys.o \ + powerpc/aes-spe-modes.o \ + powerpc/aes-tab-4k.o +endif +endif # CONFIG_PPC + endif # CONFIG_CRYPTO_LIB_AES_ARCH ################################################################################ obj-$(CONFIG_CRYPTO_LIB_AESCFB) += libaescfb.o
lib/crypto/powerpc/aes-spe-core.S renamed from arch/powerpc/crypto/aes-spe-core.S +0 -0
lib/crypto/powerpc/aes-spe-keys.S renamed from arch/powerpc/crypto/aes-spe-keys.S +0 -0
lib/crypto/powerpc/aes-spe-modes.S renamed from arch/powerpc/crypto/aes-spe-modes.S +0 -0
lib/crypto/powerpc/aes-spe-regs.h renamed from arch/powerpc/crypto/aes-spe-regs.h +0 -0
lib/crypto/powerpc/aes-tab-4k.S renamed from arch/powerpc/crypto/aes-tab-4k.S +0 -0
lib/crypto/powerpc/aes.h new file +74 -0
74 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 13/36 lib/crypto: powerpc/aes: Migrate POWER8 optimized code into library
In reply to Eric BiggersMove the POWER8 AES assembly code into lib/crypto/, wire the key expansion and single-block en/decryption functions up to the AES library API, and remove the superseded "p8_aes" crypto_cipher algorithm.
The result is that both the AES library and crypto_cipher APIs are now optimized for POWER8, whereas previously only crypto_cipher was (and optimizations weren't enabled by default, which this commit fixes too).
Note that many of the functions in the POWER8 assembly code are still used by the AES mode implementations in arch/powerpc/crypto/. For now, just export these functions. These exports will go away once the AES modes are migrated to the library as well. (Trying to split up the assembly file seemed like much more trouble than it would be worth.)
Another challenge with this code is that the POWER8 assembly code uses a custom format for the expanded AES key. Since that code is imported from OpenSSL and is also targeted to POWER8 (rather than POWER9 which has better data movement and byteswap instructions), that is not easily changed. For now I've just kept the custom format. To maintain full correctness, this requires executing some slow fallback code in the case where the usability of VSX changes between key expansion and use. This should be tolerable, as this case shouldn't happen in practice.
---
arch/powerpc/crypto/Makefile | 7 +-
arch/powerpc/crypto/aes.c | 134 --------------
arch/powerpc/crypto/aesp8-ppc.h | 23 ---
arch/powerpc/crypto/vmx.c | 10 +-
include/crypto/aes.h | 41 +++++
lib/crypto/Kconfig | 2 +-
lib/crypto/Makefile | 14 +-
lib/crypto/powerpc/.gitignore | 2 +
lib/crypto/powerpc/aes.h | 164 ++++++++++++++++++
.../crypto/powerpc}/aesp8-ppc.pl | 1 +
10 files changed, 226 insertions(+), 172 deletions(-)
delete mode 100644 arch/powerpc/crypto/aes.c
create mode 100644 lib/crypto/powerpc/.gitignore
rename {arch/powerpc/crypto => lib/crypto/powerpc}/aesp8-ppc.pl (99%)arch/powerpc/crypto/Makefile +3 -4
@@ -9,11 +9,11 @@ obj-$(CONFIG_CRYPTO_AES_PPC_SPE) += aes-ppc-spe.o obj-$(CONFIG_CRYPTO_AES_GCM_P10) += aes-gcm-p10-crypto.o obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o aes-ppc-spe-y := aes-spe-glue.o aes-gcm-p10-crypto-y := aes-gcm-p10-glue.o aes-gcm-p10.o ghashp10-ppc.o aesp10-ppc.o -vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o +vmx-crypto-objs := vmx.o ghashp8-ppc.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) override flavour := linux-ppc64le else ifdef CONFIG_PPC64_ELF_ABI_V2
@@ -24,17 +24,16 @@ endif endif quiet_cmd_perl = PERL $@ cmd_perl = $(PERL) $< $(flavour) > $@ -targets += aesp10-ppc.S ghashp10-ppc.S aesp8-ppc.S ghashp8-ppc.S +targets += aesp10-ppc.S ghashp10-ppc.S ghashp8-ppc.S $(obj)/aesp10-ppc.S $(obj)/ghashp10-ppc.S: $(obj)/%.S: $(src)/%.pl FORCE $(call if_changed,perl) -$(obj)/aesp8-ppc.S $(obj)/ghashp8-ppc.S: $(obj)/%.S: $(src)/%.pl FORCE +$(obj)/ghashp8-ppc.S: $(obj)/%.S: $(src)/%.pl FORCE $(call if_changed,perl) OBJECT_FILES_NON_STANDARD_aesp10-ppc.o := y OBJECT_FILES_NON_STANDARD_ghashp10-ppc.o := y -OBJECT_FILES_NON_STANDARD_aesp8-ppc.o := y OBJECT_FILES_NON_STANDARD_ghashp8-ppc.o := y
arch/powerpc/crypto/aes.c deleted +0 -134
134 lines not on this page · raw message
arch/powerpc/crypto/aesp8-ppc.h +0 -23
@@ -1,31 +1,8 @@/* SPDX-License-Identifier: GPL-2.0 */ #include <linux/types.h> #include <crypto/aes.h> -struct p8_aes_key { -u8 key[AES_MAX_KEYLENGTH ]; -int rounds; -}; -extern struct shash_alg p8_ghash_alg; -extern struct crypto_alg p8_aes_alg;extern struct skcipher_alg p8_aes_cbc_alg;extern struct skcipher_alg p8_aes_ctr_alg;extern struct skcipher_alg p8_aes_xts_alg; - -int aes_p8_set_encrypt_key (const u8 *userKey,const int bits, -struct p8_aes_key *key); -int aes_p8_set_decrypt_key (const u8 *userKey,const int bits, -struct p8_aes_key *key); -void aes_p8_encrypt (const u8 *in,u8 *out,const struct p8_aes_key *key); -void aes_p8_decrypt (const u8 *in,u8 *out,const struct p8_aes_key *key); -void aes_p8_cbc_encrypt (const u8 *in,u8 *out,size_t len, -const struct p8_aes_key *key,u8 *iv,const int enc); -void aes_p8_ctr32_encrypt_blocks (const u8 *in,u8 *out,size_t len, -const struct p8_aes_key *key,const u8 *iv); -void aes_p8_xts_encrypt (const u8 *in,u8 *out,size_t len, -const struct p8_aes_key *key1, -const struct p8_aes_key *key2,u8 *iv); -void aes_p8_xts_decrypt (const u8 *in,u8 *out,size_t len, -const struct p8_aes_key *key1, -const struct p8_aes_key *key2,u8 *iv);
arch/powerpc/crypto/vmx.c +1 -9
@@ -25,17 +25,13 @@ static int __init p8_init(void) ret =crypto_register_shash (&p8_ghash_alg);if (ret) goto err; - ret =crypto_register_alg (&p8_aes_alg); -if (ret) - goto err_unregister_ghash; - ret =crypto_register_skcipher (&p8_aes_cbc_alg);if (ret) - goto err_unregister_aes; + goto err_unregister_ghash; ret =crypto_register_skcipher (&p8_aes_ctr_alg);if (ret) goto err_unregister_aes_cbc;
@@ -47,12 +43,10 @@ static int __init p8_init(void) err_unregister_aes_ctr:crypto_unregister_skcipher (&p8_aes_ctr_alg); err_unregister_aes_cbc:crypto_unregister_skcipher (&p8_aes_cbc_alg); -err_unregister_aes: -crypto_unregister_alg (&p8_aes_alg); err_unregister_ghash:crypto_unregister_shash (&p8_ghash_alg); err:return ret; }
@@ -60,11 +54,10 @@ static int __init p8_init(void) static void __exit p8_exit(void) {crypto_unregister_skcipher (&p8_aes_xts_alg);crypto_unregister_skcipher (&p8_aes_ctr_alg);crypto_unregister_skcipher (&p8_aes_cbc_alg); -crypto_unregister_alg (&p8_aes_alg);crypto_unregister_shash (&p8_ghash_alg); }module_cpu_feature_match (PPC_MODULE_FEATURE_VEC_CRYPTO , p8_init);module_exit (p8_exit);
@@ -72,6 +65,5 @@ module_exit(p8_exit);MODULE_AUTHOR ("Marcelo Cerri<[email protected]>" );MODULE_DESCRIPTION ("IBM VMX cryptographic acceleration instructions " "support on Power 8" );MODULE_LICENSE ("GPL" );MODULE_VERSION ("1.0.0" ); -MODULE_IMPORT_NS ("CRYPTO_INTERNAL" );
include/crypto/aes.h +41 -0
77 lines not on this page · raw message
lib/crypto/Kconfig +1 -1
@@ -14,11 +14,11 @@ config CRYPTO_LIB_AES config CRYPTO_LIB_AES_ARCH bool depends on CRYPTO_LIB_AES && !UML && !KMSAN default y if ARM default y if ARM64 - default y if PPC && SPE + default y if PPC && (SPE || (PPC64 && VSX)) config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/Makefile +13 -1
@@ -33,11 +33,23 @@ ifeq ($(CONFIG_PPC),y) ifeq ($(CONFIG_SPE),y) libaes-y += powerpc/aes-spe-core.o \ powerpc/aes-spe-keys.o \ powerpc/aes-spe-modes.o \ powerpc/aes-tab-4k.o -endif +else +libaes-y += powerpc/aesp8-ppc.o +aes-perlasm-flavour-y := linux-ppc64 +aes-perlasm-flavour-$(CONFIG_PPC64_ELF_ABI_V2) := linux-ppc64-elfv2 +aes-perlasm-flavour-$(CONFIG_CPU_LITTLE_ENDIAN) := linux-ppc64le +quiet_cmd_perlasm_aes = PERLASM $@ + cmd_perlasm_aes = $(PERL) $< $(aes-perlasm-flavour-y) $@ +# Use if_changed instead of cmd, in case the flavour changed. +$(obj)/powerpc/aesp8-ppc.S: $(src)/powerpc/aesp8-ppc.pl FORCE + $(call if_changed,perlasm_aes) +targets += powerpc/aesp8-ppc.S +OBJECT_FILES_NON_STANDARD_powerpc/aesp8-ppc.o := y +endif # !CONFIG_SPE endif # CONFIG_PPC endif # CONFIG_CRYPTO_LIB_AES_ARCH ################################################################################
lib/crypto/powerpc/.gitignore new file +2 -0
@@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +aesp8-ppc.S
lib/crypto/powerpc/aes.h +164 -0
186 lines not on this page · raw message
lib/crypto/powerpc/aesp8-ppc.pl renamed from arch/powerpc/crypto/aesp8-ppc.pl +1 -0
@@ -103,10 +103,11 @@ if ($flavour =~ /64/) { $LITTLE_ENDIAN = ($flavour=~/le$/) ? $SIZE_T : 0; $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; ( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or ( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +( $xlate="${dir}../../../arch/powerpc/crypto/ppc-xlate.pl" and -f $xlate) or die "can't locate ppc-xlate.pl"; open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; $FRAME=8*$SIZE_T;
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 14/36 lib/crypto: riscv/aes: Migrate optimized code into library
In reply to Eric BiggersMove the aes_encrypt_zvkned() and aes_decrypt_zvkned() assembly functions into lib/crypto/, wire them up to the AES library API, and remove the "aes-riscv64-zvkned" crypto_cipher algorithm.
To make this possible, change the prototypes of these functions to take (rndkeys, key_len) instead of a pointer to crypto_aes_ctx, and change the RISC-V AES-XTS code to implement tweak encryption using the AES library instead of directly calling aes_encrypt_zvkned().
The result is that both the AES library and crypto_cipher APIs use RISC-V's AES instructions, whereas previously only crypto_cipher did (and it wasn't enabled by default, which this commit fixes as well).
--- arch/riscv/crypto/Kconfig | 2 - arch/riscv/crypto/aes-macros.S | 12 +++- arch/riscv/crypto/aes-riscv64-glue.c | 78 ++---------------------- arch/riscv/crypto/aes-riscv64-zvkned.S | 27 --------- lib/crypto/Kconfig | 2 + lib/crypto/Makefile | 1 + lib/crypto/riscv/aes-riscv64-zvkned.S | 84 ++++++++++++++++++++++++++ lib/crypto/riscv/aes.h | 63 +++++++++++++++++++ 8 files changed, 165 insertions(+), 104 deletions(-) create mode 100644 lib/crypto/riscv/aes-riscv64-zvkned.S create mode 100644 lib/crypto/riscv/aes.h
arch/riscv/crypto/Kconfig +0 -2
@@ -4,15 +4,13 @@ menu "Accelerated Cryptographic Algorithms for CPU (riscv)" config CRYPTO_AES_RISCV64 tristate "Ciphers: AES, modes: ECB, CBC, CTS, CTR, XTS" depends on 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS - select CRYPTO_ALGAPI select CRYPTO_LIB_AES select CRYPTO_SKCIPHER help - Block cipher: AES cipher algorithms Length-preserving ciphers: AES with ECB, CBC, CTS, CTR, XTS Architecture: riscv64 using: - Zvkned vector crypto extension - Zvbb vector extension (XTS)
arch/riscv/crypto/aes-macros.S +11 -1
@@ -49,12 +49,14 @@ // - If AES-128, loads round keys into v1-v11 and jumps to \label128. // - If AES-192, loads round keys into v1-v13 and jumps to \label192. // - If AES-256, loads round keys into v1-v15 and continues onwards. // // Also sets vl=4 and vtype=e32,m1,ta,ma. Clobbers t0 and t1. -.macro aes_begin keyp, label128, label192 +.macro aes_begin keyp, label128, label192, key_len +.ifb \key_len lwu t0, 480(\keyp) // t0 = key length in bytes +.endif li t1, 24 // t1 = key length for AES-192 vsetivli zero, 4, e32, m1, ta, ma vle32.v v1, (\keyp) addi \keyp, \keyp, 16 vle32.v v2, (\keyp)
@@ -74,16 +76,24 @@ vle32.v v9, (\keyp) addi \keyp, \keyp, 16 vle32.v v10, (\keyp) addi \keyp, \keyp, 16 vle32.v v11, (\keyp) +.ifb \key_len blt t0, t1, \label128 // If AES-128, goto label128. +.else + blt \key_len, t1, \label128 // If AES-128, goto label128. +.endif addi \keyp, \keyp, 16 vle32.v v12, (\keyp) addi \keyp, \keyp, 16 vle32.v v13, (\keyp) +.ifb \key_len beq t0, t1, \label192 // If AES-192, goto label192. +.else + beq \key_len, t1, \label192 // If AES-192, goto label192. +.endif // Else, it's AES-256. addi \keyp, \keyp, 16 vle32.v v14, (\keyp) addi \keyp, \keyp, 16 vle32.v v15, (\keyp)
arch/riscv/crypto/aes-riscv64-glue.c +4 -74
186 lines not on this page · raw message
arch/riscv/crypto/aes-riscv64-zvkned.S +0 -27
@@ -54,37 +54,10 @@ #define INP a1 #define OUTP a2 #define LEN a3 #define IVP a4 -.macro __aes_crypt_zvkned enc, keylen - vle32.v v16, (INP) - aes_crypt v16, \enc, \keylen - vse32.v v16, (OUTP) - ret -.endm - -.macro aes_crypt_zvkned enc - aes_begin KEYP, 128f, 192f - __aes_crypt_zvkned \enc, 256 -128: - __aes_crypt_zvkned \enc, 128 -192: - __aes_crypt_zvkned \enc, 192 -.endm - -// void aes_encrypt_zvkned(const struct crypto_aes_ctx *key, -// const u8 in[16], u8 out[16]); -SYM_FUNC_START(aes_encrypt_zvkned) - aes_crypt_zvkned 1 -SYM_FUNC_END(aes_encrypt_zvkned) - -// Same prototype and calling convention as the encryption function -SYM_FUNC_START(aes_decrypt_zvkned) - aes_crypt_zvkned 0 -SYM_FUNC_END(aes_decrypt_zvkned) - .macro __aes_ecb_crypt enc, keylen srli t0, LEN, 2 // t0 is the remaining length in 32-bit words. It's a multiple of 4. 1: vsetvli t1, t0, e32, m8, ta, ma
lib/crypto/Kconfig +2 -0
@@ -15,10 +15,12 @@ config CRYPTO_LIB_AES_ARCH bool depends on CRYPTO_LIB_AES && !UML && !KMSAN default y if ARM default y if ARM64 default y if PPC && (SPE || (PPC64 && VSX)) + default y if RISCV && 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ + RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/Makefile +1 -0
@@ -48,10 +48,11 @@ $(obj)/powerpc/aesp8-ppc.S: $(src)/powerpc/aesp8-ppc.pl FORCE targets += powerpc/aesp8-ppc.S OBJECT_FILES_NON_STANDARD_powerpc/aesp8-ppc.o := y endif # !CONFIG_SPE endif # CONFIG_PPC +libaes-$(CONFIG_RISCV) += riscv/aes-riscv64-zvkned.o endif # CONFIG_CRYPTO_LIB_AES_ARCH ################################################################################ obj-$(CONFIG_CRYPTO_LIB_AESCFB) += libaescfb.o
lib/crypto/riscv/aes-riscv64-zvkned.S new file +84 -0
84 lines not on this page · raw message
lib/crypto/riscv/aes.h new file +63 -0
63 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 15/36 lib/crypto: s390/aes: Migrate optimized code into library
In reply to Eric BiggersImplement aes_preparekey_arch(), aes_encrypt_arch(), and aes_decrypt_arch() using the CPACF AES instructions.
Then, remove the superseded "aes-s390" crypto_cipher.
The result is that both the AES library and crypto_cipher APIs use the CPACF AES instructions, whereas previously only crypto_cipher did (and it wasn't enabled by default, which this commit fixes as well).
Note that this preserves the optimization where the AES key is stored in raw form rather than expanded form. CPACF just takes the raw key.
--- arch/s390/crypto/Kconfig | 2 - arch/s390/crypto/aes_s390.c | 113 ------------------------------------ include/crypto/aes.h | 3 + lib/crypto/Kconfig | 1 + lib/crypto/s390/aes.h | 106 +++++++++++++++++++++++++++++++++ 5 files changed, 110 insertions(+), 115 deletions(-) create mode 100644 lib/crypto/s390/aes.h
arch/s390/crypto/Kconfig +0 -2
@@ -12,14 +12,12 @@ config CRYPTO_GHASH_S390 It is available as of z196. config CRYPTO_AES_S390 tristate "Ciphers: AES, modes: ECB, CBC, CTR, XTS, GCM" - select CRYPTO_ALGAPI select CRYPTO_SKCIPHER help - Block cipher: AES cipher algorithms (FIPS 197) AEAD cipher: AES with GCM Length-preserving ciphers: AES with ECB, CBC, XTS, and CTR modes Architecture: s390
arch/s390/crypto/aes_s390.c +0 -113
178 lines not on this page · raw message
include/crypto/aes.h +3 -0
@@ -44,10 +44,13 @@ union aes_enckey_arch {* when that code is usable at key preparation time. Otherwise they * fall back to rndkeys. In the latter case, p8.nrounds (which doesn't * overlap rndkeys) is set to 0 to differentiate the two formats. */ struct p8_aes_key p8; +#elif defined(CONFIG_S390 ) +/* Used when the CPU supports CPACF AES for this key's length */ +u8 raw_key[AES_MAX_KEY_SIZE ];#endif #endif /* CONFIG_CRYPTO_LIB_AES_ARCH */ };union aes_invkey_arch {
lib/crypto/Kconfig +1 -0
@@ -17,10 +17,11 @@ config CRYPTO_LIB_AES_ARCH default y if ARM default y if ARM64 default y if PPC && (SPE || (PPC64 && VSX)) default y if RISCV && 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS + default y if S390 config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/s390/aes.h new file +106 -0
106 lines not on this page · raw message
Signature · 1 line
2.52.0
Holger Dengler
maintainerRe: [PATCH 15/36] lib/crypto: s390/aes: Migrate optimized code into library
Hi Eric,
first of all: happy New Year! ANd thanks for the series.
Quoted 2 lines · Eric Biggers
Implement
aes_preparekey_arch(),aes_encrypt_arch(), andaes_decrypt_arch()using the CPACF AES instructions.
I'm not sure, it it makes sense to implement this on s390 at all. The CPACF instructions cover full modes of operations and are optimized to process more than one cipher-block-size (*). For single-block operations, the performance might be worth than using the generic functions. I will look into it and do some performance tests. If there is a possibility to plug-in to the level where the modes of operation are implemented, it would make much more sense for s390.
(*) Yes, it's a bit uncommon, but the CPACF instructions on s390 can process multiple block with a single instruction call! They are so called long running instructions.
Quoted 10 lines
Then, remove the superseded "aes-s390"
crypto_cipher.The result is that both the AES library and
crypto_cipherAPIs use the CPACF AES instructions, whereas previously onlycrypto_cipherdid (and it wasn't enabled by default, which this commit fixes as well).Note that this preserves the optimization where the AES key is stored in raw form rather than expanded form. CPACF just takes the raw key.
Signed-off-by Eric Biggers <[email protected]> --- arch/s390/crypto/
-- Mit freundlichen Grüßen / Kind regards
Holger Dengler
--
IBM Systems, Linux on IBM Z Development
[email protected]
Eric Biggers
maintainerRe: [PATCH 15/36] lib/crypto: s390/aes: Migrate optimized code into library
Quoted 16 lines · Holger Dengler
Hi Eric,
first of all: happy New Year! ANd thanks for the series.
Quoted 2 lines · Eric Biggers
Implement
aes_preparekey_arch(),aes_encrypt_arch(), andaes_decrypt_arch()using the CPACF AES instructions.I'm not sure, it it makes sense to implement this on s390 at all. The CPACF instructions cover full modes of operations and are to process more than one cipher-block-size (*). For single-block operations, the performance might be worth than using the generic functions. I will look into it and do some performance tests. If there is a possibility to plug-in to the level where the modes of operation are implemented, it would make much more sense for s390.
Quoted 3 lines
(*) Yes, it's a bit uncommon, but the CPACF instructions on s390 can process multiple block with a single instruction call! They are so called long running instructions.
I'm happy to drop the CPACF single-block AES code if it's not worthwhile. I included it only because arch/s390/crypto/ already has such code. Since I'm making it so that the crypto_cipher API simply wraps the library API, if this code is not brought into the library it will effectively be dropped. You had pushed back the last time I proposed dropping one of the s390 optimizations, even a fairly minor one
(https://lore.kernel.org/linux-crypto/[email protected]/).
But I have no way to test or benchmark the s390 code myself. If the CPACF single-block AES en/decryption code isn't worthwhile, there's no reason to keep it, so I'll remove it.
As for AES modes, later patchsets are going to introduce architecture-optimized AES modes into the library, and the traditional crypto API for those modes will similarly be reimplemented on top of it. This patchset just focuses on the existing library API for key expansion and single block en/decryption as a first step. (As with the traditional API, single block en/decryption is needed as a fallback to handle any modes that don't have a standalone implementation.)
- Eric
Holger Dengler
maintainerRe: [PATCH 15/36] lib/crypto: s390/aes: Migrate optimized code into library
Quoted 29 lines · Eric Biggers
Quoted 16 lines · Holger Dengler
Hi Eric,
first of all: happy New Year! ANd thanks for the series.
Quoted 2 lines · Eric Biggers
Implement
aes_preparekey_arch(),aes_encrypt_arch(), andaes_decrypt_arch()using the CPACF AES instructions.I'm not sure, it it makes sense to implement this on s390 at all. The CPACF instructions cover full modes of operations and are to process more than one cipher-block-size (*). For single-block operations, the performance might be worth than using the generic functions. I will look into it and do some performance tests. If there is a possibility to plug-in to the level where the modes of operation are implemented, it would make much more sense for s390.
Quoted 3 lines
(*) Yes, it's a bit uncommon, but the CPACF instructions on s390 can process multiple block with a single instruction call! They are so called long running instructions.
I'm happy to drop the CPACF single-block AES code if it's not worthwhile. I included it only because
arch/s390/crypto/already has such code. Since I'm making it so that thecrypto_cipherAPI simply wraps the library API, if this code is not brought into the library it will effectively be dropped. You had pushed back the last time I proposed dropping one of the s390 optimizations, even a fairly minor one
(https://lore.kernel.org/linux-crypto/[email protected]/).
Quoted 3 lines
But I have no way to test or benchmark the s390 code myself. If the CPACF single-block AES en/decryption code isn't worthwhile, there's no reason to keep it, so I'll remove it.
My assumtion, that the aes single-block-operation operation is slower in CPACF than in software, seems to be wrong. I did some measurements on different machines and it turns out, that it is up to ~2x faster doing it in CPACF.
So, sorry for the noise. Please leave your s390 implementation as it is.
PS: I have a simple kunit test for aes (KAT and benchmark for each direction and key-size). I'll send it in a separate reply. Feel free to pick it.
Quoted 7 lines
As for AES modes, later patchsets are going to introduce architecture-optimized AES modes into the library, and the traditional crypto API for those modes will similarly be reimplemented on top of it. This patchset just focuses on the existing library API for key expansion and single block en/decryption as a first step. (As with the traditional API, single block en/decryption is needed as a fallback to handle any modes that don't have a standalone implementation.)
Ok. So we'll wait for upcoming patchsets.
Signature · 5 lines
Mit freundlichen Grüßen / Kind regards Holger Dengler -- IBM Systems, Linux on IBM Z Development [email protected]
Eric Biggers
maintainerPATCH 16/36 lib/crypto: sparc/aes: Migrate optimized code into library
In reply to Eric BiggersMove the SPARC64 AES assembly code into lib/crypto/, wire the key expansion and single-block en/decryption functions up to the AES library API, and remove the "aes-sparc64" crypto_cipher algorithm.
The result is that both the AES library and crypto_cipher APIs use the SPARC64 AES opcodes, whereas previously only crypto_cipher did (and it wasn't enabled by default, which this commit fixes as well).
Note that some of the functions in the SPARC64 AES assembly code are still used by the AES mode implementations in arch/sparc/crypto/aes_glue.c. For now, just export these functions. These exports will go away once the AES mode implementations are migrated to the library as well. (Trying to split up the assembly file seemed like much more trouble than it would be worth.)
---
arch/sparc/crypto/Kconfig | 2 +-
arch/sparc/crypto/Makefile | 2 +-
arch/sparc/crypto/aes_glue.c | 140 +---------------
include/crypto/aes.h | 42 +++++
lib/crypto/Kconfig | 1 +
lib/crypto/Makefile | 1 +
lib/crypto/sparc/aes.h | 149 ++++++++++++++++++
.../crypto => lib/crypto/sparc}/aes_asm.S | 0
8 files changed, 200 insertions(+), 137 deletions(-)
create mode 100644 lib/crypto/sparc/aes.h
rename {arch/sparc/crypto => lib/crypto/sparc}/aes_asm.S (100%)arch/sparc/crypto/Kconfig +1 -1
@@ -17,13 +17,13 @@ config CRYPTO_DES_SPARC64 Architecture: sparc64 config CRYPTO_AES_SPARC64 tristate "Ciphers: AES, modes: ECB, CBC, CTR" depends on SPARC64 + select CRYPTO_LIB_AES select CRYPTO_SKCIPHER help - Block ciphers: AES cipher algorithms (FIPS-197) Length-preseving ciphers: AES with ECB, CBC, and CTR modes Architecture: sparc64 using crypto instructions config CRYPTO_CAMELLIA_SPARC64
arch/sparc/crypto/Makefile +1 -1
@@ -5,8 +5,8 @@ obj-$(CONFIG_CRYPTO_AES_SPARC64) += aes-sparc64.o obj-$(CONFIG_CRYPTO_DES_SPARC64) += des-sparc64.o obj-$(CONFIG_CRYPTO_CAMELLIA_SPARC64) += camellia-sparc64.o -aes-sparc64-y := aes_asm.o aes_glue.o +aes-sparc64-y := aes_glue.o des-sparc64-y := des_asm.o des_glue.o camellia-sparc64-y := camellia_asm.o camellia_glue.o
arch/sparc/crypto/aes_glue.c +5 -135
230 lines not on this page · raw message
include/crypto/aes.h +42 -0
62 lines not on this page · raw message
lib/crypto/Kconfig +1 -0
@@ -18,10 +18,11 @@ config CRYPTO_LIB_AES_ARCH default y if ARM64 default y if PPC && (SPE || (PPC64 && VSX)) default y if RISCV && 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS default y if S390 + default y if SPARC64 config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/Makefile +1 -0
@@ -49,10 +49,11 @@ targets += powerpc/aesp8-ppc.S OBJECT_FILES_NON_STANDARD_powerpc/aesp8-ppc.o := y endif # !CONFIG_SPE endif # CONFIG_PPC libaes-$(CONFIG_RISCV) += riscv/aes-riscv64-zvkned.o +libaes-$(CONFIG_SPARC) += sparc/aes_asm.o endif # CONFIG_CRYPTO_LIB_AES_ARCH ################################################################################ obj-$(CONFIG_CRYPTO_LIB_AESCFB) += libaescfb.o
lib/crypto/sparc/aes.h new file +149 -0
149 lines not on this page · raw message
lib/crypto/sparc/aes_asm.S renamed from arch/sparc/crypto/aes_asm.S +0 -0
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 17/36 lib/crypto: x86/aes: Add AES-NI optimization
In reply to Eric BiggersOptimize the AES library with x86 AES-NI instructions.
The relevant existing assembly functions, aesni_set_key(), aesni_enc(), and aesni_dec(), are a bit difficult to extract into the library:
- They're coupled to the code for the AES modes.
- They operate on struct crypto_aes_ctx. The AES library now uses different structs.
- They assume the key is 16-byte aligned. The AES library only *prefers* 16-byte alignment; it doesn't require it.
Moreover, they're not all that great in the first place:
- They use unrolled loops, which isn't a great choice on x86.
- They use the 'aeskeygenassist' instruction, which is unnecessary, is slow on Intel CPUs, and forces the loop to be unrolled.
- They have special code for AES-192 key expansion, despite that being kind of useless. AES-128 and AES-256 are the ones used in practice.
These are small functions anyway.
Therefore, I opted to just write replacements of these functions for the library. They address all the above issues.
--- lib/crypto/Kconfig | 1 + lib/crypto/Makefile | 1 + lib/crypto/x86/aes-aesni.S | 261 +++++++++++++++++++++++++++++++++++++ lib/crypto/x86/aes.h | 85 ++++++++++++ 4 files changed, 348 insertions(+) create mode 100644 lib/crypto/x86/aes-aesni.S create mode 100644 lib/crypto/x86/aes.h
lib/crypto/Kconfig +1 -0
@@ -19,10 +19,11 @@ config CRYPTO_LIB_AES_ARCH default y if PPC && (SPE || (PPC64 && VSX)) default y if RISCV && 64BIT && TOOLCHAIN_HAS_VECTOR_CRYPTO && \ RISCV_EFFICIENT_VECTOR_UNALIGNED_ACCESS default y if S390 default y if SPARC64 + default y if X86 config CRYPTO_LIB_AESCFB tristate select CRYPTO_LIB_AES select CRYPTO_LIB_UTILS
lib/crypto/Makefile +1 -0
@@ -50,10 +50,11 @@ OBJECT_FILES_NON_STANDARD_powerpc/aesp8-ppc.o := y endif # !CONFIG_SPE endif # CONFIG_PPC libaes-$(CONFIG_RISCV) += riscv/aes-riscv64-zvkned.o libaes-$(CONFIG_SPARC) += sparc/aes_asm.o +libaes-$(CONFIG_X86) += x86/aes-aesni.o endif # CONFIG_CRYPTO_LIB_AES_ARCH ################################################################################ obj-$(CONFIG_CRYPTO_LIB_AESCFB) += libaescfb.o
lib/crypto/x86/aes-aesni.S new file +261 -0
261 lines not on this page · raw message
lib/crypto/x86/aes.h new file +85 -0
85 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 18/36 crypto: x86/aes - Remove the superseded AES-NI crypto_cipher
In reply to Eric BiggersRemove the "aes-aesni" crypto_cipher algorithm and the code specific to its implementation. It is no longer necessary because the AES library is now optimized with x86 AES-NI, and crypto/aes.c exposes the AES library via the crypto_cipher API.
--- arch/x86/crypto/Kconfig | 2 - arch/x86/crypto/aesni-intel_asm.S | 25 ------------ arch/x86/crypto/aesni-intel_glue.c | 62 +----------------------------- 3 files changed, 1 insertion(+), 88 deletions(-)
arch/x86/crypto/Kconfig +0 -2
@@ -5,14 +5,12 @@ menu "Accelerated Cryptographic Algorithms for CPU (x86)" config CRYPTO_AES_NI_INTEL tristate "Ciphers: AES, modes: ECB, CBC, CTS, CTR, XCTR, XTS, GCM (AES-NI/VAES)" select CRYPTO_AEAD select CRYPTO_LIB_AES select CRYPTO_LIB_GF128MUL - select CRYPTO_ALGAPI select CRYPTO_SKCIPHER help - Block cipher: AES cipher algorithms AEAD cipher: AES with GCM Length-preserving ciphers: AES with ECB, CBC, CTS, CTR, XCTR, XTS Architecture: x86 (32-bit and 64-bit) using: - AES-NI (AES new instructions)
arch/x86/crypto/aesni-intel_asm.S +0 -25
@@ -434,35 +434,10 @@ SYM_FUNC_START_LOCAL(_aesni_enc4) aesenclast KEY, STATE3 aesenclast KEY, STATE4 RET SYM_FUNC_END(_aesni_enc4) -/* - * void aesni_dec (const void *ctx, u8 *dst, const u8 *src) - */ -SYM_FUNC_START(aesni_dec) - FRAME_BEGIN -#ifndef __x86_64__ - pushl KEYP - pushl KLEN - movl (FRAME_OFFSET+12)(%esp), KEYP # ctx - movl (FRAME_OFFSET+16)(%esp), OUTP # dst - movl (FRAME_OFFSET+20)(%esp), INP # src -#endif - mov 480(KEYP), KLEN # key length - add $240, KEYP - movups (INP), STATE # input - call _aesni_dec1 - movups STATE, (OUTP) #output -#ifndef __x86_64__ - popl KLEN - popl KEYP -#endif - FRAME_END - RET -SYM_FUNC_END(aesni_dec) - /* * _aesni_dec1: internal ABI * input: * KEYP: key struct pointer * KLEN: key length
arch/x86/crypto/aesni-intel_glue.c +1 -61
124 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 19/36 Bluetooth: SMP: Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- net/bluetooth/smp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/bluetooth/smp.c +4 -4
@@ -372,36 +372,36 @@ static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],* s1 and ah. */ static int smp_e (const u8 *k,u8 *r) { -struct crypto_aes_ctx ctx; +struct aes_enckey aes;uint8_t tmp[16 ], data[16 ];int err;SMP_DBG ("k %16phN r %16phN" , k, r);/* The most significant octet of key corresponds to k[0] */ swap_buf (k, tmp,16 ); - err =aes_expandkey (&ctx, tmp,16 ); + err =aes_prepareenckey (&aes, tmp,16 );if (err) {BT_ERR ("cipher setkey failed: %d" , err);return err; }/* Most significant octet of plaintextData corresponds to data[0] */ swap_buf (r, data,16 ); -aes_encrypt (&ctx, data, data); +aes_encrypt_new (&aes, data, data);/* Most significant octet of encryptedData corresponds to data[0] */ swap_buf (data, r,16 );SMP_DBG ("r %16phN" , r); -memzero_explicit (&ctx,sizeof (ctx)); +memzero_explicit (&aes,sizeof (aes));return err; } static int smp_c1(const u8 k[16], const u8 r[16], const u8 preq[7], const u8 pres[7], u8 _iat,
Signature · 1 line
2.52.0
Re: [PATCH 19/36] Bluetooth: SMP: Use new AES library API
net/bluetooth/smp.c static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],
Quoted 4 lines
net/bluetooth/smp.c +0
-1/* Most significant octet of plaintextData corresponds to data[0] */ swap_buf (r, data,16 ); -aes_encrypt (&ctx, data, data); +aes_encrypt_new (&aes, data, data);
One thing you might want to consider, which reduces the churn in the series.
You can use _Generic() to do type-based dispatch on the first pointer. Something like this:
void aes_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); void aes_encrypt_new(aes_encrypt_arg key, u8 out[at_least AES_BLOCK_SIZE], const u8 in[at_least AES_BLOCK_SIZE]);
#define aes_encrypt(ctx, out, in) \
_Generic(ctx, \
const struct crypto_aes_ctx *: aes_encrypt(ctx, out, in), \
aes_encrypt_arg: aes_encrypt_new(ctx, out, in))
i.e. it keeps the _new()-ism in a single header, without needing to change the drivers a second time.
~Andrew
Re: [PATCH 19/36] Bluetooth: SMP: Use new AES library API
Quoted 14 lines · On Mon, 5 Jan 2026 15:40:22 +0000 Andrew Cooper <[email protected]>…
net/bluetooth/smp.c static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],
Quoted 4 lines
net/bluetooth/smp.c +0
-1/* Most significant octet of plaintextData corresponds to data[0] */ swap_buf (r, data,16 ); -aes_encrypt (&ctx, data, data); +aes_encrypt_new (&aes, data, data);One thing you might want to consider, which reduces the churn in the series.
You can use
_Generic()to do type-based dispatch on the first pointer. Something like this:void
aes_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); voidaes_encrypt_new(aes_encrypt_arg key, u8 out[at_least AES_BLOCK_SIZE], const u8 in[at_least AES_BLOCK_SIZE]);
Quoted 8 lines
#define
aes_encrypt(ctx, out, in)\
_Generic(ctx, \
const structcrypto_aes_ctx*:aes_encrypt(ctx, out, in), \
aes_encrypt_arg:aes_encrypt_new(ctx, out, in))i.e. it keeps the _new()-ism in a single header, without needing to change the drivers a second time.
You'll need to cast the 'ctx' argument in both calls.
All the code in an _Generic() must compile cleanly in all the cases. (Totally annoying....)
David
Quoted 3 lines
~Andrew
Eric Biggers
maintainerRe: [PATCH 19/36] Bluetooth: SMP: Use new AES library API
Quoted 23 lines · David Laight
Quoted 20 lines · On Mon, 5 Jan 2026 15:40:22 +0000 Andrew Cooper <[email protected]>…
net/bluetooth/smp.c static int smp_h7(struct crypto_shash *tfm_cmac, const u8 w[16],
Quoted 4 lines
net/bluetooth/smp.c +0
-1/* Most significant octet of plaintextData corresponds to data[0] */ swap_buf (r, data,16 ); -aes_encrypt (&ctx, data, data); +aes_encrypt_new (&aes, data, data);One thing you might want to consider, which reduces the churn in the series.
You can use
_Generic()to do type-based dispatch on the first pointer. Something like this:void
aes_encrypt(const struct crypto_aes_ctx *ctx, u8 *out, const u8 *in); voidaes_encrypt_new(aes_encrypt_arg key, u8 out[at_least AES_BLOCK_SIZE], const u8 in[at_least AES_BLOCK_SIZE]);#define
aes_encrypt(ctx, out, in)\
_Generic(ctx, \
const structcrypto_aes_ctx*:aes_encrypt(ctx, out, in), \
aes_encrypt_arg:aes_encrypt_new(ctx, out, in))
Quoted 8 lines
Quoted 2 lines
i.e. it keeps the _new()-ism in a single header, without needing to change the drivers a second time.
You'll need to cast the 'ctx' argument in both calls.
All the code in an_Generic()must compile cleanly in all the cases. (Totally annoying....)David
It seems it would actually have to be:
#define aes_encrypt(key, out, in) \
_Generic(key, \ struct crypto_aes_ctx *: aes_encrypt_old((const struct crypto_aes_ctx *)key, out, in), \ const struct crypto_aes_ctx *: aes_encrypt_old((const struct crypto_aes_ctx *)key, out, in), \ struct aes_enckey *: aes_encrypt_new((const struct aes_enckey *)key, out, in), \ const struct aes_enckey *: aes_encrypt_new((const struct aes_enckey *)key, out, in), \ struct aes_key *: aes_encrypt_new((const struct aes_key *)key, out, in), \ const struct aes_key *: aes_encrypt_new((const struct aes_key *)key, out, in))
#define aes_decrypt(key, out, in) \
_Generic(key, \ struct crypto_aes_ctx *: aes_decrypt_old((const struct crypto_aes_ctx *)key, out, in), \ const struct crypto_aes_ctx *: aes_decrypt_old((const struct crypto_aes_ctx *)key, out, in), \ struct aes_key *: aes_decrypt_new((const struct aes_key *)key, out, in), \ const struct aes_key *: aes_decrypt_new((const struct aes_key *)key, out, in))
Note that both const and non-const args need to be handled.
It also doesn't work for any callers passing a 'void *' or 'const void *' and relying on an implicit cast. I didn't notice any, but that needs to be considered too.
I guess maybe it would still be worth it to avoid the "*_new" name temporarily leaking into too many files. (It goes away by the end of the series anyway.) It's just not quite as simple as you're suggesting, and all the callers have to be checked for compatibility with it.
- Eric
Eric Biggers
maintainerPATCH 20/36 chelsio: Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- .../ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c | 6 +++--- .../ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c | 8 ++++---- .../net/ethernet/chelsio/inline_crypto/chtls/chtls_hw.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-)
drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c +3 -3
@@ -168,11 +168,11 @@ static int ch_ipsec_setkey(struct xfrm_state *x, {int keylen = (x->aead->alg_key_len +7 ) /8 ;unsigned char *key = x->aead->alg_key;int ck_size, key_ctx_size =0 ;unsigned char ghash_h[AEAD_H_SIZE ]; -struct crypto_aes_ctx aes; +struct aes_enckey aes;int ret =0 ;if (keylen >3 ) { keylen -=4 ;/* nonce/salt is present in the last 4 bytes */ memcpy (sa_entry->salt, key + keylen,4 );
@@ -202,17 +202,17 @@ static int ch_ipsec_setkey(struct xfrm_state *x, key_ctx_size >> 4);/* Calculate the H = CIPH(K, 0 repeated 16 times). * It will go in key context */ - ret =aes_expandkey (&aes, key, keylen); + ret =aes_prepareenckey (&aes, key, keylen);if (ret) { sa_entry->enckey_len =0 ; goto out; }memset (ghash_h,0 ,AEAD_H_SIZE ); -aes_encrypt (&aes, ghash_h, ghash_h); +aes_encrypt_new (&aes, ghash_h, ghash_h);memzero_explicit (&aes,sizeof (aes));memcpy (sa_entry->key + (DIV_ROUND_UP (sa_entry->enckey_len,16 ) *16 ), ghash_h,AEAD_H_SIZE ); sa_entry->kctx_len = ((DIV_ROUND_UP(sa_entry->enckey_len, 16)) << 4) +
drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c +4 -4
@@ -74,11 +74,11 @@ static int chcr_ktls_save_keys(struct chcr_ktls_info *tx_info, {int ck_size, key_ctx_size, mac_key_size, keylen, ghash_size, ret;unsigned char ghash_h[TLS_CIPHER_AES_GCM_256_TAG_SIZE ];struct tls12_crypto_info_aes_gcm_128 *info_128_gcm;struct ktls_key_ctx *kctx = &tx_info->key_ctx; -struct crypto_aes_ctx aes_ctx; +struct aes_enckey aes;unsigned char *key, *salt;switch (crypto_info->cipher_type) {case TLS_CIPHER_AES_GCM_128 : info_128_gcm =
@@ -136,17 +136,17 @@ static int chcr_ktls_save_keys(struct chcr_ktls_info *tx_info,roundup (keylen,16 ) + ghash_size;/* Calculate the H = CIPH(K, 0 repeated 16 times). * It will go in key context */ - ret =aes_expandkey (&aes_ctx, key, keylen); + ret =aes_prepareenckey (&aes, key, keylen);if (ret) goto out;memset (ghash_h,0 , ghash_size); -aes_encrypt (&aes_ctx, ghash_h, ghash_h); -memzero_explicit (&aes_ctx,sizeof (aes_ctx)); +aes_encrypt_new (&aes, ghash_h, ghash_h); +memzero_explicit (&aes,sizeof (aes));/* fill the Key context */ if (direction ==TLS_OFFLOAD_CTX_DIR_TX ) { kctx->ctx_hdr = FILL_KEY_CTX_HDR(ck_size, mac_key_size,
drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_hw.c +3 -3
@@ -245,11 +245,11 @@ static int chtls_key_info(struct chtls_sock *csk, {unsigned char key[AES_MAX_KEY_SIZE ];unsigned char *key_p, *salt;unsigned char ghash_h[AEAD_H_SIZE ];int ck_size, key_ctx_size, kctx_mackey_size, salt_size; -struct crypto_aes_ctx aes; +struct aes_enckey aes;int ret; key_ctx_size =sizeof (struct _key_ctx ) +roundup (keylen,16 ) +AEAD_H_SIZE ;
@@ -289,16 +289,16 @@ static int chtls_key_info(struct chtls_sock *csk, }/* Calculate the H = CIPH(K, 0 repeated 16 times). * It will go in key context */ - ret =aes_expandkey (&aes, key, keylen); + ret =aes_prepareenckey (&aes, key, keylen);if (ret)return ret;memset (ghash_h,0 ,AEAD_H_SIZE ); -aes_encrypt (&aes, ghash_h, ghash_h); +aes_encrypt_new (&aes, ghash_h, ghash_h);memzero_explicit (&aes,sizeof (aes)); csk->tlshws.keylen = key_ctx_size;/* Copy the Key context */ if (optname ==TLS_RX ) {
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 21/36 net: phy: mscc: macsec: Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- drivers/net/phy/mscc/mscc_macsec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/phy/mscc/mscc_macsec.c +4 -4
@@ -502,19 +502,19 @@ static u32 vsc8584_macsec_flow_context_id(struct macsec_flow *flow)/* Derive the AES key to get a key for the hash autentication */ static int vsc8584_macsec_derive_key (const u8 *key,u16 key_len,u8 hkey[16 ]) {const u8 input[AES_BLOCK_SIZE ] = {0 }; -struct crypto_aes_ctx ctx; +struct aes_enckey aes;int ret; - ret =aes_expandkey (&ctx, key, key_len); + ret =aes_prepareenckey (&aes, key, key_len);if (ret)return ret; -aes_encrypt (&ctx, hkey, input); -memzero_explicit (&ctx,sizeof (ctx)); +aes_encrypt_new (&aes, hkey, input); +memzero_explicit (&aes,sizeof (aes));return 0 ; } static int vsc8584_macsec_transformation(struct phy_device *phydev, struct macsec_flow *flow,
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 22/36 staging: rtl8723bs: core: Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- drivers/staging/rtl8723bs/core/rtw_security.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)
drivers/staging/rtl8723bs/core/rtw_security.c +10 -10
@@ -635,15 +635,15 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)/* Performs a 128 bit AES encrypt with */ /* 128 bit data. */ /****************************************/ static void aes128k128d (u8 *key,u8 *data,u8 *ciphertext) { -struct crypto_aes_ctx ctx; +struct aes_enckey aes; -aes_expandkey (&ctx, key,16 ); -aes_encrypt (&ctx, ciphertext, data); -memzero_explicit (&ctx,sizeof (ctx)); +aes_prepareenckey (&aes, key,16 ); +aes_encrypt_new (&aes, ciphertext, data); +memzero_explicit (&aes,sizeof (aes)); }/************************************************/ /* construct_mic_iv() */ /* Builds the MIC IV from header fields and PN */
@@ -1404,17 +1404,17 @@ static void gf_mulx(u8 *pad)* (SP) 800-38B. */ static int omac1_aes_128_vector (u8 *key,size_t num_elem,u8 *addr[],size_t *len,u8 *mac) { -struct crypto_aes_ctx ctx; +struct aes_enckey aes;u8 cbc[AES_BLOCK_SIZE ], pad[AES_BLOCK_SIZE ];u8 *pos, *end;size_t i, e, left, total_len;int ret; - ret =aes_expandkey (&ctx, key,16 ); + ret =aes_prepareenckey (&aes, key,16 );if (ret)return -1 ;memset (cbc,0 ,AES_BLOCK_SIZE ); total_len =0 ;
@@ -1434,16 +1434,16 @@ static int omac1_aes_128_vector(u8 *key, size_t num_elem, pos = addr[e]; end = pos + len[e]; } }if (left >AES_BLOCK_SIZE ) -aes_encrypt (&ctx, cbc, cbc); +aes_encrypt_new (&aes, cbc, cbc); left -=AES_BLOCK_SIZE ; }memset (pad,0 ,AES_BLOCK_SIZE ); -aes_encrypt (&ctx, pad, pad); +aes_encrypt_new (&aes, pad, pad);gf_mulx (pad);if (left || total_len ==0 ) {for (i =0 ; i < left; i++) { cbc[i] ^= *pos++;
@@ -1457,12 +1457,12 @@ static int omac1_aes_128_vector(u8 *key, size_t num_elem,gf_mulx (pad); }for (i =0 ; i <AES_BLOCK_SIZE ; i++) pad[i] ^= cbc[i]; -aes_encrypt (&ctx, pad, mac); -memzero_explicit (&ctx,sizeof (ctx)); +aes_encrypt_new (&aes, pad, mac); +memzero_explicit (&aes,sizeof (aes));return 0 ; }/** * omac1_aes_128 - One-Key CBC MAC (OMAC1) hash with AES-128 (aka AES-CMAC)
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 23/36 crypto: arm/ghash - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- arch/arm/crypto/ghash-ce-glue.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
arch/arm/crypto/ghash-ce-glue.c +9 -5
@@ -202,24 +202,28 @@ int pmull_gcm_dec_final(int bytes, u64 dg[], char *tag,static int gcm_aes_setkey (struct crypto_aead *tfm,const u8 *inkey,unsigned int keylen) {struct gcm_key *ctx =crypto_aead_ctx (tfm); -struct crypto_aes_ctx aes_ctx; +struct aes_enckey aes_key;be128 h, k;int ret; - ret =aes_expandkey (&aes_ctx, inkey, keylen); + ret =aes_prepareenckey (&aes_key, inkey, keylen);if (ret)return -EINVAL ; -aes_encrypt (&aes_ctx, (u8 *)&k, (u8 [AES_BLOCK_SIZE ]){}); +aes_encrypt_new (&aes_key, (u8 *)&k, (u8 [AES_BLOCK_SIZE ]){}); -memcpy (ctx->rk, aes_ctx.key_enc,sizeof (ctx->rk)); +/* +* Note: this assumes that the arm implementation of the AES library +* stores the standard round keys in k.rndkeys. +*/ +memcpy (ctx->rk, aes_key.k.rndkeys,sizeof (ctx->rk)); ctx->rounds =6 + keylen /4 ; -memzero_explicit (&aes_ctx,sizeof (aes_ctx)); +memzero_explicit (&aes_key,sizeof (aes_key));ghash_reflect (ctx->h[0 ], &k); h = k;gf128mul_lle (&h, &k);
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 24/36 crypto: arm64/ghash - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- arch/arm64/crypto/ghash-ce-glue.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-)
arch/arm64/crypto/ghash-ce-glue.c +8 -21
@@ -38,11 +38,11 @@ struct ghash_key {struct arm_ghash_desc_ctx {u64 digest[GHASH_DIGEST_SIZE /sizeof (u64)]; };struct gcm_aes_ctx { -struct crypto_aes_ctx aes_key; +struct aes_enckey aes_key;u8 nonce[RFC4106_NONCE_SIZE ];struct ghash_key ghash_key; }; asmlinkage void pmull_ghash_update_p64(int blocks, u64 dg[], const char *src,
@@ -184,35 +184,23 @@ static struct shash_alg ghash_alg = { .import = ghash_import, .descsize = sizeof(struct arm_ghash_desc_ctx), .statesize = sizeof(struct ghash_desc_ctx), }; -static int num_rounds (struct crypto_aes_ctx *ctx) -{ -/* -* # of rounds specified by AES: -* 128 bit key 10 rounds -* 192 bit key 12 rounds -* 256 bit key 14 rounds -* => n byte key => 6 + (n/4) rounds -*/ -return 6 + ctx->key_length /4 ; -} -static int gcm_aes_setkey (struct crypto_aead *tfm,const u8 *inkey,unsigned int keylen) {struct gcm_aes_ctx *ctx =crypto_aead_ctx (tfm);u8 key[GHASH_BLOCK_SIZE ];be128 h;int ret; - ret =aes_expandkey (&ctx->aes_key, inkey, keylen); + ret =aes_prepareenckey (&ctx->aes_key, inkey, keylen);if (ret)return -EINVAL ; -aes_encrypt (&ctx->aes_key, key, (u8 [AES_BLOCK_SIZE ]){}); +aes_encrypt_new (&ctx->aes_key, key, (u8 [AES_BLOCK_SIZE ]){});/* needed for the fallback */ memcpy (&ctx->ghash_key.k, key,GHASH_BLOCK_SIZE );ghash_reflect (ctx->ghash_key.h[0 ], &ctx->ghash_key.k);
@@ -294,11 +282,10 @@ static void gcm_calculate_auth_mac(struct aead_request *req, u64 dg[], u32 len)static int gcm_encrypt (struct aead_request *req,char *iv,int assoclen) {struct crypto_aead *aead =crypto_aead_reqtfm (req);struct gcm_aes_ctx *ctx =crypto_aead_ctx (aead); -int nrounds =num_rounds (&ctx->aes_key);struct skcipher_walk walk;u8 buf[AES_BLOCK_SIZE ];u64 dg[2 ] = {};be128 lengths;u8 *tag;
@@ -329,12 +316,12 @@ static int gcm_encrypt(struct aead_request *req, char *iv, int assoclen) tag =NULL ; } scoped_ksimd()pmull_gcm_encrypt (nbytes, dst, src, ctx->ghash_key.h, - dg, iv, ctx->aes_key.key_enc, nrounds, - tag); + dg, iv, ctx->aes_key.k.rndkeys, + ctx->aes_key.nrounds, tag);if (unlikely (!nbytes))break ;if (unlikely (nbytes >0 && nbytes <AES_BLOCK_SIZE ))
@@ -357,11 +344,10 @@ static int gcm_encrypt(struct aead_request *req, char *iv, int assoclen)static int gcm_decrypt (struct aead_request *req,char *iv,int assoclen) {struct crypto_aead *aead =crypto_aead_reqtfm (req);struct gcm_aes_ctx *ctx =crypto_aead_ctx (aead);unsigned int authsize =crypto_aead_authsize (aead); -int nrounds =num_rounds (&ctx->aes_key);struct skcipher_walk walk;u8 otag[AES_BLOCK_SIZE ];u8 buf[AES_BLOCK_SIZE ];u64 dg[2 ] = {};be128 lengths;
@@ -399,12 +385,13 @@ static int gcm_decrypt(struct aead_request *req, char *iv, int assoclen) }scoped_ksimd () ret = pmull_gcm_decrypt(nbytes, dst, src, ctx->ghash_key.h, - dg, iv, ctx->aes_key.key_enc, - nrounds, tag, otag, authsize); + dg, iv, ctx->aes_key.k.rndkeys, + ctx->aes_key.nrounds, tag, otag, + authsize);if (unlikely (!nbytes))break ;if (unlikely (nbytes >0 && nbytes <AES_BLOCK_SIZE ))
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 25/36 crypto: x86/aes-gcm - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Since this changes the format of the AES-GCM key structures that are used by the AES-GCM assembly code, the offsets in the assembly code had to be updated to match. Note that the new key structures are smaller, since the decryption round keys are no longer unnecessarily included.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- arch/x86/crypto/aes-gcm-aesni-x86_64.S | 33 +++++++------- arch/x86/crypto/aes-gcm-vaes-avx2.S | 21 ++++----- arch/x86/crypto/aes-gcm-vaes-avx512.S | 25 ++++++----- arch/x86/crypto/aesni-intel_glue.c | 59 ++++++++++++-------------- 4 files changed, 68 insertions(+), 70 deletions(-)
arch/x86/crypto/aes-gcm-aesni-x86_64.S +17 -16
@@ -141,14 +141,15 @@ .Lzeropad_mask: .octa 0xffffffffffffffffffffffffffffffff .octa 0 // Offsets in struct aes_gcm_key_aesni -#define OFFSETOF_AESKEYLEN 480 -#define OFFSETOF_H_POWERS 496 -#define OFFSETOF_H_POWERS_XORED 624 -#define OFFSETOF_H_TIMES_X64 688 +#define OFFSETOF_AESKEYLEN 0 +#define OFFSETOF_AESROUNDKEYS 16 +#define OFFSETOF_H_POWERS 272 +#define OFFSETOF_H_POWERS_XORED 400 +#define OFFSETOF_H_TIMES_X64 464 .text // Do a vpclmulqdq, or fall back to a movdqa and a pclmulqdq. The fallback // assumes that all operands are distinct and that any mem operand is aligned.
@@ -503,13 +504,13 @@ .set H_POW1_X64, %xmm4 // H^1 * x^64 .set GFPOLY, %xmm5 // Encrypt an all-zeroes block to get the raw hash subkey. movl OFFSETOF_AESKEYLEN(KEY), %eax - lea 6*16(KEY,%rax,4), RNDKEYLAST_PTR - movdqa (KEY), H_POW1 // Zero-th round key XOR all-zeroes block - lea 16(KEY), %rax + lea OFFSETOF_AESROUNDKEYS+6*16(KEY,%rax,4), RNDKEYLAST_PTR + movdqa OFFSETOF_AESROUNDKEYS(KEY), H_POW1 + lea OFFSETOF_AESROUNDKEYS+16(KEY), %rax 1: aesenc (%rax), H_POW1 add $16, %rax cmp %rax, RNDKEYLAST_PTR jne 1b
@@ -622,11 +623,11 @@ // Increment LE_CTR eight times to generate eight little-endian counter blocks, // swap each to big-endian, and store them in AESDATA[0-7]. Also XOR them with // the zero-th AES round key. Clobbers TMP0 and TMP1. .macro _ctr_begin_8x movq .Lone(%rip), TMP0 - movdqa (KEY), TMP1 // zero-th round key + movdqa OFFSETOF_AESROUNDKEYS(KEY), TMP1 // zero-th round key .irp i, 0,1,2,3,4,5,6,7 _vpshufb BSWAP_MASK, LE_CTR, AESDATA\i pxor TMP1, AESDATA\i paddd TMP0, LE_CTR .endr
@@ -724,11 +725,11 @@ movdqa .Lbswap_mask(%rip), BSWAP_MASK movdqu (GHASH_ACC_PTR), GHASH_ACC movdqu (LE_CTR_PTR), LE_CTR movl OFFSETOF_AESKEYLEN(KEY), AESKEYLEN - lea 6*16(KEY,AESKEYLEN64,4), RNDKEYLAST_PTR + lea OFFSETOF_AESROUNDKEYS+6*16(KEY,AESKEYLEN64,4), RNDKEYLAST_PTR // If there are at least 8*16 bytes of data, then continue into the main // loop, which processes 8*16 bytes of data per iteration. // // The main loop interleaves AES and GHASH to improve performance on
@@ -743,11 +744,11 @@ add $-8*16, DATALEN jl .Lcrypt_loop_8x_done\@ .if \enc // Encrypt the first 8 plaintext blocks. _ctr_begin_8x - lea 16(KEY), %rsi + lea OFFSETOF_AESROUNDKEYS+16(KEY), %rsi .p2align 4 1: movdqa (%rsi), TMP0 _aesenc_8x TMP0 add $16, %rsi
@@ -765,11 +766,11 @@ .p2align 4 .Lcrypt_loop_8x\@: // Generate the next set of 8 counter blocks and start encrypting them. _ctr_begin_8x - lea 16(KEY), %rsi + lea OFFSETOF_AESROUNDKEYS+16(KEY), %rsi // Do a round of AES, and start the GHASH update of 8 ciphertext blocks // by doing the unreduced multiplication for the first ciphertext block. movdqa (%rsi), TMP0 add $16, %rsi
@@ -867,11 +868,11 @@ .Lcrypt_loop_1x\@: // Encrypt the next counter block. _vpshufb BSWAP_MASK, LE_CTR, TMP0 paddd ONE, LE_CTR - pxor (KEY), TMP0 + pxor OFFSETOF_AESROUNDKEYS(KEY), TMP0 lea -6*16(RNDKEYLAST_PTR), %rsi // Reduce code size cmp $24, AESKEYLEN jl 128f // AES-128? je 192f // AES-192? // AES-256
@@ -924,12 +925,12 @@ // Process a partial block of length 1 <= DATALEN <= 15. // Encrypt a counter block for the last time. pshufb BSWAP_MASK, LE_CTR - pxor (KEY), LE_CTR - lea 16(KEY), %rsi + pxor OFFSETOF_AESROUNDKEYS(KEY), LE_CTR + lea OFFSETOF_AESROUNDKEYS+16(KEY), %rsi 1: aesenc (%rsi), LE_CTR add $16, %rsi cmp %rsi, RNDKEYLAST_PTR jne 1b
@@ -1036,16 +1037,16 @@ movdqa OFFSETOF_H_TIMES_X64(KEY), H_POW1_X64 movq .Lgfpoly(%rip), GFPOLY // Make %rax point to the 6th from last AES round key. (Using signed // byte offsets -7*16 through 6*16 decreases code size.) - lea (KEY,AESKEYLEN64,4), %rax + lea OFFSETOF_AESROUNDKEYS(KEY,AESKEYLEN64,4), %rax // AES-encrypt the counter block and also multiply GHASH_ACC by H^1. // Interleave the AES and GHASH instructions to improve performance. pshufb BSWAP_MASK, %xmm0 - pxor (KEY), %xmm0 + pxor OFFSETOF_AESROUNDKEYS(KEY), %xmm0 cmp $24, AESKEYLEN jl 128f // AES-128? je 192f // AES-192? // AES-256 aesenc -7*16(%rax), %xmm0
arch/x86/crypto/aes-gcm-vaes-avx2.S +11 -10
@@ -120,12 +120,13 @@ // The number of AES blocks per vector, as a 128-bit value. .Linc_2blocks: .octa 2 // Offsets in struct aes_gcm_key_vaes_avx2 -#define OFFSETOF_AESKEYLEN 480 -#define OFFSETOF_H_POWERS 512 +#define OFFSETOF_AESKEYLEN 0 +#define OFFSETOF_AESROUNDKEYS 16 +#define OFFSETOF_H_POWERS 288 #define NUM_H_POWERS 8 #define OFFSETOFEND_H_POWERS (OFFSETOF_H_POWERS + (NUM_H_POWERS * 16)) #define OFFSETOF_H_POWERS_XORED OFFSETOFEND_H_POWERS .text
@@ -238,13 +239,13 @@ SYM_FUNC_START(aes_gcm_precompute_vaes_avx2) .set GFPOLY, %ymm6 .set GFPOLY_XMM, %xmm6 // Encrypt an all-zeroes block to get the raw hash subkey. movl OFFSETOF_AESKEYLEN(KEY), %eax - lea 6*16(KEY,%rax,4), RNDKEYLAST_PTR - vmovdqu (KEY), H_CUR_XMM // Zero-th round key XOR all-zeroes block - lea 16(KEY), %rax + lea OFFSETOF_AESROUNDKEYS+6*16(KEY,%rax,4), RNDKEYLAST_PTR + vmovdqu OFFSETOF_AESROUNDKEYS(KEY), H_CUR_XMM + lea OFFSETOF_AESROUNDKEYS+16(KEY), %rax 1: vaesenc (%rax), H_CUR_XMM, H_CUR_XMM add $16, %rax cmp %rax, RNDKEYLAST_PTR jne 1b
@@ -633,11 +634,11 @@ SYM_FUNC_END(aes_gcm_aad_update_vaes_avx2) // Generate and encrypt counter blocks in the given AESDATA vectors, excluding // the last AES round. Clobbers %rax and TMP0. .macro _aesenc_loop vecs:vararg _ctr_begin \vecs - lea 16(KEY), %rax + lea OFFSETOF_AESROUNDKEYS+16(KEY), %rax .Laesenc_loop\@: vbroadcasti128 (%rax), TMP0 _vaesenc TMP0, \vecs add $16, %rax cmp %rax, RNDKEYLAST_PTR
@@ -766,12 +767,12 @@ SYM_FUNC_END(aes_gcm_aad_update_vaes_avx2) movl OFFSETOF_AESKEYLEN(KEY), AESKEYLEN // Make RNDKEYLAST_PTR point to the last AES round key. This is the // round key with index 10, 12, or 14 for AES-128, AES-192, or AES-256 // respectively. Then load the zero-th and last round keys. - lea 6*16(KEY,AESKEYLEN64,4), RNDKEYLAST_PTR - vbroadcasti128 (KEY), RNDKEY0 + lea OFFSETOF_AESROUNDKEYS+6*16(KEY,AESKEYLEN64,4), RNDKEYLAST_PTR + vbroadcasti128 OFFSETOF_AESROUNDKEYS(KEY), RNDKEY0 vbroadcasti128 (RNDKEYLAST_PTR), RNDKEYLAST // Finish initializing LE_CTR by adding 1 to the second block. vpaddd .Lctr_pattern(%rip), LE_CTR, LE_CTR
@@ -1067,16 +1068,16 @@ SYM_FUNC_END(aes_gcm_aad_update_vaes_avx2) .if !\enc movl 8(%rsp), TAGLEN .endif // Make %rax point to the last AES round key for the chosen AES variant. - lea 6*16(KEY,AESKEYLEN64,4), %rax + lea OFFSETOF_AESROUNDKEYS+6*16(KEY,AESKEYLEN64,4), %rax // Start the AES encryption of the counter block by swapping the counter // block to big-endian and XOR-ing it with the zero-th AES round key. vpshufb BSWAP_MASK, LE_CTR, %xmm0 - vpxor (KEY), %xmm0, %xmm0 + vpxor OFFSETOF_AESROUNDKEYS(KEY), %xmm0, %xmm0 // Complete the AES encryption and multiply GHASH_ACC by H^1. // Interleave the AES and GHASH instructions to improve performance. cmp $24, AESKEYLEN jl 128f // AES-128?
arch/x86/crypto/aes-gcm-vaes-avx512.S +14 -11
@@ -84,14 +84,17 @@ // Number of powers of the hash key stored in the key struct. The powers are // stored from highest (H^NUM_H_POWERS) to lowest (H^1). #define NUM_H_POWERS 16 // Offset to AES key length (in bytes) in the key struct -#define OFFSETOF_AESKEYLEN 480 +#define OFFSETOF_AESKEYLEN 0 + +// Offset to AES round keys in the key struct +#define OFFSETOF_AESROUNDKEYS 16 // Offset to start of hash key powers array in the key struct -#define OFFSETOF_H_POWERS 512 +#define OFFSETOF_H_POWERS 320 // Offset to end of hash key powers array in the key struct. // // This is immediately followed by three zeroized padding blocks, which are // included so that partial vectors can be handled more easily. E.g. if two
@@ -299,13 +302,13 @@ SYM_FUNC_START(aes_gcm_precompute_vaes_avx512) // Get pointer to lowest set of key powers (located at end of array). lea OFFSETOFEND_H_POWERS-64(KEY), POWERS_PTR // Encrypt an all-zeroes block to get the raw hash subkey. movl OFFSETOF_AESKEYLEN(KEY), %eax - lea 6*16(KEY,%rax,4), RNDKEYLAST_PTR - vmovdqu (KEY), %xmm0 // Zero-th round key XOR all-zeroes block - add $16, KEY + lea OFFSETOF_AESROUNDKEYS+6*16(KEY,%rax,4), RNDKEYLAST_PTR + vmovdqu OFFSETOF_AESROUNDKEYS(KEY), %xmm0 + add $OFFSETOF_AESROUNDKEYS+16, KEY 1: vaesenc (KEY), %xmm0, %xmm0 add $16, KEY cmp KEY, RNDKEYLAST_PTR jne 1b
@@ -788,12 +791,12 @@ SYM_FUNC_END(aes_gcm_aad_update_vaes_avx512) movl OFFSETOF_AESKEYLEN(KEY), AESKEYLEN // Make RNDKEYLAST_PTR point to the last AES round key. This is the // round key with index 10, 12, or 14 for AES-128, AES-192, or AES-256 // respectively. Then load the zero-th and last round keys. - lea 6*16(KEY,AESKEYLEN64,4), RNDKEYLAST_PTR - vbroadcasti32x4 (KEY), RNDKEY0 + lea OFFSETOF_AESROUNDKEYS+6*16(KEY,AESKEYLEN64,4), RNDKEYLAST_PTR + vbroadcasti32x4 OFFSETOF_AESROUNDKEYS(KEY), RNDKEY0 vbroadcasti32x4 (RNDKEYLAST_PTR), RNDKEYLAST // Finish initializing LE_CTR by adding [0, 1, ...] to its low words. vpaddd .Lctr_pattern(%rip), LE_CTR, LE_CTR
@@ -832,11 +835,11 @@ SYM_FUNC_END(aes_gcm_aad_update_vaes_avx512) .if \enc // Encrypt the first 4 vectors of plaintext blocks. Leave the resulting // ciphertext in GHASHDATA[0-3] for GHASH. _ctr_begin_4x - lea 16(KEY), %rax + lea OFFSETOF_AESROUNDKEYS+16(KEY), %rax 1: vbroadcasti32x4 (%rax), RNDKEY _vaesenc_4x RNDKEY add $16, %rax cmp %rax, RNDKEYLAST_PTR
@@ -955,11 +958,11 @@ SYM_FUNC_END(aes_gcm_aad_update_vaes_avx512) // Encrypt a vector of counter blocks. This does not need to be masked. vpshufb BSWAP_MASK, LE_CTR, %zmm0 vpaddd LE_CTR_INC, LE_CTR, LE_CTR vpxord RNDKEY0, %zmm0, %zmm0 - lea 16(KEY), %rax + lea OFFSETOF_AESROUNDKEYS+16(KEY), %rax 1: vbroadcasti32x4 (%rax), RNDKEY vaesenc RNDKEY, %zmm0, %zmm0 add $16, %rax cmp %rax, RNDKEYLAST_PTR
@@ -1085,16 +1088,16 @@ SYM_FUNC_END(aes_gcm_aad_update_vaes_avx512) bzhi TAGLEN, %eax, %eax kmovd %eax, %k1 .endif // Make %rax point to the last AES round key for the chosen AES variant. - lea 6*16(KEY,AESKEYLEN64,4), %rax + lea OFFSETOF_AESROUNDKEYS+6*16(KEY,AESKEYLEN64,4), %rax // Start the AES encryption of the counter block by swapping the counter // block to big-endian and XOR-ing it with the zero-th AES round key. vpshufb BSWAP_MASK, LE_CTR, %xmm0 - vpxor (KEY), %xmm0, %xmm0 + vpxor OFFSETOF_AESROUNDKEYS(KEY), %xmm0, %xmm0 // Complete the AES encryption and multiply GHASH_ACC by H^1. // Interleave the AES and GHASH instructions to improve performance. cmp $24, AESKEYLEN jl 128f // AES-128?
arch/x86/crypto/aesni-intel_glue.c +26 -33
124 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 26/36 crypto: ccp - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- drivers/crypto/ccp/ccp-crypto-aes-cmac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/crypto/ccp/ccp-crypto-aes-cmac.c +3 -3
@@ -259,11 +259,11 @@ static int ccp_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,struct ccp_ctx *ctx =crypto_ahash_ctx_dma (tfm);struct ccp_crypto_ahash_alg *alg =ccp_crypto_ahash_alg (crypto_ahash_tfm (tfm));u64 k0_hi, k0_lo, k1_hi, k1_lo, k2_hi, k2_lo;u64 rb_hi =0x00 , rb_lo =0x87 ; -struct crypto_aes_ctx aes; +struct aes_enckey aes;__be64 *gk;int ret;switch (key_len) {case AES_KEYSIZE_128 :
@@ -282,17 +282,17 @@ static int ccp_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,/* Set to zero until complete */ ctx->u.aes.key_len =0 ;/* Set the key for the AES cipher used to generate the keys */ - ret =aes_expandkey (&aes, key, key_len); + ret =aes_prepareenckey (&aes, key, key_len);if (ret)return ret;/* Encrypt a block of zeroes - use key area in context */ memset (ctx->u.aes.key,0 ,sizeof (ctx->u.aes.key)); -aes_encrypt (&aes, ctx->u.aes.key, ctx->u.aes.key); +aes_encrypt_new (&aes, ctx->u.aes.key, ctx->u.aes.key);memzero_explicit (&aes,sizeof (aes));/* Generate K1 and K2 */ k0_hi =be64_to_cpu (*((__be64 *)ctx->u.aes.key)); k0_lo =be64_to_cpu (*((__be64 *)ctx->u.aes.key +1 ));
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 27/36 crypto: chelsio - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_key and struct aes_enckey). In encryption-only use cases, this eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() and aes_decrypt_new() will be renamed to aes_encrypt() and aes_decrypt(), respectively, once all callers of the old aes_encrypt() and aes_decrypt() have been updated.
--- drivers/crypto/chelsio/chcr_algo.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/crypto/chelsio/chcr_algo.c +8 -8
@@ -1026,11 +1026,11 @@ static int chcr_update_tweak(struct skcipher_request *req, u8 *iv, u32 isfinal) {struct crypto_skcipher *tfm =crypto_skcipher_reqtfm (req);struct ablk_ctx *ablkctx =ABLK_CTX (c_ctx (tfm));struct chcr_skcipher_req_ctx *reqctx =skcipher_request_ctx (req); -struct crypto_aes_ctx aes; +struct aes_key aes;int ret, i;u8 *key;unsigned int keylen;int round = reqctx->last_req_len /AES_BLOCK_SIZE ;int round8 = round /8 ;
@@ -1042,24 +1042,24 @@ static int chcr_update_tweak(struct skcipher_request *req, u8 *iv,/* For a 192 bit key remove the padded zeroes which was * added in chcr_xts_setkey */ if (KEY_CONTEXT_CK_SIZE_G (ntohl (ablkctx->key_ctx_hdr)) ==CHCR_KEYCTX_CIPHER_KEY_SIZE_192 ) - ret =aes_expandkey (&aes, key, keylen -8 ); + ret =aes_preparekey (&aes, key, keylen -8 );else - ret =aes_expandkey (&aes, key, keylen); + ret =aes_preparekey (&aes, key, keylen);if (ret)return ret; -aes_encrypt (&aes, iv, iv); +aes_encrypt_new (&aes, iv, iv);for (i =0 ; i < round8; i++)gf128mul_x8_ble ((le128 *)iv, (le128 *)iv);for (i =0 ; i < (round %8 ); i++)gf128mul_x_ble ((le128 *)iv, (le128 *)iv);if (!isfinal) -aes_decrypt (&aes, iv, iv); +aes_decrypt_new (&aes, iv, iv);memzero_explicit (&aes,sizeof (aes));return 0 ; }
@@ -3404,11 +3404,11 @@ static int chcr_gcm_setkey(struct crypto_aead *aead, const u8 *key, {struct chcr_aead_ctx *aeadctx =AEAD_CTX (a_ctx (aead));struct chcr_gcm_ctx *gctx =GCM_CTX (aeadctx);unsigned int ck_size;int ret =0 , key_ctx_size =0 ; -struct crypto_aes_ctx aes; +struct aes_enckey aes; aeadctx->enckey_len =0 ;crypto_aead_clear_flags (aeadctx->sw_cipher,CRYPTO_TFM_REQ_MASK );crypto_aead_set_flags (aeadctx->sw_cipher,crypto_aead_get_flags (aead) &CRYPTO_TFM_REQ_MASK );
@@ -3442,17 +3442,17 @@ static int chcr_gcm_setkey(struct crypto_aead *aead, const u8 *key,0 ,0 , key_ctx_size >> 4);/* Calculate the H = CIPH(K, 0 repeated 16 times). * It will go in key context */ - ret =aes_expandkey (&aes, key, keylen); + ret =aes_prepareenckey (&aes, key, keylen);if (ret) { aeadctx->enckey_len =0 ; goto out; }memset (gctx->ghash_h,0 ,AEAD_H_SIZE ); -aes_encrypt (&aes, gctx->ghash_h, gctx->ghash_h); +aes_encrypt_new (&aes, gctx->ghash_h, gctx->ghash_h);memzero_explicit (&aes,sizeof (aes)); out:return ret; }
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 28/36 crypto: crypto4xx - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- drivers/crypto/amcc/crypto4xx_alg.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/crypto/amcc/crypto4xx_alg.c +5 -5
@@ -489,23 +489,23 @@ static int crypto4xx_aes_gcm_validate_keylen(unsigned int keylen) }static int crypto4xx_compute_gcm_hash_key_sw (__le32 *hash_start,const u8 *key,unsigned int keylen) { -struct crypto_aes_ctx ctx; +struct aes_enckey aes;uint8_t src[16 ] = {0 };int rc; - rc =aes_expandkey (&ctx, key, keylen); + rc =aes_prepareenckey (&aes, key, keylen);if (rc) { -pr_err ("aes_expandkey() failed: %d\n" , rc); +pr_err ("aes_prepareenckey() failed: %d\n" , rc);return rc; } -aes_encrypt (&ctx, src, src); +aes_encrypt_new (&aes, src, src);crypto4xx_memcpy_to_le32 (hash_start, src,16 ); -memzero_explicit (&ctx,sizeof (ctx)); +memzero_explicit (&aes,sizeof (aes));return 0 ; }int crypto4xx_setkey_aes_gcm (struct crypto_aead *cipher,const u8 *key,unsigned int keylen)
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 29/36 crypto: drbg - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- crypto/df_sp80090a.c | 30 ++++++++++------------------- crypto/drbg.c | 12 ++++++------ drivers/crypto/xilinx/xilinx-trng.c | 8 ++++---- include/crypto/df_sp80090a.h | 2 +- 4 files changed, 21 insertions(+), 31 deletions(-)
crypto/df_sp80090a.c +10 -20
@@ -12,31 +12,21 @@#include <linux/string.h> #include <crypto/aes.h> #include <crypto/df_sp80090a.h> #include <crypto/internal/drbg.h> -static void drbg_kcapi_symsetkey (struct crypto_aes_ctx *aesctx, -const unsigned char *key, -u8 keylen); -static void drbg_kcapi_symsetkey (struct crypto_aes_ctx *aesctx, -const unsigned char *key,u8 keylen) -{ -aes_expandkey (aesctx, key, keylen); -} - -static void drbg_kcapi_sym (struct crypto_aes_ctx *aesctx, -unsigned char *outval, +static void drbg_kcapi_sym (struct aes_enckey *aeskey,unsigned char *outval,const struct drbg_string *in,u8 blocklen_bytes) {/* there is only component in *in */ BUG_ON (in->len < blocklen_bytes); -aes_encrypt (aesctx, outval, in->buf); +aes_encrypt_new (aeskey, outval, in->buf); }/* BCC function for CTR DRBG as defined in 10.4.3 */ -static void drbg_ctr_bcc (struct crypto_aes_ctx *aesctx, +static void drbg_ctr_bcc (struct aes_enckey *aeskey,unsigned char *out,const unsigned char *key,struct list_head *in,u8 blocklen_bytes,u8 keylen) {
@@ -45,30 +35,30 @@ static void drbg_ctr_bcc(struct crypto_aes_ctx *aesctx,short cnt =0 ;drbg_string_fill (&data, out, blocklen_bytes);/* 10.4.3 step 2 / 4 */ -drbg_kcapi_symsetkey (aesctx, key, keylen); +aes_prepareenckey (aeskey, key, keylen);list_for_each_entry (curr, in, list) {const unsigned char *pos = curr->buf;size_t len = curr->len;/* 10.4.3 step 4.1 */ while (len) {/* 10.4.3 step 4.2 */ if (blocklen_bytes == cnt) { cnt =0 ; -drbg_kcapi_sym (aesctx, out, &data, blocklen_bytes); +drbg_kcapi_sym (aeskey, out, &data, blocklen_bytes); } out[cnt] ^= *pos; pos++; cnt++; len--; } }/* 10.4.3 step 4.2 for last block */ if (cnt) -drbg_kcapi_sym (aesctx, out, &data, blocklen_bytes); +drbg_kcapi_sym (aeskey, out, &data, blocklen_bytes); }/* * scratchpad usage: drbg_ctr_update is interlinked with crypto_drbg_ctr_df * (and drbg_ctr_bcc, but this function does not need any temporary buffers),
@@ -108,11 +98,11 @@ static void drbg_ctr_bcc(struct crypto_aes_ctx *aesctx,* possibilities. * refer to crypto_drbg_ctr_df_datalen() to get required length */ /* Derivation Function for CTR DRBG as defined in 10.4.2 */ -int crypto_drbg_ctr_df (struct crypto_aes_ctx *aesctx, +int crypto_drbg_ctr_df (struct aes_enckey *aeskey,unsigned char *df_data,size_t bytes_to_return,struct list_head *seedlist,u8 blocklen_bytes,u8 statelen) {
@@ -185,11 +175,11 @@ int crypto_drbg_ctr_df(struct crypto_aes_ctx *aesctx,* holds zeros after allocation -- even the increment of i * is irrelevant as the increment remains within length of i */ drbg_cpu_to_be32 (i, iv);/* 10.4.2 step 9.2 -- BCC and concatenation with temp */ -drbg_ctr_bcc (aesctx, temp + templen,K , &bcc_list, +drbg_ctr_bcc (aeskey, temp + templen,K , &bcc_list, blocklen_bytes, keylen);/* 10.4.2 step 9.3 */ i++; templen += blocklen_bytes; }
@@ -199,19 +189,19 @@ int crypto_drbg_ctr_df(struct crypto_aes_ctx *aesctx,drbg_string_fill (&cipherin,X , blocklen_bytes);/* 10.4.2 step 12: overwriting of outval is implemented in next step */ /* 10.4.2 step 13 */ -drbg_kcapi_symsetkey (aesctx, temp, keylen); +aes_prepareenckey (aeskey, temp, keylen);while (generated_len < bytes_to_return) {short blocklen =0 ;/* * 10.4.2 step 13.1: the truncation of the key length is * implicit as the key is only drbg_blocklen in size based on * the implementation of the cipher function callback */ -drbg_kcapi_sym (aesctx,X , &cipherin, blocklen_bytes); +drbg_kcapi_sym (aeskey,X , &cipherin, blocklen_bytes); blocklen = (blocklen_bytes < (bytes_to_return - generated_len)) ? blocklen_bytes : (bytes_to_return - generated_len);/* 10.4.2 step 13.2 and 14 */
crypto/drbg.c +6 -6
@@ -1503,13 +1503,13 @@ static int drbg_kcapi_hash(struct drbg_state *drbg, unsigned char *outval,#endif /* (CONFIG_CRYPTO_DRBG_HASH || CONFIG_CRYPTO_DRBG_HMAC) */ #ifdef CONFIG_CRYPTO_DRBG_CTR static int drbg_fini_sym_kernel (struct drbg_state *drbg) { -struct crypto_aes_ctx *aesctx = (struct crypto_aes_ctx *)drbg->priv_data; +struct aes_enckey *aeskey = drbg->priv_data; -kfree (aesctx); +kfree (aeskey); drbg->priv_data =NULL ;if (drbg->ctr_handle)crypto_free_skcipher (drbg->ctr_handle); drbg->ctr_handle =NULL ;
@@ -1524,20 +1524,20 @@ static int drbg_fini_sym_kernel(struct drbg_state *drbg)return 0 ; }static int drbg_init_sym_kernel (struct drbg_state *drbg) { -struct crypto_aes_ctx *aesctx; +struct aes_enckey *aeskey;struct crypto_skcipher *sk_tfm;struct skcipher_request *req;unsigned int alignmask;char ctr_name[CRYPTO_MAX_ALG_NAME ]; - aesctx =kzalloc (sizeof (*aesctx),GFP_KERNEL ); -if (!aesctx) + aeskey =kzalloc (sizeof (*aeskey),GFP_KERNEL ); +if (!aeskey)return -ENOMEM ; - drbg->priv_data = aesctx; + drbg->priv_data = aeskey;if (snprintf (ctr_name,CRYPTO_MAX_ALG_NAME ,"ctr(%s)" , drbg->core->backend_cra_name) >=CRYPTO_MAX_ALG_NAME ) {drbg_fini_sym_kernel (drbg);return -EINVAL ;
drivers/crypto/xilinx/xilinx-trng.c +4 -4
@@ -58,11 +58,11 @@struct xilinx_rng {void __iomem *rng_base;struct device *dev;unsigned char *scratchpadbuf; -struct crypto_aes_ctx *aesctx; +struct aes_enckey *aeskey;struct mutex lock;/* Protect access to TRNG device */ struct hwrng trng; };struct xilinx_rng_ctx {
@@ -196,11 +196,11 @@ static int xtrng_reseed_internal(struct xilinx_rng *rng)/* collect random data to use it as entropy (input for DF) */ ret =xtrng_collect_random_data (rng, entropy,TRNG_SEED_LEN_BYTES , true);if (ret !=TRNG_SEED_LEN_BYTES )return -EINVAL ; - ret =crypto_drbg_ctr_df (rng->aesctx, rng->scratchpadbuf, + ret =crypto_drbg_ctr_df (rng->aeskey, rng->scratchpadbuf,TRNG_SEED_LEN_BYTES , &seedlist,AES_BLOCK_SIZE ,TRNG_SEED_LEN_BYTES );if (ret)return ret;
@@ -347,12 +347,12 @@ static int xtrng_probe(struct platform_device *pdev)if (IS_ERR (rng->rng_base)) {dev_err (&pdev->dev,"Failed to map resource %pe\n" , rng->rng_base);return PTR_ERR (rng->rng_base); } - rng->aesctx =devm_kzalloc (&pdev->dev,sizeof (*rng->aesctx),GFP_KERNEL ); -if (!rng->aesctx) + rng->aeskey =devm_kzalloc (&pdev->dev,sizeof (*rng->aeskey),GFP_KERNEL ); +if (!rng->aeskey)return -ENOMEM ; sb_size =crypto_drbg_ctr_df_datalen (TRNG_SEED_LEN_BYTES ,AES_BLOCK_SIZE ); rng->scratchpadbuf =devm_kzalloc (&pdev->dev, sb_size,GFP_KERNEL );if (!rng->scratchpadbuf) {
include/crypto/df_sp80090a.h +1 -1
@@ -16,11 +16,11 @@ static inline int crypto_drbg_ctr_df_datalen(u8 statelen, u8 blocklen) blocklen +/* pad */ blocklen +/* iv */ statelen + blocklen;/* temp */ } -int crypto_drbg_ctr_df (struct crypto_aes_ctx *aes, +int crypto_drbg_ctr_df (struct aes_enckey *aes,unsigned char *df_data,size_t bytes_to_return,struct list_head *seedlist,u8 blocklen_bytes,u8 statelen);
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 30/36 crypto: inside-secure - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note that this driver used crypto_aes_ctx::key_enc, but only to access the copy of the raw key that is stored at the beginning of the expanded key. To eliminate the dependency on this field, instead just access the raw key directly, which is already available in the relevant functions.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- .../crypto/inside-secure/safexcel_cipher.c | 14 ++++----- drivers/crypto/inside-secure/safexcel_hash.c | 30 +++++++++---------- 2 files changed, 21 insertions(+), 23 deletions(-)
drivers/crypto/inside-secure/safexcel_cipher.c +6 -8
@@ -2505,37 +2505,35 @@ static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, unsigned int len) {struct crypto_tfm *tfm =crypto_aead_tfm (ctfm);struct safexcel_cipher_ctx *ctx =crypto_tfm_ctx (tfm);struct safexcel_crypto_priv *priv = ctx->base.priv; -struct crypto_aes_ctx aes; +struct aes_enckey aes;u32 hashkey[AES_BLOCK_SIZE >>2 ];int ret, i; - ret =aes_expandkey (&aes, key, len); -if (ret) { -memzero_explicit (&aes,sizeof (aes)); + ret =aes_prepareenckey (&aes, key, len); +if (ret)return ret; - }if (priv->flags &EIP197_TRC_CACHE && ctx->base.ctxr_dma) {for (i =0 ; i < len /sizeof (u32); i++) { -if (le32_to_cpu (ctx->key[i]) != aes.key_enc[i]) { +if (ctx->key[i] !=get_unaligned ((__le32 *)key + i)) { ctx->base.needs_inv = true;break ; } } }for (i =0 ; i < len /sizeof (u32); i++) - ctx->key[i] =cpu_to_le32 (aes.key_enc[i]); + ctx->key[i] =get_unaligned ((__le32 *)key + i); ctx->key_len = len;/* Compute hash key by encrypting zeroes with cipher key */ memset (hashkey,0 ,AES_BLOCK_SIZE ); -aes_encrypt (&aes, (u8 *)hashkey, (u8 *)hashkey); +aes_encrypt_new (&aes, (u8 *)hashkey, (u8 *)hashkey);if (priv->flags &EIP197_TRC_CACHE && ctx->base.ctxr_dma) {for (i =0 ; i <AES_BLOCK_SIZE /sizeof (u32); i++) {if (be32_to_cpu (ctx->base.ipad.be[i]) != hashkey[i]) { ctx->base.needs_inv = true;
drivers/crypto/inside-secure/safexcel_hash.c +15 -15
@@ -28,11 +28,11 @@ struct safexcel_ahash_ctx {bool cbcmac;bool do_fallback;bool fb_init_done;bool fb_do_setkey; -struct crypto_aes_ctx *aes; +struct aes_enckey *aes;struct crypto_ahash *fback;struct crypto_shash *shpre;struct shash_desc *shdesc; };
@@ -820,11 +820,11 @@ static int safexcel_ahash_final(struct ahash_request *areq)/* K3 */ result[i] =swab32 (ctx->base.ipad.word[i +4 ]); } areq->result[0 ] ^=0x80 ;// 10- padding -aes_encrypt (ctx->aes, areq->result, areq->result); +aes_encrypt_new (ctx->aes, areq->result, areq->result);return 0 ; }else if (unlikely (req->hmac && (req->len == req->block_sz) && !areq->nbytes)) {/*
@@ -1974,27 +1974,27 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, {struct safexcel_ahash_ctx *ctx =crypto_tfm_ctx (crypto_ahash_tfm (tfm));u32 key_tmp[3 *AES_BLOCK_SIZE /sizeof (u32)];int ret, i; - ret =aes_expandkey (ctx->aes, key, len); + ret =aes_prepareenckey (ctx->aes, key, len);if (ret)return ret;/* precompute the XCBC key material */ -aes_encrypt (ctx->aes, (u8 *)key_tmp +2 *AES_BLOCK_SIZE , -"\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1" ); -aes_encrypt (ctx->aes, (u8 *)key_tmp, -"\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2" ); -aes_encrypt (ctx->aes, (u8 *)key_tmp +AES_BLOCK_SIZE , -"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" ); +aes_encrypt_new (ctx->aes, (u8 *)key_tmp +2 *AES_BLOCK_SIZE , +"\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1" ); +aes_encrypt_new (ctx->aes, (u8 *)key_tmp, +"\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2" ); +aes_encrypt_new (ctx->aes, (u8 *)key_tmp +AES_BLOCK_SIZE , +"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" );for (i =0 ; i <3 *AES_BLOCK_SIZE /sizeof (u32); i++) ctx->base.ipad.word[i] =swab32 (key_tmp[i]); - ret =aes_expandkey (ctx->aes, - (u8 *)key_tmp +2 *AES_BLOCK_SIZE , -AES_MIN_KEY_SIZE ); + ret =aes_prepareenckey (ctx->aes, + (u8 *)key_tmp +2 *AES_BLOCK_SIZE , +AES_MIN_KEY_SIZE );if (ret)return ret; ctx->alg =CONTEXT_CONTROL_CRYPTO_ALG_XCBC128 ; ctx->key_sz =AES_MIN_KEY_SIZE +2 *AES_BLOCK_SIZE ;
@@ -2060,21 +2060,21 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,u64 _const[2 ];u8 msb_mask, gfmask;int ret, i;/* precompute the CMAC key material */ - ret =aes_expandkey (ctx->aes, key, len); + ret =aes_prepareenckey (ctx->aes, key, len);if (ret)return ret;for (i =0 ; i < len /sizeof (u32); i++) - ctx->base.ipad.word[i +8 ] =swab32 (ctx->aes->key_enc[i]); + ctx->base.ipad.word[i +8 ] =get_unaligned_be32 (&key[4 * i]);/* code below borrowed from crypto/cmac.c */ /* encrypt the zero block */ memset (consts,0 ,AES_BLOCK_SIZE ); -aes_encrypt (ctx->aes, (u8 *)consts, (u8 *)consts); +aes_encrypt_new (ctx->aes, (u8 *)consts, (u8 *)consts); gfmask =0x87 ; _const[0 ] =be64_to_cpu (consts[1 ]); _const[1 ] =be64_to_cpu (consts[0 ]);
Signature · 1 line
2.52.0
Re: [PATCH 30/36] crypto: inside-secure - Use new AES library API
Quoted 15 lines · Eric Biggers
drivers/crypto/inside-secure/safexcel_cipher.c +1
-3@@ -2505,37 +2505,35 @@ static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, unsigned int len) {struct crypto_tfm *tfm =crypto_aead_tfm (ctfm);struct safexcel_cipher_ctx *ctx =crypto_tfm_ctx (tfm);struct safexcel_crypto_priv *priv = ctx->base.priv; -struct crypto_aes_ctx aes; +struct aes_enckey aes;u32 hashkey[AES_BLOCK_SIZE >>2 ];int ret, i; - ret =aes_expandkey (&aes, key, len); -if (ret) {
drivers/crypto/inside-secure/safexcel_cipher.c static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, · line 2520
Quoted 10 lines
drivers/crypto/inside-secure/safexcel_cipher.c +3
-3-memzero_explicit (&aes,sizeof (aes)); + ret =aes_prepareenckey (&aes, key, len); +if (ret)return ret; - }if (priv->flags &EIP197_TRC_CACHE && ctx->base.ctxr_dma) {for (i =0 ; i < len /sizeof (u32); i++) { -if (le32_to_cpu (ctx->key[i]) != aes.key_enc[i]) { +if (ctx->key[i] !=get_unaligned ((__le32 *)key + i)) {
"key" is big-endian. Casting it to __le32 does not seem correct. Did you mean "get_unaligned_le32", which also convert the endianness?
drivers/crypto/inside-secure/safexcel_cipher.c static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, · line 2528
Quoted 9 lines
drivers/crypto/inside-secure/safexcel_cipher.c +1
-1ctx->base.needs_inv = true;break ; } } }for (i =0 ; i < len /sizeof (u32); i++) - ctx->key[i] =cpu_to_le32 (aes.key_enc[i]); + ctx->key[i] =get_unaligned ((__le32 *)key + i);
Same here.
Quoted 12 lines
drivers/crypto/inside-secure/safexcel_cipher.c +1
-1ctx->key_len = len;/* Compute hash key by encrypting zeroes with cipher key */ memset (hashkey,0 ,AES_BLOCK_SIZE ); -aes_encrypt (&aes, (u8 *)hashkey, (u8 *)hashkey); +aes_encrypt_new (&aes, (u8 *)hashkey, (u8 *)hashkey);if (priv->flags &EIP197_TRC_CACHE && ctx->base.ctxr_dma) {for (i =0 ; i <AES_BLOCK_SIZE /sizeof (u32); i++) {if (be32_to_cpu (ctx->base.ipad.be[i]) != hashkey[i]) { ctx->base.needs_inv = true;
Eric Biggers
maintainerRe: [PATCH 30/36] crypto: inside-secure - Use new AES library API
Quoted 22 lines · Qingfang Deng
Quoted 21 lines · Eric Biggers
drivers/crypto/inside-secure/safexcel_cipher.c +3
-5@@ -2505,37 +2505,35 @@ static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, unsigned int len) {struct crypto_tfm *tfm =crypto_aead_tfm (ctfm);struct safexcel_cipher_ctx *ctx =crypto_tfm_ctx (tfm);struct safexcel_crypto_priv *priv = ctx->base.priv; -struct crypto_aes_ctx aes; +struct aes_enckey aes;u32 hashkey[AES_BLOCK_SIZE >>2 ];int ret, i; - ret =aes_expandkey (&aes, key, len); -if (ret) { -memzero_explicit (&aes,sizeof (aes)); + ret =aes_prepareenckey (&aes, key, len); +if (ret)return ret; - }
Quoted 7 lines
drivers/crypto/inside-secure/safexcel_cipher.c static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, · line 2520
Quoted 4 lines
drivers/crypto/inside-secure/safexcel_cipher.c +1
-1if (priv->flags &EIP197_TRC_CACHE && ctx->base.ctxr_dma) {for (i =0 ; i < len /sizeof (u32); i++) { -if (le32_to_cpu (ctx->key[i]) != aes.key_enc[i]) { +if (ctx->key[i] !=get_unaligned ((__le32 *)key + i)) {"key" is big-endian. Casting it to
__le32does not seem correct. Did you mean "get_unaligned_le32", which also convert the endianness?
No. Previously, in this driver the 32-bit words of the AES key went from little endian in their original byte array in 'key', to CPU endian in 'aes.key_enc' (via the get_unaligned_le32() in aes_expandkey()), to little endian in 'ctx->key' (via the cpu_to_le32() in this function). Note that ctx->key is an array of __le32.
Those two conversions canceled out. So I've simplified it to just grab the little endian words of the key directly.
- Eric
Eric Biggers
maintainerPATCH 31/36 crypto: omap - Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- drivers/crypto/omap-aes-gcm.c | 6 +++--- drivers/crypto/omap-aes.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-)
drivers/crypto/omap-aes-gcm.c +3 -3
@@ -175,11 +175,11 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd,static int do_encrypt_iv (struct aead_request *req,u32 *tag,u32 *iv) {struct omap_aes_gcm_ctx *ctx =crypto_aead_ctx (crypto_aead_reqtfm (req)); -aes_encrypt (&ctx->actx, (u8 *)tag, (u8 *)iv); +aes_encrypt_new (&ctx->akey, (u8 *)tag, (const u8 *)iv);return 0 ; }void omap_aes_gcm_dma_out_callback (void *data) {
@@ -312,11 +312,11 @@ int omap_aes_gcm_setkey(struct crypto_aead *tfm, const u8 *key, unsigned int keylen) {struct omap_aes_gcm_ctx *ctx =crypto_aead_ctx (tfm);int ret; - ret =aes_expandkey (&ctx->actx, key, keylen); + ret =aes_prepareenckey (&ctx->akey, key, keylen);if (ret)return ret;memcpy (ctx->octx.key, key, keylen); ctx->octx.keylen = keylen;
@@ -332,11 +332,11 @@ int omap_aes_4106gcm_setkey(struct crypto_aead *tfm, const u8 *key,if (keylen <4 )return -EINVAL ; keylen -=4 ; - ret =aes_expandkey (&ctx->actx, key, keylen); + ret =aes_prepareenckey (&ctx->akey, key, keylen);if (ret)return ret;memcpy (ctx->octx.key, key, keylen);memcpy (ctx->octx.nonce, key + keylen,4 );
drivers/crypto/omap-aes.h +1 -1
@@ -96,11 +96,11 @@ struct omap_aes_ctx {struct crypto_skcipher *fallback; };struct omap_aes_gcm_ctx {struct omap_aes_ctx octx; -struct crypto_aes_ctx actx; +struct aes_enckey akey; };struct omap_aes_reqctx {struct omap_aes_dev *dd;unsigned long mode;
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 32/36 lib/crypto: aescfb: Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- drivers/char/tpm/tpm2-sessions.c | 10 +++++----- include/crypto/aes.h | 4 ++-- lib/crypto/aescfb.c | 30 +++++++++++++++--------------- 3 files changed, 22 insertions(+), 22 deletions(-)
drivers/char/tpm/tpm2-sessions.c +5 -5
@@ -124,11 +124,11 @@ struct tpm2_auth {* session_key and passphrase. */ u8 session_key[SHA256_DIGEST_SIZE ];u8 passphrase[SHA256_DIGEST_SIZE ];int passphrase_len; -struct crypto_aes_ctx aes_ctx; +struct aes_enckey aes_key;/* saved session attributes: */ u8 attrs;__be32 ordinal;/*
@@ -675,12 +675,12 @@ int tpm_buf_fill_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf) + auth->passphrase_len,"CFB" , auth->our_nonce, auth->tpm_nonce,AES_KEY_BYTES +AES_BLOCK_SIZE , auth->scratch); len =tpm_buf_read_u16 (buf, &offset_p); -aes_expandkey (&auth->aes_ctx, auth->scratch,AES_KEY_BYTES ); -aescfb_encrypt (&auth->aes_ctx, &buf->data[offset_p], +aes_prepareenckey (&auth->aes_key, auth->scratch,AES_KEY_BYTES ); +aescfb_encrypt (&auth->aes_key, &buf->data[offset_p], &buf->data[offset_p], len, auth->scratch +AES_KEY_BYTES );/* reset p to beginning of parameters for HMAC */ offset_p -=2 ; }
@@ -856,12 +856,12 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf, + auth->passphrase_len,"CFB" , auth->tpm_nonce, auth->our_nonce,AES_KEY_BYTES +AES_BLOCK_SIZE , auth->scratch); len =tpm_buf_read_u16 (buf, &offset_p); -aes_expandkey (&auth->aes_ctx, auth->scratch,AES_KEY_BYTES ); -aescfb_decrypt (&auth->aes_ctx, &buf->data[offset_p], +aes_prepareenckey (&auth->aes_key, auth->scratch,AES_KEY_BYTES ); +aescfb_decrypt (&auth->aes_key, &buf->data[offset_p], &buf->data[offset_p], len, auth->scratch +AES_KEY_BYTES ); } out:
include/crypto/aes.h +2 -2
@@ -342,11 +342,11 @@ void aes_decrypt_new(const struct aes_key *key, u8 out[at_least AES_BLOCK_SIZE],extern const u8 crypto_aes_sbox[];extern const u8 crypto_aes_inv_sbox[]; extern const u32 __cacheline_aligned aes_enc_tab[256]; extern const u32 __cacheline_aligned aes_dec_tab[256]; -void aescfb_encrypt (const struct crypto_aes_ctx *ctx,u8 *dst,const u8 *src, +void aescfb_encrypt (const struct aes_enckey *key,u8 *dst,const u8 *src,int len,const u8 iv[AES_BLOCK_SIZE ]); -void aescfb_decrypt (const struct crypto_aes_ctx *ctx,u8 *dst,const u8 *src, +void aescfb_decrypt (const struct aes_enckey *key,u8 *dst,const u8 *src,int len,const u8 iv[AES_BLOCK_SIZE ]);#endif
lib/crypto/aescfb.c +15 -15
@@ -9,11 +9,11 @@#include <crypto/algapi.h> #include <linux/export.h> #include <linux/module.h> #include <asm/irqflags.h> -static void aescfb_encrypt_block (const struct crypto_aes_ctx *ctx,void *dst, +static void aescfb_encrypt_block (const struct aes_enckey *key,void *dst,const void *src) {unsigned long flags;/*
@@ -23,31 +23,31 @@ static void aescfb_encrypt_block(const struct crypto_aes_ctx *ctx, void *dst,* extent by pulling the entire S-box into the caches before doing any * substitutions, but this strategy is more effective when running with * interrupts disabled. */ local_irq_save (flags); -aes_encrypt (ctx, dst, src); +aes_encrypt_new (key, dst, src);local_irq_restore (flags); }/** * aescfb_encrypt - Perform AES-CFB encryption on a block of data * -* @ctx: The AES-CFB key schedule +* @key: The AES-CFB key schedule * @dst: Pointer to the ciphertext output buffer * @src: Pointer the plaintext (may equal @dst for encryption in place) * @len: The size in bytes of the plaintext and ciphertext. * @iv: The initialization vector (IV) to use for this block of data */ -void aescfb_encrypt (const struct crypto_aes_ctx *ctx,u8 *dst,const u8 *src, +void aescfb_encrypt (const struct aes_enckey *key,u8 *dst,const u8 *src,int len,const u8 iv[AES_BLOCK_SIZE ]) {u8 ks[AES_BLOCK_SIZE ];const u8 *v = iv;while (len >0 ) { -aescfb_encrypt_block (ctx, ks, v); +aescfb_encrypt_block (key, ks, v);crypto_xor_cpy (dst, src, ks,min (len,AES_BLOCK_SIZE )); v = dst; dst +=AES_BLOCK_SIZE ; src +=AES_BLOCK_SIZE ;
@@ -59,31 +59,31 @@ void aescfb_encrypt(const struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src,EXPORT_SYMBOL (aescfb_encrypt);/** * aescfb_decrypt - Perform AES-CFB decryption on a block of data * -* @ctx: The AES-CFB key schedule +* @key: The AES-CFB key schedule * @dst: Pointer to the plaintext output buffer * @src: Pointer the ciphertext (may equal @dst for decryption in place) * @len: The size in bytes of the plaintext and ciphertext. * @iv: The initialization vector (IV) to use for this block of data */ -void aescfb_decrypt (const struct crypto_aes_ctx *ctx,u8 *dst,const u8 *src, +void aescfb_decrypt (const struct aes_enckey *key,u8 *dst,const u8 *src,int len,const u8 iv[AES_BLOCK_SIZE ]) {u8 ks[2 ][AES_BLOCK_SIZE ]; -aescfb_encrypt_block (ctx, ks[0 ], iv); +aescfb_encrypt_block (key, ks[0 ], iv);for (int i =0 ; len >0 ; i ^=1 ) {if (len >AES_BLOCK_SIZE )/* * Generate the keystream for the next block before * performing the XOR, as that may update in place and * overwrite the ciphertext. */ -aescfb_encrypt_block (ctx, ks[!i], src); +aescfb_encrypt_block (key, ks[!i], src);crypto_xor_cpy (dst, src, ks[i],min (len,AES_BLOCK_SIZE )); dst +=AES_BLOCK_SIZE ; src +=AES_BLOCK_SIZE ;
@@ -212,34 +212,34 @@ static struct { };static int __init libaescfb_init (void ) {for (int i =0 ; i <ARRAY_SIZE (aescfb_tv); i++) { -struct crypto_aes_ctx ctx; +struct aes_enckey key;u8 buf[64 ]; -if (aes_expandkey (&ctx, aescfb_tv[i].key, aescfb_tv[i].klen)) { -pr_err ("aes_expandkey() failed on vector %d\n" , i); +if (aes_prepareenckey (&key, aescfb_tv[i].key, aescfb_tv[i].klen)) { +pr_err ("aes_prepareenckey() failed on vector %d\n" , i);return -ENODEV ; } -aescfb_encrypt (&ctx, buf, aescfb_tv[i].ptext, aescfb_tv[i].len, +aescfb_encrypt (&key, buf, aescfb_tv[i].ptext, aescfb_tv[i].len, aescfb_tv[i].iv);if (memcmp (buf, aescfb_tv[i].ctext, aescfb_tv[i].len)) {pr_err ("aescfb_encrypt() #1 failed on vector %d\n" , i);return -ENODEV ; }/* decrypt in place */ -aescfb_decrypt (&ctx, buf, buf, aescfb_tv[i].len, aescfb_tv[i].iv); +aescfb_decrypt (&key, buf, buf, aescfb_tv[i].len, aescfb_tv[i].iv);if (memcmp (buf, aescfb_tv[i].ptext, aescfb_tv[i].len)) {pr_err ("aescfb_decrypt() failed on vector %d\n" , i);return -ENODEV ; }/* encrypt in place */ -aescfb_encrypt (&ctx, buf, buf, aescfb_tv[i].len, aescfb_tv[i].iv); +aescfb_encrypt (&key, buf, buf, aescfb_tv[i].len, aescfb_tv[i].iv);if (memcmp (buf, aescfb_tv[i].ctext, aescfb_tv[i].len)) {pr_err ("aescfb_encrypt() #2 failed on vector %d\n" , i);return -ENODEV ; }
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 33/36 lib/crypto: aesgcm: Use new AES library API
In reply to Eric BiggersSwitch from the old AES library functions (which use struct crypto_aes_ctx) to the new ones (which use struct aes_enckey). This eliminates the unnecessary computation and caching of the decryption round keys. The new AES en/decryption functions are also much faster and use AES instructions when supported by the CPU.
Note: aes_encrypt_new() will be renamed to aes_encrypt() once all callers of the old aes_encrypt() have been updated.
--- include/crypto/gcm.h | 2 +- lib/crypto/aesgcm.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-)
include/crypto/gcm.h +1 -1
@@ -64,11 +64,11 @@ static inline int crypto_ipsec_check_assoclen(unsigned int assoclen)return 0 ; }struct aesgcm_ctx {be128 ghash_key; -struct crypto_aes_ctx aes_ctx; +struct aes_enckey aes_key;unsigned int authsize; };int aesgcm_expandkey (struct aesgcm_ctx *ctx,const u8 *key,unsigned int keysize,unsigned int authsize);
lib/crypto/aesgcm.c +6 -6
@@ -10,11 +10,11 @@#include <crypto/ghash.h> #include <linux/export.h> #include <linux/module.h> #include <asm/irqflags.h> -static void aesgcm_encrypt_block (const struct crypto_aes_ctx *ctx,void *dst, +static void aesgcm_encrypt_block (const struct aes_enckey *key,void *dst,const void *src) {unsigned long flags;/*
@@ -24,11 +24,11 @@ static void aesgcm_encrypt_block(const struct crypto_aes_ctx *ctx, void *dst,* mitigates this risk to some extent by pulling the entire S-box into * the caches before doing any substitutions, but this strategy is more * effective when running with interrupts disabled. */ local_irq_save (flags); -aes_encrypt (ctx, dst, src); +aes_encrypt_new (key, dst, src);local_irq_restore (flags); }/** * aesgcm_expandkey - Expands the AES and GHASH keys for the AES-GCM key
@@ -47,16 +47,16 @@ int aesgcm_expandkey(struct aesgcm_ctx *ctx, const u8 *key, {u8 kin[AES_BLOCK_SIZE ] = {};int ret; ret =crypto_gcm_check_authsize (authsize) ?: -aes_expandkey (&ctx->aes_ctx, key, keysize); +aes_prepareenckey (&ctx->aes_key, key, keysize);if (ret)return ret; ctx->authsize = authsize; -aesgcm_encrypt_block (&ctx->aes_ctx, &ctx->ghash_key, kin); +aesgcm_encrypt_block (&ctx->aes_key, &ctx->ghash_key, kin);return 0 ; }EXPORT_SYMBOL (aesgcm_expandkey);
@@ -95,11 +95,11 @@ static void aesgcm_mac(const struct aesgcm_ctx *ctx, const u8 *src, int src_len,aesgcm_ghash (&ghash, &ctx->ghash_key, assoc, assoc_len);aesgcm_ghash (&ghash, &ctx->ghash_key, src, src_len);aesgcm_ghash (&ghash, &ctx->ghash_key, &tail,sizeof (tail)); ctr[3 ] =cpu_to_be32 (1 ); -aesgcm_encrypt_block (&ctx->aes_ctx, buf, ctr); +aesgcm_encrypt_block (&ctx->aes_key, buf, ctr);crypto_xor_cpy (authtag, buf, (u8 *)&ghash, ctx->authsize);memzero_explicit (&ghash,sizeof (ghash));memzero_explicit (buf,sizeof (buf)); }
@@ -117,11 +117,11 @@ static void aesgcm_crypt(const struct aesgcm_ctx *ctx, u8 *dst, const u8 *src,* inadvertent IV reuse, which must be avoided at all cost for * stream ciphers such as AES-CTR. Given the range of 'int * len', this cannot happen, so no explicit test is necessary. */ ctr[3 ] =cpu_to_be32 (n++); -aesgcm_encrypt_block (&ctx->aes_ctx, buf, ctr); +aesgcm_encrypt_block (&ctx->aes_key, buf, ctr);crypto_xor_cpy (dst, src, buf,min (len,AES_BLOCK_SIZE )); dst +=AES_BLOCK_SIZE ; src +=AES_BLOCK_SIZE ; len -=AES_BLOCK_SIZE ;
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 34/36 lib/crypto: aes: Remove old AES en/decryption functions
In reply to Eric BiggersNow that no callers of the original aes_encrypt() and aes_decrypt() remain, remove them. This frees up their names for aes_encrypt_new() and aes_decrypt_new() to be renamed to.
--- include/crypto/aes.h | 16 ------ lib/crypto/aes.c | 118 ------------------------------------------- 2 files changed, 134 deletions(-)
include/crypto/aes.h +0 -16
@@ -293,26 +293,10 @@ int aes_preparekey(struct aes_key *key, const u8 *in_key, size_t key_len);* Context: Any context. */ int aes_prepareenckey (struct aes_enckey *enc_key,const u8 *in_key,size_t key_len); -/** -* aes_encrypt - Encrypt a single AES block -* @ctx: Context struct containing the key schedule -* @out: Buffer to store the ciphertext -* @in: Buffer containing the plaintext -*/ -void aes_encrypt (const struct crypto_aes_ctx *ctx,u8 *out,const u8 *in); - -/** -* aes_decrypt - Decrypt a single AES block -* @ctx: Context struct containing the key schedule -* @out: Buffer to store the plaintext -* @in: Buffer containing the ciphertext -*/ -void aes_decrypt (const struct crypto_aes_ctx *ctx,u8 *out,const u8 *in); -typedef union {const struct aes_enckey *enc_key;const struct aes_key *full_key; }aes_encrypt_arg __attribute__ ((__transparent_union__));
lib/crypto/aes.c +0 -118
148 lines not on this page · raw message
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 35/36 lib/crypto: aes: Drop "_new" suffix from en/decryption functions
In reply to Eric BiggersNow that all callers of aes_encrypt() and aes_decrypt() have been updated to use aes_encrypt_new() and aes_decrypt_new() instead, and the original aes_encrypt() and aes_decrypt() have been removed, drop the "_new" suffix. This completes the migration to the revised AES API, which uses a different type for the key argument and is more efficient when the user only requires the encryption direction of the cipher.
--- arch/arm/crypto/aes-neonbs-glue.c | 8 ++++---- arch/arm/crypto/ghash-ce-glue.c | 2 +- arch/arm64/crypto/ghash-ce-glue.c | 2 +- arch/riscv/crypto/aes-riscv64-glue.c | 2 +- arch/x86/crypto/aesni-intel_glue.c | 2 +- crypto/aes.c | 4 ++-- crypto/df_sp80090a.c | 2 +- drivers/crypto/amcc/crypto4xx_alg.c | 2 +- drivers/crypto/ccp/ccp-crypto-aes-cmac.c | 2 +- drivers/crypto/chelsio/chcr_algo.c | 6 +++--- drivers/crypto/inside-secure/safexcel_cipher.c | 2 +- drivers/crypto/inside-secure/safexcel_hash.c | 16 ++++++++-------- drivers/crypto/omap-aes-gcm.c | 2 +- .../chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c | 2 +- .../chelsio/inline_crypto/ch_ktls/chcr_ktls.c | 2 +- .../chelsio/inline_crypto/chtls/chtls_hw.c | 2 +- drivers/net/phy/mscc/mscc_macsec.c | 2 +- drivers/staging/rtl8723bs/core/rtw_security.c | 8 ++++---- include/crypto/aes.h | 12 ++++++------ lib/crypto/aes.c | 12 ++++++------ lib/crypto/aescfb.c | 2 +- lib/crypto/aesgcm.c | 2 +- net/bluetooth/smp.c | 2 +- 23 files changed, 49 insertions(+), 49 deletions(-)
arch/arm/crypto/aes-neonbs-glue.c +4 -4
@@ -154,11 +154,11 @@ static int cbc_encrypt(struct skcipher_request *req)u8 *dst = walk.dst.virt.addr;u8 *prev = walk.iv;do {crypto_xor_cpy (dst, src, prev,AES_BLOCK_SIZE ); -aes_encrypt_new (&ctx->fallback, dst, dst); +aes_encrypt (&ctx->fallback, dst, dst); prev = dst; src +=AES_BLOCK_SIZE ; dst +=AES_BLOCK_SIZE ; nbytes -=AES_BLOCK_SIZE ; }while (nbytes >=AES_BLOCK_SIZE );
@@ -280,11 +280,11 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt, err =skcipher_walk_virt (&walk, req, true);if (err)return err; -aes_encrypt_new (&ctx->tweak_key, walk.iv, walk.iv); +aes_encrypt (&ctx->tweak_key, walk.iv, walk.iv);while (walk.nbytes >=AES_BLOCK_SIZE ) {unsigned int blocks = walk.nbytes /AES_BLOCK_SIZE ;int reorder_last_tweak = !encrypt && tail >0 ;
@@ -312,13 +312,13 @@ static int __xts_crypt(struct skcipher_request *req, bool encrypt,scatterwalk_map_and_copy (buf, req->src, req->cryptlen, tail,0 );crypto_xor (buf, req->iv,AES_BLOCK_SIZE );if (encrypt) -aes_encrypt_new (&ctx->fallback, buf, buf); +aes_encrypt (&ctx->fallback, buf, buf);else -aes_decrypt_new (&ctx->fallback, buf, buf); +aes_decrypt (&ctx->fallback, buf, buf);crypto_xor (buf, req->iv,AES_BLOCK_SIZE );scatterwalk_map_and_copy (buf, req->dst, req->cryptlen -AES_BLOCK_SIZE ,AES_BLOCK_SIZE + tail,1 );
arch/arm/crypto/ghash-ce-glue.c +1 -1
@@ -210,11 +210,11 @@ static int gcm_aes_setkey(struct crypto_aead *tfm, const u8 *inkey, ret =aes_prepareenckey (&aes_key, inkey, keylen);if (ret)return -EINVAL ; -aes_encrypt_new (&aes_key, (u8 *)&k, (u8 [AES_BLOCK_SIZE ]){}); +aes_encrypt (&aes_key, (u8 *)&k, (u8 [AES_BLOCK_SIZE ]){});/* * Note: this assumes that the arm implementation of the AES library * stores the standard round keys in k.rndkeys. */
arch/arm64/crypto/ghash-ce-glue.c +1 -1
@@ -196,11 +196,11 @@ static int gcm_aes_setkey(struct crypto_aead *tfm, const u8 *inkey, ret =aes_prepareenckey (&ctx->aes_key, inkey, keylen);if (ret)return -EINVAL ; -aes_encrypt_new (&ctx->aes_key, key, (u8 [AES_BLOCK_SIZE ]){}); +aes_encrypt (&ctx->aes_key, key, (u8 [AES_BLOCK_SIZE ]){});/* needed for the fallback */ memcpy (&ctx->ghash_key.k, key,GHASH_BLOCK_SIZE );ghash_reflect (ctx->ghash_key.h[0 ], &ctx->ghash_key.k);
arch/riscv/crypto/aes-riscv64-glue.c +1 -1
@@ -320,11 +320,11 @@ static int riscv64_aes_xts_crypt(struct skcipher_request *req, bool enc)if (req->cryptlen <AES_BLOCK_SIZE )return -EINVAL ;/* Encrypt the IV with the tweak key to get the first tweak. */ -aes_encrypt_new (&ctx->tweak_key, req->iv, req->iv); +aes_encrypt (&ctx->tweak_key, req->iv, req->iv); err =skcipher_walk_virt (&walk, req, false);/* * If the message length isn't divisible by the AES block size and the
arch/x86/crypto/aesni-intel_glue.c +1 -1
@@ -1211,11 +1211,11 @@ static int gcm_setkey(struct crypto_aead *tfm, const u8 *raw_key,be128 h1 = {};be128 h;int i;/* Encrypt the all-zeroes block to get the hash key H^1 */ -aes_encrypt_new (&key->aes_key, (u8 *)&h1, (u8 *)&h1); +aes_encrypt (&key->aes_key, (u8 *)&h1, (u8 *)&h1);/* Compute H^1 * x^-1 */ h = h1;gf128mul_lle (&h, (const be128 *)x_to_the_minus1);
crypto/aes.c +2 -2
@@ -21,18 +21,18 @@ static int crypto_aes_setkey(struct crypto_tfm *tfm, const u8 *in_key,static void crypto_aes_encrypt (struct crypto_tfm *tfm,u8 *out,const u8 *in) {const struct aes_key *key =crypto_tfm_ctx (tfm); -aes_encrypt_new (key, out, in); +aes_encrypt (key, out, in); }static void crypto_aes_decrypt (struct crypto_tfm *tfm,u8 *out,const u8 *in) {const struct aes_key *key =crypto_tfm_ctx (tfm); -aes_decrypt_new (key, out, in); +aes_decrypt (key, out, in); }static struct crypto_alg alg = { .cra_name ="aes" , .cra_driver_name ="aes-lib" ,
crypto/df_sp80090a.c +1 -1
@@ -17,11 +17,11 @@static void drbg_kcapi_sym (struct aes_enckey *aeskey,unsigned char *outval,const struct drbg_string *in,u8 blocklen_bytes) {/* there is only component in *in */ BUG_ON (in->len < blocklen_bytes); -aes_encrypt_new (aeskey, outval, in->buf); +aes_encrypt (aeskey, outval, in->buf); }/* BCC function for CTR DRBG as defined in 10.4.3 */ static void drbg_ctr_bcc(struct aes_enckey *aeskey,
drivers/crypto/amcc/crypto4xx_alg.c +1 -1
@@ -499,11 +499,11 @@ static int crypto4xx_compute_gcm_hash_key_sw(__le32 *hash_start, const u8 *key,if (rc) {pr_err ("aes_prepareenckey() failed: %d\n" , rc);return rc; } -aes_encrypt_new (&aes, src, src); +aes_encrypt (&aes, src, src);crypto4xx_memcpy_to_le32 (hash_start, src,16 );memzero_explicit (&aes,sizeof (aes));return 0 ; }
drivers/crypto/ccp/ccp-crypto-aes-cmac.c +1 -1
@@ -288,11 +288,11 @@ static int ccp_aes_cmac_setkey(struct crypto_ahash *tfm, const u8 *key,if (ret)return ret;/* Encrypt a block of zeroes - use key area in context */ memset (ctx->u.aes.key,0 ,sizeof (ctx->u.aes.key)); -aes_encrypt_new (&aes, ctx->u.aes.key, ctx->u.aes.key); +aes_encrypt (&aes, ctx->u.aes.key, ctx->u.aes.key);memzero_explicit (&aes,sizeof (aes));/* Generate K1 and K2 */ k0_hi =be64_to_cpu (*((__be64 *)ctx->u.aes.key)); k0_lo =be64_to_cpu (*((__be64 *)ctx->u.aes.key +1 ));
drivers/crypto/chelsio/chcr_algo.c +3 -3
@@ -1047,19 +1047,19 @@ static int chcr_update_tweak(struct skcipher_request *req, u8 *iv, ret =aes_preparekey (&aes, key, keylen -8 ); else ret =aes_preparekey (&aes, key, keylen);if (ret)return ret; -aes_encrypt_new (&aes, iv, iv); +aes_encrypt (&aes, iv, iv);for (i =0 ; i < round8; i++)gf128mul_x8_ble ((le128 *)iv, (le128 *)iv);for (i =0 ; i < (round %8 ); i++)gf128mul_x_ble ((le128 *)iv, (le128 *)iv);if (!isfinal) -aes_decrypt_new (&aes, iv, iv); +aes_decrypt (&aes, iv, iv);memzero_explicit (&aes,sizeof (aes));return 0 ; }
@@ -3448,11 +3448,11 @@ static int chcr_gcm_setkey(struct crypto_aead *aead, const u8 *key,if (ret) { aeadctx->enckey_len =0 ; goto out; }memset (gctx->ghash_h,0 ,AEAD_H_SIZE ); -aes_encrypt_new (&aes, gctx->ghash_h, gctx->ghash_h); +aes_encrypt (&aes, gctx->ghash_h, gctx->ghash_h);memzero_explicit (&aes,sizeof (aes)); out:return ret; }
drivers/crypto/inside-secure/safexcel_cipher.c +1 -1
@@ -2529,11 +2529,11 @@ static int safexcel_aead_gcm_setkey(struct crypto_aead *ctfm, const u8 *key, ctx->key_len = len;/* Compute hash key by encrypting zeroes with cipher key */ memset (hashkey,0 ,AES_BLOCK_SIZE ); -aes_encrypt_new (&aes, (u8 *)hashkey, (u8 *)hashkey); +aes_encrypt (&aes, (u8 *)hashkey, (u8 *)hashkey);if (priv->flags &EIP197_TRC_CACHE && ctx->base.ctxr_dma) {for (i =0 ; i <AES_BLOCK_SIZE /sizeof (u32); i++) {if (be32_to_cpu (ctx->base.ipad.be[i]) != hashkey[i]) { ctx->base.needs_inv = true;
drivers/crypto/inside-secure/safexcel_hash.c +8 -8
@@ -820,11 +820,11 @@ static int safexcel_ahash_final(struct ahash_request *areq)/* K3 */ result[i] =swab32 (ctx->base.ipad.word[i +4 ]); } areq->result[0 ] ^=0x80 ;// 10- padding -aes_encrypt_new (ctx->aes, areq->result, areq->result); +aes_encrypt (ctx->aes, areq->result, areq->result);return 0 ; }else if (unlikely (req->hmac && (req->len == req->block_sz) && !areq->nbytes)) {/*
@@ -1979,16 +1979,16 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, ret =aes_prepareenckey (ctx->aes, key, len);if (ret)return ret;/* precompute the XCBC key material */ -aes_encrypt_new (ctx->aes, (u8 *)key_tmp +2 *AES_BLOCK_SIZE , -"\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1" ); -aes_encrypt_new (ctx->aes, (u8 *)key_tmp, -"\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2" ); -aes_encrypt_new (ctx->aes, (u8 *)key_tmp +AES_BLOCK_SIZE , -"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" ); +aes_encrypt (ctx->aes, (u8 *)key_tmp +2 *AES_BLOCK_SIZE , +"\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1\x1" ); +aes_encrypt (ctx->aes, (u8 *)key_tmp, +"\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2\x2" ); +aes_encrypt (ctx->aes, (u8 *)key_tmp +AES_BLOCK_SIZE , +"\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3\x3" );for (i =0 ; i <3 *AES_BLOCK_SIZE /sizeof (u32); i++) ctx->base.ipad.word[i] =swab32 (key_tmp[i]); ret = aes_prepareenckey(ctx->aes, (u8 *)key_tmp + 2 * AES_BLOCK_SIZE,
@@ -2070,11 +2070,11 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, ctx->base.ipad.word[i +8 ] =get_unaligned_be32 (&key[4 * i]);/* code below borrowed from crypto/cmac.c */ /* encrypt the zero block */ memset (consts,0 ,AES_BLOCK_SIZE ); -aes_encrypt_new (ctx->aes, (u8 *)consts, (u8 *)consts); +aes_encrypt (ctx->aes, (u8 *)consts, (u8 *)consts); gfmask =0x87 ; _const[0 ] =be64_to_cpu (consts[1 ]); _const[1 ] =be64_to_cpu (consts[0 ]);
drivers/crypto/omap-aes-gcm.c +1 -1
@@ -175,11 +175,11 @@ static int omap_aes_gcm_copy_buffers(struct omap_aes_dev *dd,static int do_encrypt_iv (struct aead_request *req,u32 *tag,u32 *iv) {struct omap_aes_gcm_ctx *ctx =crypto_aead_ctx (crypto_aead_reqtfm (req)); -aes_encrypt_new (&ctx->akey, (u8 *)tag, (const u8 *)iv); +aes_encrypt (&ctx->akey, (u8 *)tag, (const u8 *)iv);return 0 ; }void omap_aes_gcm_dma_out_callback (void *data) {
drivers/net/ethernet/chelsio/inline_crypto/ch_ipsec/chcr_ipsec.c +1 -1
@@ -208,11 +208,11 @@ static int ch_ipsec_setkey(struct xfrm_state *x,if (ret) { sa_entry->enckey_len =0 ; goto out; }memset (ghash_h,0 ,AEAD_H_SIZE ); -aes_encrypt_new (&aes, ghash_h, ghash_h); +aes_encrypt (&aes, ghash_h, ghash_h);memzero_explicit (&aes,sizeof (aes));memcpy (sa_entry->key + (DIV_ROUND_UP (sa_entry->enckey_len,16 ) *16 ), ghash_h,AEAD_H_SIZE ); sa_entry->kctx_len = ((DIV_ROUND_UP(sa_entry->enckey_len, 16)) << 4) +
drivers/net/ethernet/chelsio/inline_crypto/ch_ktls/chcr_ktls.c +1 -1
@@ -141,11 +141,11 @@ static int chcr_ktls_save_keys(struct chcr_ktls_info *tx_info, ret =aes_prepareenckey (&aes, key, keylen);if (ret) goto out;memset (ghash_h,0 , ghash_size); -aes_encrypt_new (&aes, ghash_h, ghash_h); +aes_encrypt (&aes, ghash_h, ghash_h);memzero_explicit (&aes,sizeof (aes));/* fill the Key context */ if (direction ==TLS_OFFLOAD_CTX_DIR_TX ) { kctx->ctx_hdr = FILL_KEY_CTX_HDR(ck_size,
drivers/net/ethernet/chelsio/inline_crypto/chtls/chtls_hw.c +1 -1
@@ -294,11 +294,11 @@ static int chtls_key_info(struct chtls_sock *csk, ret =aes_prepareenckey (&aes, key, keylen);if (ret)return ret;memset (ghash_h,0 ,AEAD_H_SIZE ); -aes_encrypt_new (&aes, ghash_h, ghash_h); +aes_encrypt (&aes, ghash_h, ghash_h);memzero_explicit (&aes,sizeof (aes)); csk->tlshws.keylen = key_ctx_size;/* Copy the Key context */ if (optname ==TLS_RX ) {
drivers/net/phy/mscc/mscc_macsec.c +1 -1
@@ -509,11 +509,11 @@ static int vsc8584_macsec_derive_key(const u8 *key, u16 key_len, u8 hkey[16]) ret =aes_prepareenckey (&aes, key, key_len);if (ret)return ret; -aes_encrypt_new (&aes, hkey, input); +aes_encrypt (&aes, hkey, input);memzero_explicit (&aes,sizeof (aes));return 0 ; } static int vsc8584_macsec_transformation(struct phy_device *phydev,
drivers/staging/rtl8723bs/core/rtw_security.c +4 -4
@@ -638,11 +638,11 @@ u32 rtw_tkip_decrypt(struct adapter *padapter, u8 *precvframe)static void aes128k128d (u8 *key,u8 *data,u8 *ciphertext) {struct aes_enckey aes;aes_prepareenckey (&aes, key,16 ); -aes_encrypt_new (&aes, ciphertext, data); +aes_encrypt (&aes, ciphertext, data);memzero_explicit (&aes,sizeof (aes)); }/************************************************/ /* construct_mic_iv() */
@@ -1434,16 +1434,16 @@ static int omac1_aes_128_vector(u8 *key, size_t num_elem, pos = addr[e]; end = pos + len[e]; } }if (left >AES_BLOCK_SIZE ) -aes_encrypt_new (&aes, cbc, cbc); +aes_encrypt (&aes, cbc, cbc); left -=AES_BLOCK_SIZE ; }memset (pad,0 ,AES_BLOCK_SIZE ); -aes_encrypt_new (&aes, pad, pad); +aes_encrypt (&aes, pad, pad);gf_mulx (pad);if (left || total_len ==0 ) {for (i =0 ; i < left; i++) { cbc[i] ^= *pos++;
@@ -1457,11 +1457,11 @@ static int omac1_aes_128_vector(u8 *key, size_t num_elem,gf_mulx (pad); }for (i =0 ; i <AES_BLOCK_SIZE ; i++) pad[i] ^= cbc[i]; -aes_encrypt_new (&aes, pad, mac); +aes_encrypt (&aes, pad, mac);memzero_explicit (&aes,sizeof (aes));return 0 ; }/**
include/crypto/aes.h +6 -6
@@ -299,31 +299,31 @@ typedef union {const struct aes_enckey *enc_key;const struct aes_key *full_key; } aes_encrypt_arg __attribute__ ((__transparent_union__));/** -* aes_encrypt_new() - Encrypt a single AES block +* aes_encrypt() - Encrypt a single AES block * @key: The AES key, as a pointer to either an encryption-only key * (struct aes_enckey) or a full, bidirectional key (struct aes_key). * @out: Buffer to store the ciphertext block * @in: Buffer containing the plaintext block * * Context: Any context. */ -void aes_encrypt_new(aes_encrypt_arg key, u8 out[at_least AES_BLOCK_SIZE], - const u8 in[at_least AES_BLOCK_SIZE]); +void aes_encrypt(aes_encrypt_arg key, u8 out[at_least AES_BLOCK_SIZE], + const u8 in[at_least AES_BLOCK_SIZE]);/** -* aes_decrypt_new() - Decrypt a single AES block +* aes_decrypt() - Decrypt a single AES block * @key: The AES key, previously initialized by aes_preparekey() * @out: Buffer to store the plaintext block * @in: Buffer containing the ciphertext block * * Context: Any context. */ -void aes_decrypt_new(const struct aes_key *key, u8 out[at_least AES_BLOCK_SIZE], - const u8 in[at_least AES_BLOCK_SIZE]); +void aes_decrypt(const struct aes_key *key, u8 out[at_least AES_BLOCK_SIZE], + const u8 in[at_least AES_BLOCK_SIZE]);extern const u8 crypto_aes_sbox[];extern const u8 crypto_aes_inv_sbox[]; extern const u32 __cacheline_aligned aes_enc_tab[256]; extern const u32 __cacheline_aligned aes_dec_tab[256];
lib/crypto/aes.c +6 -6
@@ -500,23 +500,23 @@ int aes_prepareenckey(struct aes_enckey *key, const u8 *in_key, size_t key_len) {return __aes_preparekey (key,NULL , in_key, key_len); }EXPORT_SYMBOL (aes_prepareenckey); -void aes_encrypt_new (aes_encrypt_arg key,u8 out[AES_BLOCK_SIZE ], -const u8 in[AES_BLOCK_SIZE ]) +void aes_encrypt (aes_encrypt_arg key,u8 out[AES_BLOCK_SIZE ], +const u8 in[AES_BLOCK_SIZE ]) {aes_encrypt_arch (key.enc_key, out, in); } -EXPORT_SYMBOL (aes_encrypt_new); +EXPORT_SYMBOL (aes_encrypt); -void aes_decrypt_new (const struct aes_key *key,u8 out[AES_BLOCK_SIZE ], -const u8 in[AES_BLOCK_SIZE ]) +void aes_decrypt (const struct aes_key *key,u8 out[AES_BLOCK_SIZE ], +const u8 in[AES_BLOCK_SIZE ]) {aes_decrypt_arch (key, out, in); } -EXPORT_SYMBOL (aes_decrypt_new); +EXPORT_SYMBOL (aes_decrypt);#ifdef aes_mod_init_archstatic int __init aes_mod_init (void ) {aes_mod_init_arch ();
lib/crypto/aescfb.c +1 -1
@@ -23,11 +23,11 @@ static void aescfb_encrypt_block(const struct aes_enckey *key, void *dst,* extent by pulling the entire S-box into the caches before doing any * substitutions, but this strategy is more effective when running with * interrupts disabled. */ local_irq_save (flags); -aes_encrypt_new (key, dst, src); +aes_encrypt (key, dst, src);local_irq_restore (flags); }/** * aescfb_encrypt - Perform AES-CFB encryption on a block of data
lib/crypto/aesgcm.c +1 -1
@@ -24,11 +24,11 @@ static void aesgcm_encrypt_block(const struct aes_enckey *key, void *dst,* mitigates this risk to some extent by pulling the entire S-box into * the caches before doing any substitutions, but this strategy is more * effective when running with interrupts disabled. */ local_irq_save (flags); -aes_encrypt_new (key, dst, src); +aes_encrypt (key, dst, src);local_irq_restore (flags); }/** * aesgcm_expandkey - Expands the AES and GHASH keys for the AES-GCM key
net/bluetooth/smp.c +1 -1
@@ -390,11 +390,11 @@ static int smp_e(const u8 *k, u8 *r) }/* Most significant octet of plaintextData corresponds to data[0] */ swap_buf (r, data,16 ); -aes_encrypt_new (&aes, data, data); +aes_encrypt (&aes, data, data);/* Most significant octet of encryptedData corresponds to data[0] */ swap_buf (data, r,16 );SMP_DBG ("r %16phN" , r);
Signature · 1 line
2.52.0
Eric Biggers
maintainerPATCH 36/36 lib/crypto: aes: Drop 'volatile' from aes_sbox and aes_inv_sbox
In reply to Eric BiggersThe volatile keyword is no longer necessary or useful on aes_sbox and aes_inv_sbox, since the table prefetching is now done using a helper function that casts to volatile itself and also includes an optimization barrier. Since it prevents some compiler optimizations, remove it.
--- lib/crypto/aes.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
lib/crypto/aes.c +3 -7
@@ -9,15 +9,11 @@#include <linux/crypto.h> #include <linux/export.h> #include <linux/module.h> #include <linux/unaligned.h> -/* -* Emit the sbox as volatile const to prevent the compiler from doing -* constant folding on sbox references involving fixed indexes. -*/ -static volatile const u8 __cacheline_aligned aes_sbox[] = { +static const u8 __cacheline_aligned aes_sbox[] = {0x63 ,0x7c ,0x77 ,0x7b ,0xf2 ,0x6b ,0x6f ,0xc5 ,0x30 ,0x01 ,0x67 ,0x2b ,0xfe ,0xd7 ,0xab ,0x76 ,0xca ,0x82 ,0xc9 ,0x7d ,0xfa ,0x59 ,0x47 ,0xf0 ,0xad ,0xd4 ,0xa2 ,0xaf ,0x9c ,0xa4 ,0x72 ,0xc0 ,0xb7 ,0xfd ,0x93 ,0x26 ,0x36 ,0x3f ,0xf7 ,0xcc ,
@@ -48,11 +44,11 @@ static volatile const u8 __cacheline_aligned aes_sbox[] = {0x9b ,0x1e ,0x87 ,0xe9 ,0xce ,0x55 ,0x28 ,0xdf ,0x8c ,0xa1 ,0x89 ,0x0d ,0xbf ,0xe6 ,0x42 ,0x68 , 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16, }; -static volatile const u8 __cacheline_aligned aes_inv_sbox[] = { +static const u8 __cacheline_aligned aes_inv_sbox[] = {0x52 ,0x09 ,0x6a ,0xd5 ,0x30 ,0x36 ,0xa5 ,0x38 ,0xbf ,0x40 ,0xa3 ,0x9e ,0x81 ,0xf3 ,0xd7 ,0xfb ,0x7c ,0xe3 ,0x39 ,0x82 ,0x9b ,0x2f ,0xff ,0x87 ,0x34 ,0x8e ,0x43 ,0x44 ,0xc4 ,0xde ,0xe9 ,0xcb , 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
@@ -428,11 +424,11 @@ static void __maybe_unused aes_decrypt_generic(const u32 inv_rndkeys[], w[1 ] = w1; w[2 ] = w2; w[3 ] = w3; }while (--n); -aes_prefetch ((const void *)aes_inv_sbox,sizeof (aes_inv_sbox)); +aes_prefetch (aes_inv_sbox,sizeof (aes_inv_sbox));put_unaligned_le32 (declast_quarterround (w,0 , *rkp++), &out[0 ]);put_unaligned_le32 (declast_quarterround (w,1 , *rkp++), &out[4 ]);put_unaligned_le32 (declast_quarterround (w,2 , *rkp++), &out[8 ]);put_unaligned_le32 (declast_quarterround (w,3 , *rkp++), &out[12 ]); }
Signature · 1 line
2.52.0
Quoted 19 lines · Eric Biggers
This series applies to libcrypto-next. It can also be retrieved from:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git aes-lib-v1
This series makes three main improvements to the kernel's AES library:
1. Make it use the kernel's existing architecture-optimized AES code, including AES instructions, when available. Previously, only the traditional crypto API gave access to the optimized AES code. (As a reminder, AES instructions typically make AES over 10 times as fast as the generic code. They also make it constant-time.)
2. Support preparing an AES key for only the forward direction of the block cipher, using about half as much memory. This is a helpful optimization for many common AES modes of operation. It also helps keep structs small enough to be allocated on the stack, especially considering potential future library APIs for AES modes.
Quoted 6 lines
3. Replace the library's generic AES implementation with a much faster one that is almost as fast as "aes-generic", while still keeping the table size reasonably small and maintaining some constant-time hardening. This allows removing "aes-generic", unifying the current two generic AES implementations in the kernel tree.
Architectures that support memory operands will be impacted by dropping the pre-rotated lookup tables, especially if they have few GPRs.
I suspect that doesn't really matter in practice: if your pre-AESNI IA-32 workload has a bottleneck on "aes-generic", you would have probably moved it to a different machine by now. But the performance delta will likely be noticeable so it is something that deserves a mention.
Quoted 51 lines
(1) and (2) end up being interrelated: the existing 'struct
crypto_aes_ctx' does not work for either one (in general). Thus, this series reworks the AES library to be based around new data types 'structaes_key' and 'structaes_enckey'.As has been the case for other algorithms, to achieve (1) without duplicating the architecture-optimized code, it had to be moved into
lib/crypto/rather than copied. To allow actually removing the arch-specificcrypto_cipher"aes" algorithms, a consolidated "aes-lib"crypto_cipheralgorithm which simply wraps the library is also added. That's most easily done with it replacing "aes-generic" too, so that is done too. (That's another reason for doing (3) at the same time.)As usual, care is taken to support all the existing arch-optimized code. This makes it possible for users of the traditional crypto API to switch to the library API, which is generally much easier to use, without being concerned about performance regressions.
That being said, this series only deals with the bare (single-block) AES library. Future patchsets are expected to build on this work to provide architecture-optimized library APIs for specific AES modes of operation.
Eric Biggers (36):
crypto: powerpc/aes - Rename structaes_key
lib/crypto: aes: Introduce improved AES library
crypto: arm/aes-neonbs - Use AES library for single blocks
crypto: arm/aes - Switch to aes_enc_tab[] and aes_dec_tab[]
crypto: arm64/aes - Switch to aes_enc_tab[] and aes_dec_tab[]
crypto: arm64/aes - SelectCRYPTO_LIB_SHA256from correct places
crypto: aegis - Switch from crypto_ft_tab[] to aes_enc_tab[]
crypto: aes - Remove aes-fixed-time /CONFIG_CRYPTO_AES_TI
crypto: aes - Replace aes-generic with wrapper around lib lib/crypto: arm/aes: Migrate optimized code into library lib/crypto: arm64/aes: Migrate optimized code into library lib/crypto: powerpc/aes: Migrate SPE optimized code into library lib/crypto: powerpc/aes: Migrate POWER8 optimized code into library lib/crypto: riscv/aes: Migrate optimized code into library lib/crypto: s390/aes: Migrate optimized code into library lib/crypto: sparc/aes: Migrate optimized code into library lib/crypto: x86/aes: Add AES-NI optimization
crypto: x86/aes - Remove the superseded AES-NIcrypto_cipher
Bluetooth: SMP: Use new AES library API
chelsio: Use new AES library API
net: phy: mscc: macsec: Use new AES library API
staging: rtl8723bs: core: Use new AES library API
crypto: arm/ghash - Use new AES library API
crypto: arm64/ghash - Use new AES library API
crypto: x86/aes-gcm - Use new AES library API
crypto: ccp - Use new AES library API
crypto: chelsio - Use new AES library API
crypto: crypto4xx - Use new AES library API
Quoted 9 lines
crypto: drbg - Use new AES library API
crypto: inside-secure - Use new AES library API
crypto: omap - Use new AES library API
lib/crypto: aescfb: Use new AES library API lib/crypto: aesgcm: Use new AES library API lib/crypto: aes: Remove old AES en/decryption functions lib/crypto: aes: Drop "_new" suffix from en/decryption functions lib/crypto: aes: Drop 'volatile' fromaes_sboxandaes_inv_sbox
Nice cleanup
Eric Biggers
maintainerQuoted 31 lines · Ard Biesheuvel
Quoted 19 lines · Eric Biggers
This series applies to libcrypto-next. It can also be retrieved from:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git aes-lib-v1
This series makes three main improvements to the kernel's AES library:
1. Make it use the kernel's existing architecture-optimized AES code, including AES instructions, when available. Previously, only the traditional crypto API gave access to the optimized AES code. (As a reminder, AES instructions typically make AES over 10 times as fast as the generic code. They also make it constant-time.)
2. Support preparing an AES key for only the forward direction of the block cipher, using about half as much memory. This is a helpful optimization for many common AES modes of operation. It also helps keep structs small enough to be allocated on the stack, especially considering potential future library APIs for AES modes.
Quoted 6 lines
3. Replace the library's generic AES implementation with a much faster one that is almost as fast as "aes-generic", while still keeping the table size reasonably small and maintaining some constant-time hardening. This allows removing "aes-generic", unifying the current two generic AES implementations in the kernel tree.
Architectures that support memory operands will be impacted by dropping the pre-rotated lookup tables, especially if they have few GPRs.
Quoted 5 lines
I suspect that doesn't really matter in practice: if your pre-AESNI IA-32 workload has a bottleneck on "aes-generic", you would have probably moved it to a different machine by now. But the performance delta will likely be noticeable so it is something that deserves a mention.
Sure. I only claimed that the new implementation is "almost as fast" as aes-generic, not "as fast".
By the way, these are the results I get for crypto_cipher_encrypt_one() and crypto_cipher_decrypt_one() (averaged together) in a loop on an i386 kernel patched to not use AES-NI:
aes-fixed-time: 77 MB/s
aes-generic: 192 MB/s
aes-lib: 185 MB/sI'm not sure how relevant these are, considering that this was collected on a modern CPU, not one of the (very) old ones that would actually be running i386 non-AESNI code. But if they are even vaguely representative, this suggests the new code does quite well: little slowdown over aes-generic, while adding some constant-time hardening (which arguably was an undeserved shortcut to not include before) and also using a lot less dcache.
At the same time, there's clearly a large speedup vs. aes-fixed-time. So this will actually be a significant performance improvement on systems that were using aes-fixed-time. Many people may have been doing that unintentionally, due to it being set to a higher priority than aes-generic in the crypto_cipher API.
I'll also note that the state of the art for parallelizable AES modes on CPUs without AES instructions is bit-slicing with vector registers. The kernel has such code for arm and arm64, but not for x86. If x86 without AES-NI was actually important, we should be adding that. But it seems clear that x86 CPUs have moved on, and hardly anyone cares anymore. If for now we can just provide something that's almost as fast as before (and maybe even a lot faster in some cases!), that seems fine.
- Eric
Eric Biggers
maintainerQuoted 63 lines · Eric Biggers
Quoted 31 lines · Ard Biesheuvel
Quoted 19 lines · Eric Biggers
This series applies to libcrypto-next. It can also be retrieved from:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git aes-lib-v1
This series makes three main improvements to the kernel's AES library:
1. Make it use the kernel's existing architecture-optimized AES code, including AES instructions, when available. Previously, only the traditional crypto API gave access to the optimized AES code. (As a reminder, AES instructions typically make AES over 10 times as fast as the generic code. They also make it constant-time.)
2. Support preparing an AES key for only the forward direction of the block cipher, using about half as much memory. This is a helpful optimization for many common AES modes of operation. It also helps keep structs small enough to be allocated on the stack, especially considering potential future library APIs for AES modes.
Quoted 6 lines
3. Replace the library's generic AES implementation with a much faster one that is almost as fast as "aes-generic", while still keeping the table size reasonably small and maintaining some constant-time hardening. This allows removing "aes-generic", unifying the current two generic AES implementations in the kernel tree.
Architectures that support memory operands will be impacted by dropping the pre-rotated lookup tables, especially if they have few GPRs.
Quoted 5 lines
I suspect that doesn't really matter in practice: if your pre-AESNI IA-32 workload has a bottleneck on "aes-generic", you would have probably moved it to a different machine by now. But the performance delta will likely be noticeable so it is something that deserves a mention.
Sure. I only claimed that the new implementation is "almost as fast" as aes-generic, not "as fast".
By the way, these are the results I get for
crypto_cipher_encrypt_one()andcrypto_cipher_decrypt_one()(averaged together) in a loop on an i386 kernel patched to not use AES-NI:aes-fixed-time: 77 MB/s aes-generic: 192 MB/s aes-lib: 185 MB/sI'm not sure how relevant these are, considering that this was collected on a modern CPU, not one of the (very) old ones that would actually be running i386 non-AESNI code. But if they are even vaguely representative, this suggests the new code does quite well: little slowdown over aes-generic, while adding some constant-time hardening (which arguably was an undeserved shortcut to not include before) and also using a lot less dcache.
At the same time, there's clearly a large speedup vs. aes-fixed-time. So this will actually be a significant performance improvement on systems that were using aes-fixed-time. Many people may have been doing that unintentionally, due to it being set to a higher priority than aes-generic in the
crypto_cipherAPI.
Quoted 7 lines
I'll also note that the state of the art for parallelizable AES modes on CPUs without AES instructions is bit-slicing with vector registers. The kernel has such code for arm and arm64, but not for x86. If x86 without AES-NI was actually important, we should be adding that. But it seems clear that x86 CPUs have moved on, and hardly anyone cares anymore. If for now we can just provide something that's almost as fast as before (and maybe even a lot faster in some cases!), that seems fine.
It's also worth emphasizing that there are likely to be systems that support AES instructions but are not using them due to the corresponding kconfig options (e.g. CONFIG_CRYPTO_AES_NI_INTEL) not being set to 'y'. As we know, missing the crypto optimization kconfig options is a common mistake. This series fixes that for single-block AES.
So (in addition to the aes-fixed-time case) that's another case that just gets faster, and where the difference between aes-generic and the new generic code isn't actually relevant.
- Eric
Ard Biesheuvel
maintainerQuoted 79 lines · Eric Biggers
Quoted 63 lines · Eric Biggers
Quoted 31 lines · Ard Biesheuvel
Quoted 19 lines · Eric Biggers
This series applies to libcrypto-next. It can also be retrieved from:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux.git aes-lib-v1
This series makes three main improvements to the kernel's AES library:
1. Make it use the kernel's existing architecture-optimized AES code, including AES instructions, when available. Previously, only the traditional crypto API gave access to the optimized AES code. (As a reminder, AES instructions typically make AES over 10 times as fast as the generic code. They also make it constant-time.)
2. Support preparing an AES key for only the forward direction of the block cipher, using about half as much memory. This is a helpful optimization for many common AES modes of operation. It also helps keep structs small enough to be allocated on the stack, especially considering potential future library APIs for AES modes.
Quoted 6 lines
3. Replace the library's generic AES implementation with a much faster one that is almost as fast as "aes-generic", while still keeping the table size reasonably small and maintaining some constant-time hardening. This allows removing "aes-generic", unifying the current two generic AES implementations in the kernel tree.
Architectures that support memory operands will be impacted by dropping the pre-rotated lookup tables, especially if they have few GPRs.
Quoted 5 lines
I suspect that doesn't really matter in practice: if your pre-AESNI IA-32 workload has a bottleneck on "aes-generic", you would have probably moved it to a different machine by now. But the performance delta will likely be noticeable so it is something that deserves a mention.
Sure. I only claimed that the new implementation is "almost as fast" as aes-generic, not "as fast".
By the way, these are the results I get for
crypto_cipher_encrypt_one()andcrypto_cipher_decrypt_one()(averaged together) in a loop on an i386 kernel patched to not use AES-NI:aes-fixed-time: 77 MB/s aes-generic: 192 MB/s aes-lib: 185 MB/sI'm not sure how relevant these are, considering that this was collected on a modern CPU, not one of the (very) old ones that would actually be running i386 non-AESNI code. But if they are even vaguely representative, this suggests the new code does quite well: little slowdown over aes-generic, while adding some constant-time hardening (which arguably was an undeserved shortcut to not include before) and also using a lot less dcache.
At the same time, there's clearly a large speedup vs. aes-fixed-time. So this will actually be a significant performance improvement on systems that were using aes-fixed-time. Many people may have been doing that unintentionally, due to it being set to a higher priority than aes-generic in the
crypto_cipherAPI.Quoted 7 lines
I'll also note that the state of the art for parallelizable AES modes on CPUs without AES instructions is bit-slicing with vector registers. The kernel has such code for arm and arm64, but not for x86. If x86 without AES-NI was actually important, we should be adding that. But it seems clear that x86 CPUs have moved on, and hardly anyone cares anymore. If for now we can just provide something that's almost as fast as before (and maybe even a lot faster in some cases!), that seems fine.
It's also worth emphasizing that there are likely to be systems that support AES instructions but are not using them due to the corresponding kconfig options (e.g.
CONFIG_CRYPTO_AES_NI_INTEL) not being set to 'y'. As we know, missing the crypto optimization kconfig options is a common mistake. This series fixes that for single-block AES.
Quoted 4 lines
So (in addition to the aes-fixed-time case) that's another case that just gets faster, and where the difference between aes-generic and the new generic code isn't actually relevant.
Fair enough. Thanks for the elaboration.