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 */