From 3dee94d4a401b413d1a1a1522e11dcea5394ff6b Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Sat, 23 May 2026 15:43:03 -0400 Subject: [PATCH] crypto: af_alg - Drop support for off-CPU cryptography AF_ALG is deprecated and exposed to unprivileged userspace. Only use the least buggy algorithm implementations: the pure software ones. This removes one of the main advantages of AF_ALG, which is the ability to use it with off-CPU accelerators. However, using off-CPU accelerators has huge overheads, both in performance and attack surface. I have yet to see real-world, performance-critical workloads where using an accelerator via AF_ALG is actually a win over doing cryptography in userspace. If using an off-CPU accelerator really does turn out to be a win, a new API should be developed that is actually a good fit for it. Signed-off-by: Demi Marie Obenour Signed-off-by: Herbert Xu [WangYuli: Rewirte userspace-if.rst because of conflicts] Link: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git/commit/?id=7524070f26d8d347c26787dc297fb844baa26abf Signed-off-by: WangYuli --- Documentation/crypto/userspace-if.rst | 9 +++++++++ crypto/af_alg.c | 2 +- crypto/algif_aead.c | 4 ++-- crypto/algif_hash.c | 4 ++-- crypto/algif_rng.c | 4 ++-- crypto/algif_skcipher.c | 4 ++-- include/crypto/if_alg.h | 14 +++++++++++++- 7 files changed, 31 insertions(+), 10 deletions(-) diff --git a/Documentation/crypto/userspace-if.rst b/Documentation/crypto/userspace-if.rst index 4630d3d74913b..f9003a2414ed1 100644 --- a/Documentation/crypto/userspace-if.rst +++ b/Documentation/crypto/userspace-if.rst @@ -80,6 +80,15 @@ performed by the consumer: system calls to send data to the kernel or obtain data from the kernel, the file descriptor returned by accept must be used. +.. caution:: + + Support for hardware cryptographic accelerators has been removed from + AF_ALG. Only algorithms implemented in software are now accessible + through this interface. Hardware accelerator drivers are frequently + buggy, and removing their exposure via AF_ALG reduces the kernel's + attack surface. This means AF_ALG no longer fulfills its original + purpose of providing access to off-CPU cryptography. + In-place Cipher operation ------------------------- diff --git a/crypto/af_alg.c b/crypto/af_alg.c index e7fea668473d9..3c49f6d7ee163 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -181,7 +181,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) if (IS_ERR(type)) return PTR_ERR(type); - private = type->bind(sa->salg_name, sa->salg_feat, sa->salg_mask); + private = type->bind(sa->salg_name); if (IS_ERR(private)) { module_put(type->owner); return PTR_ERR(private); diff --git a/crypto/algif_aead.c b/crypto/algif_aead.c index c6c2ce21895dd..bad7cab68ca51 100644 --- a/crypto/algif_aead.c +++ b/crypto/algif_aead.c @@ -365,9 +365,9 @@ static struct proto_ops algif_aead_ops_nokey = { .poll = af_alg_poll, }; -static void *aead_bind(const char *name, u32 type, u32 mask) +static void *aead_bind(const char *name) { - return crypto_alloc_aead(name, type, mask); + return crypto_alloc_aead(name, 0, AF_ALG_CRYPTOAPI_MASK); } static void aead_release(void *private) diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 265cabcb95e09..f1537b7c07b80 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c @@ -380,9 +380,9 @@ static struct proto_ops algif_hash_ops_nokey = { .accept = hash_accept_nokey, }; -static void *hash_bind(const char *name, u32 type, u32 mask) +static void *hash_bind(const char *name) { - return crypto_alloc_ahash(name, type, mask); + return crypto_alloc_ahash(name, 0, AF_ALG_CRYPTOAPI_MASK); } static void hash_release(void *private) diff --git a/crypto/algif_rng.c b/crypto/algif_rng.c index 1a86e40c8372e..b7b7fa0434c93 100644 --- a/crypto/algif_rng.c +++ b/crypto/algif_rng.c @@ -197,7 +197,7 @@ static struct proto_ops __maybe_unused algif_rng_test_ops = { .sendmsg = rng_test_sendmsg, }; -static void *rng_bind(const char *name, u32 type, u32 mask) +static void *rng_bind(const char *name) { struct rng_parent_ctx *pctx; struct crypto_rng *rng; @@ -206,7 +206,7 @@ static void *rng_bind(const char *name, u32 type, u32 mask) if (!pctx) return ERR_PTR(-ENOMEM); - rng = crypto_alloc_rng(name, type, mask); + rng = crypto_alloc_rng(name, 0, AF_ALG_CRYPTOAPI_MASK); if (IS_ERR(rng)) { kfree(pctx); return ERR_CAST(rng); diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index e31b1da58dba4..feabe79f9d5f0 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -276,9 +276,9 @@ static struct proto_ops algif_skcipher_ops_nokey = { .poll = af_alg_poll, }; -static void *skcipher_bind(const char *name, u32 type, u32 mask) +static void *skcipher_bind(const char *name) { - return crypto_alloc_skcipher(name, type, mask); + return crypto_alloc_skcipher(name, 0, AF_ALG_CRYPTOAPI_MASK); } static void skcipher_release(void *private) diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h index b4f40454449b0..7a301f4d8f56d 100644 --- a/include/crypto/if_alg.h +++ b/include/crypto/if_alg.h @@ -44,7 +44,7 @@ struct af_alg_control { }; struct af_alg_type { - void *(*bind)(const char *name, u32 type, u32 mask); + void *(*bind)(const char *name); void (*release)(void *private); int (*setkey)(void *private, const u8 *key, unsigned int keylen); int (*setentropy)(void *private, sockptr_t entropy, unsigned int len); @@ -253,4 +253,16 @@ int af_alg_get_rsgl(struct sock *sk, struct msghdr *msg, int flags, struct af_alg_async_req *areq, size_t maxsize, size_t *outlen); +/* + * Mask used to disable unsupported algorithm implementations. + * + * This is the same as FSCRYPT_CRYPTOAPI_MASK in fs/crypto/fscrypt_private.h. + * In additions to the motivations there, this API is exposed to userspace + * that might not be fully trusted. + */ +#define AF_ALG_CRYPTOAPI_MASK \ + (CRYPTO_ALG_ASYNC | CRYPTO_ALG_ALLOCATES_MEMORY | \ + CRYPTO_ALG_KERN_DRIVER_ONLY) + + #endif /* _CRYPTO_IF_ALG_H */