From: Lukas Wunner <lukas@wunner.de>
To: Herbert Xu <herbert@gondor.apana.org.au>,
"David S. Miller" <davem@davemloft.net>,
Stefan Berger <stefanb@linux.ibm.com>,
Vitaly Chikunov <vt@altlinux.org>
Cc: David Howells <dhowells@redhat.com>,
Ignat Korchagin <ignat@cloudflare.com>,
linux-crypto@vger.kernel.org, keyrings@vger.kernel.org
Subject: [PATCH v2 1/4] crypto: sig - Prepare for algorithms with variable signature size
Date: Sun, 2 Feb 2025 20:00:51 +0100 [thread overview]
Message-ID: <981e7c8b3f061f3effd253b8cfc6632e52e3e8fe.1738521533.git.lukas@wunner.de> (raw)
In-Reply-To: <cover.1738521533.git.lukas@wunner.de>
The callers of crypto_sig_sign() assume that the signature size is
always equivalent to the key size.
This happens to be true for RSA, which is currently the only algorithm
implementing the ->sign() callback. But it is false e.g. for X9.62
encoded ECDSA signatures because they have variable length.
Prepare for addition of a ->sign() callback to such algorithms by
letting the callback return the signature size (or a negative integer
on error). When testing the ->sign() callback in test_sig_one(),
use crypto_sig_maxsize() instead of crypto_sig_keysize() to verify that
the test vector's signature does not exceed an algorithm's maximum
signature size.
There has been a relatively recent effort to upstream ECDSA signature
generation support which may benefit from this change:
https://lore.kernel.org/linux-crypto/20220908200036.2034-1-ignat@cloudflare.com/
However the main motivation for this commit is to reduce the number of
crypto_sig_keysize() callers: This function is about to be changed to
return the size in bits instead of bytes and that will require amending
most callers to divide the return value by 8.
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Cc: Ignat Korchagin <ignat@cloudflare.com>
---
crypto/asymmetric_keys/public_key.c | 9 ++-------
crypto/rsassa-pkcs1.c | 2 +-
crypto/testmgr.c | 7 ++++---
include/crypto/sig.h | 5 +++--
4 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index bbd07a9022e6..bf165d321440 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -267,7 +267,6 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
struct crypto_sig *sig;
char *key, *ptr;
bool issig;
- int ksz;
int ret;
pr_devel("==>%s()\n", __func__);
@@ -302,8 +301,6 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
ret = crypto_sig_set_pubkey(sig, key, pkey->keylen);
if (ret)
goto error_free_tfm;
-
- ksz = crypto_sig_keysize(sig);
} else {
tfm = crypto_alloc_akcipher(alg_name, 0, 0);
if (IS_ERR(tfm)) {
@@ -317,8 +314,6 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
ret = crypto_akcipher_set_pub_key(tfm, key, pkey->keylen);
if (ret)
goto error_free_tfm;
-
- ksz = crypto_akcipher_maxsize(tfm);
}
ret = -EINVAL;
@@ -347,8 +342,8 @@ static int software_key_eds_op(struct kernel_pkey_params *params,
BUG();
}
- if (ret == 0)
- ret = ksz;
+ if (!issig && ret == 0)
+ ret = crypto_akcipher_maxsize(tfm);
error_free_tfm:
if (issig)
diff --git a/crypto/rsassa-pkcs1.c b/crypto/rsassa-pkcs1.c
index f68ffd338f48..d01ac75635e0 100644
--- a/crypto/rsassa-pkcs1.c
+++ b/crypto/rsassa-pkcs1.c
@@ -210,7 +210,7 @@ static int rsassa_pkcs1_sign(struct crypto_sig *tfm,
memset(dst, 0, pad_len);
}
- return 0;
+ return ctx->key_size;
}
static int rsassa_pkcs1_verify(struct crypto_sig *tfm,
diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index e61490ba4095..b69877db3f33 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -4328,7 +4328,7 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs)
if (vecs->public_key_vec)
return 0;
- sig_size = crypto_sig_keysize(tfm);
+ sig_size = crypto_sig_maxsize(tfm);
if (sig_size < vecs->c_size) {
pr_err("alg: sig: invalid maxsize %u\n", sig_size);
return -EINVAL;
@@ -4340,13 +4340,14 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs)
/* Run asymmetric signature generation */
err = crypto_sig_sign(tfm, vecs->m, vecs->m_size, sig, sig_size);
- if (err) {
+ if (err < 0) {
pr_err("alg: sig: sign test failed: err %d\n", err);
return err;
}
/* Verify that generated signature equals cooked signature */
- if (memcmp(sig, vecs->c, vecs->c_size) ||
+ if (err != vecs->c_size ||
+ memcmp(sig, vecs->c, vecs->c_size) ||
memchr_inv(sig + vecs->c_size, 0, sig_size - vecs->c_size)) {
pr_err("alg: sig: sign test failed: invalid output\n");
hexdump(sig, sig_size);
diff --git a/include/crypto/sig.h b/include/crypto/sig.h
index cff41ad93824..11024708c069 100644
--- a/include/crypto/sig.h
+++ b/include/crypto/sig.h
@@ -23,7 +23,8 @@ struct crypto_sig {
* struct sig_alg - generic public key signature algorithm
*
* @sign: Function performs a sign operation as defined by public key
- * algorithm. Optional.
+ * algorithm. On success, the signature size is returned.
+ * Optional.
* @verify: Function performs a complete verify operation as defined by
* public key algorithm, returning verification status. Optional.
* @set_pub_key: Function invokes the algorithm specific set public key
@@ -186,7 +187,7 @@ static inline unsigned int crypto_sig_maxsize(struct crypto_sig *tfm)
* @dst: destination obuffer
* @dlen: destination length
*
- * Return: zero on success; error code in case of error
+ * Return: signature size on success; error code in case of error
*/
static inline int crypto_sig_sign(struct crypto_sig *tfm,
const void *src, unsigned int slen,
--
2.43.0
next prev parent reply other threads:[~2025-02-02 19:20 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-02 19:00 [PATCH v2 0/4] ecdsa KEYCTL_PKEY_QUERY fixes Lukas Wunner
2025-02-02 19:00 ` Lukas Wunner [this message]
2025-02-02 19:00 ` [PATCH v2 2/4] crypto: ecdsa - Harden against integer overflows in DIV_ROUND_UP() Lukas Wunner
2025-02-03 5:11 ` Lukas Wunner
2025-02-02 19:00 ` [PATCH v2 3/4] crypto: ecdsa - Fix enc/dec size reported by KEYCTL_PKEY_QUERY Lukas Wunner
2025-02-09 9:58 ` Herbert Xu
2025-02-09 11:29 ` Lukas Wunner
2025-02-09 13:16 ` Ignat Korchagin
2025-02-10 7:54 ` Herbert Xu
2025-02-10 18:53 ` Lukas Wunner
2025-02-10 20:29 ` Lukas Wunner
2025-02-11 9:16 ` Herbert Xu
2025-02-16 4:19 ` Herbert Xu
2025-02-16 10:45 ` Lukas Wunner
2025-03-02 7:47 ` Herbert Xu
2025-03-02 9:25 ` Lukas Wunner
2025-03-02 10:11 ` Herbert Xu
2025-03-15 14:37 ` Lukas Wunner
2025-03-17 9:37 ` Herbert Xu
2025-03-17 9:40 ` Herbert Xu
2025-02-02 19:00 ` [PATCH v2 4/4] crypto: ecdsa - Fix NIST P521 key " Lukas Wunner
2025-02-09 10:25 ` [PATCH v2 0/4] ecdsa KEYCTL_PKEY_QUERY fixes Herbert Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=981e7c8b3f061f3effd253b8cfc6632e52e3e8fe.1738521533.git.lukas@wunner.de \
--to=lukas@wunner.de \
--cc=davem@davemloft.net \
--cc=dhowells@redhat.com \
--cc=herbert@gondor.apana.org.au \
--cc=ignat@cloudflare.com \
--cc=keyrings@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=stefanb@linux.ibm.com \
--cc=vt@altlinux.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).