Re: [RFC PATCH] KEYS: Double max_size to make keyctl pkey_verify work

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On 2/20/22 21:43, Vitaly Chikunov wrote:
On Mon, Feb 21, 2022 at 12:29:13AM +0100, Jarkko Sakkinen wrote:
On Wed, Feb 02, 2022 at 10:15:24PM -0500, Stefan Berger wrote:
On 2/2/22 01:59, Vitaly Chikunov wrote:
Rarely used `keyctl pkey_verify' can verify raw signatures, but was
failing, because ECDSA/EC-RDSA signature sizes are twice key sizes which
does not pass in/out sizes check in keyctl_pkey_params_get_2.
This in turn because these values cannot be distinguished by a single
`max_size' callback return value.
Also, `keyctl pkey_query` displays incorrect `max_sig_size' about these
algorithms.

Signed-off-by: Vitaly Chikunov <vt@xxxxxxxxxxxx>
---
   crypto/asymmetric_keys/public_key.c | 15 +++++++++++++--
   1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c
index 4fefb219bfdc..3ffbab07ed2a 100644
--- a/crypto/asymmetric_keys/public_key.c
+++ b/crypto/asymmetric_keys/public_key.c
@@ -143,8 +143,19 @@ static int software_key_query(const struct kernel_pkey_params *params,
   	len = crypto_akcipher_maxsize(tfm);
   	info->key_size = len * 8;
-	info->max_data_size = len;
-	info->max_sig_size = len;
+	if (strcmp(alg_name, "ecrdsa") == 0 ||
+	    strncmp(alg_name, "ecdsa-", 6) == 0) {
+		/*
+		 * For these algos sig size is twice key size.
+		 * keyctl uses max_sig_size as minimum input size, and
+		 * max_data_size as minimum output size for a signature.
+		 */
+		info->max_data_size = len * 2;
+		info->max_sig_size = len * 2;
I don't know about the data size but following my tests this is not enough
for ECDSA signature size. In ECDSA case the r and s components of the
signature are encode in asn.1, not 'raw'. So there are 2 bytes at the
beginning for sequence identifier , 2 bytes asn.1 for the r component, 1
additional 0-byte to make the r component always a positive number, then the
r component, then 2 bytes asn.1 for the s component, 1 addition 0-byte to
make the s component a positive number, then the s component. Phew.

info->max_sig_size = 2 + (2 + 1 + len) * 2;

so for NIST P384 it's: 2 + (2+1+48) * 2 = 104

Then it works for me as well.
Thank you for the trouble of providing this great explanation. This
reasoning should be included to the commit message for future reference.

It would be also nice to encapsulate this calculation to an inline
function.
I wanted to discuss if there's a better way to do it. For example,
instead of calculating algorithm specific information in
software_key_query maybe we should extend akcipher_alg API with a
pkey_params request (just for keyctl)?

Also, there possible other solution - instead of setting info in
software_key_query depending on algo (as in this patch), it's possible
(in a hackish way) just to return larger value from
akcipher_alg::max_size. But this will possible somewhat confuse keyctl
users, as, for example, they will see arbitrary value for a key_size.

Currently, this patch is the simplest non-confusing solution, and it's
in accord with how we calculate algorithm specific things all around
the code base (outside of algorithm implementation itself).

I don't know the answer to the other questions, but I agree that your patch seem to be the simplest non-confusing solution. Are you going to repost it, possibly with my ECDSA modifications added?

   Stefan



Thanks,

/Jarkko



[Index of Archives]     [Kernel]     [Gnu Classpath]     [Gnu Crypto]     [DM Crypt]     [Netfilter]     [Bugtraq]

  Powered by Linux