Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1582883 > unrolled thread

[PATCH v2 0/7] in-kernel resource manager

Started byJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
First post2017-02-16 20:30 +0100
Last post2017-02-24 18:10 +0100
Articles 20 on this page of 33 — 6 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 0/7] in-kernel resource manager Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-16 20:30 +0100
    [PATCH v2 1/7] tpm: move length validation to tpm_transmit() Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-16 20:30 +0100
    [PATCH v2 7/7] tpm2: add session handle context saving and restoring to the space code Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-16 20:30 +0100
      Re: [PATCH v2 7/7] tpm2: add session handle context saving and  restoring to the space code Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-23 10:10 +0100
    [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-16 20:30 +0100
      Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-23 10:10 +0100
        Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-24 14:10 +0100
          Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-24 18:40 +0100
            Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-24 19:20 +0100
              Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-24 21:30 +0100
                Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-24 22:00 +0100
                  Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device  link /dev/tpms<n> James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-25 00:10 +0100
                    Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device  link /dev/tpms<n> Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-25 00:30 +0100
                      Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device  link /dev/tpms<n> James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-25 00:50 +0100
                        Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device  link /dev/tpms<n> Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-25 01:30 +0100
                          Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device  link /dev/tpms<n> James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-25 18:10 +0100
                            Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device  link /dev/tpms<n> Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-27 18:40 +0100
          Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-26 12:50 +0100
            Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> "Dr. Greg Wettstein" <greg@enjellic.com> - 2017-02-26 19:40 +0100
              Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> Ken Goldman <kgold@linux.vnet.ibm.com> - 2017-02-28 20:00 +0100
            Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n> Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-27 18:40 +0100
      Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link  /dev/tpms<n> Nayna <nayna@linux.vnet.ibm.com> - 2017-02-24 08:10 +0100
        Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device  link /dev/tpms<n> James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-24 14:00 +0100
          Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link  /dev/tpms<n> Nayna <nayna@linux.vnet.ibm.com> - 2017-02-27 12:50 +0100
            Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device  link /dev/tpms<n> James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-27 16:10 +0100
    [PATCH v2 4/7] tpm: infrastructure for TPM spaces Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-16 20:30 +0100
      Re: [tpmdd-devel] [PATCH v2 4/7] tpm: infrastructure for TPM spaces Nayna <nayna@linux.vnet.ibm.com> - 2017-02-21 19:30 +0100
        Re: [tpmdd-devel] [PATCH v2 4/7] tpm: infrastructure for TPM spaces James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-22 18:40 +0100
          Re: [tpmdd-devel] [PATCH v2 4/7] tpm: infrastructure for TPM spaces Ken Goldman <kgold@linux.vnet.ibm.com> - 2017-02-22 22:00 +0100
        Re: [tpmdd-devel] [PATCH v2 4/7] tpm: infrastructure for TPM spaces Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-22 22:20 +0100
        Re: [tpmdd-devel] [PATCH v2 4/7] tpm: infrastructure for TPM spaces Ken Goldman <kgold@linux.vnet.ibm.com> - 2017-02-22 22:30 +0100
      Re: [PATCH v2 4/7] tpm: infrastructure for TPM spaces James Bottomley <James.Bottomley@HansenPartnership.com> - 2017-02-24 14:00 +0100
        Re: [PATCH v2 4/7] tpm: infrastructure for TPM spaces Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> - 2017-02-24 18:10 +0100

Page 1 of 2  [1] 2  Next page →


#1582883 — [PATCH v2 0/7] in-kernel resource manager

FromJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date2017-02-16 20:30 +0100
Subject[PATCH v2 0/7] in-kernel resource manager
Message-ID<tbzUB-2oT-3@gated-at.bofh.it>
This patch set adds support for TPM spaces that provide an isolated
execution context for transient objects and HMAC and policy sessions. A
space is swapped into TPM volatile memory only when it is used and
swapped out after the use.

There's a test script for trying out TPM spaces in

  git://git.infradead.org/users/jjs/tpm2-scripts.git

A simple smoke test suite can be run by

  sudo python -m unittest -v tpm2_smoke.SpaceTest   

v2:
* Substitute virtual handle in ContextSave.
* Substitute virtual handles in GetCapability.
* Validate that the real response length and the one reported in the
  header match in tpm_transmit().

James Bottomley (3):
  tpm: split out tpm-dev.c into tpm-dev.c and tpm-common-dev.c
  tpm: expose spaces via a device link /dev/tpms<n>
  tpm2: add session handle context saving and restoring to the space
    code

Jarkko Sakkinen (4):
  tpm: move length validation to tpm_transmit()
  tpm: validate TPM 2.0 commands
  tpm: export tpm2_flush_context_cmd
  tpm: infrastructure for TPM spaces

 drivers/char/tpm/Makefile         |   3 +-
 drivers/char/tpm/tpm-chip.c       |  86 +++++-
 drivers/char/tpm/tpm-dev-common.c | 148 +++++++++++
 drivers/char/tpm/tpm-dev.c        | 143 +---------
 drivers/char/tpm/tpm-dev.h        |  27 ++
 drivers/char/tpm/tpm-interface.c  | 131 +++++++---
 drivers/char/tpm/tpm-sysfs.c      |   2 +-
 drivers/char/tpm/tpm.h            |  49 +++-
 drivers/char/tpm/tpm2-cmd.c       | 168 ++++++++----
 drivers/char/tpm/tpm2-space.c     | 532 ++++++++++++++++++++++++++++++++++++++
 drivers/char/tpm/tpms-dev.c       |  65 +++++
 11 files changed, 1135 insertions(+), 219 deletions(-)
 create mode 100644 drivers/char/tpm/tpm-dev-common.c
 create mode 100644 drivers/char/tpm/tpm-dev.h
 create mode 100644 drivers/char/tpm/tpm2-space.c
 create mode 100644 drivers/char/tpm/tpms-dev.c

-- 
2.9.3

[toc] | [next] | [standalone]


#1582884 — [PATCH v2 1/7] tpm: move length validation to tpm_transmit()

FromJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date2017-02-16 20:30 +0100
Subject[PATCH v2 1/7] tpm: move length validation to tpm_transmit()
Message-ID<tbzUC-2oT-15@gated-at.bofh.it>
In reply to#1582883
Check that the length matches the length reported by the response
header already in tpm_transmit() to improve validation.

Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
---
 drivers/char/tpm/tpm-interface.c | 20 ++++++++++++--------
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index bd2128e..708d356 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -343,6 +343,7 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
 ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
 		     unsigned int flags)
 {
+	const struct tpm_output_header *header = (void *)buf;
 	ssize_t rc;
 	u32 count, ordinal;
 	unsigned long stop;
@@ -406,9 +407,18 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
 
 out_recv:
 	rc = chip->ops->recv(chip, (u8 *) buf, bufsiz);
-	if (rc < 0)
+	if (rc < 0) {
 		dev_err(&chip->dev,
 			"tpm_transmit: tpm_recv: error %zd\n", rc);
+		goto out;
+	} else if (rc < TPM_HEADER_SIZE) {
+		rc = -EFAULT;
+		goto out;
+	}
+
+	if (rc != be32_to_cpu(header->length))
+		goto out;
+
 out:
 	if (chip->dev.parent)
 		pm_runtime_put_sync(chip->dev.parent);
@@ -438,19 +448,13 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *buf,
 			 size_t bufsiz, size_t min_rsp_body_length,
 			 unsigned int flags, const char *desc)
 {
-	const struct tpm_output_header *header;
+	const struct tpm_output_header *header = buf;
 	int err;
 	ssize_t len;
 
 	len = tpm_transmit(chip, (const u8 *)buf, bufsiz, flags);
 	if (len <  0)
 		return len;
-	else if (len < TPM_HEADER_SIZE)
-		return -EFAULT;
-
-	header = buf;
-	if (len != be32_to_cpu(header->length))
-		return -EFAULT;
 
 	err = be32_to_cpu(header->return_code);
 	if (err != 0 && desc)
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1582885 — [PATCH v2 7/7] tpm2: add session handle context saving and restoring to the space code

FromJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date2017-02-16 20:30 +0100
Subject[PATCH v2 7/7] tpm2: add session handle context saving and restoring to the space code
Message-ID<tbzUC-2oT-23@gated-at.bofh.it>
In reply to#1582883
From: James Bottomley <James.Bottomley@HansenPartnership.com>

Sessions are different from transient objects in that their handles
may not be virtualized (because they're used for some hmac
calculations).  Additionally when a session is context saved, a
vestigial memory remains in the TPM and if it is also flushed, that
will be lost and the session context will refuse to load next time, so
the code is updated to flush only transient objects after a context
save.  Add a separate array (chip->session_tbl) to save and restore
sessions by handle.  Use the failure of a context save or load to
signal that the session has been flushed from the TPM and we can
remove its memory from chip->session_tbl.

Sessions are also isolated during each instance of a tpm space.  This
means that spaces shouldn't be able to see each other's sessions and
is enforced by ensuring that a space user may only refer to sessions
handles that are present in their own chip->session_tbl.  Finally when
a space is closed, all the sessions belonging to it should be flushed
so the handles may be re-used by other spaces.

Note that if we get a session save or load error, all sessions are
effectively flushed.  Even though we restore the session buffer, all
the old sessions will refuse to load after the flush and they'll be
purged from our session memory.  This means that while transient
context handling is still soft in the face of errors, session handling
is hard (any failure of the model means all sessions are lost).

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
 drivers/char/tpm/tpm-chip.c   |   6 +++
 drivers/char/tpm/tpm.h        |   4 +-
 drivers/char/tpm/tpm2-space.c | 105 +++++++++++++++++++++++++++++++++++++++++-
 drivers/char/tpm/tpms-dev.c   |   2 +-
 4 files changed, 113 insertions(+), 4 deletions(-)

diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index c71c353..e8536ab 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);
 }
 
@@ -224,6 +225,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 822ca67..ffee8b5 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -161,6 +161,8 @@ enum tpm2_cc_attrs {
 struct tpm_space {
 	u32 context_tbl[3];
 	u8 *context_buf;
+	u32 session_tbl[3];
+	u8 *session_buf;
 };
 
 enum tpm_chip_flags {
@@ -589,7 +591,7 @@ int tpm2_probe(struct tpm_chip *chip);
 ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
 int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
 int tpm2_init_space(struct tpm_space *space);
-void tpm2_del_space(struct tpm_space *space);
+void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
 int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
 		       u8 *cmd);
 int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index e955548..d36d81e 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -32,18 +32,39 @@ struct tpm2_context {
 	__be16 blob_size;
 } __packed;
 
+static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+		if (space->session_tbl[i])
+			tpm2_flush_context_cmd(chip, space->session_tbl[i],
+					       TPM_TRANSMIT_UNLOCKED);
+	}
+}
+
 int tpm2_init_space(struct tpm_space *space)
 {
 	space->context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!space->context_buf)
 		return -ENOMEM;
 
+	space->session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (space->session_buf == NULL) {
+		kfree(space->context_buf);
+		return -ENOMEM;
+	}
+
 	return 0;
 }
 
-void tpm2_del_space(struct tpm_space *space)
+void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space)
 {
+	mutex_lock(&chip->tpm_mutex);
+	tpm2_flush_sessions(chip, space);
+	mutex_unlock(&chip->tpm_mutex);
 	kfree(space->context_buf);
+	kfree(space->session_buf);
 }
 
 static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
@@ -69,6 +90,20 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
 			 __func__, rc);
 		tpm_buf_destroy(&tbuf);
 		return -EFAULT;
+	} else if (tpm2_rc_value(rc) == TPM2_RC_HANDLE ||
+		   rc == TPM2_RC_REFERENCE_H0) {
+		/*
+		 * TPM_RC_HANDLE means that the session context can't
+		 * be loaded because of an internal counter mismatch
+		 * that makes the TPM think there might have been a
+		 * replay.  This might happen if the context was saved
+		 * and loaded outside the space.
+		 *
+		 * TPM_RC_REFERENCE_H0 means the session has been
+		 * flushed outside the space
+		 */
+		rc = -ENOENT;
+		tpm_buf_destroy(&tbuf);
 	} else if (rc > 0) {
 		dev_warn(&chip->dev, "%s: failed with a TPM error 0x%04X\n",
 			 __func__, rc);
@@ -121,7 +156,6 @@ static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
 	}
 
 	memcpy(&buf[*offset], &tbuf.data[TPM_HEADER_SIZE], body_size);
-	tpm2_flush_context_cmd(chip, handle, TPM_TRANSMIT_UNLOCKED);
 	*offset += body_size;
 	tpm_buf_destroy(&tbuf);
 	return 0;
@@ -136,6 +170,8 @@ static void tpm2_flush_space(struct tpm_chip *chip)
 		if (space->context_tbl[i] && ~space->context_tbl[i])
 			tpm2_flush_context_cmd(chip, space->context_tbl[i],
 					       TPM_TRANSMIT_UNLOCKED);
+
+	tpm2_flush_sessions(chip, space);
 }
 
 static int tpm2_load_space(struct tpm_chip *chip)
@@ -161,6 +197,28 @@ static int tpm2_load_space(struct tpm_chip *chip)
 			return rc;
 	}
 
+	for (i = 0, offset = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+		u32 handle;
+
+		if (!space->session_tbl[i])
+			continue;
+
+		rc = tpm2_load_context(chip, space->session_buf,
+				       &offset, &handle);
+		if (rc == -ENOENT) {
+			/* load failed, just forget session */
+			space->session_tbl[i] = 0;
+		} else if (rc) {
+			tpm2_flush_space(chip);
+			return rc;
+		}
+		if (handle != space->session_tbl[i]) {
+			dev_warn(&chip->dev, "session restored to wrong handle\n");
+			tpm2_flush_space(chip);
+			return -EFAULT;
+		}
+	}
+
 	return 0;
 }
 
@@ -215,7 +273,10 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
 
 	memcpy(&chip->work_space.context_tbl, &space->context_tbl,
 	       sizeof(space->context_tbl));
+	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_load_space(chip);
 	if (rc) {
@@ -232,6 +293,22 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
 	return 0;
 }
 
+static bool tpm2_add_session(struct tpm_chip *chip, u32 handle)
+{
+	struct tpm_space *space = &chip->work_space;
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++)
+		if (space->session_tbl[i] == 0)
+			break;
+
+	if (i == ARRAY_SIZE(space->session_tbl))
+		return false;
+
+	space->session_tbl[i] = handle;
+	return true;
+}
+
 static u32 tpm2_map_to_vhandle(struct tpm_space *space, u32 phandle, bool alloc)
 {
 	int i;
@@ -288,6 +365,8 @@ static int tpm2_map_response_header(struct tpm_chip *chip, u32 cc, u8 *rsp,
 		break;
 	case TPM2_HT_HMAC_SESSION:
 	case TPM2_HT_POLICY_SESSION:
+		if (!tpm2_add_session(chip, phandle))
+			goto out_no_slots;
 		break;
 	default:
 		dev_err(&chip->dev, "%s: unknown handle 0x%08X\n",
@@ -388,9 +467,28 @@ static int tpm2_save_space(struct tpm_chip *chip)
 		} else if (rc)
 			return rc;
 
+		tpm2_flush_context_cmd(chip, space->context_tbl[i],
+				       TPM_TRANSMIT_UNLOCKED);
 		space->context_tbl[i] = ~0;
 	}
 
+	for (i = 0, offset = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
+		if (!space->session_tbl[i])
+			continue;
+
+		rc = tpm2_save_context(chip, space->session_tbl[i],
+				       space->session_buf, PAGE_SIZE,
+				       &offset);
+
+		if (rc == -ENOENT) {
+			/* handle error saving session, just forget it */
+			space->session_tbl[i] = 0;
+		} else if (rc < 0) {
+			tpm2_flush_space(chip);
+			return rc;
+		}
+	}
+
 	return 0;
 }
 
@@ -425,7 +523,10 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
 
 	memcpy(&space->context_tbl, &chip->work_space.context_tbl,
 	       sizeof(space->context_tbl));
+	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 5720885..4c98db8 100644
--- a/drivers/char/tpm/tpms-dev.c
+++ b/drivers/char/tpm/tpms-dev.c
@@ -39,7 +39,7 @@ static int tpms_release(struct inode *inode, struct file *file)
 	struct tpms_priv *priv = container_of(fpriv, struct tpms_priv, priv);
 
 	tpm_common_release(file, fpriv);
-	tpm2_del_space(&priv->space);
+	tpm2_del_space(fpriv->chip, &priv->space);
 	kfree(priv);
 
 	return 0;
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1586756 — Re: [PATCH v2 7/7] tpm2: add session handle context saving and restoring to the space code

FromJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date2017-02-23 10:10 +0100
SubjectRe: [PATCH v2 7/7] tpm2: add session handle context saving and restoring to the space code
Message-ID<tdXzr-7EZ-5@gated-at.bofh.it>
In reply to#1582885
On Thu, Feb 16, 2017 at 09:25:20PM +0200, Jarkko Sakkinen wrote:
> From: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> Sessions are different from transient objects in that their handles
> may not be virtualized (because they're used for some hmac
> calculations).  Additionally when a session is context saved, a
> vestigial memory remains in the TPM and if it is also flushed, that
> will be lost and the session context will refuse to load next time, so
> the code is updated to flush only transient objects after a context
> save.  Add a separate array (chip->session_tbl) to save and restore
> sessions by handle.  Use the failure of a context save or load to
> signal that the session has been flushed from the TPM and we can
> remove its memory from chip->session_tbl.
> 
> Sessions are also isolated during each instance of a tpm space.  This
> means that spaces shouldn't be able to see each other's sessions and
> is enforced by ensuring that a space user may only refer to sessions
> handles that are present in their own chip->session_tbl.  Finally when
> a space is closed, all the sessions belonging to it should be flushed
> so the handles may be re-used by other spaces.
> 
> Note that if we get a session save or load error, all sessions are
> effectively flushed.  Even though we restore the session buffer, all
> the old sessions will refuse to load after the flush and they'll be
> purged from our session memory.  This means that while transient
> context handling is still soft in the face of errors, session handling
> is hard (any failure of the model means all sessions are lost).
> 
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

Reviewed-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>

I'll give Tested-by separately once I've updated tpm2_smoke.py

/Jarkko

> ---
>  drivers/char/tpm/tpm-chip.c   |   6 +++
>  drivers/char/tpm/tpm.h        |   4 +-
>  drivers/char/tpm/tpm2-space.c | 105 +++++++++++++++++++++++++++++++++++++++++-
>  drivers/char/tpm/tpms-dev.c   |   2 +-
>  4 files changed, 113 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index c71c353..e8536ab 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);
>  }
>  
> @@ -224,6 +225,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 822ca67..ffee8b5 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -161,6 +161,8 @@ enum tpm2_cc_attrs {
>  struct tpm_space {
>  	u32 context_tbl[3];
>  	u8 *context_buf;
> +	u32 session_tbl[3];
> +	u8 *session_buf;
>  };
>  
>  enum tpm_chip_flags {
> @@ -589,7 +591,7 @@ int tpm2_probe(struct tpm_chip *chip);
>  ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
>  int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
>  int tpm2_init_space(struct tpm_space *space);
> -void tpm2_del_space(struct tpm_space *space);
> +void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
>  int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
>  		       u8 *cmd);
>  int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
> diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
> index e955548..d36d81e 100644
> --- a/drivers/char/tpm/tpm2-space.c
> +++ b/drivers/char/tpm/tpm2-space.c
> @@ -32,18 +32,39 @@ struct tpm2_context {
>  	__be16 blob_size;
>  } __packed;
>  
> +static void tpm2_flush_sessions(struct tpm_chip *chip, struct tpm_space *space)
> +{
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
> +		if (space->session_tbl[i])
> +			tpm2_flush_context_cmd(chip, space->session_tbl[i],
> +					       TPM_TRANSMIT_UNLOCKED);
> +	}
> +}
> +
>  int tpm2_init_space(struct tpm_space *space)
>  {
>  	space->context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
>  	if (!space->context_buf)
>  		return -ENOMEM;
>  
> +	space->session_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
> +	if (space->session_buf == NULL) {
> +		kfree(space->context_buf);
> +		return -ENOMEM;
> +	}
> +
>  	return 0;
>  }
>  
> -void tpm2_del_space(struct tpm_space *space)
> +void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space)
>  {
> +	mutex_lock(&chip->tpm_mutex);
> +	tpm2_flush_sessions(chip, space);
> +	mutex_unlock(&chip->tpm_mutex);
>  	kfree(space->context_buf);
> +	kfree(space->session_buf);
>  }
>  
>  static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
> @@ -69,6 +90,20 @@ static int tpm2_load_context(struct tpm_chip *chip, u8 *buf,
>  			 __func__, rc);
>  		tpm_buf_destroy(&tbuf);
>  		return -EFAULT;
> +	} else if (tpm2_rc_value(rc) == TPM2_RC_HANDLE ||
> +		   rc == TPM2_RC_REFERENCE_H0) {
> +		/*
> +		 * TPM_RC_HANDLE means that the session context can't
> +		 * be loaded because of an internal counter mismatch
> +		 * that makes the TPM think there might have been a
> +		 * replay.  This might happen if the context was saved
> +		 * and loaded outside the space.
> +		 *
> +		 * TPM_RC_REFERENCE_H0 means the session has been
> +		 * flushed outside the space
> +		 */
> +		rc = -ENOENT;
> +		tpm_buf_destroy(&tbuf);
>  	} else if (rc > 0) {
>  		dev_warn(&chip->dev, "%s: failed with a TPM error 0x%04X\n",
>  			 __func__, rc);
> @@ -121,7 +156,6 @@ static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
>  	}
>  
>  	memcpy(&buf[*offset], &tbuf.data[TPM_HEADER_SIZE], body_size);
> -	tpm2_flush_context_cmd(chip, handle, TPM_TRANSMIT_UNLOCKED);
>  	*offset += body_size;
>  	tpm_buf_destroy(&tbuf);
>  	return 0;
> @@ -136,6 +170,8 @@ static void tpm2_flush_space(struct tpm_chip *chip)
>  		if (space->context_tbl[i] && ~space->context_tbl[i])
>  			tpm2_flush_context_cmd(chip, space->context_tbl[i],
>  					       TPM_TRANSMIT_UNLOCKED);
> +
> +	tpm2_flush_sessions(chip, space);
>  }
>  
>  static int tpm2_load_space(struct tpm_chip *chip)
> @@ -161,6 +197,28 @@ static int tpm2_load_space(struct tpm_chip *chip)
>  			return rc;
>  	}
>  
> +	for (i = 0, offset = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
> +		u32 handle;
> +
> +		if (!space->session_tbl[i])
> +			continue;
> +
> +		rc = tpm2_load_context(chip, space->session_buf,
> +				       &offset, &handle);
> +		if (rc == -ENOENT) {
> +			/* load failed, just forget session */
> +			space->session_tbl[i] = 0;
> +		} else if (rc) {
> +			tpm2_flush_space(chip);
> +			return rc;
> +		}
> +		if (handle != space->session_tbl[i]) {
> +			dev_warn(&chip->dev, "session restored to wrong handle\n");
> +			tpm2_flush_space(chip);
> +			return -EFAULT;
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> @@ -215,7 +273,10 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
>  
>  	memcpy(&chip->work_space.context_tbl, &space->context_tbl,
>  	       sizeof(space->context_tbl));
> +	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_load_space(chip);
>  	if (rc) {
> @@ -232,6 +293,22 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
>  	return 0;
>  }
>  
> +static bool tpm2_add_session(struct tpm_chip *chip, u32 handle)
> +{
> +	struct tpm_space *space = &chip->work_space;
> +	int i;
> +
> +	for (i = 0; i < ARRAY_SIZE(space->session_tbl); i++)
> +		if (space->session_tbl[i] == 0)
> +			break;
> +
> +	if (i == ARRAY_SIZE(space->session_tbl))
> +		return false;
> +
> +	space->session_tbl[i] = handle;
> +	return true;
> +}
> +
>  static u32 tpm2_map_to_vhandle(struct tpm_space *space, u32 phandle, bool alloc)
>  {
>  	int i;
> @@ -288,6 +365,8 @@ static int tpm2_map_response_header(struct tpm_chip *chip, u32 cc, u8 *rsp,
>  		break;
>  	case TPM2_HT_HMAC_SESSION:
>  	case TPM2_HT_POLICY_SESSION:
> +		if (!tpm2_add_session(chip, phandle))
> +			goto out_no_slots;
>  		break;
>  	default:
>  		dev_err(&chip->dev, "%s: unknown handle 0x%08X\n",
> @@ -388,9 +467,28 @@ static int tpm2_save_space(struct tpm_chip *chip)
>  		} else if (rc)
>  			return rc;
>  
> +		tpm2_flush_context_cmd(chip, space->context_tbl[i],
> +				       TPM_TRANSMIT_UNLOCKED);
>  		space->context_tbl[i] = ~0;
>  	}
>  
> +	for (i = 0, offset = 0; i < ARRAY_SIZE(space->session_tbl); i++) {
> +		if (!space->session_tbl[i])
> +			continue;
> +
> +		rc = tpm2_save_context(chip, space->session_tbl[i],
> +				       space->session_buf, PAGE_SIZE,
> +				       &offset);
> +
> +		if (rc == -ENOENT) {
> +			/* handle error saving session, just forget it */
> +			space->session_tbl[i] = 0;
> +		} else if (rc < 0) {
> +			tpm2_flush_space(chip);
> +			return rc;
> +		}
> +	}
> +
>  	return 0;
>  }
>  
> @@ -425,7 +523,10 @@ int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
>  
>  	memcpy(&space->context_tbl, &chip->work_space.context_tbl,
>  	       sizeof(space->context_tbl));
> +	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 5720885..4c98db8 100644
> --- a/drivers/char/tpm/tpms-dev.c
> +++ b/drivers/char/tpm/tpms-dev.c
> @@ -39,7 +39,7 @@ static int tpms_release(struct inode *inode, struct file *file)
>  	struct tpms_priv *priv = container_of(fpriv, struct tpms_priv, priv);
>  
>  	tpm_common_release(file, fpriv);
> -	tpm2_del_space(&priv->space);
> +	tpm2_del_space(fpriv->chip, &priv->space);
>  	kfree(priv);
>  
>  	return 0;
> -- 
> 2.9.3
> 

[toc] | [prev] | [next] | [standalone]


#1582887 — [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date2017-02-16 20:30 +0100
Subject[PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tbzUC-2oT-27@gated-at.bofh.it>
In reply to#1582883
From: James Bottomley <James.Bottomley@HansenPartnership.com>

Currently the tpm spaces are not exposed to userspace.  Make this
exposure via a separate device, which can now be opened multiple times
because each read/write transaction goes separately via the space.

Concurrency is protected by the chip->tpm_mutex for each read/write
transaction separately.  The TPM is cleared of all transient objects
by the time the mutex is dropped, so there should be no interference
between the kernel and userspace.

Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
 drivers/char/tpm/Makefile        |  3 +-
 drivers/char/tpm/tpm-chip.c      | 73 ++++++++++++++++++++++++++++++++++++++--
 drivers/char/tpm/tpm-interface.c | 13 +++++--
 drivers/char/tpm/tpm.h           |  4 +++
 drivers/char/tpm/tpms-dev.c      | 65 +++++++++++++++++++++++++++++++++++
 5 files changed, 152 insertions(+), 6 deletions(-)
 create mode 100644 drivers/char/tpm/tpms-dev.c

diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
index 10e5827..bbe6531 100644
--- a/drivers/char/tpm/Makefile
+++ b/drivers/char/tpm/Makefile
@@ -3,7 +3,8 @@
 #
 obj-$(CONFIG_TCG_TPM) += tpm.o
 tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
-	 tpm-dev-common.o tpm1_eventlog.o tpm2_eventlog.o tpm2-space.o
+	 tpm-dev-common.o tpms-dev.o tpm1_eventlog.o tpm2_eventlog.o \
+         tpm2-space.o
 tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o
 tpm-$(CONFIG_OF) += tpm_of.o
 obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 993b9ae..c71c353 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -33,6 +33,7 @@ DEFINE_IDR(dev_nums_idr);
 static DEFINE_MUTEX(idr_lock);
 
 struct class *tpm_class;
+struct class *tpms_class;
 dev_t tpm_devt;
 
 /**
@@ -132,6 +133,14 @@ static void tpm_dev_release(struct device *dev)
 	kfree(chip);
 }
 
+static void tpm_devs_release(struct device *dev)
+{
+	struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
+
+	/* release the master device reference */
+	put_device(&chip->dev);
+}
+
 /**
  * tpm_chip_alloc() - allocate a new struct tpm_chip instance
  * @pdev: device to which the chip is associated
@@ -168,27 +177,47 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
 	chip->dev_num = rc;
 
 	device_initialize(&chip->dev);
+	device_initialize(&chip->devs);
 
 	chip->dev.class = tpm_class;
 	chip->dev.release = tpm_dev_release;
 	chip->dev.parent = pdev;
 	chip->dev.groups = chip->groups;
 
+	chip->devs.parent = pdev;
+	chip->devs.class = tpms_class;
+	chip->devs.release = tpm_devs_release;
+	/* get extra reference on main device to hold on
+	 * behalf of devs.  This holds the chip structure
+	 * while cdevs is in use.  The corresponding put
+	 * is in the tpm_devs_release
+	 */
+	get_device(&chip->dev);
+
 	if (chip->dev_num == 0)
 		chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
 	else
 		chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
 
+	chip->devs.devt =
+		MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
+
 	rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
 	if (rc)
 		goto out;
+	rc = dev_set_name(&chip->devs, "tpms%d", chip->dev_num);
+	if (rc)
+		goto out;
 
 	if (!pdev)
 		chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
 
 	cdev_init(&chip->cdev, &tpm_fops);
+	cdev_init(&chip->cdevs, &tpms_fops);
 	chip->cdev.owner = THIS_MODULE;
+	chip->cdevs.owner = THIS_MODULE;
 	chip->cdev.kobj.parent = &chip->dev.kobj;
+	chip->cdevs.kobj.parent = &chip->devs.kobj;
 
 	chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!chip->work_space.context_buf) {
@@ -199,6 +228,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
 	return chip;
 
 out:
+	put_device(&chip->devs);
 	put_device(&chip->dev);
 	return ERR_PTR(rc);
 }
@@ -244,7 +274,7 @@ static int tpm_add_char_device(struct tpm_chip *chip)
 			dev_name(&chip->dev), MAJOR(chip->dev.devt),
 			MINOR(chip->dev.devt), rc);
 
-		return rc;
+		goto err_1;
 	}
 
 	rc = device_add(&chip->dev);
@@ -254,16 +284,44 @@ static int tpm_add_char_device(struct tpm_chip *chip)
 			dev_name(&chip->dev), MAJOR(chip->dev.devt),
 			MINOR(chip->dev.devt), rc);
 
-		cdev_del(&chip->cdev);
-		return rc;
+		goto err_2;
+	}
+
+	if (chip->flags & TPM_CHIP_FLAG_TPM2)
+		rc = cdev_add(&chip->cdevs, chip->devs.devt, 1);
+	if (rc) {
+		dev_err(&chip->dev,
+			"unable to cdev_add() %s, major %d, minor %d, err=%d\n",
+			dev_name(&chip->devs), MAJOR(chip->devs.devt),
+			MINOR(chip->devs.devt), rc);
+
+		goto err_3;
 	}
 
+	if (chip->flags & TPM_CHIP_FLAG_TPM2)
+		rc = device_add(&chip->devs);
+	if (rc) {
+		dev_err(&chip->dev,
+			"unable to device_register() %s, major %d, minor %d, err=%d\n",
+			dev_name(&chip->devs), MAJOR(chip->devs.devt),
+			MINOR(chip->devs.devt), rc);
+
+		goto err_4;
+	}
 	/* Make the chip available. */
 	mutex_lock(&idr_lock);
 	idr_replace(&dev_nums_idr, chip, chip->dev_num);
 	mutex_unlock(&idr_lock);
 
 	return rc;
+ err_4:
+	cdev_del(&chip->cdevs);
+ err_3:
+	device_del(&chip->dev);
+ err_2:
+	cdev_del(&chip->cdev);
+ err_1:
+	return rc;
 }
 
 static void tpm_del_char_device(struct tpm_chip *chip)
@@ -271,6 +329,11 @@ static void tpm_del_char_device(struct tpm_chip *chip)
 	cdev_del(&chip->cdev);
 	device_del(&chip->dev);
 
+	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+		cdev_del(&chip->cdevs);
+		device_del(&chip->devs);
+	}
+
 	/* Make the chip unavailable. */
 	mutex_lock(&idr_lock);
 	idr_replace(&dev_nums_idr, NULL, chip->dev_num);
@@ -282,6 +345,10 @@ static void tpm_del_char_device(struct tpm_chip *chip)
 		tpm2_shutdown(chip, TPM2_SU_CLEAR);
 	chip->ops = NULL;
 	up_write(&chip->ops_sem);
+	/* will release the devs reference to the chip->dev unless
+	 * something has cdevs open
+	 */
+	put_device(&chip->devs);
 }
 
 static void tpm_del_legacy_sysfs(struct tpm_chip *chip)
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index db5ffe9..deb2021 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -1257,9 +1257,17 @@ static int __init tpm_init(void)
 		return PTR_ERR(tpm_class);
 	}
 
-	rc = alloc_chrdev_region(&tpm_devt, 0, TPM_NUM_DEVICES, "tpm");
+	tpms_class = class_create(THIS_MODULE, "tpms");
+	if (IS_ERR(tpms_class)) {
+		pr_err("couldn't create tpms class\n");
+		class_destroy(tpm_class);
+		return PTR_ERR(tpms_class);
+	}
+
+	rc = alloc_chrdev_region(&tpm_devt, 0, 2*TPM_NUM_DEVICES, "tpm");
 	if (rc < 0) {
 		pr_err("tpm: failed to allocate char dev region\n");
+		class_destroy(tpms_class);
 		class_destroy(tpm_class);
 		return rc;
 	}
@@ -1271,7 +1279,8 @@ static void __exit tpm_exit(void)
 {
 	idr_destroy(&dev_nums_idr);
 	class_destroy(tpm_class);
-	unregister_chrdev_region(tpm_devt, TPM_NUM_DEVICES);
+	class_destroy(tpms_class);
+	unregister_chrdev_region(tpm_devt, 2*TPM_NUM_DEVICES);
 }
 
 subsys_initcall(tpm_init);
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 97e48a4..822ca67 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -182,7 +182,9 @@ struct tpm_chip_seqops {
 
 struct tpm_chip {
 	struct device dev;
+	struct device devs;
 	struct cdev cdev;
+	struct cdev cdevs;
 
 	/* A driver callback under ops cannot be run unless ops_sem is held
 	 * (sometimes implicitly, eg for the sysfs code). ops becomes null
@@ -510,8 +512,10 @@ static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
 }
 
 extern struct class *tpm_class;
+extern struct class *tpms_class;
 extern dev_t tpm_devt;
 extern const struct file_operations tpm_fops;
+extern const struct file_operations tpms_fops;
 extern struct idr dev_nums_idr;
 
 enum tpm_transmit_flags {
diff --git a/drivers/char/tpm/tpms-dev.c b/drivers/char/tpm/tpms-dev.c
new file mode 100644
index 0000000..5720885
--- /dev/null
+++ b/drivers/char/tpm/tpms-dev.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2017 James.Bottomley@HansenPartnership.com
+ *
+ * GPLv2
+ */
+#include <linux/slab.h>
+#include "tpm-dev.h"
+
+struct tpms_priv {
+	struct file_priv priv;
+	struct tpm_space space;
+};
+
+static int tpms_open(struct inode *inode, struct file *file)
+{
+	struct tpm_chip *chip;
+	struct tpms_priv *priv;
+	int rc;
+
+	chip = container_of(inode->i_cdev, struct tpm_chip, cdevs);
+	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+	if (priv == NULL)
+		return -ENOMEM;
+
+	rc = tpm2_init_space(&priv->space);
+	if (rc) {
+		kfree(priv);
+		return -ENOMEM;
+	}
+
+	tpm_common_open(file, chip, &priv->priv);
+
+	return 0;
+}
+
+static int tpms_release(struct inode *inode, struct file *file)
+{
+	struct file_priv *fpriv = file->private_data;
+	struct tpms_priv *priv = container_of(fpriv, struct tpms_priv, priv);
+
+	tpm_common_release(file, fpriv);
+	tpm2_del_space(&priv->space);
+	kfree(priv);
+
+	return 0;
+}
+
+ssize_t tpms_write(struct file *file, const char __user *buf,
+		   size_t size, loff_t *off)
+{
+	struct file_priv *fpriv = file->private_data;
+	struct tpms_priv *priv = container_of(fpriv, struct tpms_priv, priv);
+
+	return tpm_common_write(file, buf, size, off, &priv->space);
+}
+
+const struct file_operations tpms_fops = {
+	.owner = THIS_MODULE,
+	.llseek = no_llseek,
+	.open = tpms_open,
+	.read = tpm_common_read,
+	.write = tpms_write,
+	.release = tpms_release,
+};
+
-- 
2.9.3

[toc] | [prev] | [next] | [standalone]


#1586761 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date2017-02-23 10:10 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tdXzr-7EZ-15@gated-at.bofh.it>
In reply to#1582887
On Thu, Feb 16, 2017 at 09:25:19PM +0200, Jarkko Sakkinen wrote:
> From: James Bottomley <James.Bottomley@HansenPartnership.com>
> 
> Currently the tpm spaces are not exposed to userspace.  Make this
> exposure via a separate device, which can now be opened multiple times
> because each read/write transaction goes separately via the space.
> 
> Concurrency is protected by the chip->tpm_mutex for each read/write
> transaction separately.  The TPM is cleared of all transient objects
> by the time the mutex is dropped, so there should be no interference
> between the kernel and userspace.
> 
> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>

Reviewed-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>
Tested-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>

Nitpicking but I've been thinking about naming. What about calling the
device as tpmrc0 as in resource context. I think that would be a better
name than TPM space. You do not mix it up with namespaces and/or
virtualization. With resource in front it cannot be easily mixed up with
TPM contexts either.

This does not require any effort from your side. I could do the
renaming.

PS. Could you go through my commits and test and review them at some
point so we would have the whole patch set peer tested?

/Jarkko

> ---
>  drivers/char/tpm/Makefile        |  3 +-
>  drivers/char/tpm/tpm-chip.c      | 73 ++++++++++++++++++++++++++++++++++++++--
>  drivers/char/tpm/tpm-interface.c | 13 +++++--
>  drivers/char/tpm/tpm.h           |  4 +++
>  drivers/char/tpm/tpms-dev.c      | 65 +++++++++++++++++++++++++++++++++++
>  5 files changed, 152 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/char/tpm/tpms-dev.c
> 
> diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile
> index 10e5827..bbe6531 100644
> --- a/drivers/char/tpm/Makefile
> +++ b/drivers/char/tpm/Makefile
> @@ -3,7 +3,8 @@
>  #
>  obj-$(CONFIG_TCG_TPM) += tpm.o
>  tpm-y := tpm-interface.o tpm-dev.o tpm-sysfs.o tpm-chip.o tpm2-cmd.o \
> -	 tpm-dev-common.o tpm1_eventlog.o tpm2_eventlog.o tpm2-space.o
> +	 tpm-dev-common.o tpms-dev.o tpm1_eventlog.o tpm2_eventlog.o \
> +         tpm2-space.o
>  tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_acpi.o
>  tpm-$(CONFIG_OF) += tpm_of.o
>  obj-$(CONFIG_TCG_TIS_CORE) += tpm_tis_core.o
> diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
> index 993b9ae..c71c353 100644
> --- a/drivers/char/tpm/tpm-chip.c
> +++ b/drivers/char/tpm/tpm-chip.c
> @@ -33,6 +33,7 @@ DEFINE_IDR(dev_nums_idr);
>  static DEFINE_MUTEX(idr_lock);
>  
>  struct class *tpm_class;
> +struct class *tpms_class;
>  dev_t tpm_devt;
>  
>  /**
> @@ -132,6 +133,14 @@ static void tpm_dev_release(struct device *dev)
>  	kfree(chip);
>  }
>  
> +static void tpm_devs_release(struct device *dev)
> +{
> +	struct tpm_chip *chip = container_of(dev, struct tpm_chip, devs);
> +
> +	/* release the master device reference */
> +	put_device(&chip->dev);
> +}
> +
>  /**
>   * tpm_chip_alloc() - allocate a new struct tpm_chip instance
>   * @pdev: device to which the chip is associated
> @@ -168,27 +177,47 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
>  	chip->dev_num = rc;
>  
>  	device_initialize(&chip->dev);
> +	device_initialize(&chip->devs);
>  
>  	chip->dev.class = tpm_class;
>  	chip->dev.release = tpm_dev_release;
>  	chip->dev.parent = pdev;
>  	chip->dev.groups = chip->groups;
>  
> +	chip->devs.parent = pdev;
> +	chip->devs.class = tpms_class;
> +	chip->devs.release = tpm_devs_release;
> +	/* get extra reference on main device to hold on
> +	 * behalf of devs.  This holds the chip structure
> +	 * while cdevs is in use.  The corresponding put
> +	 * is in the tpm_devs_release
> +	 */
> +	get_device(&chip->dev);
> +
>  	if (chip->dev_num == 0)
>  		chip->dev.devt = MKDEV(MISC_MAJOR, TPM_MINOR);
>  	else
>  		chip->dev.devt = MKDEV(MAJOR(tpm_devt), chip->dev_num);
>  
> +	chip->devs.devt =
> +		MKDEV(MAJOR(tpm_devt), chip->dev_num + TPM_NUM_DEVICES);
> +
>  	rc = dev_set_name(&chip->dev, "tpm%d", chip->dev_num);
>  	if (rc)
>  		goto out;
> +	rc = dev_set_name(&chip->devs, "tpms%d", chip->dev_num);
> +	if (rc)
> +		goto out;
>  
>  	if (!pdev)
>  		chip->flags |= TPM_CHIP_FLAG_VIRTUAL;
>  
>  	cdev_init(&chip->cdev, &tpm_fops);
> +	cdev_init(&chip->cdevs, &tpms_fops);
>  	chip->cdev.owner = THIS_MODULE;
> +	chip->cdevs.owner = THIS_MODULE;
>  	chip->cdev.kobj.parent = &chip->dev.kobj;
> +	chip->cdevs.kobj.parent = &chip->devs.kobj;
>  
>  	chip->work_space.context_buf = kzalloc(PAGE_SIZE, GFP_KERNEL);
>  	if (!chip->work_space.context_buf) {
> @@ -199,6 +228,7 @@ struct tpm_chip *tpm_chip_alloc(struct device *pdev,
>  	return chip;
>  
>  out:
> +	put_device(&chip->devs);
>  	put_device(&chip->dev);
>  	return ERR_PTR(rc);
>  }
> @@ -244,7 +274,7 @@ static int tpm_add_char_device(struct tpm_chip *chip)
>  			dev_name(&chip->dev), MAJOR(chip->dev.devt),
>  			MINOR(chip->dev.devt), rc);
>  
> -		return rc;
> +		goto err_1;
>  	}
>  
>  	rc = device_add(&chip->dev);
> @@ -254,16 +284,44 @@ static int tpm_add_char_device(struct tpm_chip *chip)
>  			dev_name(&chip->dev), MAJOR(chip->dev.devt),
>  			MINOR(chip->dev.devt), rc);
>  
> -		cdev_del(&chip->cdev);
> -		return rc;
> +		goto err_2;
> +	}
> +
> +	if (chip->flags & TPM_CHIP_FLAG_TPM2)
> +		rc = cdev_add(&chip->cdevs, chip->devs.devt, 1);
> +	if (rc) {
> +		dev_err(&chip->dev,
> +			"unable to cdev_add() %s, major %d, minor %d, err=%d\n",
> +			dev_name(&chip->devs), MAJOR(chip->devs.devt),
> +			MINOR(chip->devs.devt), rc);
> +
> +		goto err_3;
>  	}
>  
> +	if (chip->flags & TPM_CHIP_FLAG_TPM2)
> +		rc = device_add(&chip->devs);
> +	if (rc) {
> +		dev_err(&chip->dev,
> +			"unable to device_register() %s, major %d, minor %d, err=%d\n",
> +			dev_name(&chip->devs), MAJOR(chip->devs.devt),
> +			MINOR(chip->devs.devt), rc);
> +
> +		goto err_4;
> +	}
>  	/* Make the chip available. */
>  	mutex_lock(&idr_lock);
>  	idr_replace(&dev_nums_idr, chip, chip->dev_num);
>  	mutex_unlock(&idr_lock);
>  
>  	return rc;
> + err_4:
> +	cdev_del(&chip->cdevs);
> + err_3:
> +	device_del(&chip->dev);
> + err_2:
> +	cdev_del(&chip->cdev);
> + err_1:
> +	return rc;
>  }
>  
>  static void tpm_del_char_device(struct tpm_chip *chip)
> @@ -271,6 +329,11 @@ static void tpm_del_char_device(struct tpm_chip *chip)
>  	cdev_del(&chip->cdev);
>  	device_del(&chip->dev);
>  
> +	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> +		cdev_del(&chip->cdevs);
> +		device_del(&chip->devs);
> +	}
> +
>  	/* Make the chip unavailable. */
>  	mutex_lock(&idr_lock);
>  	idr_replace(&dev_nums_idr, NULL, chip->dev_num);
> @@ -282,6 +345,10 @@ static void tpm_del_char_device(struct tpm_chip *chip)
>  		tpm2_shutdown(chip, TPM2_SU_CLEAR);
>  	chip->ops = NULL;
>  	up_write(&chip->ops_sem);
> +	/* will release the devs reference to the chip->dev unless
> +	 * something has cdevs open
> +	 */
> +	put_device(&chip->devs);
>  }
>  
>  static void tpm_del_legacy_sysfs(struct tpm_chip *chip)
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index db5ffe9..deb2021 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -1257,9 +1257,17 @@ static int __init tpm_init(void)
>  		return PTR_ERR(tpm_class);
>  	}
>  
> -	rc = alloc_chrdev_region(&tpm_devt, 0, TPM_NUM_DEVICES, "tpm");
> +	tpms_class = class_create(THIS_MODULE, "tpms");
> +	if (IS_ERR(tpms_class)) {
> +		pr_err("couldn't create tpms class\n");
> +		class_destroy(tpm_class);
> +		return PTR_ERR(tpms_class);
> +	}
> +
> +	rc = alloc_chrdev_region(&tpm_devt, 0, 2*TPM_NUM_DEVICES, "tpm");
>  	if (rc < 0) {
>  		pr_err("tpm: failed to allocate char dev region\n");
> +		class_destroy(tpms_class);
>  		class_destroy(tpm_class);
>  		return rc;
>  	}
> @@ -1271,7 +1279,8 @@ static void __exit tpm_exit(void)
>  {
>  	idr_destroy(&dev_nums_idr);
>  	class_destroy(tpm_class);
> -	unregister_chrdev_region(tpm_devt, TPM_NUM_DEVICES);
> +	class_destroy(tpms_class);
> +	unregister_chrdev_region(tpm_devt, 2*TPM_NUM_DEVICES);
>  }
>  
>  subsys_initcall(tpm_init);
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 97e48a4..822ca67 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -182,7 +182,9 @@ struct tpm_chip_seqops {
>  
>  struct tpm_chip {
>  	struct device dev;
> +	struct device devs;
>  	struct cdev cdev;
> +	struct cdev cdevs;
>  
>  	/* A driver callback under ops cannot be run unless ops_sem is held
>  	 * (sometimes implicitly, eg for the sysfs code). ops becomes null
> @@ -510,8 +512,10 @@ static inline void tpm_buf_append_u32(struct tpm_buf *buf, const u32 value)
>  }
>  
>  extern struct class *tpm_class;
> +extern struct class *tpms_class;
>  extern dev_t tpm_devt;
>  extern const struct file_operations tpm_fops;
> +extern const struct file_operations tpms_fops;
>  extern struct idr dev_nums_idr;
>  
>  enum tpm_transmit_flags {
> diff --git a/drivers/char/tpm/tpms-dev.c b/drivers/char/tpm/tpms-dev.c
> new file mode 100644
> index 0000000..5720885
> --- /dev/null
> +++ b/drivers/char/tpm/tpms-dev.c
> @@ -0,0 +1,65 @@
> +/*
> + * Copyright (C) 2017 James.Bottomley@HansenPartnership.com
> + *
> + * GPLv2
> + */
> +#include <linux/slab.h>
> +#include "tpm-dev.h"
> +
> +struct tpms_priv {
> +	struct file_priv priv;
> +	struct tpm_space space;
> +};
> +
> +static int tpms_open(struct inode *inode, struct file *file)
> +{
> +	struct tpm_chip *chip;
> +	struct tpms_priv *priv;
> +	int rc;
> +
> +	chip = container_of(inode->i_cdev, struct tpm_chip, cdevs);
> +	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
> +	if (priv == NULL)
> +		return -ENOMEM;
> +
> +	rc = tpm2_init_space(&priv->space);
> +	if (rc) {
> +		kfree(priv);
> +		return -ENOMEM;
> +	}
> +
> +	tpm_common_open(file, chip, &priv->priv);
> +
> +	return 0;
> +}
> +
> +static int tpms_release(struct inode *inode, struct file *file)
> +{
> +	struct file_priv *fpriv = file->private_data;
> +	struct tpms_priv *priv = container_of(fpriv, struct tpms_priv, priv);
> +
> +	tpm_common_release(file, fpriv);
> +	tpm2_del_space(&priv->space);
> +	kfree(priv);
> +
> +	return 0;
> +}
> +
> +ssize_t tpms_write(struct file *file, const char __user *buf,
> +		   size_t size, loff_t *off)
> +{
> +	struct file_priv *fpriv = file->private_data;
> +	struct tpms_priv *priv = container_of(fpriv, struct tpms_priv, priv);
> +
> +	return tpm_common_write(file, buf, size, off, &priv->space);
> +}
> +
> +const struct file_operations tpms_fops = {
> +	.owner = THIS_MODULE,
> +	.llseek = no_llseek,
> +	.open = tpms_open,
> +	.read = tpm_common_read,
> +	.write = tpms_write,
> +	.release = tpms_release,
> +};
> +
> -- 
> 2.9.3
> 

[toc] | [prev] | [next] | [standalone]


#1587610 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJames Bottomley <James.Bottomley@HansenPartnership.com>
Date2017-02-24 14:10 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tenNh-yV-31@gated-at.bofh.it>
In reply to#1586761
On Thu, 2017-02-23 at 11:09 +0200, Jarkko Sakkinen wrote:
> On Thu, Feb 16, 2017 at 09:25:19PM +0200, Jarkko Sakkinen wrote:
> > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> > 
> > Currently the tpm spaces are not exposed to userspace.  Make this
> > exposure via a separate device, which can now be opened multiple 
> > times because each read/write transaction goes separately via the
> > space.
> > 
> > Concurrency is protected by the chip->tpm_mutex for each read/write
> > transaction separately.  The TPM is cleared of all transient 
> > objects by the time the mutex is dropped, so there should be no
> > interference between the kernel and userspace.
> > Signed-off-by: James Bottomley <
> > 
> > James.Bottomley@HansenPartnershp.com>

> Reviewed-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>
> Tested-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>

Thanks!

> Nitpicking but I've been thinking about naming. What about calling 
> the device as tpmrc0 as in resource context. I think that would be a
> better name than TPM space.

Well the original name was tpmrm<n> for TPM with Resource Manager.  You
wanted it to be tpms<n> for TPM with Spaces.

I'm not entirely sold on the Resource Context name ... I think Resource Manager (because it's what the TCG calls it) or Spaces (because it's what all the code comments call it) are better.  Resource Context sounds like what TPM2_SaveContext() creates for you rather than the interface.

>  You do not mix it up with namespaces and/or virtualization. With
> resource in front it cannot be easily mixed up with TPM contexts
> either.

I'm a containers person.  What this set of patches does is precisely OS
level virtualization in my book, so I don't think you need to pretend
it is't; and OS level virtualization is what a namespace does.  The
only difference between this and the other kernel namespaces is that
you get a new namespace automatically when you open the device and you
can't enter an existing namespace.

I think therefore that tpmns<n> for TPM Namespace would be very
appropriate.

> This does not require any effort from your side. I could do the
> renaming.
>
> PS. Could you go through my commits and test and review them at some
> point so we would have the whole patch set peer tested?

Already reviewed, just doing a test build (I'm travelling, so it
actually has to be on my physical laptop).

James

[toc] | [prev] | [next] | [standalone]


#1587831 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date2017-02-24 18:40 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tes0y-3rI-27@gated-at.bofh.it>
In reply to#1587610
On Fri, Feb 24, 2017 at 08:02:08AM -0500, James Bottomley wrote:
> On Thu, 2017-02-23 at 11:09 +0200, Jarkko Sakkinen wrote:
> > On Thu, Feb 16, 2017 at 09:25:19PM +0200, Jarkko Sakkinen wrote:
> > > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> > > 
> > > Currently the tpm spaces are not exposed to userspace.  Make this
> > > exposure via a separate device, which can now be opened multiple 
> > > times because each read/write transaction goes separately via the
> > > space.
> > > 
> > > Concurrency is protected by the chip->tpm_mutex for each read/write
> > > transaction separately.  The TPM is cleared of all transient 
> > > objects by the time the mutex is dropped, so there should be no
> > > interference between the kernel and userspace.
> > > Signed-off-by: James Bottomley <
> > > 
> > > James.Bottomley@HansenPartnershp.com>
> 
> > Reviewed-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>
> > Tested-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>
> 
> Thanks!
> 
> > Nitpicking but I've been thinking about naming. What about calling 
> > the device as tpmrc0 as in resource context. I think that would be a
> > better name than TPM space.
> 
> Well the original name was tpmrm<n> for TPM with Resource Manager.  You
> wanted it to be tpms<n> for TPM with Spaces.
> 
> I'm not entirely sold on the Resource Context name ... I think Resource Manager (because it's what the TCG calls it) or Spaces (because it's what all the code comments call it) are better.  Resource Context sounds like what TPM2_SaveContext() creates for you rather than the interface.
> 
> >  You do not mix it up with namespaces and/or virtualization. With
> > resource in front it cannot be easily mixed up with TPM contexts
> > either.
> 
> I'm a containers person.  What this set of patches does is precisely OS
> level virtualization in my book, so I don't think you need to pretend
> it is't; and OS level virtualization is what a namespace does.  The
> only difference between this and the other kernel namespaces is that
> you get a new namespace automatically when you open the device and you
> can't enter an existing namespace.
> 
> I think therefore that tpmns<n> for TPM Namespace would be very
> appropriate.

Makes sense. We can go with tpmns.

/Jarkko

[toc] | [prev] | [next] | [standalone]


#1587845 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Date2017-02-24 19:20 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tesDg-3VB-5@gated-at.bofh.it>
In reply to#1587831
On Fri, Feb 24, 2017 at 07:39:22PM +0200, Jarkko Sakkinen wrote:

> > I think therefore that tpmns<n> for TPM Namespace would be very
> > appropriate.
> 
> Makes sense. We can go with tpmns.

When we have talked about TPM namespaces in the past it has been
around the idea of restricting which TPMs the namespace has access too
and changing the 'kernel tpm' for that namespace.

Jason

[toc] | [prev] | [next] | [standalone]


#1587919 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJames Bottomley <James.Bottomley@HansenPartnership.com>
Date2017-02-24 21:30 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<teuF4-5q2-19@gated-at.bofh.it>
In reply to#1587845
On Fri, 2017-02-24 at 11:11 -0700, Jason Gunthorpe wrote:
> On Fri, Feb 24, 2017 at 07:39:22PM +0200, Jarkko Sakkinen wrote:
> 
> > > I think therefore that tpmns<n> for TPM Namespace would be very
> > > appropriate.
> > 
> > Makes sense. We can go with tpmns.
> 
> When we have talked about TPM namespaces in the past it has been
> around the idea of restricting which TPMs the namespace has access 
> too and changing the 'kernel tpm' for that namespace.

Well, you know, nothing in the TPM Space code prevents us from exposing
the namespace so that it could be shared.  However, I think the
namespace follows connect (device open) paradigm is pretty much the
behaviour everyone (including the kernel) wants, mostly because TPM2
has such a tiny amount of resources that you're always dealing with
loadable keys meaning you don't really want to see anyone else's
volatile state.

James

[toc] | [prev] | [next] | [standalone]


#1587934 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Date2017-02-24 22:00 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tev85-5AX-3@gated-at.bofh.it>
In reply to#1587919
On Fri, Feb 24, 2017 at 03:29:15PM -0500, James Bottomley wrote:
> On Fri, 2017-02-24 at 11:11 -0700, Jason Gunthorpe wrote:
> > On Fri, Feb 24, 2017 at 07:39:22PM +0200, Jarkko Sakkinen wrote:
> > 
> > > > I think therefore that tpmns<n> for TPM Namespace would be very
> > > > appropriate.
> > > 
> > > Makes sense. We can go with tpmns.
> > 
> > When we have talked about TPM namespaces in the past it has been
> > around the idea of restricting which TPMs the namespace has access 
> > too and changing the 'kernel tpm' for that namespace.
> 
> Well, you know, nothing in the TPM Space code prevents us from exposing
> the namespace so that it could be shared.  However, I think the
> namespace follows connect (device open) paradigm is pretty much the
> behaviour everyone (including the kernel) wants, mostly because TPM2
> has such a tiny amount of resources that you're always dealing with
> loadable keys meaning you don't really want to see anyone else's
> volatile state.

I'm not arguing with that use model, I am asking what do you want to
call the future feature that restricts which TPMs a process can view
if you want to use the word namespace for the resource manager?

This is something Stephen B has been exploring in conjunction with
vtpm. (eg restrict a container to only use a single vtpm and ban it
from the system tpm)

Jason

[toc] | [prev] | [next] | [standalone]


#1587995 — Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJames Bottomley <James.Bottomley@HansenPartnership.com>
Date2017-02-25 00:10 +0100
SubjectRe: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tex9T-7mc-7@gated-at.bofh.it>
In reply to#1587934
On Fri, 2017-02-24 at 13:52 -0700, Jason Gunthorpe wrote:
> On Fri, Feb 24, 2017 at 03:29:15PM -0500, James Bottomley wrote:
> > On Fri, 2017-02-24 at 11:11 -0700, Jason Gunthorpe wrote:
> > > On Fri, Feb 24, 2017 at 07:39:22PM +0200, Jarkko Sakkinen wrote:
> > > 
> > > > > I think therefore that tpmns<n> for TPM Namespace would be
> > > > > very
> > > > > appropriate.
> > > > 
> > > > Makes sense. We can go with tpmns.
> > > 
> > > When we have talked about TPM namespaces in the past it has been
> > > around the idea of restricting which TPMs the namespace has
> > > access 
> > > too and changing the 'kernel tpm' for that namespace.
> > 
> > Well, you know, nothing in the TPM Space code prevents us from
> > exposing
> > the namespace so that it could be shared.  However, I think the
> > namespace follows connect (device open) paradigm is pretty much the
> > behaviour everyone (including the kernel) wants, mostly because
> > TPM2
> > has such a tiny amount of resources that you're always dealing with
> > loadable keys meaning you don't really want to see anyone else's
> > volatile state.
> 
> I'm not arguing with that use model, I am asking what do you want to
> call the future feature that restricts which TPMs a process can view
> if you want to use the word namespace for the resource manager?

Well, as a glib answer, I'd say the TPM is a device, so the thing which
restricts device access to containers is the device cgroup ... that's
what we should be plugging into.  I'd have to look, but I suspect the
device cgroup basically operates on device node appearance, so it
should "just work"(tm).  I can explore when I'm back home.

James

> This is something Stephen B has been exploring in conjunction with
> vtpm. (eg restrict a container to only use a single vtpm and ban it
> from the system tpm)
> 
> Jason
> 
> ---------------------------------------------------------------------
> ---------
> 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]


#1588000 — Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Date2017-02-25 00:30 +0100
SubjectRe: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<textf-7sW-7@gated-at.bofh.it>
In reply to#1587995
On Fri, Feb 24, 2017 at 06:01:00PM -0500, James Bottomley wrote:

> Well, as a glib answer, I'd say the TPM is a device, so the thing which
> restricts device access to containers is the device cgroup ... that's
> what we should be plugging into.  I'd have to look, but I suspect the
> device cgroup basically operates on device node appearance, so it
> should "just work"(tm).  I can explore when I'm back home.

Seems reasonable..

It just seems confusing to call something a namespace that isn't also
a CLONE_NEW* option..

FWIW more background on the topic:

Stefan was concerned about information leakage via sysfs of TPM data,
eg that a container could still touch the host's TPM. I wonder if
device cgroup could be extended to block access to the sysfs
directories containing a disallowed 'dev' ?

I was also wondering about kernel use from within the container -
all kernel consumers are locked to physical tpm0.. But maybe the
kernel can consult the right device cgroup to find an allowed TPM?

Jason

[toc] | [prev] | [next] | [standalone]


#1588008 — Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJames Bottomley <James.Bottomley@HansenPartnership.com>
Date2017-02-25 00:50 +0100
SubjectRe: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<texMC-7D1-5@gated-at.bofh.it>
In reply to#1588000
On Fri, 2017-02-24 at 16:23 -0700, Jason Gunthorpe wrote:
> On Fri, Feb 24, 2017 at 06:01:00PM -0500, James Bottomley wrote:
> 
> > Well, as a glib answer, I'd say the TPM is a device, so the thing 
> > which restricts device access to containers is the device cgroup 
> > ... that's what we should be plugging into.  I'd have to look, but 
> > I suspect the device cgroup basically operates on device node 
> > appearance, so it should "just work"(tm).  I can explore when I'm
> > back home.
> 
> Seems reasonable..
> 
> It just seems confusing to call something a namespace that isn't also
> a CLONE_NEW* option..

Well, there's namespace behaviour and then there's how you enter them. 
 We have namespace behaviour with the /dev/tpms<n> but the namespace is
entered on opening the device, even if the same process opens the
device more than once.  So we have namespace behaviour with a non clone
entry mechanism.  Since we're namespaceing a device, that seems to me
to be the correct semantic.

> FWIW more background on the topic:
> 
> Stefan was concerned about information leakage via sysfs of TPM data,
> eg that a container could still touch the host's TPM. I wonder if
> device cgroup could be extended to block access to the sysfs
> directories containing a disallowed 'dev' ?

It doesn't need to.  The sysfs entries (those that ask the TPM
something) are surrounded by chip->tpm_mutex, so when it asks, we know
all the spaces are context saved (i.e. the only TPM visible state is
global not anything space local).

> I was also wondering about kernel use from within the container -
> all kernel consumers are locked to physical tpm0.. But maybe the
> kernel can consult the right device cgroup to find an allowed TPM?

I'd use the device cgroup to determine what's allowable per container
(i.e. what tpm you can see) then within the container I'd open the
tpms<n> device ... because the TPM volatile storage is so tiny its not
inconceivable that multiple processes, even within a single container,
need access ... and they'd each need their own "namespace" (which they
get with the current model).  However, this is opinion ... we should
try it out and see what works best.

James

[toc] | [prev] | [next] | [standalone]


#1588017 — Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Date2017-02-25 01:30 +0100
SubjectRe: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<teypk-86z-21@gated-at.bofh.it>
In reply to#1588008
On Fri, Feb 24, 2017 at 06:43:27PM -0500, James Bottomley wrote:

> > It just seems confusing to call something a namespace that isn't also
> > a CLONE_NEW* option..
> 
> Well, there's namespace behaviour and then there's how you enter them. 
>  We have namespace behaviour with the /dev/tpms<n> but the namespace is
> entered on opening the device, even if the same process opens the
> device more than once.  So we have namespace behaviour with a non clone
> entry mechanism.  Since we're namespaceing a device, that seems to me
> to be the correct semantic.

I'm looking at it from a documentation perspective, look at
namespaces(7) for instance

Lots of FD things have 'namespace behavior' but we don't call
them namespaces..

> > Stefan was concerned about information leakage via sysfs of TPM data,
> > eg that a container could still touch the host's TPM. I wonder if
> > device cgroup could be extended to block access to the sysfs
> > directories containing a disallowed 'dev' ?
> 
> It doesn't need to.  The sysfs entries (those that ask the TPM
> something) are surrounded by chip->tpm_mutex, so when it asks, we know
> all the spaces are context saved (i.e. the only TPM visible state is
> global not anything space local).

Yes, I understand that - the concern is that a container can still
read the global state from tpm0 (eg ek/srk/pcrs) even if it is setup to
exclusively use a vtpm. device cgroup blocks access to the cdevs of
tpm0 but not to the sysfs files.

Maybe we should just make those debug files readable only by root and
forget about that worry.

> > I was also wondering about kernel use from within the container -
> > all kernel consumers are locked to physical tpm0.. But maybe the
> > kernel can consult the right device cgroup to find an allowed TPM?
> 
> I'd use the device cgroup to determine what's allowable per container
> (i.e. what tpm you can see) then within the container I'd open the
> tpms<n> device ...

I am talking about using a situation like kernel IMA or keyring in the
container with a tpm that is not tpm0, eg a vtpm.

Jason

[toc] | [prev] | [next] | [standalone]


#1588168 — Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJames Bottomley <James.Bottomley@HansenPartnership.com>
Date2017-02-25 18:10 +0100
SubjectRe: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<teO14-2yE-1@gated-at.bofh.it>
In reply to#1588017
On Fri, 2017-02-24 at 17:25 -0700, Jason Gunthorpe wrote:
> On Fri, Feb 24, 2017 at 06:43:27PM -0500, James Bottomley wrote:
> 
> > > It just seems confusing to call something a namespace that isn't 
> > > also a CLONE_NEW* option..
> > 
> > Well, there's namespace behaviour and then there's how you enter 
> > them.  We have namespace behaviour with the /dev/tpms<n> but the
> > namespace is entered on opening the device, even if the same 
> > process opens the device more than once.  So we have namespace 
> > behaviour with a non clone entry mechanism.  Since we're 
> > namespaceing a device, that seems to me to be the correct semantic.
> 
> I'm looking at it from a documentation perspective, look at
> namespaces(7) for instance

The term "namespace" is way broader than that

https://en.wikipedia.org/wiki/Namespace

> Lots of FD things have 'namespace behavior' but we don't call
> them namespaces..

At it's simplest, the virtual memory process model of UNIX is a
namespace.  That doesn't make the term inapplicable in this case.

> > > Stefan was concerned about information leakage via sysfs of TPM
> > > data, eg that a container could still touch the host's TPM. I
> > > wonder if device cgroup could be extended to block access to the
> > > sysfs directories containing a disallowed 'dev' ?
> > 
> > It doesn't need to.  The sysfs entries (those that ask the TPM
> > something) are surrounded by chip->tpm_mutex, so when it asks, we 
> > know all the spaces are context saved (i.e. the only TPM visible 
> > state is global not anything space local).
> 
> Yes, I understand that - the concern is that a container can still
> read the global state from tpm0 (eg ek/srk/pcrs) even if it is setup 
> to exclusively use a vtpm.

The TPM2 namespace as laid out by these patches only applies to objects
of type 80, 02 and 03.  The Storage and Endorsement seeds can't be
virtualized because they're one per physical instance.  81 objects
could be virtualised, but I don't really think we should. PCR
virtualisation is another whole interesting area of study.

>  device cgroup blocks access to the cdevs of tpm0 but not to the
> sysfs files.

What the device cgroup currently does for us and what it could do are
two different things.  It seems if it exported
__devcgroup_check_permission, we could use that as a check to gate the
sysfs file access.

> Maybe we should just make those debug files readable only by root and
> forget about that worry.
> 
> > > I was also wondering about kernel use from within the container -
> > > all kernel consumers are locked to physical tpm0.. But maybe the
> > > kernel can consult the right device cgroup to find an allowed
> > > TPM?
> > 
> > I'd use the device cgroup to determine what's allowable per 
> > container (i.e. what tpm you can see) then within the container I'd 
> > open the tpms<n> device ...
> 
> I am talking about using a situation like kernel IMA or keyring in 
> the container with a tpm that is not tpm0, eg a vtpm.

a vtpm appears as a tpm device so it can be controlled by the device
cgroup ... I think I'm not seeing the issue.

I should also say that discussion of mechanisms is usually the wrong
way to begin for OS virtualisation.  Almost anything can be virtualised
in a variety of ways, so to find the best way (or indeed if it should
be done at all) it's usually better to start with use cases.  So
instead of saying we need to virtualize the PCRs we should start with X
container has this requirement for attestation of its Y state.  Often
the best way simply is an extension of the multi user model for the
resource ... in this case no-one's really come up with one for PCRs, so
that might be the place to begin.

James

[toc] | [prev] | [next] | [standalone]


#1588837 — Re: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJason Gunthorpe <jgunthorpe@obsidianresearch.com>
Date2017-02-27 18:40 +0100
SubjectRe: [tpmdd-devel] [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tfxrc-n1-13@gated-at.bofh.it>
In reply to#1588168
On Sat, Feb 25, 2017 at 12:04:49PM -0500, James Bottomley wrote:

> >  device cgroup blocks access to the cdevs of tpm0 but not to the
> > sysfs files.
> 
> What the device cgroup currently does for us and what it could do are
> two different things.  It seems if it exported
> __devcgroup_check_permission, we could use that as a check to gate the
> sysfs file access.

Make sense, maybe we should be doing that..

Stefan, are you still interested in this? This seems like a fairly
simple solution to your problem???

> > I am talking about using a situation like kernel IMA or keyring in 
> > the container with a tpm that is not tpm0, eg a vtpm.
> 
> a vtpm appears as a tpm device so it can be controlled by the device
> cgroup ... I think I'm not seeing the issue.

When an in-kernel call opens the TPM it does not go through the cdev,
it does something like this:

extern int tpm_pcr_read(u32 chip_num, int pcr_idx, u8 *res_buf);

And hardwires 'chip_num' to TPM_ANY_NUM. Keyring does the same (see
trusted_instantiate)

Practically speaking this means in-kernel callers pretty much always
operate on tpm0.

I think we need to change TPM_ANY_NUM to something more container
friendly, but I'm not sure what that should be.

> be done at all) it's usually better to start with use cases.  So
> instead of saying we need to virtualize the PCRs we should start with X
> container has this requirement for attestation of its Y state.  Often
> the best way simply is an extension of the multi user model for the
> resource ... in this case no-one's really come up with one for PCRs, so
> that might be the place to begin.

Broadly makes sense to me.

Maybe kernel keyring is a better example, it already has a multi-user
model.

Jason

[toc] | [prev] | [next] | [standalone]


#1588315 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Date2017-02-26 12:50 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tf5uV-6ca-11@gated-at.bofh.it>
In reply to#1587610
On Fri, Feb 24, 2017 at 08:02:08AM -0500, James Bottomley wrote:
> On Thu, 2017-02-23 at 11:09 +0200, Jarkko Sakkinen wrote:
> > On Thu, Feb 16, 2017 at 09:25:19PM +0200, Jarkko Sakkinen wrote:
> > > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> > > 
> > > Currently the tpm spaces are not exposed to userspace.  Make this
> > > exposure via a separate device, which can now be opened multiple 
> > > times because each read/write transaction goes separately via the
> > > space.
> > > 
> > > Concurrency is protected by the chip->tpm_mutex for each read/write
> > > transaction separately.  The TPM is cleared of all transient 
> > > objects by the time the mutex is dropped, so there should be no
> > > interference between the kernel and userspace.
> > > Signed-off-by: James Bottomley <
> > > 
> > > James.Bottomley@HansenPartnershp.com>
> 
> > Reviewed-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>
> > Tested-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>
> 
> Thanks!
> 
> > Nitpicking but I've been thinking about naming. What about calling 
> > the device as tpmrc0 as in resource context. I think that would be a
> > better name than TPM space.
> 
> Well the original name was tpmrm<n> for TPM with Resource Manager.  You
> wanted it to be tpms<n> for TPM with Spaces.
> 
> I'm not entirely sold on the Resource Context name ... I think
> Resource Manager (because it's what the TCG calls it) or Spaces
> (because it's what all the code comments call it) are better.
> Resource Context sounds like what TPM2_SaveContext() creates for you
> rather than the interface.
> 
> >  You do not mix it up with namespaces and/or virtualization. With
> > resource in front it cannot be easily mixed up with TPM contexts
> > either.
> 
> I'm a containers person.  What this set of patches does is precisely OS
> level virtualization in my book, so I don't think you need to pretend
> it is't; and OS level virtualization is what a namespace does.  The
> only difference between this and the other kernel namespaces is that
> you get a new namespace automatically when you open the device and you
> can't enter an existing namespace.
> 
> I think therefore that tpmns<n> for TPM Namespace would be very
> appropriate.

Sorry for going back and forth with this but I turn it back to your
original tpmrm. It's in the end of the day the least confusing option. I
think this has been anyway useful to trip a bit around the options
because it is hard to rollback API...

> > This does not equire any effort from your side. I could do the
> > renaming.
> >
> > PS. Could you go through my commits and test and review them at some
> > point so we would have the whole patch set peer tested?
> 
> Already reviewed, just doing a test build (I'm travelling, so it
> actually has to be on my physical laptop).
> 
> James

There's now tabrm-v3 branch. I had to tweak error handling in your
device adding patch because of b4e9d7561a70. I hope I didn't break
anything.

/Jarkko

[toc] | [prev] | [next] | [standalone]


#1588373 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

From"Dr. Greg Wettstein" <greg@enjellic.com>
Date2017-02-26 19:40 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tfbTH-23I-1@gated-at.bofh.it>
In reply to#1588315
On Sun, Feb 26, 2017 at 01:44:40PM +0200, Jarkko Sakkinen wrote:

Good day, I hope this note finds the week starting well for everyone.

> On Fri, Feb 24, 2017 at 08:02:08AM -0500, James Bottomley wrote:
> > On Thu, 2017-02-23 at 11:09 +0200, Jarkko Sakkinen wrote:
> > > On Thu, Feb 16, 2017 at 09:25:19PM +0200, Jarkko Sakkinen wrote:
> > > > From: James Bottomley <James.Bottomley@HansenPartnership.com>
> > > > 
> > > > Currently the tpm spaces are not exposed to userspace.  Make this
> > > > exposure via a separate device, which can now be opened multiple 
> > > > times because each read/write transaction goes separately via the
> > > > space.
> > > > 
> > > > Concurrency is protected by the chip->tpm_mutex for each read/write
> > > > transaction separately.  The TPM is cleared of all transient 
> > > > objects by the time the mutex is dropped, so there should be no
> > > > interference between the kernel and userspace.
> > > > Signed-off-by: James Bottomley <
> > > > 
> > > > James.Bottomley@HansenPartnershp.com>
> > 
> > > Reviewed-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>
> > > Tested-by: Jarkko Sakkinen <jarkko.sakkine@linux.intel.com>
> > 
> > Thanks!
> > 
> > > Nitpicking but I've been thinking about naming. What about calling 
> > > the device as tpmrc0 as in resource context. I think that would be a
> > > better name than TPM space.
> > 
> > Well the original name was tpmrm<n> for TPM with Resource Manager.  You
> > wanted it to be tpms<n> for TPM with Spaces.
> > 
> > I'm not entirely sold on the Resource Context name ... I think
> > Resource Manager (because it's what the TCG calls it) or Spaces
> > (because it's what all the code comments call it) are better.
> > Resource Context sounds like what TPM2_SaveContext() creates for you
> > rather than the interface.
> > 
> > >  You do not mix it up with namespaces and/or virtualization. With
> > > resource in front it cannot be easily mixed up with TPM contexts
> > > either.
> > 
> > I'm a containers person.  What this set of patches does is precisely OS
> > level virtualization in my book, so I don't think you need to pretend
> > it is't; and OS level virtualization is what a namespace does.  The
> > only difference between this and the other kernel namespaces is that
> > you get a new namespace automatically when you open the device and you
> > can't enter an existing namespace.
> > 
> > I think therefore that tpmns<n> for TPM Namespace would be very
> > appropriate.

> Sorry for going back and forth with this but I turn it back to your
> original tpmrm. It's in the end of the day the least confusing
> option. I think this has been anyway useful to trip a bit around the
> options because it is hard to rollback API...

Indeed, which is why we have watched this conversation with some
interest regarding exactly what the tpm{rm,ns} will represent.

In order to get a handle on how the resource manager will affect
Trusted Execution Technology (TXT) environments we downloaded your
branch and experimented with it a bit.  Our overall impression is that
it will be important to educate the user community on exactly what the
'tpm spaces' management device actually represents.

It is not a TPM device as much as it is a method of surfacing a subset
of TPM functionality over the lifespan of a file descriptor.  There is
certainly nothing wrong with this but users and system administrators
will need to understand the implications of this and not confuse the
two devices.

For example, Ken's tools which come in his TSS2 library, don't work
properly with the 'spaces' device due to the virtualization lifetime.
As an example, the getcapability call will 'lie' about the number of
transient handles which are available through the device.  Attempts to
string multiple transaction sequences together will fail as well.

So I think it will be important to stress that the 'spaces' device is
something an individual application will use to gain unimpeded access
to TPM functionality and not a representation of the device itself.
Given the quality of userspace simulators and their flexibility and
operational fidelity, I anticipate we will eventually come to the
conclusion that this problem will have been best solved by creating
and adopting a framework which provides the anchoring and spawning of
userspace TPM2 instances.

Just as an aside we still haven't been able to verify the
inter-operability of the 'spaces' driver with TXT.  There are larger
TXT/TPM2 operational issues which we are working to run down before we
can determine how the two systems will inter-operate or not.

> /Jarkko

Have a good day.

Greg

As always,
Dr. G.W. Wettstein, Ph.D.   Enjellic Systems Development, LLC.
4206 N. 19th Ave.           Specializing in information infra-structure
Fargo, ND  58102            development.
PH: 701-281-1686
FAX: 701-281-3949           EMAIL: greg@enjellic.com
------------------------------------------------------------------------------
"You've got to be kidding me Nate.  You've seen the shit that has come
 through my office in the last two hours.  You think I'm even remotely
 worried about one SATA cable being six inches longer than the other."
                                -- Dr. Greg Wettstein
                                   Resurrection

[toc] | [prev] | [next] | [standalone]


#1589703 — Re: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>

FromKen Goldman <kgold@linux.vnet.ibm.com>
Date2017-02-28 20:00 +0100
SubjectRe: [PATCH v2 6/7] tpm: expose spaces via a device link /dev/tpms<n>
Message-ID<tfVa9-8nb-1@gated-at.bofh.it>
In reply to#1588373
On 2/26/2017 1:30 PM, Dr. Greg Wettstein wrote:
>
> For example, Ken's tools which come in his TSS2 library, don't work
> properly with the 'spaces' device due to the virtualization lifetime.
> As an example, the getcapability call will 'lie' about the number of
> transient handles which are available through the device.  Attempts to
> string multiple transaction sequences together will fail as well.

Two comments:

1 = The intent of the command line tools was for rapid prototyping 
scripts against a SW TPM, and then as sample code for writing the 
application.

2 - If you really want to script against a hardware TPM, it can be done. 
  Simply place a proxy between the TSS and the TPM device driver.  The 
proxy passes commands from the TCP socket to the TPM device driver.  It 
keeps the connection open so the resource manager doesn't flush between 
transactions.

The proxy can be obtained from here.  It's from TPM 1.2 days, but it 
works for TPM 2.0 as well.

https://sourceforge.net/projects/ibmswtpm/files/?source=navbar

[toc] | [prev] | [next] | [standalone]


Page 1 of 2  [1] 2  Next page →

Back to top | Article view | linux.kernel


csiph-web