Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

crypto: ecdsa - Fix NIST P521 key size reported by KEYCTL_PKEY_QUERY

When user space issues a KEYCTL_PKEY_QUERY system call for a NIST P521
key, the key_size is incorrectly reported as 528 bits instead of 521.

That's because the key size obtained through crypto_sig_keysize() is in
bytes and software_key_query() multiplies by 8 to yield the size in bits.
The underlying assumption is that the key size is always a multiple of 8.
With the recent addition of NIST P521, that's no longer the case.

Fix by returning the key_size in bits from crypto_sig_keysize() and
adjusting the calculations in software_key_query().

The ->key_size() callbacks of sig_alg algorithms now return the size in
bits, whereas the ->digest_size() and ->max_size() callbacks return the
size in bytes. This matches with the units in struct keyctl_pkey_query.

Fixes: a7d45ba77d3d ("crypto: ecdsa - Register NIST P521 and extend test suite")
Signed-off-by: Lukas Wunner <lukas@wunner.de>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Ignat Korchagin <ignat@cloudflare.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Lukas Wunner and committed by
Herbert Xu
6b7f9397 3828485e

+22 -14
+4 -4
crypto/asymmetric_keys/public_key.c
··· 205 205 goto error_free_tfm; 206 206 207 207 len = crypto_sig_keysize(sig); 208 + info->key_size = len; 208 209 info->max_sig_size = crypto_sig_maxsize(sig); 209 210 info->max_data_size = crypto_sig_digestsize(sig); 210 211 ··· 214 213 info->supported_ops |= KEYCTL_SUPPORTS_SIGN; 215 214 216 215 if (strcmp(params->encoding, "pkcs1") == 0) { 217 - info->max_enc_size = len; 218 - info->max_dec_size = len; 216 + info->max_enc_size = len / BITS_PER_BYTE; 217 + info->max_dec_size = len / BITS_PER_BYTE; 219 218 220 219 info->supported_ops |= KEYCTL_SUPPORTS_ENCRYPT; 221 220 if (pkey->key_is_private) ··· 236 235 goto error_free_tfm; 237 236 238 237 len = crypto_akcipher_maxsize(tfm); 238 + info->key_size = len * BITS_PER_BYTE; 239 239 info->max_sig_size = len; 240 240 info->max_data_size = len; 241 241 info->max_enc_size = len; ··· 246 244 if (pkey->key_is_private) 247 245 info->supported_ops |= KEYCTL_SUPPORTS_DECRYPT; 248 246 } 249 - 250 - info->key_size = len * 8; 251 247 252 248 ret = 0; 253 249
+4 -2
crypto/ecdsa-p1363.c
··· 21 21 const void *digest, unsigned int dlen) 22 22 { 23 23 struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm); 24 - unsigned int keylen = crypto_sig_keysize(ctx->child); 24 + unsigned int keylen = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child), 25 + BITS_PER_BYTE); 25 26 unsigned int ndigits = DIV_ROUND_UP_POW2(keylen, sizeof(u64)); 26 27 struct ecdsa_raw_sig sig; 27 28 ··· 46 45 { 47 46 struct ecdsa_p1363_ctx *ctx = crypto_sig_ctx(tfm); 48 47 49 - return 2 * crypto_sig_keysize(ctx->child); 48 + return 2 * DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child), 49 + BITS_PER_BYTE); 50 50 } 51 51 52 52 static unsigned int ecdsa_p1363_digest_size(struct crypto_sig *tfm)
+3 -2
crypto/ecdsa-x962.c
··· 82 82 int err; 83 83 84 84 sig_ctx.ndigits = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child), 85 - sizeof(u64)); 85 + sizeof(u64) * BITS_PER_BYTE); 86 86 87 87 err = asn1_ber_decoder(&ecdsasignature_decoder, &sig_ctx, src, slen); 88 88 if (err < 0) ··· 103 103 { 104 104 struct ecdsa_x962_ctx *ctx = crypto_sig_ctx(tfm); 105 105 struct sig_alg *alg = crypto_sig_alg(ctx->child); 106 - int slen = crypto_sig_keysize(ctx->child); 106 + int slen = DIV_ROUND_UP_POW2(crypto_sig_keysize(ctx->child), 107 + BITS_PER_BYTE); 107 108 108 109 /* 109 110 * Verify takes ECDSA-Sig-Value (described in RFC 5480) as input,
+1 -1
crypto/ecdsa.c
··· 167 167 { 168 168 struct ecc_ctx *ctx = crypto_sig_ctx(tfm); 169 169 170 - return DIV_ROUND_UP(ctx->curve->nbits, 8); 170 + return ctx->curve->nbits; 171 171 } 172 172 173 173 static unsigned int ecdsa_digest_size(struct crypto_sig *tfm)
+1 -1
crypto/ecrdsa.c
··· 249 249 * Verify doesn't need any output, so it's just informational 250 250 * for keyctl to determine the key bit size. 251 251 */ 252 - return ctx->pub_key.ndigits * sizeof(u64); 252 + return ctx->pub_key.ndigits * sizeof(u64) * BITS_PER_BYTE; 253 253 } 254 254 255 255 static unsigned int ecrdsa_max_size(struct crypto_sig *tfm)
+1 -1
crypto/rsassa-pkcs1.c
··· 301 301 { 302 302 struct rsassa_pkcs1_ctx *ctx = crypto_sig_ctx(tfm); 303 303 304 - return ctx->key_size; 304 + return ctx->key_size * BITS_PER_BYTE; 305 305 } 306 306 307 307 static int rsassa_pkcs1_set_pub_key(struct crypto_sig *tfm,
+7 -2
crypto/sig.c
··· 102 102 return -ENOSYS; 103 103 } 104 104 105 + static unsigned int sig_default_size(struct crypto_sig *tfm) 106 + { 107 + return DIV_ROUND_UP_POW2(crypto_sig_keysize(tfm), BITS_PER_BYTE); 108 + } 109 + 105 110 static int sig_prepare_alg(struct sig_alg *alg) 106 111 { 107 112 struct crypto_alg *base = &alg->base; ··· 122 117 if (!alg->key_size) 123 118 return -EINVAL; 124 119 if (!alg->max_size) 125 - alg->max_size = alg->key_size; 120 + alg->max_size = sig_default_size; 126 121 if (!alg->digest_size) 127 - alg->digest_size = alg->key_size; 122 + alg->digest_size = sig_default_size; 128 123 129 124 base->cra_type = &crypto_sig_type; 130 125 base->cra_flags &= ~CRYPTO_ALG_TYPE_MASK;
+1 -1
include/crypto/sig.h
··· 128 128 /** 129 129 * crypto_sig_keysize() - Get key size 130 130 * 131 - * Function returns the key size in bytes. 131 + * Function returns the key size in bits. 132 132 * Function assumes that the key is already set in the transformation. If this 133 133 * function is called without a setkey or with a failed setkey, you may end up 134 134 * in a NULL dereference.