tpm: remove @space from tpm_transmit()

Remove @space from tpm_transmit() API` in order to completely remove the
bound between low-level transmission functionality and TPM spaces. The
only real dependency existing is the amount of data saved before trying
to send a command to the TPM.

It doesn't really matter if we save always a bit more than needed so
this commit changes the amount saved always to be the size of the TPM
header and three handles.

Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Reviewed-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Tested-by: Alexander Steffen <Alexander.Steffen@infineon.com>
This commit is contained in:
Jarkko Sakkinen 2018-11-03 15:15:07 +02:00
parent 29b47ce987
commit 5faafbab77
8 changed files with 43 additions and 53 deletions

View File

@ -48,7 +48,7 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space,
if (ret) if (ret)
goto out_lock; goto out_lock;
len = tpm_transmit(chip, space, buf, bufsiz, TPM_TRANSMIT_UNLOCKED); len = tpm_transmit(chip, buf, bufsiz, TPM_TRANSMIT_UNLOCKED);
if (len < 0) if (len < 0)
ret = len; ret = len;

View File

@ -120,8 +120,8 @@ static int tpm_go_idle(struct tpm_chip *chip, unsigned int flags)
return chip->ops->go_idle(chip); return chip->ops->go_idle(chip);
} }
static ssize_t tpm_try_transmit(struct tpm_chip *chip, struct tpm_space *space, static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz,
void *buf, size_t bufsiz, unsigned int flags) unsigned int flags)
{ {
struct tpm_header *header = buf; struct tpm_header *header = buf;
int rc; int rc;
@ -199,7 +199,6 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, struct tpm_space *space,
/** /**
* tpm_transmit - Internal kernel interface to transmit TPM commands. * tpm_transmit - Internal kernel interface to transmit TPM commands.
* @chip: a TPM chip to use * @chip: a TPM chip to use
* @space: a TPM space
* @buf: a TPM command buffer * @buf: a TPM command buffer
* @bufsiz: length of the TPM command buffer * @bufsiz: length of the TPM command buffer
* @flags: TPM transmit flags * @flags: TPM transmit flags
@ -215,8 +214,8 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, struct tpm_space *space,
* * The response length - OK * * The response length - OK
* * -errno - A system error * * -errno - A system error
*/ */
ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
u8 *buf, size_t bufsiz, unsigned int flags) unsigned int flags)
{ {
struct tpm_header *header = (struct tpm_header *)buf; struct tpm_header *header = (struct tpm_header *)buf;
/* space for header and handles */ /* space for header and handles */
@ -225,8 +224,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
bool has_locality = false; bool has_locality = false;
u32 rc = 0; u32 rc = 0;
ssize_t ret; ssize_t ret;
const size_t save_size = min(space ? sizeof(save) : TPM_HEADER_SIZE, const size_t save_size = min(sizeof(save), bufsiz);
bufsiz);
/* the command code is where the return code will be */ /* the command code is where the return code will be */
u32 cc = be32_to_cpu(header->return_code); u32 cc = be32_to_cpu(header->return_code);
@ -256,7 +254,7 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
if (ret) if (ret)
goto out_locality; goto out_locality;
ret = tpm_try_transmit(chip, space, buf, bufsiz, flags); ret = tpm_try_transmit(chip, buf, bufsiz, flags);
/* This may fail but do not override ret. */ /* This may fail but do not override ret. */
tpm_go_idle(chip, flags); tpm_go_idle(chip, flags);
@ -302,7 +300,6 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
/** /**
* tpm_transmit_cmd - send a tpm command to the device * tpm_transmit_cmd - send a tpm command to the device
* @chip: a TPM chip to use * @chip: a TPM chip to use
* @space: a TPM space
* @buf: a TPM command buffer * @buf: a TPM command buffer
* @min_rsp_body_length: minimum expected length of response body * @min_rsp_body_length: minimum expected length of response body
* @flags: TPM transmit flags * @flags: TPM transmit flags
@ -313,15 +310,15 @@ ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space,
* * -errno - A system error * * -errno - A system error
* * TPM_RC - A TPM error * * TPM_RC - A TPM error
*/ */
ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
struct tpm_buf *buf, size_t min_rsp_body_length, size_t min_rsp_body_length, unsigned int flags,
unsigned int flags, const char *desc) const char *desc)
{ {
const struct tpm_header *header = (struct tpm_header *)buf->data; const struct tpm_header *header = (struct tpm_header *)buf->data;
int err; int err;
ssize_t len; ssize_t len;
len = tpm_transmit(chip, space, buf->data, PAGE_SIZE, flags); len = tpm_transmit(chip, buf->data, PAGE_SIZE, flags);
if (len < 0) if (len < 0)
return len; return len;
@ -470,7 +467,7 @@ int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen)
goto out; goto out;
memcpy(buf.data, cmd, buflen); memcpy(buf.data, cmd, buflen);
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, rc = tpm_transmit_cmd(chip, &buf, 0, 0,
"attempting to a send a command"); "attempting to a send a command");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
out: out:

View File

@ -52,9 +52,8 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
tpm_buf_append(&tpm_buf, anti_replay, sizeof(anti_replay)); tpm_buf_append(&tpm_buf, anti_replay, sizeof(anti_replay));
rc = tpm_transmit_cmd(chip, NULL, &tpm_buf, rc = tpm_transmit_cmd(chip, &tpm_buf, READ_PUBEK_RESULT_MIN_BODY_SIZE,
READ_PUBEK_RESULT_MIN_BODY_SIZE, 0, 0, "attempting to read the PUBEK");
"attempting to read the PUBEK");
if (rc) { if (rc) {
tpm_buf_destroy(&tpm_buf); tpm_buf_destroy(&tpm_buf);
return 0; return 0;

View File

@ -498,11 +498,11 @@ enum tpm_transmit_flags {
TPM_TRANSMIT_NESTED = BIT(1), TPM_TRANSMIT_NESTED = BIT(1),
}; };
ssize_t tpm_transmit(struct tpm_chip *chip, struct tpm_space *space, ssize_t tpm_transmit(struct tpm_chip *chip, u8 *buf, size_t bufsiz,
u8 *buf, size_t bufsiz, unsigned int flags); unsigned int flags);
ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_space *space, ssize_t tpm_transmit_cmd(struct tpm_chip *chip, struct tpm_buf *buf,
struct tpm_buf *buf, size_t min_rsp_body_length, size_t min_rsp_body_length, unsigned int flags,
unsigned int flags, const char *desc); const char *desc);
int tpm_get_timeouts(struct tpm_chip *); int tpm_get_timeouts(struct tpm_chip *);
int tpm_auto_startup(struct tpm_chip *chip); int tpm_auto_startup(struct tpm_chip *chip);

View File

@ -334,8 +334,7 @@ static int tpm1_startup(struct tpm_chip *chip)
tpm_buf_append_u16(&buf, TPM_ST_CLEAR); tpm_buf_append_u16(&buf, TPM_ST_CLEAR);
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, rc = tpm_transmit_cmd(chip, &buf, 0, 0, "attempting to start the TPM");
"attempting to start the TPM");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
return rc; return rc;
} }
@ -459,7 +458,7 @@ int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
tpm_buf_append_u32(&buf, pcr_idx); tpm_buf_append_u32(&buf, pcr_idx);
tpm_buf_append(&buf, hash, TPM_DIGEST_SIZE); tpm_buf_append(&buf, hash, TPM_DIGEST_SIZE);
rc = tpm_transmit_cmd(chip, NULL, &buf, TPM_DIGEST_SIZE, 0, log_msg); rc = tpm_transmit_cmd(chip, &buf, TPM_DIGEST_SIZE, 0, log_msg);
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
return rc; return rc;
} }
@ -489,7 +488,7 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
tpm_buf_append_u32(&buf, 4); tpm_buf_append_u32(&buf, 4);
tpm_buf_append_u32(&buf, subcap_id); tpm_buf_append_u32(&buf, subcap_id);
} }
rc = tpm_transmit_cmd(chip, NULL, &buf, min_cap_length, 0, desc); rc = tpm_transmit_cmd(chip, &buf, min_cap_length, 0, desc);
if (!rc) if (!rc)
*cap = *(cap_t *)&buf.data[TPM_HEADER_SIZE + 4]; *cap = *(cap_t *)&buf.data[TPM_HEADER_SIZE + 4];
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
@ -530,8 +529,7 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
do { do {
tpm_buf_append_u32(&buf, num_bytes); tpm_buf_append_u32(&buf, num_bytes);
rc = tpm_transmit_cmd(chip, NULL, &buf, rc = tpm_transmit_cmd(chip, &buf, sizeof(out->rng_data_len), 0,
sizeof(out->rng_data_len), 0,
"attempting get random"); "attempting get random");
if (rc) if (rc)
goto out; goto out;
@ -576,7 +574,7 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
tpm_buf_append_u32(&buf, pcr_idx); tpm_buf_append_u32(&buf, pcr_idx);
rc = tpm_transmit_cmd(chip, NULL, &buf, TPM_DIGEST_SIZE, 0, rc = tpm_transmit_cmd(chip, &buf, TPM_DIGEST_SIZE, 0,
"attempting to read a pcr value"); "attempting to read a pcr value");
if (rc) if (rc)
goto out; goto out;
@ -610,7 +608,7 @@ static int tpm1_continue_selftest(struct tpm_chip *chip)
if (rc) if (rc)
return rc; return rc;
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, "continue selftest"); rc = tpm_transmit_cmd(chip, &buf, 0, 0, "continue selftest");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
return rc; return rc;
} }
@ -736,7 +734,7 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
return rc; return rc;
/* now do the actual savestate */ /* now do the actual savestate */
for (try = 0; try < TPM_RETRY; try++) { for (try = 0; try < TPM_RETRY; try++) {
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, NULL); rc = tpm_transmit_cmd(chip, &buf, 0, 0, NULL);
/* /*
* If the TPM indicates that it is too busy to respond to * If the TPM indicates that it is too busy to respond to
* this command then retry before giving up. It can take * this command then retry before giving up. It can take

View File

@ -197,7 +197,7 @@ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
tpm_buf_append(&buf, (const unsigned char *)pcr_select, tpm_buf_append(&buf, (const unsigned char *)pcr_select,
sizeof(pcr_select)); sizeof(pcr_select));
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, res_buf ? rc = tpm_transmit_cmd(chip, &buf, 0, 0, res_buf ?
"attempting to read a pcr value" : NULL); "attempting to read a pcr value" : NULL);
if (rc == 0 && res_buf) { if (rc == 0 && res_buf) {
out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE]; out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE];
@ -264,7 +264,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count,
} }
} }
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, rc = tpm_transmit_cmd(chip, &buf, 0, 0,
"attempting extend a PCR value"); "attempting extend a PCR value");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
@ -309,7 +309,7 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
do { do {
tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM); tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_RANDOM);
tpm_buf_append_u16(&buf, num_bytes); tpm_buf_append_u16(&buf, num_bytes);
err = tpm_transmit_cmd(chip, NULL, &buf, err = tpm_transmit_cmd(chip, &buf,
offsetof(struct tpm2_get_random_out, offsetof(struct tpm2_get_random_out,
buffer), buffer),
0, "attempting get random"); 0, "attempting get random");
@ -362,7 +362,7 @@ void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
tpm_buf_append_u32(&buf, handle); tpm_buf_append_u32(&buf, handle);
tpm_transmit_cmd(chip, NULL, &buf, 0, flags, "flushing context"); tpm_transmit_cmd(chip, &buf, 0, flags, "flushing context");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
} }
@ -476,7 +476,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
goto out; goto out;
} }
rc = tpm_transmit_cmd(chip, NULL, &buf, 4, 0, "sealing data"); rc = tpm_transmit_cmd(chip, &buf, 4, 0, "sealing data");
if (rc) if (rc)
goto out; goto out;
@ -558,7 +558,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
goto out; goto out;
} }
rc = tpm_transmit_cmd(chip, NULL, &buf, 4, flags, "loading blob"); rc = tpm_transmit_cmd(chip, &buf, 4, flags, "loading blob");
if (!rc) if (!rc)
*blob_handle = be32_to_cpup( *blob_handle = be32_to_cpup(
(__be32 *) &buf.data[TPM_HEADER_SIZE]); (__be32 *) &buf.data[TPM_HEADER_SIZE]);
@ -608,7 +608,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
options->blobauth /* hmac */, options->blobauth /* hmac */,
TPM_DIGEST_SIZE); TPM_DIGEST_SIZE);
rc = tpm_transmit_cmd(chip, NULL, &buf, 6, flags, "unsealing"); rc = tpm_transmit_cmd(chip, &buf, 6, flags, "unsealing");
if (rc > 0) if (rc > 0)
rc = -EPERM; rc = -EPERM;
@ -698,7 +698,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id, u32 *value,
tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES); tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES);
tpm_buf_append_u32(&buf, property_id); tpm_buf_append_u32(&buf, property_id);
tpm_buf_append_u32(&buf, 1); tpm_buf_append_u32(&buf, 1);
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, NULL); rc = tpm_transmit_cmd(chip, &buf, 0, 0, NULL);
if (!rc) { if (!rc) {
out = (struct tpm2_get_cap_out *) out = (struct tpm2_get_cap_out *)
&buf.data[TPM_HEADER_SIZE]; &buf.data[TPM_HEADER_SIZE];
@ -728,7 +728,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
if (rc) if (rc)
return; return;
tpm_buf_append_u16(&buf, shutdown_type); tpm_buf_append_u16(&buf, shutdown_type);
tpm_transmit_cmd(chip, NULL, &buf, 0, 0, "stopping the TPM"); tpm_transmit_cmd(chip, &buf, 0, 0, "stopping the TPM");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
} }
@ -757,7 +757,7 @@ static int tpm2_do_selftest(struct tpm_chip *chip)
return rc; return rc;
tpm_buf_append_u8(&buf, full); tpm_buf_append_u8(&buf, full);
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, rc = tpm_transmit_cmd(chip, &buf, 0, 0,
"attempting the self test"); "attempting the self test");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
@ -794,7 +794,7 @@ int tpm2_probe(struct tpm_chip *chip)
tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES); tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES);
tpm_buf_append_u32(&buf, TPM_PT_TOTAL_COMMANDS); tpm_buf_append_u32(&buf, TPM_PT_TOTAL_COMMANDS);
tpm_buf_append_u32(&buf, 1); tpm_buf_append_u32(&buf, 1);
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, NULL); rc = tpm_transmit_cmd(chip, &buf, 0, 0, NULL);
/* We ignore TPM return codes on purpose. */ /* We ignore TPM return codes on purpose. */
if (rc >= 0) { if (rc >= 0) {
out = (struct tpm_header *)buf.data; out = (struct tpm_header *)buf.data;
@ -833,8 +833,7 @@ static ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
tpm_buf_append_u32(&buf, 0); tpm_buf_append_u32(&buf, 0);
tpm_buf_append_u32(&buf, 1); tpm_buf_append_u32(&buf, 1);
rc = tpm_transmit_cmd(chip, NULL, &buf, 9, 0, rc = tpm_transmit_cmd(chip, &buf, 9, 0, "get tpm pcr allocation");
"get tpm pcr allocation");
if (rc) if (rc)
goto out; goto out;
@ -905,7 +904,7 @@ static int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
tpm_buf_append_u32(&buf, TPM2_CC_FIRST); tpm_buf_append_u32(&buf, TPM2_CC_FIRST);
tpm_buf_append_u32(&buf, nr_commands); tpm_buf_append_u32(&buf, nr_commands);
rc = tpm_transmit_cmd(chip, NULL, &buf, 9 + 4 * nr_commands, 0, NULL); rc = tpm_transmit_cmd(chip, &buf, 9 + 4 * nr_commands, 0, NULL);
if (rc) { if (rc) {
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
goto out; goto out;
@ -962,8 +961,7 @@ static int tpm2_startup(struct tpm_chip *chip)
return rc; return rc;
tpm_buf_append_u16(&buf, TPM2_SU_CLEAR); tpm_buf_append_u16(&buf, TPM2_SU_CLEAR);
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, 0, rc = tpm_transmit_cmd(chip, &buf, 0, 0, "attempting to start the TPM");
"attempting to start the TPM");
tpm_buf_destroy(&buf); tpm_buf_destroy(&buf);
return rc; return rc;

View File

@ -83,8 +83,7 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
body_size = sizeof(*ctx) + be16_to_cpu(ctx->blob_size); body_size = sizeof(*ctx) + be16_to_cpu(ctx->blob_size);
tpm_buf_append(&tbuf, &buf[*offset], body_size); tpm_buf_append(&tbuf, &buf[*offset], body_size);
rc = tpm_transmit_cmd(chip, NULL, &tbuf, 4, rc = tpm_transmit_cmd(chip, &tbuf, 4, TPM_TRANSMIT_UNLOCKED, NULL);
TPM_TRANSMIT_UNLOCKED, NULL);
if (rc < 0) { if (rc < 0) {
dev_warn(&chip->dev, "%s: failed with a system error %d\n", dev_warn(&chip->dev, "%s: failed with a system error %d\n",
__func__, rc); __func__, rc);
@ -132,8 +131,7 @@ static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
tpm_buf_append_u32(&tbuf, handle); tpm_buf_append_u32(&tbuf, handle);
rc = tpm_transmit_cmd(chip, NULL, &tbuf, 0, rc = tpm_transmit_cmd(chip, &tbuf, 0, TPM_TRANSMIT_UNLOCKED, NULL);
TPM_TRANSMIT_UNLOCKED, NULL);
if (rc < 0) { if (rc < 0) {
dev_warn(&chip->dev, "%s: failed with a system error %d\n", dev_warn(&chip->dev, "%s: failed with a system error %d\n",
__func__, rc); __func__, rc);

View File

@ -416,7 +416,7 @@ static int vtpm_proxy_request_locality(struct tpm_chip *chip, int locality)
proxy_dev->state |= STATE_DRIVER_COMMAND; proxy_dev->state |= STATE_DRIVER_COMMAND;
rc = tpm_transmit_cmd(chip, NULL, &buf, 0, TPM_TRANSMIT_NESTED, rc = tpm_transmit_cmd(chip, &buf, 0, TPM_TRANSMIT_NESTED,
"attempting to set locality"); "attempting to set locality");
proxy_dev->state &= ~STATE_DRIVER_COMMAND; proxy_dev->state &= ~STATE_DRIVER_COMMAND;