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


+	} else {
+		info->max_data_size = len;
+		info->max_sig_size = len;
+	}
  	info->max_enc_size = len;
  	info->max_dec_size = len;
  	info->supported_ops = (KEYCTL_SUPPORTS_ENCRYPT |



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

  Powered by Linux