Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1561884 > unrolled thread
| Started by | James Bottomley <James.Bottomley@HansenPartnership.com> |
|---|---|
| First post | 2017-01-18 16:20 +0100 |
| Last post | 2017-01-19 13:20 +0100 |
| Articles | 3 — 2 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 2/2] tpm2: context save and restore space managed sessions James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-01-18 16:20 +0100
Re: [tpmdd-devel] [PATCH 2/2] tpm2: context save and restore space managed sessions Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-01-19 13:10 +0100
Re: [tpmdd-devel] [PATCH 2/2] tpm2: context save and restore space managed sessions James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-01-19 13:20 +0100
| From | James Bottomley <James.Bottomley@HansenPartnership.com> |
|---|---|
| Date | 2017-01-18 16:20 +0100 |
| Subject | [PATCH 2/2] tpm2: context save and restore space managed sessions |
| Message-ID | <t10bL-5IB-5@gated-at.bofh.it> |
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
[toc] | [next] | [standalone]
| From | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> |
|---|---|
| Date | 2017-01-19 13:10 +0100 |
| Subject | Re: [tpmdd-devel] [PATCH 2/2] tpm2: context save and restore space managed sessions |
| Message-ID | <t1jHs-1mS-35@gated-at.bofh.it> |
| In reply to | #1561884 |
On Wed, Jan 18, 2017 at 10:10:42AM -0500, James Bottomley wrote:
> 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.
Again I don't understand the interception part. Like with transient
objects I just catch TPM_RC_HANDLE error and forget them in the save
part.
PS. Do you mind if I take part of the patch that encapsulates a
single context save as of my patch that implements transient object
swapping? It merely moves the code in there to a different location.
Would just make the patch set cleaner. I would do this for v4 of the
patch set.
/Jarkko
>
> 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
>
>
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> _______________________________________________
> tpmdd-devel mailing list
> tpmdd-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/tpmdd-devel
[toc] | [prev] | [next] | [standalone]
| From | James Bottomley <James.Bottomley@HansenPartnership.com> |
|---|---|
| Date | 2017-01-19 13:20 +0100 |
| Subject | Re: [tpmdd-devel] [PATCH 2/2] tpm2: context save and restore space managed sessions |
| Message-ID | <t1jR8-1qs-25@gated-at.bofh.it> |
| In reply to | #1562659 |
On Thu, 2017-01-19 at 14:04 +0200, Jarkko Sakkinen wrote: > On Wed, Jan 18, 2017 at 10:10:42AM -0500, James Bottomley wrote: > > 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. > > Again I don't understand the interception part. Like with transient > objects I just catch TPM_RC_HANDLE error and forget them in the save > part. it's for the global session tracking patch (see other email for details) > PS. Do you mind if I take part of the patch that encapsulates a > single context save as of my patch that implements transient object > swapping? It merely moves the code in there to a different location. > Would just make the patch set cleaner. I would do this for v4 of the > patch set. Sure. Rebase should be able to do this easily for me. James
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web