Skip to contentSkip to conversation

add integrity and security to TPM2 transactions

RFC In review James Bottomley 2 participants 9 messages Mar 7, 2018 – Mar 12, 2018

Subsystems (3)
lore
Share & tools
lore

James Bottomley

author maintainer
#0 lore raw

cover add integrity and security to TPM2 transactions

By now, everybody knows we have a problem with the TPM2_RS_PW easy button on TPM2 in that transactions on the TPM bus can be intercepted and altered. ?The way to fix this is to use real sessions for HMAC capabilities to ensure integrity and to use parameter and response encryption to ensure confidentiality of the data flowing over the TPM bus.

This RFC is about adding a simple API which can ensure the above properties as a layered addition to the existing TPM handling code. ?Eventually we can add this to the random number generator, the PCR extensions and the trusted key handling, but this all depends on the conversion to tpm_buf which is not yet upstream, so I've constructed a second patch which demonstrates the new API in a test module for those who wish to play with it.

This series is also dependent on additions to the crypto subsystem to fix problems in the elliptic curve key handling and add the Cipher FeedBack encryption scheme:

https://marc.info/?l=linux-crypto-vger&m=151994371015475

In the second version, I added security HMAC to our PCR extend and encryption to the returned random number generators and also extracted the parsing and tpm2b construction API into a new file.

James

---

James Bottomley (5):
tpm-buf: create new functions for handling TPM buffers
tpm2-sessions: Add full HMAC and encrypt/decrypt session handling
tpm2: add hmac checks to tpm2_pcr_extend()
tpm2: add session encryption protection to tpm2_get_random()
tpm2-sessions: NOT FOR COMMITTING add sessions testing

 drivers/char/tpm/Kconfig              |    3 +
 drivers/char/tpm/Makefile             |    3 +-
 drivers/char/tpm/tpm-buf.c            |  184 ++++++
 drivers/char/tpm/tpm-chip.c           |    1 +
 drivers/char/tpm/tpm.h                |  116 ++--
 drivers/char/tpm/tpm2-cmd.c           |  129 ++---
 drivers/char/tpm/tpm2-sessions-test.c |  177 ++++++
 drivers/char/tpm/tpm2-sessions.c      | 1030 +++++++++++++++++++++++++++++++++
 drivers/char/tpm/tpm2-sessions.h      |   56 ++
 9 files changed, 1548 insertions(+), 151 deletions(-)
 create mode 100644 drivers/char/tpm/tpm-buf.c
 create mode 100644 drivers/char/tpm/tpm2-sessions-test.c
 create mode 100644 drivers/char/tpm/tpm2-sessions.c
 create mode 100644 drivers/char/tpm/tpm2-sessions.h
Signature · 5 lines
2.12.3
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author maintainer
#1 lore raw

RFC v2 1/5 tpm-buf: create new functions for handling TPM buffers

This separates out the old tpm_buf_... handling functions from static inlines into tpm.h and makes them their own tpm-buf.c file. It also adds handling for tpm2b structures and also incremental pointer advancing parsers.

---

v2: added this patch to separate out the API changes

---
 drivers/char/tpm/Makefile  |   2 +-
 drivers/char/tpm/tpm-buf.c | 184 +++++++++++++++++++++++++++++++++++++++++++++
 drivers/char/tpm/tpm.h     |  94 ++++-------------------
 3 files changed, 200 insertions(+), 80 deletions(-)
 create mode 100644 drivers/char/tpm/tpm-buf.c
drivers/char/tpm/Makefile +1 -1
index d37c4a1748f5..41b2482b97c3 100644
@@ -5,7 +5,7 @@
 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 tpmrm-dev.o tpm1_eventlog.o tpm2_eventlog.o \
-         tpm2-space.o
+         tpm2-space.o tpm-buf.o
 tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_eventlog_acpi.o
 tpm-$(CONFIG_EFI) += tpm_eventlog_efi.o
 tpm-$(CONFIG_OF) += tpm_eventlog_of.o
drivers/char/tpm/tpm-buf.c new file +184 -0

184 lines not on this page · raw message

drivers/char/tpm/tpm.h +15 -79

106 lines not on this page · raw message

Signature · 5 lines
2.12.3
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author maintainer
#2 lore raw

RFC v2 2/5 tpm2-sessions: Add full HMAC and encrypt/decrypt session handling

In reply to James Bottomley

This code adds true session based HMAC authentication plus parameter decryption and response encryption using AES.

The basic design of this code is to segregate all the nasty crypto, hash and hmac code into tpm2-sessions.c and export a usable API.

The API first of all starts off by gaining a session with

tpm2_start_auth_session()

Which initiates a session with the TPM and allocates an opaque tpm2_auth structure to handle the session parameters. Then the use is simply:

* tpm_buf_append_name() in place of the tpm_buf_append_u32 for the handles

* tpm_buf_append_hmac_session() where tpm2_append_auth() would go

* tpm_buf_fill_hmac_session() called after the entire command buffer is finished but before tpm_transmit_cmd() is called which computes the correct HMAC and places it in the command at the correct location.

Finally, after tpm_transmit_cmd() is called, tpm_buf_check_hmac_response() is called to check that the returned HMAC matched and collect the new state for the next use of the session, if any.

The features of the session is controlled by the session attributes set in tpm_buf_append_hmac_session(). If TPM2_SA_CONTINUE_SESSION is not specified, the session will be flushed and the tpm2_auth structure freed in tpm_buf_check_hmac_response(); otherwise the session may be used again. Parameter encryption is specified by or'ing the flag TPM2_SA_DECRYPT and response encryption by or'ing the flag TPM2_SA_ENCRYPT. the various encryptions will be taken care of by tpm_buf_fill_hmac_session() and tpm_buf_check_hmac_response() respectively.

To get all of this to work securely, the Kernel now needs a primary key to encrypt the session salt to, so we derive an EC key from the NULL seed and store it in the tpm_chip structure. We also make sure that this seed remains for the kernel by using a kernel space to take it out of the TPM when userspace wants to use it.

---

v2: Added docbook and improved response check API

---
 drivers/char/tpm/Kconfig         |    3 +
 drivers/char/tpm/Makefile        |    2 +-
 drivers/char/tpm/tpm.h           |   26 +
 drivers/char/tpm/tpm2-cmd.c      |   22 +-
 drivers/char/tpm/tpm2-sessions.c | 1030 ++++++++++++++++++++++++++++++++++++++
 drivers/char/tpm/tpm2-sessions.h |   56 +++
 6 files changed, 1126 insertions(+), 13 deletions(-)
 create mode 100644 drivers/char/tpm/tpm2-sessions.c
 create mode 100644 drivers/char/tpm/tpm2-sessions.h
drivers/char/tpm/Kconfig +3 -0
index 0aee88df98d1..8c714d8550c4 100644
@@ -8,6 +8,9 @@ menuconfig TCG_TPM
 	select SECURITYFS
 	select CRYPTO
 	select CRYPTO_HASH_INFO
+	select CRYPTO_ECDH
+	select CRYPTO_AES
+	select CRYPTO_CFB
 	---help---
 	  If you have a TPM security chip in your system, which
 	  implements the Trusted Computing Group's specification,
drivers/char/tpm/Makefile +1 -1
index 41b2482b97c3..b83737ccaa81 100644
@@ -5,7 +5,7 @@
 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 tpmrm-dev.o tpm1_eventlog.o tpm2_eventlog.o \
-         tpm2-space.o tpm-buf.o
+         tpm2-space.o tpm-buf.o tpm2-sessions.o
 tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_eventlog_acpi.o
 tpm-$(CONFIG_EFI) += tpm_eventlog_efi.o
 tpm-$(CONFIG_OF) += tpm_eventlog_of.o
drivers/char/tpm/tpm.h +26 -0
index 51c1fab2354c..1b495d748f90 100644
@@ -42,6 +42,9 @@
 #include <asm/intel-family.h>
 #endif
 
+/* fixed define for the curve we use which is NIST_P256 */
+#define EC_PT_SZ	32
+
 enum tpm_const {
 	TPM_MINOR = 224,	/* officially assigned */
 	TPM_BUFSIZE = 4096,
@@ -93,6 +96,7 @@ enum tpm2_const {
 enum tpm2_structures {
 	TPM2_ST_NO_SESSIONS	= 0x8001,
 	TPM2_ST_SESSIONS	= 0x8002,
+	TPM2_ST_CREATION	= 0x8021,
 };
 
 /* Indicates from what layer of the software stack the error comes from */
@@ -114,16 +118,25 @@ enum tpm2_return_codes {
 enum tpm2_algorithms {
 	TPM2_ALG_ERROR		= 0x0000,
 	TPM2_ALG_SHA1		= 0x0004,
+	TPM2_ALG_AES		= 0x0006,
 	TPM2_ALG_KEYEDHASH	= 0x0008,
 	TPM2_ALG_SHA256		= 0x000B,
 	TPM2_ALG_SHA384		= 0x000C,
 	TPM2_ALG_SHA512		= 0x000D,
 	TPM2_ALG_NULL		= 0x0010,
 	TPM2_ALG_SM3_256	= 0x0012,
+	TPM2_ALG_ECC		= 0x0023,
+	TPM2_ALG_CFB		= 0x0043,
+};
+
+enum tpm2_curves {
+	TPM2_ECC_NONE		= 0x0000,
+	TPM2_ECC_NIST_P256	= 0x0003,
 };
 
 enum tpm2_command_codes {
 	TPM2_CC_FIRST		= 0x011F,
+	TPM2_CC_CREATE_PRIMARY	= 0x0131,
 	TPM2_CC_SELF_TEST	= 0x0143,
 	TPM2_CC_STARTUP		= 0x0144,
 	TPM2_CC_SHUTDOWN	= 0x0145,
@@ -133,6 +146,7 @@ enum tpm2_command_codes {
 	TPM2_CC_CONTEXT_LOAD	= 0x0161,
 	TPM2_CC_CONTEXT_SAVE	= 0x0162,
 	TPM2_CC_FLUSH_CONTEXT	= 0x0165,
+	TPM2_CC_START_AUTH_SESS	= 0x0176,
 	TPM2_CC_GET_CAPABILITY	= 0x017A,
 	TPM2_CC_GET_RANDOM	= 0x017B,
 	TPM2_CC_PCR_READ	= 0x017E,
@@ -141,6 +155,7 @@ enum tpm2_command_codes {
 };
 
 enum tpm2_permanent_handles {
+	TPM2_RH_NULL		= 0x40000007,
 	TPM2_RS_PW		= 0x40000009,
 };
 
@@ -243,11 +258,18 @@ struct tpm_chip {
 #endif /* CONFIG_ACPI */
 
 	struct tpm_space work_space;
+	struct tpm_space kernel_space;
 	u32 nr_commands;
 	u32 *cc_attrs_tbl;
 
 	/* active locality */
 	int locality;
+
+	/* details for communication security via sessions */
+	u32 tpmkey;
+	u8 tpmkeyname[34];
+	u8 ec_point_x[EC_PT_SZ];
+	u8 ec_point_y[EC_PT_SZ];
 };
 
 #define to_tpm_chip(d) container_of(d, struct tpm_chip, dev)
@@ -428,6 +450,9 @@ u8 tpm_get_inc_u8(const u8 **ptr);
 u16 tpm_get_inc_u16(const u8 **ptr);
 u32 tpm_get_inc_u32(const u8 **ptr);
 
+/* opaque structure, holds auth session parameters like the session key */
+struct tpm2_auth;
+
 extern struct class *tpm_class;
 extern struct class *tpmrm_class;
 extern dev_t tpm_devt;
@@ -547,4 +572,5 @@ static inline int tpm_read_log_efi(struct tpm_chip *chip)
 
 int tpm_bios_log_setup(struct tpm_chip *chip);
 void tpm_bios_log_teardown(struct tpm_chip *chip);
+int tpm2_sessions_init(struct tpm_chip *chip);
 #endif
drivers/char/tpm/tpm2-cmd.c +10 -12
index 13d9e74084aa..2042d4008b9c 100644
@@ -16,17 +16,10 @@
  */
 
 #include "tpm.h"
+#include "tpm2-sessions.h"
 #include <crypto/hash_info.h>
 #include <keys/trusted-type.h>
 
-enum tpm2_object_attributes {
-	TPM2_OA_USER_WITH_AUTH		= BIT(6),
-};
-
-enum tpm2_session_attributes {
-	TPM2_SA_CONTINUE_SESSION	= BIT(0),
-};
-
 struct tpm2_startup_in {
 	__be16	startup_type;
 } __packed;
@@ -435,10 +428,10 @@ void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
  * @hmac: the session HMAC or password, may be NULL if not used
  * @hmac_len: the session HMAC or password length, maybe 0 if not used
  */
-static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle,
-				 const u8 *nonce, u16 nonce_len,
-				 u8 attributes,
-				 const u8 *hmac, u16 hmac_len)
+void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle,
+			  const u8 *nonce, u16 nonce_len,
+			  u8 attributes,
+			  const u8 *hmac, u16 hmac_len)
 {
 	tpm_buf_append_u32(buf, 9 + nonce_len + hmac_len);
 	tpm_buf_append_u32(buf, session_handle);
@@ -1095,6 +1088,11 @@ int tpm2_auto_startup(struct tpm_chip *chip)
 
 	rc = tpm2_get_cc_attrs_tbl(chip);
 
+	if (rc)
+		goto out;
+
+	rc = tpm2_sessions_init(chip);
+
 out:
 	if (rc > 0)
 		rc = -ENODEV;
drivers/char/tpm/tpm2-sessions.c new file +1030 -0

1,030 lines not on this page · raw message

drivers/char/tpm/tpm2-sessions.h new file +56 -0

56 lines not on this page · raw message

Signature · 6 lines
2.12.3

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author maintainer
#3 lore raw

RFC v2 3/5 tpm2: add hmac checks to tpm2_pcr_extend()

In reply to James Bottomley

We use tpm2_pcr_extend() in trusted keys to extend a PCR to prevent a key from being re-loaded until the next reboot. To use this functionality securely, that extend must be protected by a session hmac.

---
 drivers/char/tpm/tpm2-cmd.c | 31 +++++++++++--------------------
 1 file changed, 11 insertions(+), 20 deletions(-)
drivers/char/tpm/tpm2-cmd.c +11 -20
index 2042d4008b9c..a56cdd5d55ff 100644
@@ -247,13 +247,6 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
 	return rc;
 }
 
-struct tpm2_null_auth_area {
-	__be32  handle;
-	__be16  nonce_size;
-	u8  attributes;
-	__be16  auth_size;
-} __packed;
-
 /**
  * tpm2_pcr_extend() - extend a PCR value
  *
@@ -268,7 +261,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
 		    struct tpm2_digest *digests)
 {
 	struct tpm_buf buf;
-	struct tpm2_null_auth_area auth_area;
+	struct tpm2_auth *auth;
 	int rc;
 	int i;
 	int j;
@@ -276,20 +269,17 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
 	if (count > ARRAY_SIZE(chip->active_banks))
 		return -EINVAL;
 
-	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
+	rc = tpm2_start_auth_session(chip, &auth);
 	if (rc)
 		return rc;
 
-	tpm_buf_append_u32(&buf, pcr_idx);
+	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
+	if (rc)
+		return rc;
 
-	auth_area.handle = cpu_to_be32(TPM2_RS_PW);
-	auth_area.nonce_size = 0;
-	auth_area.attributes = 0;
-	auth_area.auth_size = 0;
+	tpm_buf_append_name(&buf, auth, pcr_idx, NULL);
+	tpm_buf_append_hmac_session(&buf, auth, 0, NULL, 0);
 
-	tpm_buf_append_u32(&buf, sizeof(struct tpm2_null_auth_area));
-	tpm_buf_append(&buf, (const unsigned char *)&auth_area,
-		       sizeof(auth_area));
 	tpm_buf_append_u32(&buf, count);
 
 	for (i = 0; i < count; i++) {
@@ -302,9 +292,10 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
 			       hash_digest_size[tpm2_hash_map[j].crypto_id]);
 		}
 	}
-
-	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0,
-			      "attempting extend a PCR value");
+	tpm_buf_fill_hmac_session(&buf, auth);
+	rc = tpm_transmit_cmd(chip, &chip->kernel_space, buf.data, PAGE_SIZE,
+			      0, 0, "attempting extend a PCR value");
+	rc = tpm_buf_check_hmac_response(&buf, auth, rc);
 
 	tpm_buf_destroy(&buf);
 
Signature · 5 lines
2.12.3
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
author maintainer
#4 lore raw

RFC v2 4/5 tpm2: add session encryption protection to tpm2_get_random()

In reply to James Bottomley

If some entity is snooping the TPM bus, they can see the random numbers we're extracting from the TPM and do prediction attacks against their consumers. Foil this attack by using response encryption to prevent the attacker from seeing the random sequence.

---
 drivers/char/tpm/tpm2-cmd.c | 76 +++++++++++++++++++++------------------------
 1 file changed, 35 insertions(+), 41 deletions(-)
drivers/char/tpm/tpm2-cmd.c +35 -41
index a56cdd5d55ff..ad2a7e72bacf 100644
@@ -38,10 +38,6 @@ struct tpm2_get_tpm_pt_out {
 	__be32	value;
 } __packed;
 
-struct tpm2_get_random_in {
-	__be16	size;
-} __packed;
-
 struct tpm2_get_random_out {
 	__be16	size;
 	u8	buffer[TPM_MAX_RNG_DATA];
@@ -51,8 +47,6 @@ union tpm2_cmd_params {
 	struct	tpm2_startup_in		startup_in;
 	struct	tpm2_get_tpm_pt_in	get_tpm_pt_in;
 	struct	tpm2_get_tpm_pt_out	get_tpm_pt_out;
-	struct	tpm2_get_random_in	getrandom_in;
-	struct	tpm2_get_random_out	getrandom_out;
 };
 
 struct tpm2_cmd {
@@ -302,17 +296,6 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
 	return rc;
 }
 
-
-#define TPM2_GETRANDOM_IN_SIZE \
-	(sizeof(struct tpm_input_header) + \
-	 sizeof(struct tpm2_get_random_in))
-
-static const struct tpm_input_header tpm2_getrandom_header = {
-	.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
-	.length = cpu_to_be32(TPM2_GETRANDOM_IN_SIZE),
-	.ordinal = cpu_to_be32(TPM2_CC_GET_RANDOM)
-};
-
 /**
  * tpm2_get_random() - get random bytes from the TPM RNG
  *
@@ -325,42 +308,53 @@ static const struct tpm_input_header tpm2_getrandom_header = {
  */
 int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max)
 {
-	struct tpm2_cmd cmd;
-	u32 recd, rlength;
+	u32 recd;
 	u32 num_bytes;
 	int err;
 	int total = 0;
 	int retries = 5;
 	u8 *dest = out;
+	struct tpm_buf buf;
+	struct tpm2_get_random_out *rout;
+	struct tpm2_auth *auth;
 
-	num_bytes = min_t(u32, max, sizeof(cmd.params.getrandom_out.buffer));
+	num_bytes = min_t(u32, max, TPM_MAX_RNG_DATA);
 
-	if (!out || !num_bytes ||
-	    max > sizeof(cmd.params.getrandom_out.buffer))
+	if (!out || !num_bytes
+	    || max > TPM_MAX_RNG_DATA)
 		return -EINVAL;
 
 	do {
-		cmd.header.in = tpm2_getrandom_header;
-		cmd.params.getrandom_in.size = cpu_to_be16(num_bytes);
-
-		err = tpm_transmit_cmd(chip, NULL, &cmd, sizeof(cmd),
-				       offsetof(struct tpm2_get_random_out,
-						buffer),
-				       0, "attempting get random");
+		err = tpm2_start_auth_session(chip, &auth);
 		if (err)
 			break;
-
-		recd = min_t(u32, be16_to_cpu(cmd.params.getrandom_out.size),
-			     num_bytes);
-		rlength = be32_to_cpu(cmd.header.out.length);
-		if (rlength < offsetof(struct tpm2_get_random_out, buffer) +
-			      recd)
-			return -EFAULT;
-		memcpy(dest, cmd.params.getrandom_out.buffer, recd);
-
-		dest += recd;
-		total += recd;
-		num_bytes -= recd;
+		tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_GET_RANDOM);
+		tpm_buf_append_hmac_session(&buf, auth, TPM2_SA_ENCRYPT,
+					    NULL, 0);
+		tpm_buf_append_u16(&buf, num_bytes);
+		tpm_buf_fill_hmac_session(&buf, auth);
+		err = tpm_transmit_cmd(chip, &chip->kernel_space, buf.data,
+				       PAGE_SIZE, TPM_HEADER_SIZE + 2,
+				       0, "attempting get random");
+		err = tpm_buf_check_hmac_response(&buf, auth, err);
+		if (!err) {
+			rout = (struct tpm2_get_random_out *)&buf.data[TPM_HEADER_SIZE + 4];
+			recd = be16_to_cpu(rout->size);
+			recd = min_t(u32, recd, num_bytes);
+			if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 4
+			    + 2 + recd) {
+				total = -EFAULT;
+			} else {
+				memcpy(dest, rout->buffer, recd);
+
+				dest += recd;
+				total += recd;
+				num_bytes -= recd;
+			}
+		}
+		tpm_buf_destroy(&buf);
+		if (err || total < 0)
+			break;
 	} while (retries-- && total < max);
 
 	return total ? total : -EIO;
Signature · 5 lines
2.12.3
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info@ http://vger.kernel.org/majordomo-info.html
author maintainer
#5 lore raw

RFC v2 5/5 tpm2-sessions: NOT FOR COMMITTING add sessions testing

In reply to James Bottomley
Quoted 1 line

From f69d2ec1bdddefa87c7130699c797cd5e24fcaf2 Mon Sep 17 00:00:00 2001

This runs through a preset sequence using sessions to demonstrate that the session handling code functions. It does both HMAC, encryption and decryption by testing an encrypted sealing operation with authority and proving that the same sealed data comes back again via an HMAC and response encryption.

---
 drivers/char/tpm/Makefile             |   1 +
 drivers/char/tpm/tpm-chip.c           |   1 +
 drivers/char/tpm/tpm2-sessions-test.c | 177 ++++++++++++++++++++++++++++++++++
 3 files changed, 179 insertions(+)
 create mode 100644 drivers/char/tpm/tpm2-sessions-test.c
drivers/char/tpm/Makefile +1 -0
index b83737ccaa81..1ac7a4046630 100644
@@ -6,6 +6,7 @@ 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 tpmrm-dev.o tpm1_eventlog.o tpm2_eventlog.o \
          tpm2-space.o tpm-buf.o tpm2-sessions.o
+obj-m +=  tpm2-sessions-test.o
 tpm-$(CONFIG_ACPI) += tpm_ppi.o tpm_eventlog_acpi.o
 tpm-$(CONFIG_EFI) += tpm_eventlog_efi.o
 tpm-$(CONFIG_OF) += tpm_eventlog_of.o
drivers/char/tpm/tpm-chip.c +1 -0
index 0a62c19937b6..ca174ee1e670 100644
@@ -118,6 +118,7 @@ struct tpm_chip *tpm_chip_find_get(struct tpm_chip *chip)
 
 	return res;
 }
+EXPORT_SYMBOL(tpm_chip_find_get);
 
 /**
  * tpm_dev_release() - free chip memory and the device number
drivers/char/tpm/tpm2-sessions-test.c new file +177 -0

177 lines not on this page · raw message

Signature · 5 lines
2.12.3
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#6 lore raw
In reply to James Bottomley
Quoted 19 lines · James Bottomley

By now, everybody knows we have a problem with the TPM2_RS_PW easy button on TPM2 in that transactions on the TPM bus can be intercepted and altered. The way to fix this is to use real sessions for HMAC capabilities to ensure integrity and to use parameter and response encryption to ensure confidentiality of the data flowing over the TPM bus.

This RFC is about adding a simple API which can ensure the above properties as a layered addition to the existing TPM handling code.
Eventually we can add this to the random number generator, the PCR
extensions and the trusted key handling, but this all depends on the conversion to tpm_buf which is not yet upstream, so I've constructed a second patch which demonstrates the new API in a test module for those who wish to play with it.

This series is also dependent on additions to the crypto subsystem to fix problems in the elliptic curve key handling and add the Cipher FeedBack encryption scheme:

Quoted 7 lines

https://marc.info/?l=linux-crypto-vger&m=151994371015475

In the second version, I added security HMAC to our PCR extend and encryption to the returned random number generators and also extracted the parsing and tpm2b construction API into a new file.

James

Might take up until end of next week before I have time to try this out. Anyway, I'll see if I get this running on my systems before at the code that much.

/Jarkko
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

author maintainer
#7 lore raw
Quoted 34 lines · Jarkko Sakkinen
Quoted 33 lines · James Bottomley

By now, everybody knows we have a problem with the TPM2_RS_PW easy button on TPM2 in that transactions on the TPM bus can be intercepted
and altered.??The way to fix this is to use real sessions for HMAC capabilities to ensure integrity and to use parameter and response encryption to ensure confidentiality of the data flowing over the TPM
bus.

This RFC is about adding a simple API which can ensure the above properties as a layered addition to the existing TPM handling code. ?Eventually we can add this to the random number generator, the PCR extensions and the trusted key handling, but this all depends on the
conversion to tpm_buf which is not yet upstream, so I've constructed a
second patch which demonstrates the new API in a test module for those
who wish to play with it.

This series is also dependent on additions to the crypto subsystem to
fix problems in the elliptic curve key handling and add the Cipher FeedBack encryption scheme:

https://marc.info/?l=linux-crypto-vger&m=151994371015475

In the second version, I added security HMAC to our PCR extend and encryption to the returned random number generators and also extracted
the parsing and tpm2b construction API into a new file.

Quoted 5 lines
Quoted 1 line

James

Might take up until end of next week before I have time to try this out.Anyway, I'll see if I get this running on my systems before at the code that much.

OK, you might want to wait for v3 then. ?I've got it working with sealed (trusted) keys, well except for a problem with the trusted keys API that means we can't protect the password for policy based keys. ?I think the API is finally complete, so I'll send v3 as a PATCH not an RFC.

The point of the last patch is to show the test rig for this I'm running in a VM using an instrumented tpm2 emulator to prove we're getting all the correct data in and out (and that the encryption and hmac are working); more physical TPM testing would be useful ..

Thanks,

James

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html

#8 lore raw
Quoted 10 lines · James Bottomley

OK, you might want to wait for v3 then. I've got it working with sealed (trusted) keys, well except for a problem with the trusted keys API that means we can't protect the password for policy based keys. I think the API is finally complete, so I'll send v3 as a PATCH not an RFC.

The point of the last patch is to show the test rig for this I'm running in a VM using an instrumented tpm2 emulator to prove we're getting all the correct data in and out (and that the encryption and hmac are working); more physical TPM testing would be useful ..

Sorry, I did not notice this email in my inbox before I responded to you v3 cover letter :-) Thank you.

/Jarkko
--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html