lib/crypto: aes: Add ECB support

Add support for AES-ECB to the crypto library.

This will be used to provide a streamlined implementation of the
"ecb(aes)" crypto_skcipher algorithm.  fs/crypto/keysetup_v1.c will also
use aes_ecb_encrypt() directly.

As usual, the architecture-optimized AES-ECB code will be migrated into
the library as well (using the hooks provided in this commit),
eliminating lots of repetitive boilerplate code.

ECB is obsolete of course, but we need this for parity with the
traditional API and to support some odd users of ECB in the kernel.

Initial test coverage is provided by the crypto_skcipher support added
in a later commit.  I'm planning a KUnit test suite as well.

Create a documentation file libcrypto-unauth-encryption.rst to hold the
documentation for this and other unauthenticated encryption modes.

Reviewed-by: Thomas Huth <thuth@redhat.com>
Link: https://patch.msgid.link/20260715221153.246410-3-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
This commit is contained in:
Eric Biggers
2026-07-19 17:34:16 -07:00
parent ff3ab74623
commit 5ab301fcc2
6 changed files with 141 additions and 0 deletions
@@ -0,0 +1,28 @@
.. SPDX-License-Identifier: GPL-2.0-or-later
Unauthenticated encryption
==========================
These APIs provide support for unauthenticated encryption and decryption,
including bare stream ciphers and other length-preserving algorithms such as
block ciphers in XTS mode. The legitimate use cases for these algorithms are:
- Support for legacy protocols that really should have chosen an authenticated
mode (or even another primitive entirely) but didn't.
- Internal components of authenticated modes. For example, AES-CTR is used by
AES-GCM and AES-CCM internally.
- Storage encryption that cannot accommodate ciphertext expansion. Usually
AES-XTS is used for this.
- Stream ciphers for key derivation and random number generation.
Besides the above, these shouldn't be used.
AES-ECB
-------
This API provides support for AES in the ECB mode of operation.
.. kernel-doc:: include/crypto/aes-ecb.h
+1
View File
@@ -162,5 +162,6 @@ API documentation
libcrypto-blockcipher
libcrypto-hash
libcrypto-signature
libcrypto-unauth-encryption
libcrypto-utils
sha3
+49
View File
@@ -0,0 +1,49 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* AES-ECB unauthenticated encryption and decryption
*
* Copyright 2026 Google LLC
*/
#ifndef _CRYPTO_AES_ECB_H
#define _CRYPTO_AES_ECB_H
#include <crypto/aes.h>
/**
* aes_ecb_encrypt() - Encrypt data using AES-ECB
* @dst: The destination buffer. Can be in-place or out-of-place. For other
* overlaps the behavior is unspecified.
* @src: The source data
* @len: Number of bytes to encrypt. Must be a multiple of AES_BLOCK_SIZE.
* @key: The key, already prepared using aes_preparekey() or aes_prepareenckey()
*
* ECB mode is insecure by itself. This function exists only for compatibility
* with legacy protocols and for internal use by other modes.
*
* This supports incremental encryption, but the length of each chunk must be a
* multiple of AES_BLOCK_SIZE.
*
* Context: Any context.
*/
void aes_ecb_encrypt(u8 *dst, const u8 *src, size_t len, aes_encrypt_arg key);
/**
* aes_ecb_decrypt() - Decrypt data using AES-ECB
* @dst: The destination buffer. Can be in-place or out-of-place. For other
* overlaps the behavior is unspecified.
* @src: The source data
* @len: Number of bytes to decrypt. Must be a multiple of AES_BLOCK_SIZE.
* @key: The key, already prepared using aes_preparekey()
*
* ECB mode is insecure by itself. This function exists only for compatibility
* with legacy protocols and for internal use by other modes.
*
* This supports incremental decryption, but the length of each chunk must be a
* multiple of AES_BLOCK_SIZE.
*
* Context: Any context.
*/
void aes_ecb_decrypt(u8 *dst, const u8 *src, size_t len,
const struct aes_key *key);
#endif /* _CRYPTO_AES_ECB_H */
+6
View File
@@ -35,6 +35,12 @@ config CRYPTO_LIB_AES_CBC_MACS
this if your module uses any of the functions from
<crypto/aes-cbc-macs.h>.
config CRYPTO_LIB_AES_ECB
tristate
select CRYPTO_LIB_AES
help
The AES-ECB library functions.
config CRYPTO_LIB_AESGCM
tristate
select CRYPTO_LIB_AES
+56
View File
@@ -5,6 +5,7 @@
*/
#include <crypto/aes-cbc-macs.h>
#include <crypto/aes-ecb.h>
#include <crypto/aes.h>
#include <crypto/utils.h>
#include <linux/cache.h>
@@ -737,6 +738,61 @@ static inline void aes_cmac_fips_test(void)
}
#endif /* !CONFIG_CRYPTO_LIB_AES_CBC_MACS */
#if IS_ENABLED(CONFIG_CRYPTO_LIB_AES_ECB)
/*
* Hooks for optimized AES-ECB implementations, overridable by the architecture.
* They are called with len > 0 && len % AES_BLOCK_SIZE == 0. Returning false
* causes the fallback implementation to be used instead.
*/
#ifndef aes_ecb_encrypt_arch
static bool aes_ecb_encrypt_arch(u8 *dst, const u8 *src, size_t len,
const struct aes_enckey *key)
{
return false;
}
#endif
#ifndef aes_ecb_decrypt_arch
static bool aes_ecb_decrypt_arch(u8 *dst, const u8 *src, size_t len,
const struct aes_key *key)
{
return false;
}
#endif
void aes_ecb_encrypt(u8 *dst, const u8 *src, size_t len, aes_encrypt_arg key)
{
if (WARN_ON_ONCE(len % AES_BLOCK_SIZE))
len = round_down(len, AES_BLOCK_SIZE);
if (unlikely(len == 0))
return;
if (likely(aes_ecb_encrypt_arch(dst, src, len, key.enc_key)))
return;
for (size_t i = 0; i < len; i += AES_BLOCK_SIZE)
aes_encrypt(key, &dst[i], &src[i]);
}
EXPORT_SYMBOL_GPL(aes_ecb_encrypt);
void aes_ecb_decrypt(u8 *dst, const u8 *src, size_t len,
const struct aes_key *key)
{
if (WARN_ON_ONCE(len % AES_BLOCK_SIZE))
len = round_down(len, AES_BLOCK_SIZE);
if (unlikely(len == 0))
return;
if (likely(aes_ecb_decrypt_arch(dst, src, len, key)))
return;
for (size_t i = 0; i < len; i += AES_BLOCK_SIZE)
aes_decrypt(key, &dst[i], &src[i]);
}
EXPORT_SYMBOL_GPL(aes_ecb_decrypt);
#endif /* CONFIG_CRYPTO_LIB_AES_ECB */
static int __init aes_mod_init(void)
{
#ifdef aes_mod_init_arch
+1
View File
@@ -145,6 +145,7 @@ config CRYPTO_LIB_ENABLE_ALL_FOR_KUNIT
tristate "Enable all crypto library code for KUnit tests"
depends on KUNIT
select CRYPTO_LIB_AES_CBC_MACS
select CRYPTO_LIB_AES_ECB
select CRYPTO_LIB_BLAKE2B
select CRYPTO_LIB_CHACHA20POLY1305
select CRYPTO_LIB_CURVE25519