KEYS: Use common tpm_buf for trusted and asymmetric keys

Switch to utilize common heap based tpm_buf code for TPM based trusted
and asymmetric keys rather than using stack based tpm1_buf code. Also,
remove tpm1_buf code.

Suggested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
This commit is contained in:
Sumit Garg
2019-10-16 10:44:53 +05:30
committed by Jarkko Sakkinen
parent 74edff2d74
commit c6f61e5976
3 changed files with 89 additions and 153 deletions

View File

@@ -21,17 +21,13 @@
#define TPM_ORD_LOADKEY2 65
#define TPM_ORD_UNBIND 30
#define TPM_ORD_SIGN 60
#define TPM_LOADKEY2_SIZE 59
#define TPM_FLUSHSPECIFIC_SIZE 18
#define TPM_UNBIND_SIZE 63
#define TPM_SIGN_SIZE 63
#define TPM_RT_KEY 0x00000001
/*
* Load a TPM key from the blob provided by userspace
*/
static int tpm_loadkey2(struct tpm1_buf *tb,
static int tpm_loadkey2(struct tpm_buf *tb,
uint32_t keyhandle, unsigned char *keyauth,
const unsigned char *keyblob, int keybloblen,
uint32_t *newhandle)
@@ -68,16 +64,13 @@ static int tpm_loadkey2(struct tpm1_buf *tb,
return ret;
/* build the request buffer */
INIT_BUF(tb);
store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
store32(tb, TPM_LOADKEY2_SIZE + keybloblen);
store32(tb, TPM_ORD_LOADKEY2);
store32(tb, keyhandle);
storebytes(tb, keyblob, keybloblen);
store32(tb, authhandle);
storebytes(tb, nonceodd, TPM_NONCE_SIZE);
store8(tb, cont);
storebytes(tb, authdata, SHA1_DIGEST_SIZE);
tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_LOADKEY2);
tpm_buf_append_u32(tb, keyhandle);
tpm_buf_append(tb, keyblob, keybloblen);
tpm_buf_append_u32(tb, authhandle);
tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
tpm_buf_append_u8(tb, cont);
tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
if (ret < 0) {
@@ -99,14 +92,11 @@ static int tpm_loadkey2(struct tpm1_buf *tb,
/*
* Execute the FlushSpecific TPM command
*/
static int tpm_flushspecific(struct tpm1_buf *tb, uint32_t handle)
static int tpm_flushspecific(struct tpm_buf *tb, uint32_t handle)
{
INIT_BUF(tb);
store16(tb, TPM_TAG_RQU_COMMAND);
store32(tb, TPM_FLUSHSPECIFIC_SIZE);
store32(tb, TPM_ORD_FLUSHSPECIFIC);
store32(tb, handle);
store32(tb, TPM_RT_KEY);
tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_FLUSHSPECIFIC);
tpm_buf_append_u32(tb, handle);
tpm_buf_append_u32(tb, TPM_RT_KEY);
return trusted_tpm_send(tb->data, MAX_BUF_SIZE);
}
@@ -115,7 +105,7 @@ static int tpm_flushspecific(struct tpm1_buf *tb, uint32_t handle)
* Decrypt a blob provided by userspace using a specific key handle.
* The handle is a well known handle or previously loaded by e.g. LoadKey2
*/
static int tpm_unbind(struct tpm1_buf *tb,
static int tpm_unbind(struct tpm_buf *tb,
uint32_t keyhandle, unsigned char *keyauth,
const unsigned char *blob, uint32_t bloblen,
void *out, uint32_t outlen)
@@ -155,17 +145,14 @@ static int tpm_unbind(struct tpm1_buf *tb,
return ret;
/* build the request buffer */
INIT_BUF(tb);
store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
store32(tb, TPM_UNBIND_SIZE + bloblen);
store32(tb, TPM_ORD_UNBIND);
store32(tb, keyhandle);
store32(tb, bloblen);
storebytes(tb, blob, bloblen);
store32(tb, authhandle);
storebytes(tb, nonceodd, TPM_NONCE_SIZE);
store8(tb, cont);
storebytes(tb, authdata, SHA1_DIGEST_SIZE);
tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_UNBIND);
tpm_buf_append_u32(tb, keyhandle);
tpm_buf_append_u32(tb, bloblen);
tpm_buf_append(tb, blob, bloblen);
tpm_buf_append_u32(tb, authhandle);
tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
tpm_buf_append_u8(tb, cont);
tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
if (ret < 0) {
@@ -201,7 +188,7 @@ static int tpm_unbind(struct tpm1_buf *tb,
* up to key_length_in_bytes - 11 and not be limited to size 20 like the
* TPM_SS_RSASSAPKCS1v15_SHA1 signature scheme.
*/
static int tpm_sign(struct tpm1_buf *tb,
static int tpm_sign(struct tpm_buf *tb,
uint32_t keyhandle, unsigned char *keyauth,
const unsigned char *blob, uint32_t bloblen,
void *out, uint32_t outlen)
@@ -241,17 +228,14 @@ static int tpm_sign(struct tpm1_buf *tb,
return ret;
/* build the request buffer */
INIT_BUF(tb);
store16(tb, TPM_TAG_RQU_AUTH1_COMMAND);
store32(tb, TPM_SIGN_SIZE + bloblen);
store32(tb, TPM_ORD_SIGN);
store32(tb, keyhandle);
store32(tb, bloblen);
storebytes(tb, blob, bloblen);
store32(tb, authhandle);
storebytes(tb, nonceodd, TPM_NONCE_SIZE);
store8(tb, cont);
storebytes(tb, authdata, SHA1_DIGEST_SIZE);
tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_SIGN);
tpm_buf_append_u32(tb, keyhandle);
tpm_buf_append_u32(tb, bloblen);
tpm_buf_append(tb, blob, bloblen);
tpm_buf_append_u32(tb, authhandle);
tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
tpm_buf_append_u8(tb, cont);
tpm_buf_append(tb, authdata, SHA1_DIGEST_SIZE);
ret = trusted_tpm_send(tb->data, MAX_BUF_SIZE);
if (ret < 0) {
@@ -519,7 +503,7 @@ static int tpm_key_decrypt(struct tpm_key *tk,
struct kernel_pkey_params *params,
const void *in, void *out)
{
struct tpm1_buf *tb;
struct tpm_buf tb;
uint32_t keyhandle;
uint8_t srkauth[SHA1_DIGEST_SIZE];
uint8_t keyauth[SHA1_DIGEST_SIZE];
@@ -533,14 +517,14 @@ static int tpm_key_decrypt(struct tpm_key *tk,
if (strcmp(params->encoding, "pkcs1"))
return -ENOPKG;
tb = kzalloc(sizeof(*tb), GFP_KERNEL);
if (!tb)
return -ENOMEM;
r = tpm_buf_init(&tb, 0, 0);
if (r)
return r;
/* TODO: Handle a non-all zero SRK authorization */
memset(srkauth, 0, sizeof(srkauth));
r = tpm_loadkey2(tb, SRKHANDLE, srkauth,
r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
tk->blob, tk->blob_len, &keyhandle);
if (r < 0) {
pr_devel("loadkey2 failed (%d)\n", r);
@@ -550,16 +534,16 @@ static int tpm_key_decrypt(struct tpm_key *tk,
/* TODO: Handle a non-all zero key authorization */
memset(keyauth, 0, sizeof(keyauth));
r = tpm_unbind(tb, keyhandle, keyauth,
r = tpm_unbind(&tb, keyhandle, keyauth,
in, params->in_len, out, params->out_len);
if (r < 0)
pr_devel("tpm_unbind failed (%d)\n", r);
if (tpm_flushspecific(tb, keyhandle) < 0)
if (tpm_flushspecific(&tb, keyhandle) < 0)
pr_devel("flushspecific failed (%d)\n", r);
error:
kzfree(tb);
tpm_buf_destroy(&tb);
pr_devel("<==%s() = %d\n", __func__, r);
return r;
}
@@ -643,7 +627,7 @@ static int tpm_key_sign(struct tpm_key *tk,
struct kernel_pkey_params *params,
const void *in, void *out)
{
struct tpm1_buf *tb;
struct tpm_buf tb;
uint32_t keyhandle;
uint8_t srkauth[SHA1_DIGEST_SIZE];
uint8_t keyauth[SHA1_DIGEST_SIZE];
@@ -681,15 +665,14 @@ static int tpm_key_sign(struct tpm_key *tk,
goto error_free_asn1_wrapped;
}
r = -ENOMEM;
tb = kzalloc(sizeof(*tb), GFP_KERNEL);
if (!tb)
r = tpm_buf_init(&tb, 0, 0);
if (r)
goto error_free_asn1_wrapped;
/* TODO: Handle a non-all zero SRK authorization */
memset(srkauth, 0, sizeof(srkauth));
r = tpm_loadkey2(tb, SRKHANDLE, srkauth,
r = tpm_loadkey2(&tb, SRKHANDLE, srkauth,
tk->blob, tk->blob_len, &keyhandle);
if (r < 0) {
pr_devel("loadkey2 failed (%d)\n", r);
@@ -699,15 +682,15 @@ static int tpm_key_sign(struct tpm_key *tk,
/* TODO: Handle a non-all zero key authorization */
memset(keyauth, 0, sizeof(keyauth));
r = tpm_sign(tb, keyhandle, keyauth, in, in_len, out, params->out_len);
r = tpm_sign(&tb, keyhandle, keyauth, in, in_len, out, params->out_len);
if (r < 0)
pr_devel("tpm_sign failed (%d)\n", r);
if (tpm_flushspecific(tb, keyhandle) < 0)
if (tpm_flushspecific(&tb, keyhandle) < 0)
pr_devel("flushspecific failed (%d)\n", r);
error_free_tb:
kzfree(tb);
tpm_buf_destroy(&tb);
error_free_asn1_wrapped:
kfree(asn1_wrapped);
pr_devel("<==%s() = %d\n", __func__, r);