| From c702836c1e64788d6a862483ca3636fa4b95d9a0 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 31 Aug 2022 19:37:06 +0100 |
| Subject: crypto: akcipher - default implementation for setting a private key |
| |
| From: Ignat Korchagin <ignat@cloudflare.com> |
| |
| [ Upstream commit bc155c6c188c2f0c5749993b1405673d25a80389 ] |
| |
| Changes from v1: |
| * removed the default implementation from set_pub_key: it is assumed that |
| an implementation must always have this callback defined as there are |
| no use case for an algorithm, which doesn't need a public key |
| |
| Many akcipher implementations (like ECDSA) support only signature |
| verifications, so they don't have all callbacks defined. |
| |
| Commit 78a0324f4a53 ("crypto: akcipher - default implementations for |
| request callbacks") introduced default callbacks for sign/verify |
| operations, which just return an error code. |
| |
| However, these are not enough, because before calling sign the caller would |
| likely call set_priv_key first on the instantiated transform (as the |
| in-kernel testmgr does). This function does not have a default stub, so the |
| kernel crashes, when trying to set a private key on an akcipher, which |
| doesn't support signature generation. |
| |
| I've noticed this, when trying to add a KAT vector for ECDSA signature to |
| the testmgr. |
| |
| With this patch the testmgr returns an error in dmesg (as it should) |
| instead of crashing the kernel NULL ptr dereference. |
| |
| Fixes: 78a0324f4a53 ("crypto: akcipher - default implementations for request callbacks") |
| Signed-off-by: Ignat Korchagin <ignat@cloudflare.com> |
| Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| crypto/akcipher.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| diff --git a/crypto/akcipher.c b/crypto/akcipher.c |
| index 7d5cf4939423..ceb0c2fb2b24 100644 |
| --- a/crypto/akcipher.c |
| +++ b/crypto/akcipher.c |
| @@ -119,6 +119,12 @@ static int akcipher_default_op(struct akcipher_request *req) |
| return -ENOSYS; |
| } |
| |
| +static int akcipher_default_set_key(struct crypto_akcipher *tfm, |
| + const void *key, unsigned int keylen) |
| +{ |
| + return -ENOSYS; |
| +} |
| + |
| int crypto_register_akcipher(struct akcipher_alg *alg) |
| { |
| struct crypto_alg *base = &alg->base; |
| @@ -131,6 +137,8 @@ int crypto_register_akcipher(struct akcipher_alg *alg) |
| alg->encrypt = akcipher_default_op; |
| if (!alg->decrypt) |
| alg->decrypt = akcipher_default_op; |
| + if (!alg->set_priv_key) |
| + alg->set_priv_key = akcipher_default_set_key; |
| |
| akcipher_prepare_alg(alg); |
| return crypto_register_alg(base); |
| -- |
| 2.35.1 |
| |