mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-22 17:17:44 +07:00
KEYS: asym_tpm: Implement encryption operation [ver #2]
This patch impelements the pkey_encrypt operation. The public key portion extracted from the TPM key blob is used. The operation is performed entirely in software using the crypto API. Signed-off-by: Denis Kenzior <denkenz@gmail.com> Signed-off-by: David Howells <dhowells@redhat.com> Tested-by: Marcel Holtmann <marcel@holtmann.org> Reviewed-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: James Morris <james.morris@microsoft.com>
This commit is contained in:
parent
dff5a61a59
commit
ad4b1eb5fb
@ -165,6 +165,8 @@ static int tpm_key_query(const struct kernel_pkey_params *params,
|
|||||||
info->max_enc_size = len;
|
info->max_enc_size = len;
|
||||||
info->max_dec_size = tk->key_len / 8;
|
info->max_dec_size = tk->key_len / 8;
|
||||||
|
|
||||||
|
info->supported_ops = KEYCTL_SUPPORTS_ENCRYPT;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
error_free_tfm:
|
error_free_tfm:
|
||||||
crypto_free_akcipher(tfm);
|
crypto_free_akcipher(tfm);
|
||||||
@ -172,6 +174,87 @@ static int tpm_key_query(const struct kernel_pkey_params *params,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Encryption operation is performed with the public key. Hence it is done
|
||||||
|
* in software
|
||||||
|
*/
|
||||||
|
static int tpm_key_encrypt(struct tpm_key *tk,
|
||||||
|
struct kernel_pkey_params *params,
|
||||||
|
const void *in, void *out)
|
||||||
|
{
|
||||||
|
char alg_name[CRYPTO_MAX_ALG_NAME];
|
||||||
|
struct crypto_akcipher *tfm;
|
||||||
|
struct akcipher_request *req;
|
||||||
|
struct crypto_wait cwait;
|
||||||
|
struct scatterlist in_sg, out_sg;
|
||||||
|
uint8_t der_pub_key[PUB_KEY_BUF_SIZE];
|
||||||
|
uint32_t der_pub_key_len;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
pr_devel("==>%s()\n", __func__);
|
||||||
|
|
||||||
|
ret = determine_akcipher(params->encoding, params->hash_algo, alg_name);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
tfm = crypto_alloc_akcipher(alg_name, 0, 0);
|
||||||
|
if (IS_ERR(tfm))
|
||||||
|
return PTR_ERR(tfm);
|
||||||
|
|
||||||
|
der_pub_key_len = derive_pub_key(tk->pub_key, tk->pub_key_len,
|
||||||
|
der_pub_key);
|
||||||
|
|
||||||
|
ret = crypto_akcipher_set_pub_key(tfm, der_pub_key, der_pub_key_len);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error_free_tfm;
|
||||||
|
|
||||||
|
req = akcipher_request_alloc(tfm, GFP_KERNEL);
|
||||||
|
if (!req)
|
||||||
|
goto error_free_tfm;
|
||||||
|
|
||||||
|
sg_init_one(&in_sg, in, params->in_len);
|
||||||
|
sg_init_one(&out_sg, out, params->out_len);
|
||||||
|
akcipher_request_set_crypt(req, &in_sg, &out_sg, params->in_len,
|
||||||
|
params->out_len);
|
||||||
|
crypto_init_wait(&cwait);
|
||||||
|
akcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
|
||||||
|
CRYPTO_TFM_REQ_MAY_SLEEP,
|
||||||
|
crypto_req_done, &cwait);
|
||||||
|
|
||||||
|
ret = crypto_akcipher_encrypt(req);
|
||||||
|
ret = crypto_wait_req(ret, &cwait);
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
ret = req->dst_len;
|
||||||
|
|
||||||
|
akcipher_request_free(req);
|
||||||
|
error_free_tfm:
|
||||||
|
crypto_free_akcipher(tfm);
|
||||||
|
pr_devel("<==%s() = %d\n", __func__, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Do encryption, decryption and signing ops.
|
||||||
|
*/
|
||||||
|
static int tpm_key_eds_op(struct kernel_pkey_params *params,
|
||||||
|
const void *in, void *out)
|
||||||
|
{
|
||||||
|
struct tpm_key *tk = params->key->payload.data[asym_crypto];
|
||||||
|
int ret = -EOPNOTSUPP;
|
||||||
|
|
||||||
|
/* Perform the encryption calculation. */
|
||||||
|
switch (params->op) {
|
||||||
|
case kernel_pkey_encrypt:
|
||||||
|
ret = tpm_key_encrypt(tk, params, in, out);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse enough information out of TPM_KEY structure:
|
* Parse enough information out of TPM_KEY structure:
|
||||||
* TPM_STRUCT_VER -> 4 bytes
|
* TPM_STRUCT_VER -> 4 bytes
|
||||||
@ -329,6 +412,7 @@ struct asymmetric_key_subtype asym_tpm_subtype = {
|
|||||||
.describe = asym_tpm_describe,
|
.describe = asym_tpm_describe,
|
||||||
.destroy = asym_tpm_destroy,
|
.destroy = asym_tpm_destroy,
|
||||||
.query = tpm_key_query,
|
.query = tpm_key_query,
|
||||||
|
.eds_op = tpm_key_eds_op,
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(asym_tpm_subtype);
|
EXPORT_SYMBOL_GPL(asym_tpm_subtype);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user