@@ -6,14 +6,25 @@
#include <linux/module.h>
#include <linux/tpm.h>
-int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal)
+/**
+ * tpm_buf_init() - Initialize from the heap
+ * @buf: A @tpm_buf
+ *
+ * Initialize all structure fields to zero, allocate a page from the heap, and
+ * zero the bytes that the buffer headers will consume.
+ *
+ * Return: 0 or -ENOMEM
+ */
+int tpm_buf_init(struct tpm_buf *buf)
{
buf->data = (u8 *)__get_free_page(GFP_KERNEL);
if (!buf->data)
return -ENOMEM;
buf->flags = 0;
- tpm_buf_reset(buf, tag, ordinal);
+ buf->length = TPM_HEADER_SIZE;
+ memset(buf->data, 0, TPM_HEADER_SIZE);
+
return 0;
}
EXPORT_SYMBOL_GPL(tpm_buf_init);
@@ -44,9 +44,10 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
if (tpm_try_get_ops(chip))
return 0;
- if (tpm_buf_init(&tpm_buf, TPM_TAG_RQU_COMMAND, TPM_ORD_READPUBEK))
+ if (tpm_buf_init(&tpm_buf))
goto out_ops;
+ tpm_buf_reset(&tpm_buf, TPM_TAG_RQU_COMMAND, TPM_ORD_READPUBEK);
tpm_buf_append(&tpm_buf, anti_replay, sizeof(anti_replay));
if (tpm_transmit_cmd(chip, &tpm_buf, READ_PUBEK_RESULT_MIN_BODY_SIZE,
@@ -328,10 +328,11 @@ static int tpm1_startup(struct tpm_chip *chip)
dev_info(&chip->dev, "starting up the TPM manually\n");
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_STARTUP);
+ rc = tpm_buf_init(&buf);
if (rc < 0)
return rc;
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_STARTUP);
tpm_buf_append_u16(&buf, TPM_ST_CLEAR);
rc = tpm_transmit_cmd(chip, &buf, 0, "attempting to start the TPM");
@@ -466,10 +467,11 @@ int tpm1_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash,
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_EXTEND);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCR_EXTEND);
tpm_buf_append_u32(&buf, pcr_idx);
tpm_buf_append(&buf, hash, TPM_DIGEST_SIZE);
@@ -485,10 +487,12 @@ ssize_t tpm1_getcap(struct tpm_chip *chip, u32 subcap_id, cap_t *cap,
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_CAP);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_CAP);
+
if (subcap_id == TPM_CAP_VERSION_1_1 ||
subcap_id == TPM_CAP_VERSION_1_2) {
tpm_buf_append_u32(&buf, subcap_id);
@@ -537,10 +541,12 @@ int tpm1_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
u32 recd;
int rc;
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_RANDOM);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_GET_RANDOM);
+
do {
tpm_buf_append_u32(&buf, num_bytes);
@@ -586,10 +592,11 @@ int tpm1_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf)
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCRREAD);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_PCRREAD);
tpm_buf_append_u32(&buf, pcr_idx);
rc = tpm_transmit_cmd(chip, &buf, TPM_DIGEST_SIZE,
@@ -622,10 +629,12 @@ static int tpm1_continue_selftest(struct tpm_chip *chip)
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_CONTINUE_SELFTEST);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_CONTINUE_SELFTEST);
+
rc = tpm_transmit_cmd(chip, &buf, 0, "continue selftest");
tpm_buf_destroy(&buf);
return rc;
@@ -752,9 +761,12 @@ int tpm1_pm_suspend(struct tpm_chip *chip, u32 tpm_suspend_pcr)
rc = tpm1_pcr_extend(chip, tpm_suspend_pcr, dummy_hash,
"extending dummy pcr before suspend");
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_SAVESTATE);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_SAVESTATE);
+
/* now do the actual savestate */
for (try = 0; try < TPM_RETRY; try++) {
rc = tpm_transmit_cmd(chip, &buf, 0, NULL);
@@ -183,10 +183,12 @@ int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx,
expected_digest_size = chip->allocated_banks[i].digest_size;
}
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_PCR_READ);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_PCR_READ);
+
pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7);
tpm_buf_append_u32(&buf, 1);
@@ -240,10 +242,11 @@ int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx,
int rc;
int i;
- rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
tpm_buf_append_u32(&buf, pcr_idx);
auth_area.handle = cpu_to_be32(TPM2_RS_PW);
@@ -299,7 +302,7 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max)
if (!num_bytes || max > TPM_MAX_RNG_DATA)
return -EINVAL;
- err = tpm_buf_init(&buf, 0, 0);
+ err = tpm_buf_init(&buf);
if (err)
return err;
@@ -350,13 +353,14 @@ void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT);
+ rc = tpm_buf_init(&buf);
if (rc) {
dev_warn(&chip->dev, "0x%08x was not flushed, out of memory\n",
handle);
return;
}
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_FLUSH_CONTEXT);
tpm_buf_append_u32(&buf, handle);
tpm_transmit_cmd(chip, &buf, 0, "flushing context");
@@ -390,9 +394,11 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id, u32 *value,
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES);
tpm_buf_append_u32(&buf, property_id);
tpm_buf_append_u32(&buf, 1);
@@ -431,9 +437,11 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SHUTDOWN);
+ rc = tpm_buf_init(&buf);
if (rc)
return;
+
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SHUTDOWN);
tpm_buf_append_u16(&buf, shutdown_type);
tpm_transmit_cmd(chip, &buf, 0, "stopping the TPM");
tpm_buf_destroy(&buf);
@@ -459,10 +467,11 @@ static int tpm2_do_selftest(struct tpm_chip *chip)
int rc;
for (full = 0; full < 2; full++) {
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SELF_TEST);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_SELF_TEST);
tpm_buf_append_u8(&buf, full);
rc = tpm_transmit_cmd(chip, &buf, 0,
"attempting the self test");
@@ -495,9 +504,11 @@ int tpm2_probe(struct tpm_chip *chip)
struct tpm_buf buf;
int rc;
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
tpm_buf_append_u32(&buf, TPM2_CAP_TPM_PROPERTIES);
tpm_buf_append_u32(&buf, TPM_PT_TOTAL_COMMANDS);
tpm_buf_append_u32(&buf, 1);
@@ -560,10 +571,11 @@ ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
int rc;
int i = 0;
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
tpm_buf_append_u32(&buf, TPM2_CAP_PCRS);
tpm_buf_append_u32(&buf, 0);
tpm_buf_append_u32(&buf, 1);
@@ -649,10 +661,11 @@ int tpm2_get_cc_attrs_tbl(struct tpm_chip *chip)
goto out;
}
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
+ rc = tpm_buf_init(&buf);
if (rc)
goto out;
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
tpm_buf_append_u32(&buf, TPM2_CAP_COMMANDS);
tpm_buf_append_u32(&buf, TPM2_CC_FIRST);
tpm_buf_append_u32(&buf, nr_commands);
@@ -711,10 +724,11 @@ static int tpm2_startup(struct tpm_chip *chip)
dev_info(&chip->dev, "starting up the TPM manually\n");
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_STARTUP);
+ rc = tpm_buf_init(&buf);
if (rc < 0)
return rc;
+ tpm_buf_reset(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_STARTUP);
tpm_buf_append_u16(&buf, TPM2_SU_CLEAR);
rc = tpm_transmit_cmd(chip, &buf, 0, "attempting to start the TPM");
tpm_buf_destroy(&buf);
@@ -76,10 +76,12 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
unsigned int body_size;
int rc;
- rc = tpm_buf_init(&tbuf, TPM2_ST_NO_SESSIONS, TPM2_CC_CONTEXT_LOAD);
+ rc = tpm_buf_init(&tbuf);
if (rc)
return rc;
+ tpm_buf_reset(&tbuf, TPM2_ST_NO_SESSIONS, TPM2_CC_CONTEXT_LOAD);
+
ctx = (struct tpm2_context *)&buf[*offset];
body_size = sizeof(*ctx) + be16_to_cpu(ctx->blob_size);
tpm_buf_append(&tbuf, &buf[*offset], body_size);
@@ -126,10 +128,11 @@ static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
unsigned int body_size;
int rc;
- rc = tpm_buf_init(&tbuf, TPM2_ST_NO_SESSIONS, TPM2_CC_CONTEXT_SAVE);
+ rc = tpm_buf_init(&tbuf);
if (rc)
return rc;
+ tpm_buf_reset(&tbuf, TPM2_ST_NO_SESSIONS, TPM2_CC_CONTEXT_SAVE);
tpm_buf_append_u32(&tbuf, handle);
rc = tpm_transmit_cmd(chip, &tbuf, 0, NULL);
@@ -399,14 +399,15 @@ static int vtpm_proxy_request_locality(struct tpm_chip *chip, int locality)
const struct tpm_header *header;
struct proxy_dev *proxy_dev = dev_get_drvdata(&chip->dev);
- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS,
- TPM2_CC_SET_LOCALITY);
- else
- rc = tpm_buf_init(&buf, TPM_TAG_RQU_COMMAND,
- TPM_ORD_SET_LOCALITY);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+
+ if (chip->flags & TPM_CHIP_FLAG_TPM2)
+ tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_SET_LOCALITY);
+ else
+ tpm_buf_reset(&buf, TPM_TAG_RQU_COMMAND, TPM_ORD_SET_LOCALITY);
+
tpm_buf_append_u8(&buf, locality);
proxy_dev->state |= STATE_DRIVER_COMMAND;
@@ -328,7 +328,7 @@ struct tpm2_hash {
};
-int tpm_buf_init(struct tpm_buf *buf, u16 tag, u32 ordinal);
+int tpm_buf_init(struct tpm_buf *buf);
void tpm_buf_reset(struct tpm_buf *buf, u16 tag, u32 ordinal);
void tpm_buf_destroy(struct tpm_buf *buf);
u32 tpm_buf_length(struct tpm_buf *buf);
@@ -664,7 +664,7 @@ static int key_seal(struct trusted_key_payload *p,
struct tpm_buf tb;
int ret;
- ret = tpm_buf_init(&tb, 0, 0);
+ ret = tpm_buf_init(&tb);
if (ret)
return ret;
@@ -690,7 +690,7 @@ static int key_unseal(struct trusted_key_payload *p,
struct tpm_buf tb;
int ret;
- ret = tpm_buf_init(&tb, 0, 0);
+ ret = tpm_buf_init(&tb);
if (ret)
return ret;
@@ -252,12 +252,13 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
if (rc)
return rc;
- rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
+ rc = tpm_buf_init(&buf);
if (rc) {
tpm_put_ops(chip);
return rc;
}
+ tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
tpm_buf_append_u32(&buf, options->keyhandle);
tpm2_buf_append_auth(&buf, TPM2_RS_PW,
NULL /* nonce */, 0,
@@ -409,10 +410,11 @@ static int tpm2_load_cmd(struct tpm_chip *chip,
if (blob_len > payload->blob_len)
return -E2BIG;
- rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD);
tpm_buf_append_u32(&buf, options->keyhandle);
tpm2_buf_append_auth(&buf, TPM2_RS_PW,
NULL /* nonce */, 0,
@@ -465,10 +467,11 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip,
u8 *data;
int rc;
- rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
+ rc = tpm_buf_init(&buf);
if (rc)
return rc;
+ tpm_buf_reset(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
tpm_buf_append_u32(&buf, blob_handle);
tpm2_buf_append_auth(&buf,
options->policyhandle ?
In order to use tpm_buf_init() for other buffer types, detach tpm_buf_reset() from tpm_buf_init(). Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org> --- drivers/char/tpm/tpm-buf.c | 15 ++++++++-- drivers/char/tpm/tpm-sysfs.c | 3 +- drivers/char/tpm/tpm1-cmd.c | 26 +++++++++++----- drivers/char/tpm/tpm2-cmd.c | 36 ++++++++++++++++------- drivers/char/tpm/tpm2-space.c | 7 +++-- drivers/char/tpm/tpm_vtpm_proxy.c | 13 ++++---- include/linux/tpm.h | 2 +- security/keys/trusted-keys/trusted_tpm1.c | 4 +-- security/keys/trusted-keys/trusted_tpm2.c | 9 ++++-- 9 files changed, 80 insertions(+), 35 deletions(-)