Re: [RFC PATCH 5/8] KEYS: Provide software public key query function [ver 3]

2016-05-12 Thread Mat Martineau


On Thu, 12 May 2016, David Howells wrote:


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.


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]

2016-05-12 Thread David Howells
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.

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]

2016-05-11 Thread Tadeusz Struk
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]

2016-05-11 Thread Mat Martineau


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]

2016-05-11 Thread David Howells
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