From: James Bottomley <James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk@public.gmane.org>
To: tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: linux-security-module-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
open list <linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org>
Subject: [PATCH 2/2] tpm2: context save and restore space managed sessions
Date: Wed, 18 Jan 2017 10:10:42 -0500 [thread overview]
Message-ID: <1484752242.2717.17.camel@HansenPartnership.com> (raw)
In-Reply-To: <1484752097.2717.14.camel-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk@public.gmane.org>
Now that sessions are isolated, we can introduce a session_buf in the
tpm2 space to save and restore them. This allows us to have many more
sessions active simultaneously (up to TPM_PT_MAX_SESSIONS). As part
of this, we must intercept and manually remove contexts for flushed
sessions.
Signed-off-by: James Bottomley <James.Bottomley-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk@public.gmane.org>
---
drivers/char/tpm/tpm-chip.c | 6 ++
drivers/char/tpm/tpm.h | 1 +
drivers/char/tpm/tpm2-space.c | 223 ++++++++++++++++++++++++++++--------------
drivers/char/tpm/tpms-dev.c | 7 ++
4 files changed, 164 insertions(+), 73 deletions(-)
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 96ea93e..a625884 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -130,6 +130,7 @@ static void tpm_dev_release(struct device *dev)
kfree(chip->log.bios_event_log);
kfree(chip->work_space.context_buf);
+ kfree(chip->work_space.session_buf);
kfree(chip);
}
@@ -223,6 +224,11 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
rc = -ENOMEM;
goto out;
}
+ chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!chip->work_space.session_buf) {
+ rc = -ENOMEM;
+ goto out;
+ }
return chip;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 265b7f5..9923daa 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -159,6 +159,7 @@ struct tpm_space {
u32 context_tbl[14];
u8 *context_buf;
u32 session_tbl[6];
+ u8 *session_buf;
};
enum tpm_chip_flags {
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 49048af..04c9431 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -27,6 +27,91 @@ enum tpm2_handle_types {
#define TPM2_HT_TAG_FOR_FLUSH 0xF0000000
+struct tpm2_context {
+ __be64 sequence;
+ __be32 saved_handle;
+ __be32 hierarchy;
+ __be16 blob_size;
+} __packed;
+
+static int tpm2_context_save(struct tpm_chip *chip, u8 *area,
+ int *offset, u32 handle)
+{
+ struct tpm_buf buf;
+ u32 s;
+ int rc;
+
+ rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS,
+ TPM2_CC_CONTEXT_SAVE);
+ if (rc)
+ return rc;
+
+ tpm_buf_append_u32(&buf, handle);
+
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+ TPM_HEADER_SIZE, TPM_TRANSMIT_UNLOCKED,
+ NULL);
+ if ((rc & TPM2_RC_HANDLE) == TPM2_RC_HANDLE) {
+ /* no handle to save */
+ rc = 1;
+ goto out;
+ } else if (rc) {
+ dev_warn(&chip->dev, "%s: saving failed with %d\n",
+ __func__, rc);
+ rc = -EFAULT;
+ goto out;
+ }
+
+ s = tpm_buf_length(&buf) - TPM_HEADER_SIZE;
+ if ((*offset + s) > PAGE_SIZE) {
+ dev_warn(&chip->dev, "out of context storage\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(&area[*offset], &buf.data[TPM_HEADER_SIZE], s);
+ *offset += s;
+
+ out:
+ tpm_buf_destroy(&buf);
+ return rc;
+}
+
+static int tpm2_context_load(struct tpm_chip *chip, u8 *area,
+ int *offset, u32 *handle)
+{
+ struct tpm_buf buf;
+ struct tpm2_context *ctx;
+ int rc;
+ u32 s;
+
+ rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS,
+ TPM2_CC_CONTEXT_LOAD);
+ if (rc)
+ return rc;
+
+ ctx = (struct tpm2_context *)&area[*offset];
+ s = sizeof(*ctx) + be16_to_cpu(ctx->blob_size);
+ tpm_buf_append(&buf, (const void *)ctx, s);
+
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+ TPM_HEADER_SIZE + 4,
+ TPM_TRANSMIT_UNLOCKED, NULL);
+ if (rc) {
+ dev_warn(&chip->dev, "context loading failed with %d\n", rc);
+ rc = -EFAULT;
+ goto out;
+ }
+ *handle = get_unaligned_be32((__be32 *)&buf.data[TPM_HEADER_SIZE]);
+
+ *offset += s;
+
+ out:
+ tpm_buf_destroy(&buf);
+
+ return rc;
+}
+
static int tpm2_session_find(struct tpm_space *space, u32 handle)
{
int i;
@@ -58,11 +143,35 @@ static int tpm2_session_add(struct tpm_chip *chip,
return 0;
}
+static int tpm2_session_forget(struct tpm_space *space, u32 handle)
+{
+ int i, j;
+ struct tpm2_context *ctx;
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+ if (space->session_tbl[i] == 0)
+ continue;
+
+ ctx = (struct tpm2_context *)&space->session_buf[j];
+ j += sizeof(*ctx) + get_unaligned_be16(&ctx->blob_size);
+
+ if (space->session_tbl[i] != handle)
+ continue;
+
+ /* forget the session context */
+ memcpy(ctx, &space->session_buf[j], PAGE_SIZE - j);
+ space->session_tbl[i] = 0;
+ break;
+ }
+ if (i == ARRAY_SIZE(space->session_tbl))
+ return -EINVAL;
+ return 0;
+}
+
/* if a space is active, emulate some commands */
-static int tpm2_intercept(struct tpm_chip *chip, struct tpm_space *space,
- u32 cc, u8 *buf, size_t bufsiz)
+static int tpm2_intercept(struct tpm_chip *chip, u32 cc, u8 *buf, size_t bufsiz)
{
- int j;
+ struct tpm_space *space = &chip->work_space;
u32 handle, handle_type;
if (!space)
@@ -78,13 +187,7 @@ static int tpm2_intercept(struct tpm_chip *chip, struct tpm_space *space,
/* let the TPM figure out and return the error */
return 0;
- j = tpm2_session_find(space, handle);
- if (j < 0)
- return -EINVAL;
-
- space->session_tbl[j] |= TPM2_HT_TAG_FOR_FLUSH;
-
- return 0;
+ return tpm2_session_forget(space, handle);
}
void tpm2_flush_space(struct tpm_chip *chip, struct tpm_space *space)
@@ -104,22 +207,12 @@ void tpm2_flush_space(struct tpm_chip *chip, struct tpm_space *space)
}
}
-struct tpm2_context {
- __be64 sequence;
- __be32 saved_handle;
- __be32 hierarchy;
- __be16 blob_size;
-} __packed;
-
static int tpm2_load_space(struct tpm_chip *chip)
{
struct tpm_space *space = &chip->work_space;
- struct tpm2_context *ctx;
- struct tpm_buf buf;
int i;
int j;
int rc;
- u32 s;
for (i = 0, j = 0; i < ARRAY_SIZE(space->context_tbl); i++) {
if (!space->context_tbl[i])
@@ -131,37 +224,33 @@ static int tpm2_load_space(struct tpm_chip *chip)
return -EFAULT;
}
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS,
- TPM2_CC_CONTEXT_LOAD);
+ rc = tpm2_context_load(chip, space->context_buf,
+ &j, &space->context_tbl[i]);
if (rc)
- return rc;
-
- ctx = (struct tpm2_context *)&space->context_buf[j];
- s = sizeof(*ctx) + be16_to_cpu(ctx->blob_size);
- tpm_buf_append(&buf, &space->context_buf[j], s);
-
- rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
- TPM_HEADER_SIZE + 4,
- TPM_TRANSMIT_UNLOCKED, NULL);
- if (rc) {
- dev_warn(&chip->dev, "%s: loading failed with %d\n",
- __func__, rc);
- rc = -EFAULT;
goto out_err;
- }
- space->context_tbl[i] =
- be32_to_cpup((__be32 *)&buf.data[TPM_HEADER_SIZE]);
+ }
- j += s;
+ for (i = 0, j = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+ u32 handle;
- tpm_buf_destroy(&buf);
+ if (!space->session_tbl[i])
+ continue;
+
+ rc = tpm2_context_load(chip, space->session_buf,
+ &j, &handle);
+ if (rc)
+ goto out_err;
+ if (handle != (space->session_tbl[i] & ~TPM2_HT_TAG_FOR_FLUSH)) {
+ dev_warn(&chip->dev, "session restored to wrong handle\n");
+ rc = -EFAULT;
+ goto out_err;
+ }
}
return 0;
out_err:
- tpm_buf_destroy(&buf);
tpm2_flush_space(chip, space);
return rc;
}
@@ -297,8 +386,9 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space,
memcpy(&chip->work_space.session_tbl, &space->session_tbl,
sizeof(space->session_tbl));
memcpy(chip->work_space.context_buf, space->context_buf, PAGE_SIZE);
+ memcpy(chip->work_space.session_buf, space->session_buf, PAGE_SIZE);
- rc = tpm2_intercept(chip, space, cc, buf, bufsiz);
+ rc = tpm2_intercept(chip, cc, buf, bufsiz);
if (rc)
return rc;
@@ -384,59 +474,45 @@ static int tpm2_map_response(struct tpm_chip *chip, u32 cc, u8 *rsp, size_t len)
static int tpm2_save_space(struct tpm_chip *chip)
{
struct tpm_space *space = &chip->work_space;
- struct tpm_buf buf;
int i;
int j;
int rc;
- u32 s;
for (i = 0, j = 0; i < ARRAY_SIZE(space->context_tbl); i++) {
if (!(space->context_tbl[i] && ~space->context_tbl[i]))
continue;
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS,
- TPM2_CC_CONTEXT_SAVE);
- if (rc)
- return rc;
-
- tpm_buf_append_u32(&buf, space->context_tbl[i]);
-
- rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
- TPM_HEADER_SIZE, TPM_TRANSMIT_UNLOCKED,
- NULL);
- if ((rc & TPM2_RC_HANDLE) == TPM2_RC_HANDLE) {
+ rc = tpm2_context_save(chip, space->context_buf, &j,
+ space->context_tbl[i]);
+ if (rc < 0)
+ goto out_err;
+ if (rc > 0) {
space->context_tbl[i] = 0;
continue;
- } else if (rc) {
- dev_warn(&chip->dev, "%s: saving failed with %d\n",
- __func__, rc);
- rc = -EFAULT;
- goto out_err;
}
- s = tpm_buf_length(&buf) - TPM_HEADER_SIZE;
- if ((j + s) > PAGE_SIZE) {
- dev_warn(&chip->dev, "%s: out of backing storage\n",
- __func__);
- rc = -ENOMEM;
- goto out_err;
- }
-
- memcpy(&space->context_buf[j], &buf.data[TPM_HEADER_SIZE], s);
-
tpm2_flush_context_cmd(chip, space->context_tbl[i],
TPM_TRANSMIT_UNLOCKED);
space->context_tbl[i] = ~0;
+ }
- j += s;
+ for (i = 0, j = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+ if (!space->session_tbl[i])
+ continue;
- tpm_buf_destroy(&buf);
+ rc = tpm2_context_save(chip, space->session_buf, &j,
+ space->session_tbl[i]);
+ if (rc < 0)
+ goto out_err;
+ if (rc > 0) {
+ space->context_tbl[i] = 0;
+ continue;
+ }
}
return 0;
out_err:
- tpm_buf_destroy(&buf);
tpm2_flush_space(chip, space);
return rc;
}
@@ -462,6 +538,7 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
memcpy(&space->session_tbl, &chip->work_space.session_tbl,
sizeof(space->session_tbl));
memcpy(space->context_buf, chip->work_space.context_buf, PAGE_SIZE);
+ memcpy(space->session_buf, chip->work_space.session_buf, PAGE_SIZE);
return 0;
}
diff --git a/drivers/char/tpm/tpms-dev.c b/drivers/char/tpm/tpms-dev.c
index d6e3491..12b6e34 100644
--- a/drivers/char/tpm/tpms-dev.c
+++ b/drivers/char/tpm/tpms-dev.c
@@ -25,6 +25,12 @@ static int tpms_open(struct inode *inode, struct file *file)
kfree(priv);
return -ENOMEM;
}
+ priv->space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (priv->space.session_buf == NULL) {
+ kfree(priv->space.context_buf);
+ kfree(priv);
+ return -ENOMEM;
+ }
tpm_common_open(file, chip, &priv->priv);
@@ -39,6 +45,7 @@ static int tpms_release(struct inode *inode, struct file *file)
tpm2_flush_space(fpriv->chip, &priv->space);
tpm_common_release(file, fpriv);
kfree(priv->space.context_buf);
+ kfree(priv->space.session_buf);
kfree(priv);
return 0;
--
2.6.6
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
WARNING: multiple messages have this Message-ID (diff)
From: James Bottomley <James.Bottomley@HansenPartnership.com>
To: tpmdd-devel@lists.sourceforge.net
Cc: open list <linux-kernel@vger.kernel.org>,
linux-security-module@vger.kernel.org
Subject: [PATCH 2/2] tpm2: context save and restore space managed sessions
Date: Wed, 18 Jan 2017 10:10:42 -0500 [thread overview]
Message-ID: <1484752242.2717.17.camel@HansenPartnership.com> (raw)
In-Reply-To: <1484752097.2717.14.camel@HansenPartnership.com>
Now that sessions are isolated, we can introduce a session_buf in the
tpm2 space to save and restore them. This allows us to have many more
sessions active simultaneously (up to TPM_PT_MAX_SESSIONS). As part
of this, we must intercept and manually remove contexts for flushed
sessions.
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
drivers/char/tpm/tpm-chip.c | 6 ++
drivers/char/tpm/tpm.h | 1 +
drivers/char/tpm/tpm2-space.c | 223 ++++++++++++++++++++++++++++--------------
drivers/char/tpm/tpms-dev.c | 7 ++
4 files changed, 164 insertions(+), 73 deletions(-)
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 96ea93e..a625884 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -130,6 +130,7 @@ static void tpm_dev_release(struct device *dev)
kfree(chip->log.bios_event_log);
kfree(chip->work_space.context_buf);
+ kfree(chip->work_space.session_buf);
kfree(chip);
}
@@ -223,6 +224,11 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
rc = -ENOMEM;
goto out;
}
+ chip->work_space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!chip->work_space.session_buf) {
+ rc = -ENOMEM;
+ goto out;
+ }
return chip;
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 265b7f5..9923daa 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -159,6 +159,7 @@ struct tpm_space {
u32 context_tbl[14];
u8 *context_buf;
u32 session_tbl[6];
+ u8 *session_buf;
};
enum tpm_chip_flags {
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 49048af..04c9431 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -27,6 +27,91 @@ enum tpm2_handle_types {
#define TPM2_HT_TAG_FOR_FLUSH 0xF0000000
+struct tpm2_context {
+ __be64 sequence;
+ __be32 saved_handle;
+ __be32 hierarchy;
+ __be16 blob_size;
+} __packed;
+
+static int tpm2_context_save(struct tpm_chip *chip, u8 *area,
+ int *offset, u32 handle)
+{
+ struct tpm_buf buf;
+ u32 s;
+ int rc;
+
+ rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS,
+ TPM2_CC_CONTEXT_SAVE);
+ if (rc)
+ return rc;
+
+ tpm_buf_append_u32(&buf, handle);
+
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+ TPM_HEADER_SIZE, TPM_TRANSMIT_UNLOCKED,
+ NULL);
+ if ((rc & TPM2_RC_HANDLE) == TPM2_RC_HANDLE) {
+ /* no handle to save */
+ rc = 1;
+ goto out;
+ } else if (rc) {
+ dev_warn(&chip->dev, "%s: saving failed with %d\n",
+ __func__, rc);
+ rc = -EFAULT;
+ goto out;
+ }
+
+ s = tpm_buf_length(&buf) - TPM_HEADER_SIZE;
+ if ((*offset + s) > PAGE_SIZE) {
+ dev_warn(&chip->dev, "out of context storage\n");
+ rc = -ENOMEM;
+ goto out;
+ }
+
+ memcpy(&area[*offset], &buf.data[TPM_HEADER_SIZE], s);
+ *offset += s;
+
+ out:
+ tpm_buf_destroy(&buf);
+ return rc;
+}
+
+static int tpm2_context_load(struct tpm_chip *chip, u8 *area,
+ int *offset, u32 *handle)
+{
+ struct tpm_buf buf;
+ struct tpm2_context *ctx;
+ int rc;
+ u32 s;
+
+ rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS,
+ TPM2_CC_CONTEXT_LOAD);
+ if (rc)
+ return rc;
+
+ ctx = (struct tpm2_context *)&area[*offset];
+ s = sizeof(*ctx) + be16_to_cpu(ctx->blob_size);
+ tpm_buf_append(&buf, (const void *)ctx, s);
+
+ rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
+ TPM_HEADER_SIZE + 4,
+ TPM_TRANSMIT_UNLOCKED, NULL);
+ if (rc) {
+ dev_warn(&chip->dev, "context loading failed with %d\n", rc);
+ rc = -EFAULT;
+ goto out;
+ }
+ *handle = get_unaligned_be32((__be32 *)&buf.data[TPM_HEADER_SIZE]);
+
+ *offset += s;
+
+ out:
+ tpm_buf_destroy(&buf);
+
+ return rc;
+}
+
static int tpm2_session_find(struct tpm_space *space, u32 handle)
{
int i;
@@ -58,11 +143,35 @@ static int tpm2_session_add(struct tpm_chip *chip,
return 0;
}
+static int tpm2_session_forget(struct tpm_space *space, u32 handle)
+{
+ int i, j;
+ struct tpm2_context *ctx;
+
+ for (i = 0, j = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+ if (space->session_tbl[i] == 0)
+ continue;
+
+ ctx = (struct tpm2_context *)&space->session_buf[j];
+ j += sizeof(*ctx) + get_unaligned_be16(&ctx->blob_size);
+
+ if (space->session_tbl[i] != handle)
+ continue;
+
+ /* forget the session context */
+ memcpy(ctx, &space->session_buf[j], PAGE_SIZE - j);
+ space->session_tbl[i] = 0;
+ break;
+ }
+ if (i == ARRAY_SIZE(space->session_tbl))
+ return -EINVAL;
+ return 0;
+}
+
/* if a space is active, emulate some commands */
-static int tpm2_intercept(struct tpm_chip *chip, struct tpm_space *space,
- u32 cc, u8 *buf, size_t bufsiz)
+static int tpm2_intercept(struct tpm_chip *chip, u32 cc, u8 *buf, size_t bufsiz)
{
- int j;
+ struct tpm_space *space = &chip->work_space;
u32 handle, handle_type;
if (!space)
@@ -78,13 +187,7 @@ static int tpm2_intercept(struct tpm_chip *chip, struct tpm_space *space,
/* let the TPM figure out and return the error */
return 0;
- j = tpm2_session_find(space, handle);
- if (j < 0)
- return -EINVAL;
-
- space->session_tbl[j] |= TPM2_HT_TAG_FOR_FLUSH;
-
- return 0;
+ return tpm2_session_forget(space, handle);
}
void tpm2_flush_space(struct tpm_chip *chip, struct tpm_space *space)
@@ -104,22 +207,12 @@ void tpm2_flush_space(struct tpm_chip *chip, struct tpm_space *space)
}
}
-struct tpm2_context {
- __be64 sequence;
- __be32 saved_handle;
- __be32 hierarchy;
- __be16 blob_size;
-} __packed;
-
static int tpm2_load_space(struct tpm_chip *chip)
{
struct tpm_space *space = &chip->work_space;
- struct tpm2_context *ctx;
- struct tpm_buf buf;
int i;
int j;
int rc;
- u32 s;
for (i = 0, j = 0; i < ARRAY_SIZE(space->context_tbl); i++) {
if (!space->context_tbl[i])
@@ -131,37 +224,33 @@ static int tpm2_load_space(struct tpm_chip *chip)
return -EFAULT;
}
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS,
- TPM2_CC_CONTEXT_LOAD);
+ rc = tpm2_context_load(chip, space->context_buf,
+ &j, &space->context_tbl[i]);
if (rc)
- return rc;
-
- ctx = (struct tpm2_context *)&space->context_buf[j];
- s = sizeof(*ctx) + be16_to_cpu(ctx->blob_size);
- tpm_buf_append(&buf, &space->context_buf[j], s);
-
- rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
- TPM_HEADER_SIZE + 4,
- TPM_TRANSMIT_UNLOCKED, NULL);
- if (rc) {
- dev_warn(&chip->dev, "%s: loading failed with %d\n",
- __func__, rc);
- rc = -EFAULT;
goto out_err;
- }
- space->context_tbl[i] =
- be32_to_cpup((__be32 *)&buf.data[TPM_HEADER_SIZE]);
+ }
- j += s;
+ for (i = 0, j = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+ u32 handle;
- tpm_buf_destroy(&buf);
+ if (!space->session_tbl[i])
+ continue;
+
+ rc = tpm2_context_load(chip, space->session_buf,
+ &j, &handle);
+ if (rc)
+ goto out_err;
+ if (handle != (space->session_tbl[i] & ~TPM2_HT_TAG_FOR_FLUSH)) {
+ dev_warn(&chip->dev, "session restored to wrong handle\n");
+ rc = -EFAULT;
+ goto out_err;
+ }
}
return 0;
out_err:
- tpm_buf_destroy(&buf);
tpm2_flush_space(chip, space);
return rc;
}
@@ -297,8 +386,9 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space,
memcpy(&chip->work_space.session_tbl, &space->session_tbl,
sizeof(space->session_tbl));
memcpy(chip->work_space.context_buf, space->context_buf, PAGE_SIZE);
+ memcpy(chip->work_space.session_buf, space->session_buf, PAGE_SIZE);
- rc = tpm2_intercept(chip, space, cc, buf, bufsiz);
+ rc = tpm2_intercept(chip, cc, buf, bufsiz);
if (rc)
return rc;
@@ -384,59 +474,45 @@ static int tpm2_map_response(struct tpm_chip *chip, u32 cc, u8 *rsp, size_t len)
static int tpm2_save_space(struct tpm_chip *chip)
{
struct tpm_space *space = &chip->work_space;
- struct tpm_buf buf;
int i;
int j;
int rc;
- u32 s;
for (i = 0, j = 0; i < ARRAY_SIZE(space->context_tbl); i++) {
if (!(space->context_tbl[i] && ~space->context_tbl[i]))
continue;
- rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS,
- TPM2_CC_CONTEXT_SAVE);
- if (rc)
- return rc;
-
- tpm_buf_append_u32(&buf, space->context_tbl[i]);
-
- rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE,
- TPM_HEADER_SIZE, TPM_TRANSMIT_UNLOCKED,
- NULL);
- if ((rc & TPM2_RC_HANDLE) == TPM2_RC_HANDLE) {
+ rc = tpm2_context_save(chip, space->context_buf, &j,
+ space->context_tbl[i]);
+ if (rc < 0)
+ goto out_err;
+ if (rc > 0) {
space->context_tbl[i] = 0;
continue;
- } else if (rc) {
- dev_warn(&chip->dev, "%s: saving failed with %d\n",
- __func__, rc);
- rc = -EFAULT;
- goto out_err;
}
- s = tpm_buf_length(&buf) - TPM_HEADER_SIZE;
- if ((j + s) > PAGE_SIZE) {
- dev_warn(&chip->dev, "%s: out of backing storage\n",
- __func__);
- rc = -ENOMEM;
- goto out_err;
- }
-
- memcpy(&space->context_buf[j], &buf.data[TPM_HEADER_SIZE], s);
-
tpm2_flush_context_cmd(chip, space->context_tbl[i],
TPM_TRANSMIT_UNLOCKED);
space->context_tbl[i] = ~0;
+ }
- j += s;
+ for (i = 0, j = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+ if (!space->session_tbl[i])
+ continue;
- tpm_buf_destroy(&buf);
+ rc = tpm2_context_save(chip, space->session_buf, &j,
+ space->session_tbl[i]);
+ if (rc < 0)
+ goto out_err;
+ if (rc > 0) {
+ space->context_tbl[i] = 0;
+ continue;
+ }
}
return 0;
out_err:
- tpm_buf_destroy(&buf);
tpm2_flush_space(chip, space);
return rc;
}
@@ -462,6 +538,7 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
memcpy(&space->session_tbl, &chip->work_space.session_tbl,
sizeof(space->session_tbl));
memcpy(space->context_buf, chip->work_space.context_buf, PAGE_SIZE);
+ memcpy(space->session_buf, chip->work_space.session_buf, PAGE_SIZE);
return 0;
}
diff --git a/drivers/char/tpm/tpms-dev.c b/drivers/char/tpm/tpms-dev.c
index d6e3491..12b6e34 100644
--- a/drivers/char/tpm/tpms-dev.c
+++ b/drivers/char/tpm/tpms-dev.c
@@ -25,6 +25,12 @@ static int tpms_open(struct inode *inode, struct file *file)
kfree(priv);
return -ENOMEM;
}
+ priv->space.session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (priv->space.session_buf == NULL) {
+ kfree(priv->space.context_buf);
+ kfree(priv);
+ return -ENOMEM;
+ }
tpm_common_open(file, chip, &priv->priv);
@@ -39,6 +45,7 @@ static int tpms_release(struct inode *inode, struct file *file)
tpm2_flush_space(fpriv->chip, &priv->space);
tpm_common_release(file, fpriv);
kfree(priv->space.context_buf);
+ kfree(priv->space.session_buf);
kfree(priv);
return 0;
--
2.6.6
next prev parent reply other threads:[~2017-01-18 15:10 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-18 15:08 [PATCH 0/2] Add session isolation and context saving to the space manager James Bottomley
2017-01-18 15:08 ` James Bottomley
[not found] ` <1484752097.2717.14.camel-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk@public.gmane.org>
2017-01-18 15:09 ` [PATCH 1/2] tpm2: add session handle isolation to tpm spaces James Bottomley
2017-01-18 15:09 ` James Bottomley
2017-01-19 11:58 ` [tpmdd-devel] " Jarkko Sakkinen
[not found] ` <20170119115812.vqaoxv77mgnuq43h-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-01-19 12:11 ` James Bottomley
2017-01-19 12:11 ` [tpmdd-devel] " James Bottomley
[not found] ` <1484827883.3140.7.camel-d9PhHud1JfjCXq6kfMZ53/egYHeGw8Jk@public.gmane.org>
2017-01-20 13:23 ` Jarkko Sakkinen
2017-01-20 13:23 ` [tpmdd-devel] " Jarkko Sakkinen
[not found] ` <20170120132331.74dixmuj6htzgr4z-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
2017-01-20 14:27 ` Ken Goldman
2017-01-20 20:51 ` Jarkko Sakkinen
2017-01-20 20:51 ` [tpmdd-devel] " Jarkko Sakkinen
2017-01-20 14:39 ` James Bottomley
2017-01-20 14:39 ` [tpmdd-devel] " James Bottomley
2017-01-20 17:57 ` Jarkko Sakkinen
2017-01-18 15:10 ` James Bottomley [this message]
2017-01-18 15:10 ` [PATCH 2/2] tpm2: context save and restore space managed sessions James Bottomley
2017-01-19 12:04 ` [tpmdd-devel] " Jarkko Sakkinen
2017-01-19 12:13 ` James Bottomley
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1484752242.2717.17.camel@HansenPartnership.com \
--to=james.bottomley-d9phhud1jfjcxq6kfmz53/egyhegw8jk@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-security-module-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.