Skip to content

Commit

Permalink
KEYS: Provide software public key query function [ver #2]
Browse files Browse the repository at this point in the history
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 <[email protected]>
Tested-by: Marcel Holtmann <[email protected]>
Reviewed-by: Marcel Holtmann <[email protected]>
Reviewed-by: Denis Kenzior <[email protected]>
Tested-by: Denis Kenzior <[email protected]>
Signed-off-by: James Morris <[email protected]>
  • Loading branch information
dhowells authored and James Morris committed Oct 26, 2018
1 parent 0398849 commit 82f94f2
Showing 1 changed file with 82 additions and 17 deletions.
99 changes: 82 additions & 17 deletions crypto/asymmetric_keys/public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,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;
}

/*
* Verify a signature using a public key.
*/
Expand All @@ -69,8 +144,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;
Expand All @@ -81,21 +155,11 @@ int public_key_verify_signature(const struct public_key *pkey,
BUG_ON(!sig);
BUG_ON(!sig->s);

if (!sig->digest)
return -ENOPKG;

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))
Expand Down Expand Up @@ -167,6 +231,7 @@ struct asymmetric_key_subtype public_key_subtype = {
.name_len = sizeof("public_key") - 1,
.describe = public_key_describe,
.destroy = public_key_destroy,
.query = software_key_query,
.verify_signature = public_key_verify_signature_2,
};
EXPORT_SYMBOL_GPL(public_key_subtype);

0 comments on commit 82f94f2

Please sign in to comment.