Re: [RFC PATCH 5/8] KEYS: Provide software public key query function [ver 3]
On Thu, 12 May 2016, David Howells wrote: Mat Martineauwrote: + len = crypto_akcipher_maxsize(tfm); + info->key_size = len * 8; + info->max_data_size = len; + info->max_sig_size = len; + info->max_enc_size = len; + info->max_dec_size = len; If len > UINT16_MAX, should UINT16_MAX be reported as the max size? Similar question for len*8 and key_size. key_size is 32 bits, but the other sizes are all 16 bits, so you would need a 524288-bit key to exceed their capacity. I'm not sure that's likely anytime soon, but should I just make all the sizes 32-bit anyway? Given that cryto_akcipher_maxsize() returns an int and keyctl_pkey_query is part of the userspace API, I support bumping the sizes to 32-bit. -- Mat Martineau Intel OTC -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 5/8] KEYS: Provide software public key query function [ver 3]
Mat Martineauwrote: > > + len = crypto_akcipher_maxsize(tfm); > > + info->key_size = len * 8; > > + info->max_data_size = len; > > + info->max_sig_size = len; > > + info->max_enc_size = len; > > + info->max_dec_size = len; > > If len > UINT16_MAX, should UINT16_MAX be reported as the max size? Similar > question for len*8 and key_size. key_size is 32 bits, but the other sizes are all 16 bits, so you would need a 524288-bit key to exceed their capacity. I'm not sure that's likely anytime soon, but should I just make all the sizes 32-bit anyway? David -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 5/8] KEYS: Provide software public key query function [ver 3]
On 05/11/2016 04:50 PM, Mat Martineau wrote: > >> +len = crypto_akcipher_maxsize(tfm); >> +info->key_size = len * 8; >> +info->max_data_size = len; >> +info->max_sig_size = len; >> +info->max_enc_size = len; >> +info->max_dec_size = len; > > If len > UINT16_MAX, should UINT16_MAX be reported as the max size? Similar > question for len*8 and key_size. Hi Mat, Since all the operations performed are mod key->n the output will never be bigger than size of pkey->n, which is the return value from crypto_akcipher_maxsize(tfm) for a given key. Thanks, -- TS -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 5/8] KEYS: Provide software public key query function [ver 3]
On Wed, 11 May 2016, David Howells wrote: Provide a query function for the software public key implementation. This permits information about such a key to be obtained using query_asymmetric_key() or KEYCTL_PKEY_QUERY. Signed-off-by: David Howells--- crypto/asymmetric_keys/public_key.c | 96 ++- 1 file changed, 82 insertions(+), 14 deletions(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 96983906d2a2..e9967e5a2c25 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c +static int software_key_query(const struct kernel_pkey_params *params, + struct kernel_pkey_query *info) +{ ... + len = crypto_akcipher_maxsize(tfm); + info->key_size = len * 8; + info->max_data_size = len; + info->max_sig_size = len; + info->max_enc_size = len; + info->max_dec_size = len; If len > UINT16_MAX, should UINT16_MAX be reported as the max size? Similar question for len*8 and key_size. -- Mat Martineau Intel OTC -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[RFC PATCH 5/8] KEYS: Provide software public key query function [ver 3]
Provide a query function for the software public key implementation. This permits information about such a key to be obtained using query_asymmetric_key() or KEYCTL_PKEY_QUERY. Signed-off-by: David Howells--- crypto/asymmetric_keys/public_key.c | 96 ++- 1 file changed, 82 insertions(+), 14 deletions(-) diff --git a/crypto/asymmetric_keys/public_key.c b/crypto/asymmetric_keys/public_key.c index 96983906d2a2..e9967e5a2c25 100644 --- a/crypto/asymmetric_keys/public_key.c +++ b/crypto/asymmetric_keys/public_key.c @@ -57,6 +57,81 @@ static void public_key_destroy(void *payload0, void *payload3) public_key_signature_free(payload3); } +/* + * Determine the crypto algorithm name. + */ +static +int software_key_determine_akcipher(const char *encoding, + const char *hash_algo, + const struct public_key *pkey, + char alg_name[CRYPTO_MAX_ALG_NAME]) +{ + int n; + + if (strcmp(encoding, "pkcs1") == 0) { + /* The data wangled by the RSA algorithm is typically padded +* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447 +* sec 8.2]. +*/ + if (!hash_algo) + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, +"pkcs1pad(%s)", +pkey->pkey_algo); + else + n = snprintf(alg_name, CRYPTO_MAX_ALG_NAME, +"pkcs1pad(%s,%s)", +pkey->pkey_algo, hash_algo); + return n >= CRYPTO_MAX_ALG_NAME ? -EINVAL : 0; + } + + if (strcmp(encoding, "raw") == 0) { + strcpy(alg_name, pkey->pkey_algo); + return 0; + } + + return -ENOPKG; +} + +/* + * Query information about a key. + */ +static int software_key_query(const struct kernel_pkey_params *params, + struct kernel_pkey_query *info) +{ + struct crypto_akcipher *tfm; + struct public_key *pkey = params->key->payload.data[asym_crypto]; + char alg_name[CRYPTO_MAX_ALG_NAME]; + int ret, len; + + ret = software_key_determine_akcipher(params->encoding, + params->hash_algo, + pkey, alg_name); + if (ret < 0) + return ret; + + tfm = crypto_alloc_akcipher(alg_name, 0, 0); + if (IS_ERR(tfm)) + return PTR_ERR(tfm); + + ret = crypto_akcipher_set_pub_key(tfm, pkey->key, pkey->keylen); + if (ret < 0) + goto error_free_tfm; + + len = crypto_akcipher_maxsize(tfm); + info->key_size = len * 8; + 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_VERIFY; + ret = 0; + +error_free_tfm: + crypto_free_akcipher(tfm); + pr_devel("<==%s() = %d\n", __func__, ret); + return ret; +} + struct public_key_completion { struct completion completion; int err; @@ -83,8 +158,7 @@ int public_key_verify_signature(const struct public_key *pkey, struct crypto_akcipher *tfm; struct akcipher_request *req; struct scatterlist sig_sg, digest_sg; - const char *alg_name; - char alg_name_buf[CRYPTO_MAX_ALG_NAME]; + char alg_name[CRYPTO_MAX_ALG_NAME]; void *output; unsigned int outlen; int ret = -ENOMEM; @@ -96,18 +170,11 @@ int public_key_verify_signature(const struct public_key *pkey, BUG_ON(!sig->digest); BUG_ON(!sig->s); - alg_name = sig->pkey_algo; - if (strcmp(sig->pkey_algo, "rsa") == 0) { - /* The data wangled by the RSA algorithm is typically padded -* and encoded in some manner, such as EMSA-PKCS1-1_5 [RFC3447 -* sec 8.2]. -*/ - if (snprintf(alg_name_buf, CRYPTO_MAX_ALG_NAME, -"pkcs1pad(rsa,%s)", sig->hash_algo -) >= CRYPTO_MAX_ALG_NAME) - return -EINVAL; - alg_name = alg_name_buf; - } + ret = software_key_determine_akcipher(sig->encoding, + sig->hash_algo, + pkey, alg_name); + if (ret < 0) + return ret; tfm = crypto_alloc_akcipher(alg_name, 0, 0); if (IS_ERR(tfm)) @@ -180,6 +247,7 @@ struct asymmetric_key_subtype public_key_subtype = { .name_len = sizeof("public_key") - 1, .describe = public_key_describe, .destroy= public_key_destroy, + .query