linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] tpm: enhance TPM 2.0 extend function to support multiple PCR banks
@ 2017-01-12 16:58 Nayna Jain
  2017-01-12 16:58 ` [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active " Nayna Jain
  2017-01-12 16:58 ` [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks Nayna Jain
  0 siblings, 2 replies; 12+ messages in thread
From: Nayna Jain @ 2017-01-12 16:58 UTC (permalink / raw)
  To: tpmdd-devel
  Cc: peterhuewe, tpmdd, jarkko.sakkinen, jgunthorpe,
	linux-security-module, linux-kernel, Nayna Jain

IMA extends its hash measurements in the TPM PCRs, based on policy.
The existing in-kernel TPM extend function extends only the SHA1
PCR bank. TPM 2.0 defines multiple PCR banks, to support different
hash algorithms. The TCG TPM 2.0 Specification[1] recommends
extending all active PCR banks to prevent malicious users from
setting unused PCR banks with fake measurements and quoting them.
This patch set adds support for extending all active PCR banks,
as recommended.

The first patch implements the TPM 2.0 capability to retrieve
the list of active PCR banks.

The second patch modifies the tpm_pcr_extend() and tpm2_pcr_extend()
interface to support extending multiple PCR banks. The existing
tpm_pcr_extend() interface expects only a SHA1 digest. Hence, to
extend all active PCR banks with differing digest sizes for TPM 2.0,
the SHA1 digest is padded with 0's as needed.

This approach is taken to maintain backwards compatibility for IMA
in order to continue working with both TPM 1.2 and TPM 2.0 without
any changes and still comply with TCG TPM 2.0 Specification[1].

[1] TPM 2.0 Specification referred here is "TCG PC Client Specific
Platform Firmware Profile for TPM 2.0"

Changelog v3:
- Rebased to the Jarkko's latest master branch (8e25809 tpm:
  Do not print an error message when doing TPM auto startup)
- Patch "tpm: implement TPM 2.0 capability to get active PCR banks"
  - Included Jarkko's feedbacks
     - Removed getcap_in, getcap_out and used tpm_buf for getting
     capability.
     - Used ARRAY_SIZE in place of TPM_MAX_PCR_BANKS and included
     other feedbacks.
- Patch "tpm: enhance TPM 2.0 PCR extend to support multiple banks"
     - Fixed kbuild errors
       - Fixed buf.data uninitialized warning.
       - Added TCG_TPM dependency on CONFIG_CRYPTO_HASH_INFO in Kconfig.

Changelog v2:

- Patch "tpm: implement TPM 2.0 capability to get active PCR banks"
  - defined structs definition in tpm2-cmd.c.
  - no_of_active_banks field is removed. Instead, constant
  TPM2_MAX_PCR_BANKS is defined.
  - renamed tpm2_get_active_pcr_banks() to tpm2_get_pcr_allocation()
  - removed generic function tpm2_get_capability().

- Patch "tpm: enchance TPM 2.0 PCR extend to support multiple banks"
 - Removed tpm2.h, and defined structs common for extend and event log
  in tpm_eventlog.h
 - uses tpm_buf in tpm2_pcr_extend().

Nayna Jain (2):
  tpm: implement TPM 2.0 capability to get active PCR banks
  tpm: enhance TPM 2.0 PCR extend to support multiple banks

 drivers/char/tpm/Kconfig         |   1 +
 drivers/char/tpm/tpm-interface.c |  16 ++++-
 drivers/char/tpm/tpm.h           |   7 ++-
 drivers/char/tpm/tpm2-cmd.c      | 127 ++++++++++++++++++++++++++++++---------
 drivers/char/tpm/tpm_eventlog.h  |  18 ++++++
 5 files changed, 138 insertions(+), 31 deletions(-)

-- 
2.5.0

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active PCR banks
  2017-01-12 16:58 [PATCH v3 0/2] tpm: enhance TPM 2.0 extend function to support multiple PCR banks Nayna Jain
@ 2017-01-12 16:58 ` Nayna Jain
  2017-01-12 18:25   ` Jarkko Sakkinen
  2017-01-12 16:58 ` [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks Nayna Jain
  1 sibling, 1 reply; 12+ messages in thread
From: Nayna Jain @ 2017-01-12 16:58 UTC (permalink / raw)
  To: tpmdd-devel
  Cc: peterhuewe, tpmdd, jarkko.sakkinen, jgunthorpe,
	linux-security-module, linux-kernel, Nayna Jain

This patch implements the TPM 2.0 capability TPM_CAP_PCRS to
retrieve the active PCR banks from the TPM. This is needed
to enable extending all active banks as recommended by TPM 2.0
TCG Specification.

Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
---
 drivers/char/tpm/tpm.h      |  4 +++
 drivers/char/tpm/tpm2-cmd.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 1ae9768..dddd573 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -127,6 +127,7 @@ enum tpm2_permanent_handles {
 };
 
 enum tpm2_capabilities {
+	TPM2_CAP_PCRS		= 5,
 	TPM2_CAP_TPM_PROPERTIES = 6,
 };
 
@@ -187,6 +188,8 @@ struct tpm_chip {
 
 	const struct attribute_group *groups[3];
 	unsigned int groups_cnt;
+
+	u16 active_banks[7];
 #ifdef CONFIG_ACPI
 	acpi_handle acpi_dev_handle;
 	char ppi_version[TPM_PPI_VERSION_LEN + 1];
@@ -545,4 +548,5 @@ int tpm2_auto_startup(struct tpm_chip *chip);
 void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
 unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
 int tpm2_probe(struct tpm_chip *chip);
+ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
 #endif
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 6eda239..87388921 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -83,6 +83,12 @@ struct tpm2_get_tpm_pt_out {
 	__be32	value;
 } __packed;
 
+struct tpm2_tpms_pcr_selection {
+	__be16  hash_alg;
+	u8  size_of_select;
+	u8  pcr_select[3];
+} __packed;
+
 struct tpm2_get_random_in {
 	__be16	size;
 } __packed;
@@ -993,8 +999,61 @@ int tpm2_auto_startup(struct tpm_chip *chip)
 		}
 	}
 
+	rc = tpm2_get_pcr_allocation(chip);
+
 out:
 	if (rc > 0)
 		rc = -ENODEV;
 	return rc;
 }
+
+/**
+ * tpm2_get_pcr_allocation() - get TPM active PCR banks.
+ *
+ * @chip: TPM chip to use.
+ *
+ * Return: Same as with tpm_transmit_cmd.
+ */
+ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
+{
+	struct tpm2_tpms_pcr_selection pcr_selection;
+	struct tpm_buf buf;
+	void *marker;
+	unsigned int count = 0;
+	int rc;
+	int i;
+
+	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
+	if (rc)
+		return rc;
+
+	tpm_buf_append_u32(&buf, TPM2_CAP_PCRS);
+	tpm_buf_append_u32(&buf, 0);
+	tpm_buf_append_u32(&buf, 1);
+
+	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0,
+			      "get tpm pcr allocation");
+	if (rc < 0)
+		goto out;
+
+	count = be32_to_cpup(
+		(__be32 *) &buf.data[TPM_HEADER_SIZE + 5]);
+
+	if (count > ARRAY_SIZE(chip->active_banks))
+		return -ENODEV;
+
+	marker = &buf.data[TPM_HEADER_SIZE + 9];
+	for (i = 0; i < count; i++) {
+		memcpy(&pcr_selection, marker, sizeof(pcr_selection));
+		chip->active_banks[i] = be16_to_cpu(pcr_selection.hash_alg);
+		marker = marker + sizeof(struct tpm2_tpms_pcr_selection);
+	}
+
+out:
+	if (count < ARRAY_SIZE(chip->active_banks))
+		chip->active_banks[count] = 0;
+
+	tpm_buf_destroy(&buf);
+
+	return rc;
+}
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks
  2017-01-12 16:58 [PATCH v3 0/2] tpm: enhance TPM 2.0 extend function to support multiple PCR banks Nayna Jain
  2017-01-12 16:58 ` [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active " Nayna Jain
@ 2017-01-12 16:58 ` Nayna Jain
  2017-01-12 18:20   ` Jarkko Sakkinen
  1 sibling, 1 reply; 12+ messages in thread
From: Nayna Jain @ 2017-01-12 16:58 UTC (permalink / raw)
  To: tpmdd-devel
  Cc: peterhuewe, tpmdd, jarkko.sakkinen, jgunthorpe,
	linux-security-module, linux-kernel, Nayna Jain

The current TPM 2.0 device driver extends only the SHA1 PCR bank
but the TCG Specification[1] recommends extending all active PCR
banks, to prevent malicious users from setting unused PCR banks with
fake measurements and quoting them.

The existing in-kernel interface(tpm_pcr_extend()) expects only a
SHA1 digest.  To extend all active PCR banks with differing
digest sizes, the SHA1 digest is padded with trailing 0's as needed.

[1] TPM 2.0 Specification referred here is "TCG PC Client Specific
Platform Firmware Profile for TPM 2.0"

Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
---
 drivers/char/tpm/Kconfig         |  1 +
 drivers/char/tpm/tpm-interface.c | 16 +++++++++-
 drivers/char/tpm/tpm.h           |  3 +-
 drivers/char/tpm/tpm2-cmd.c      | 68 +++++++++++++++++++++++-----------------
 drivers/char/tpm/tpm_eventlog.h  | 18 +++++++++++
 5 files changed, 75 insertions(+), 31 deletions(-)

diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
index 277186d..af985cc 100644
--- a/drivers/char/tpm/Kconfig
+++ b/drivers/char/tpm/Kconfig
@@ -6,6 +6,7 @@ menuconfig TCG_TPM
 	tristate "TPM Hardware Support"
 	depends on HAS_IOMEM
 	select SECURITYFS
+	select CRYPTO_HASH_INFO
 	---help---
 	  If you have a TPM security chip in your system, which
 	  implements the Trusted Computing Group's specification,
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index fecdd3f..e037dd2 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -7,6 +7,7 @@
  * Dave Safford <safford@watson.ibm.com>
  * Reiner Sailer <sailer@watson.ibm.com>
  * Kylene Hall <kjhall@us.ibm.com>
+ * Nayna Jain <nayna@linux.vnet.ibm.com>
  *
  * Maintained by: <tpmdd-devel@lists.sourceforge.net>
  *
@@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = {
 int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
 {
 	struct tpm_cmd_t cmd;
+	int i;
 	int rc;
 	struct tpm_chip *chip;
 
@@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
 		return -ENODEV;
 
 	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
-		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
+		struct tpml_digest_values d_values;
+
+		memset(&d_values, 0, sizeof(d_values));
+
+		for (i = 0; (chip->active_banks[i] != 0) &&
+		     (i < ARRAY_SIZE(chip->active_banks)); i++) {
+			d_values.digests[i].alg_id = chip->active_banks[i];
+			memcpy(d_values.digests[i].digest, hash,
+			       TPM_DIGEST_SIZE);
+			d_values.count++;
+		}
+
+		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
 		tpm_put_ops(chip);
 		return rc;
 	}
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index dddd573..dd82d58 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
 #endif
 
 int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
-int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
+int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
+		    struct tpml_digest_values *digests);
 int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
 int tpm2_seal_trusted(struct tpm_chip *chip,
 		      struct trusted_key_payload *payload,
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index 87388921..5027a54 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in {
 	__be32				pcr_idx;
 	__be32				auth_area_size;
 	struct tpm2_null_auth_area	auth_area;
-	__be32				digest_cnt;
-	__be16				hash_alg;
-	u8				digest[TPM_DIGEST_SIZE];
+	struct tpml_digest_values       digests;
 } __packed;
 
 struct tpm2_get_tpm_pt_in {
@@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
 	return rc;
 }
 
-#define TPM2_GET_PCREXTEND_IN_SIZE \
-	(sizeof(struct tpm_input_header) + \
-	 sizeof(struct tpm2_pcr_extend_in))
-
-static const struct tpm_input_header tpm2_pcrextend_header = {
-	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
-	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
-	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
-};
-
 /**
  * tpm2_pcr_extend() - extend a PCR value
  *
  * @chip:	TPM chip to use.
  * @pcr_idx:	index of the PCR.
- * @hash:	hash value to use for the extend operation.
+ * @digests:	list of pcr banks and corresponding hash values to be extended.
  *
  * Return: Same as with tpm_transmit_cmd.
  */
-int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
+int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
+		    struct tpml_digest_values *digests)
 {
-	struct tpm2_cmd cmd;
+	struct tpm_buf buf;
+	struct tpm2_null_auth_area auth_area;
 	int rc;
+	int i;
+	int j;
 
-	cmd.header.in = tpm2_pcrextend_header;
-	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
-	cmd.params.pcrextend_in.auth_area_size =
-		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
-	cmd.params.pcrextend_in.auth_area.handle =
-		cpu_to_be32(TPM2_RS_PW);
-	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
-	cmd.params.pcrextend_in.auth_area.attributes = 0;
-	cmd.params.pcrextend_in.auth_area.auth_size = 0;
-	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
-	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
-	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
+	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
+	if (rc)
+		return rc;
 
-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+	tpm_buf_append_u32(&buf, pcr_idx);
+
+	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_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, digests->count);
+
+	for (i = 0; i < digests->count; i++) {
+		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
+			if (digests->digests[i].alg_id !=
+			    tpm2_hash_map[j].tpm_id)
+				continue;
+
+			tpm_buf_append_u16(&buf, digests->digests[i].alg_id);
+			tpm_buf_append(&buf, (const unsigned char
+					      *)&digests->digests[i].digest,
+				hash_digest_size[tpm2_hash_map[j].crypto_id]);
+		}
+	}
+
+	rc = tpm_transmit_cmd(chip, buf.data, tpm_buf_length(&buf), 0,
 			      "attempting extend a PCR value");
 
+	tpm_buf_destroy(&buf);
+
 	return rc;
 }
 
diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
index 1660d74..2e47f4d 100644
--- a/drivers/char/tpm/tpm_eventlog.h
+++ b/drivers/char/tpm/tpm_eventlog.h
@@ -2,9 +2,12 @@
 #ifndef __TPM_EVENTLOG_H__
 #define __TPM_EVENTLOG_H__
 
+#include <crypto/hash_info.h>
+
 #define TCG_EVENT_NAME_LEN_MAX	255
 #define MAX_TEXT_EVENT		1000	/* Max event string length */
 #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
+#define TPM2_ACTIVE_PCR_BANKS	3
 
 #ifdef CONFIG_PPC64
 #define do_endian_conversion(x) be32_to_cpu(x)
@@ -73,6 +76,21 @@ enum tcpa_pc_event_ids {
 	HOST_TABLE_OF_DEVICES,
 };
 
+/**
+ * Digest structures for TPM 2.0 as defined in document
+ * Trusted Platform Module Library Part 2: Structures, Family "2.0".
+ */
+
+struct tpmt_ha {
+	u16 alg_id;
+	u8 digest[SHA384_DIGEST_SIZE];
+} __packed;
+
+struct tpml_digest_values {
+	u32 count;
+	struct tpmt_ha digests[TPM2_ACTIVE_PCR_BANKS];
+} __packed;
+
 #if defined(CONFIG_ACPI)
 int tpm_read_log_acpi(struct tpm_chip *chip);
 #else
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks
  2017-01-12 16:58 ` [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks Nayna Jain
@ 2017-01-12 18:20   ` Jarkko Sakkinen
  2017-01-13  7:14     ` Nayna
  2017-01-17  7:53     ` Nayna
  0 siblings, 2 replies; 12+ messages in thread
From: Jarkko Sakkinen @ 2017-01-12 18:20 UTC (permalink / raw)
  To: Nayna Jain
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel

On Thu, Jan 12, 2017 at 11:58:10AM -0500, Nayna Jain wrote:
> The current TPM 2.0 device driver extends only the SHA1 PCR bank
> but the TCG Specification[1] recommends extending all active PCR
> banks, to prevent malicious users from setting unused PCR banks with
> fake measurements and quoting them.
> 
> The existing in-kernel interface(tpm_pcr_extend()) expects only a
> SHA1 digest.  To extend all active PCR banks with differing
> digest sizes, the SHA1 digest is padded with trailing 0's as needed.
> 
> [1] TPM 2.0 Specification referred here is "TCG PC Client Specific
> Platform Firmware Profile for TPM 2.0"
> 
> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
> ---
>  drivers/char/tpm/Kconfig         |  1 +
>  drivers/char/tpm/tpm-interface.c | 16 +++++++++-
>  drivers/char/tpm/tpm.h           |  3 +-
>  drivers/char/tpm/tpm2-cmd.c      | 68 +++++++++++++++++++++++-----------------
>  drivers/char/tpm/tpm_eventlog.h  | 18 +++++++++++
>  5 files changed, 75 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> index 277186d..af985cc 100644
> --- a/drivers/char/tpm/Kconfig
> +++ b/drivers/char/tpm/Kconfig
> @@ -6,6 +6,7 @@ menuconfig TCG_TPM
>  	tristate "TPM Hardware Support"
>  	depends on HAS_IOMEM
>  	select SECURITYFS
> +	select CRYPTO_HASH_INFO

In the commit message you did not mention this.

>  	---help---
>  	  If you have a TPM security chip in your system, which
>  	  implements the Trusted Computing Group's specification,
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index fecdd3f..e037dd2 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -7,6 +7,7 @@
>   * Dave Safford <safford@watson.ibm.com>
>   * Reiner Sailer <sailer@watson.ibm.com>
>   * Kylene Hall <kjhall@us.ibm.com>
> + * Nayna Jain <nayna@linux.vnet.ibm.com>

Remove.

>   *
>   * Maintained by: <tpmdd-devel@lists.sourceforge.net>
>   *
> @@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = {
>  int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>  {
>  	struct tpm_cmd_t cmd;
> +	int i;
>  	int rc;
>  	struct tpm_chip *chip;
>  
> @@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>  		return -ENODEV;
>  
>  	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> -		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
> +		struct tpml_digest_values d_values;
> +
> +		memset(&d_values, 0, sizeof(d_values));
> +
> +		for (i = 0; (chip->active_banks[i] != 0) &&
> +		     (i < ARRAY_SIZE(chip->active_banks)); i++) {
> +			d_values.digests[i].alg_id = chip->active_banks[i];
> +			memcpy(d_values.digests[i].digest, hash,
> +			       TPM_DIGEST_SIZE);
> +			d_values.count++;
> +		}
> +
> +		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
>  		tpm_put_ops(chip);
>  		return rc;
>  	}
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index dddd573..dd82d58 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
>  #endif
>  
>  int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> +		    struct tpml_digest_values *digests);
>  int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
>  int tpm2_seal_trusted(struct tpm_chip *chip,
>  		      struct trusted_key_payload *payload,
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index 87388921..5027a54 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in {
>  	__be32				pcr_idx;
>  	__be32				auth_area_size;
>  	struct tpm2_null_auth_area	auth_area;
> -	__be32				digest_cnt;
> -	__be16				hash_alg;
> -	u8				digest[TPM_DIGEST_SIZE];
> +	struct tpml_digest_values       digests;
>  } __packed;
>  
>  struct tpm2_get_tpm_pt_in {
> @@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
>  	return rc;
>  }
>  
> -#define TPM2_GET_PCREXTEND_IN_SIZE \
> -	(sizeof(struct tpm_input_header) + \
> -	 sizeof(struct tpm2_pcr_extend_in))
> -
> -static const struct tpm_input_header tpm2_pcrextend_header = {
> -	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
> -	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
> -	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
> -};
> -
>  /**
>   * tpm2_pcr_extend() - extend a PCR value
>   *
>   * @chip:	TPM chip to use.
>   * @pcr_idx:	index of the PCR.
> - * @hash:	hash value to use for the extend operation.
> + * @digests:	list of pcr banks and corresponding hash values to be extended.
>   *
>   * Return: Same as with tpm_transmit_cmd.
>   */
> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> +		    struct tpml_digest_values *digests)
>  {
> -	struct tpm2_cmd cmd;
> +	struct tpm_buf buf;
> +	struct tpm2_null_auth_area auth_area;
>  	int rc;
> +	int i;
> +	int j;
>  
> -	cmd.header.in = tpm2_pcrextend_header;
> -	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
> -	cmd.params.pcrextend_in.auth_area_size =
> -		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
> -	cmd.params.pcrextend_in.auth_area.handle =
> -		cpu_to_be32(TPM2_RS_PW);
> -	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
> -	cmd.params.pcrextend_in.auth_area.attributes = 0;
> -	cmd.params.pcrextend_in.auth_area.auth_size = 0;
> -	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
> -	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
> -	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
> +	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
> +	if (rc)
> +		return rc;
>  
> -	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
> +	tpm_buf_append_u32(&buf, pcr_idx);
> +
> +	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_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, digests->count);
> +
> +	for (i = 0; i < digests->count; i++) {
> +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
> +			if (digests->digests[i].alg_id !=
> +			    tpm2_hash_map[j].tpm_id)
> +				continue;
> +
> +			tpm_buf_append_u16(&buf, digests->digests[i].alg_id);
> +			tpm_buf_append(&buf, (const unsigned char
> +					      *)&digests->digests[i].digest,
> +				hash_digest_size[tpm2_hash_map[j].crypto_id]);
> +		}
> +	}
> +
> +	rc = tpm_transmit_cmd(chip, buf.data, tpm_buf_length(&buf), 0,
>  			      "attempting extend a PCR value");
>  
> +	tpm_buf_destroy(&buf);
> +
>  	return rc;
>  }
>  
> diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
> index 1660d74..2e47f4d 100644
> --- a/drivers/char/tpm/tpm_eventlog.h
> +++ b/drivers/char/tpm/tpm_eventlog.h
> @@ -2,9 +2,12 @@
>  #ifndef __TPM_EVENTLOG_H__
>  #define __TPM_EVENTLOG_H__
>  
> +#include <crypto/hash_info.h>
> +
>  #define TCG_EVENT_NAME_LEN_MAX	255
>  #define MAX_TEXT_EVENT		1000	/* Max event string length */
>  #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
> +#define TPM2_ACTIVE_PCR_BANKS	3
>  
>  #ifdef CONFIG_PPC64
>  #define do_endian_conversion(x) be32_to_cpu(x)
> @@ -73,6 +76,21 @@ enum tcpa_pc_event_ids {
>  	HOST_TABLE_OF_DEVICES,
>  };
>  
> +/**
> + * Digest structures for TPM 2.0 as defined in document
> + * Trusted Platform Module Library Part 2: Structures, Family "2.0".
> + */

Please remove this comment

> +
> +struct tpmt_ha {
> +	u16 alg_id;
> +	u8 digest[SHA384_DIGEST_SIZE];
> +} __packed;

struct tpm2_hash

> +struct tpml_digest_values {
> +	u32 count;
> +	struct tpmt_ha digests[TPM2_ACTIVE_PCR_BANKS];
> +} __packed;

Please remove this structure.

> +
>  #if defined(CONFIG_ACPI)
>  int tpm_read_log_acpi(struct tpm_chip *chip);
>  #else
> -- 
> 2.5.0
> 

/Jarkko

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active PCR banks
  2017-01-12 16:58 ` [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active " Nayna Jain
@ 2017-01-12 18:25   ` Jarkko Sakkinen
  2017-01-13  7:24     ` Nayna
  0 siblings, 1 reply; 12+ messages in thread
From: Jarkko Sakkinen @ 2017-01-12 18:25 UTC (permalink / raw)
  To: Nayna Jain
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel

On Thu, Jan 12, 2017 at 11:58:09AM -0500, Nayna Jain wrote:
> This patch implements the TPM 2.0 capability TPM_CAP_PCRS to
> retrieve the active PCR banks from the TPM. This is needed
> to enable extending all active banks as recommended by TPM 2.0
> TCG Specification.
> 
> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
> ---
>  drivers/char/tpm/tpm.h      |  4 +++
>  drivers/char/tpm/tpm2-cmd.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 63 insertions(+)
> 
> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> index 1ae9768..dddd573 100644
> --- a/drivers/char/tpm/tpm.h
> +++ b/drivers/char/tpm/tpm.h
> @@ -127,6 +127,7 @@ enum tpm2_permanent_handles {
>  };
>  
>  enum tpm2_capabilities {
> +	TPM2_CAP_PCRS		= 5,
>  	TPM2_CAP_TPM_PROPERTIES = 6,
>  };
>  
> @@ -187,6 +188,8 @@ struct tpm_chip {
>  
>  	const struct attribute_group *groups[3];
>  	unsigned int groups_cnt;
> +
> +	u16 active_banks[7];
>  #ifdef CONFIG_ACPI
>  	acpi_handle acpi_dev_handle;
>  	char ppi_version[TPM_PPI_VERSION_LEN + 1];
> @@ -545,4 +548,5 @@ int tpm2_auto_startup(struct tpm_chip *chip);
>  void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
>  unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
>  int tpm2_probe(struct tpm_chip *chip);
> +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
>  #endif
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index 6eda239..87388921 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -83,6 +83,12 @@ struct tpm2_get_tpm_pt_out {
>  	__be32	value;
>  } __packed;
>  
> +struct tpm2_tpms_pcr_selection {
> +	__be16  hash_alg;
> +	u8  size_of_select;
> +	u8  pcr_select[3];
> +} __packed;

Please move this right before tpm2_get_pcr_allocation.
Drop 'tpms_'.

> +
>  struct tpm2_get_random_in {
>  	__be16	size;
>  } __packed;
> @@ -993,8 +999,61 @@ int tpm2_auto_startup(struct tpm_chip *chip)
>  		}
>  	}
>  
> +	rc = tpm2_get_pcr_allocation(chip);
> +

Please have this call in the commit where you actually use it
Does not make any sense here

>  out:
>  	if (rc > 0)
>  		rc = -ENODEV;
>  	return rc;
>  }
> +
> +/**
> + * tpm2_get_pcr_allocation() - get TPM active PCR banks.
> + *
> + * @chip: TPM chip to use.
> + *
> + * Return: Same as with tpm_transmit_cmd.
> + */
> +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
> +{
> +	struct tpm2_tpms_pcr_selection pcr_selection;
> +	struct tpm_buf buf;
> +	void *marker;
> +	unsigned int count = 0;
> +	int rc;
> +	int i;
> +
> +	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
> +	if (rc)
> +		return rc;
> +
> +	tpm_buf_append_u32(&buf, TPM2_CAP_PCRS);
> +	tpm_buf_append_u32(&buf, 0);
> +	tpm_buf_append_u32(&buf, 1);
> +
> +	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0,
> +			      "get tpm pcr allocation");
> +	if (rc < 0)
> +		goto out;
> +
> +	count = be32_to_cpup(
> +		(__be32 *) &buf.data[TPM_HEADER_SIZE + 5]);

Please do not add a space after cast. This has been an issue in your
previous patches too so try to do it right next time.

> +
> +	if (count > ARRAY_SIZE(chip->active_banks))
> +		return -ENODEV;
> +
> +	marker = &buf.data[TPM_HEADER_SIZE + 9];
> +	for (i = 0; i < count; i++) {
> +		memcpy(&pcr_selection, marker, sizeof(pcr_selection));
> +		chip->active_banks[i] = be16_to_cpu(pcr_selection.hash_alg);
> +		marker = marker + sizeof(struct tpm2_tpms_pcr_selection);
> +	}
> +
> +out:
> +	if (count < ARRAY_SIZE(chip->active_banks))
> +		chip->active_banks[count] = 0;
> +
> +	tpm_buf_destroy(&buf);
> +
> +	return rc;
> +}
> -- 
> 2.5.0
> 

/Jarkko

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks
  2017-01-12 18:20   ` Jarkko Sakkinen
@ 2017-01-13  7:14     ` Nayna
  2017-01-13 16:43       ` Jarkko Sakkinen
  2017-01-17  7:53     ` Nayna
  1 sibling, 1 reply; 12+ messages in thread
From: Nayna @ 2017-01-13  7:14 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel



On 01/12/2017 11:50 PM, Jarkko Sakkinen wrote:
> On Thu, Jan 12, 2017 at 11:58:10AM -0500, Nayna Jain wrote:
>> The current TPM 2.0 device driver extends only the SHA1 PCR bank
>> but the TCG Specification[1] recommends extending all active PCR
>> banks, to prevent malicious users from setting unused PCR banks with
>> fake measurements and quoting them.
>>
>> The existing in-kernel interface(tpm_pcr_extend()) expects only a
>> SHA1 digest.  To extend all active PCR banks with differing
>> digest sizes, the SHA1 digest is padded with trailing 0's as needed.
>>
>> [1] TPM 2.0 Specification referred here is "TCG PC Client Specific
>> Platform Firmware Profile for TPM 2.0"
>>
>> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
>> ---
>>   drivers/char/tpm/Kconfig         |  1 +
>>   drivers/char/tpm/tpm-interface.c | 16 +++++++++-
>>   drivers/char/tpm/tpm.h           |  3 +-
>>   drivers/char/tpm/tpm2-cmd.c      | 68 +++++++++++++++++++++++-----------------
>>   drivers/char/tpm/tpm_eventlog.h  | 18 +++++++++++
>>   5 files changed, 75 insertions(+), 31 deletions(-)
>>
>> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
>> index 277186d..af985cc 100644
>> --- a/drivers/char/tpm/Kconfig
>> +++ b/drivers/char/tpm/Kconfig
>> @@ -6,6 +6,7 @@ menuconfig TCG_TPM
>>   	tristate "TPM Hardware Support"
>>   	depends on HAS_IOMEM
>>   	select SECURITYFS
>> +	select CRYPTO_HASH_INFO
>
> In the commit message you did not mention this.
>
>>   	---help---
>>   	  If you have a TPM security chip in your system, which
>>   	  implements the Trusted Computing Group's specification,
>> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
>> index fecdd3f..e037dd2 100644
>> --- a/drivers/char/tpm/tpm-interface.c
>> +++ b/drivers/char/tpm/tpm-interface.c
>> @@ -7,6 +7,7 @@
>>    * Dave Safford <safford@watson.ibm.com>
>>    * Reiner Sailer <sailer@watson.ibm.com>
>>    * Kylene Hall <kjhall@us.ibm.com>
>> + * Nayna Jain <nayna@linux.vnet.ibm.com>
>
> Remove.
>
>>    *
>>    * Maintained by: <tpmdd-devel@lists.sourceforge.net>
>>    *
>> @@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = {
>>   int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>>   {
>>   	struct tpm_cmd_t cmd;
>> +	int i;
>>   	int rc;
>>   	struct tpm_chip *chip;
>>
>> @@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>>   		return -ENODEV;
>>
>>   	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
>> -		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
>> +		struct tpml_digest_values d_values;
>> +
>> +		memset(&d_values, 0, sizeof(d_values));
>> +
>> +		for (i = 0; (chip->active_banks[i] != 0) &&
>> +		     (i < ARRAY_SIZE(chip->active_banks)); i++) {
>> +			d_values.digests[i].alg_id = chip->active_banks[i];
>> +			memcpy(d_values.digests[i].digest, hash,
>> +			       TPM_DIGEST_SIZE);
>> +			d_values.count++;
>> +		}
>> +
>> +		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
>>   		tpm_put_ops(chip);
>>   		return rc;
>>   	}
>> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
>> index dddd573..dd82d58 100644
>> --- a/drivers/char/tpm/tpm.h
>> +++ b/drivers/char/tpm/tpm.h
>> @@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
>>   #endif
>>
>>   int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
>> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
>> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
>> +		    struct tpml_digest_values *digests);
>>   int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
>>   int tpm2_seal_trusted(struct tpm_chip *chip,
>>   		      struct trusted_key_payload *payload,
>> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
>> index 87388921..5027a54 100644
>> --- a/drivers/char/tpm/tpm2-cmd.c
>> +++ b/drivers/char/tpm/tpm2-cmd.c
>> @@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in {
>>   	__be32				pcr_idx;
>>   	__be32				auth_area_size;
>>   	struct tpm2_null_auth_area	auth_area;
>> -	__be32				digest_cnt;
>> -	__be16				hash_alg;
>> -	u8				digest[TPM_DIGEST_SIZE];
>> +	struct tpml_digest_values       digests;
>>   } __packed;
>>
>>   struct tpm2_get_tpm_pt_in {
>> @@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
>>   	return rc;
>>   }
>>
>> -#define TPM2_GET_PCREXTEND_IN_SIZE \
>> -	(sizeof(struct tpm_input_header) + \
>> -	 sizeof(struct tpm2_pcr_extend_in))
>> -
>> -static const struct tpm_input_header tpm2_pcrextend_header = {
>> -	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
>> -	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
>> -	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
>> -};
>> -
>>   /**
>>    * tpm2_pcr_extend() - extend a PCR value
>>    *
>>    * @chip:	TPM chip to use.
>>    * @pcr_idx:	index of the PCR.
>> - * @hash:	hash value to use for the extend operation.
>> + * @digests:	list of pcr banks and corresponding hash values to be extended.
>>    *
>>    * Return: Same as with tpm_transmit_cmd.
>>    */
>> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
>> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
>> +		    struct tpml_digest_values *digests)
>>   {
>> -	struct tpm2_cmd cmd;
>> +	struct tpm_buf buf;
>> +	struct tpm2_null_auth_area auth_area;
>>   	int rc;
>> +	int i;
>> +	int j;
>>
>> -	cmd.header.in = tpm2_pcrextend_header;
>> -	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
>> -	cmd.params.pcrextend_in.auth_area_size =
>> -		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
>> -	cmd.params.pcrextend_in.auth_area.handle =
>> -		cpu_to_be32(TPM2_RS_PW);
>> -	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
>> -	cmd.params.pcrextend_in.auth_area.attributes = 0;
>> -	cmd.params.pcrextend_in.auth_area.auth_size = 0;
>> -	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
>> -	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
>> -	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
>> +	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
>> +	if (rc)
>> +		return rc;
>>
>> -	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
>> +	tpm_buf_append_u32(&buf, pcr_idx);
>> +
>> +	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_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, digests->count);
>> +
>> +	for (i = 0; i < digests->count; i++) {
>> +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
>> +			if (digests->digests[i].alg_id !=
>> +			    tpm2_hash_map[j].tpm_id)
>> +				continue;
>> +
>> +			tpm_buf_append_u16(&buf, digests->digests[i].alg_id);
>> +			tpm_buf_append(&buf, (const unsigned char
>> +					      *)&digests->digests[i].digest,
>> +				hash_digest_size[tpm2_hash_map[j].crypto_id]);
>> +		}
>> +	}
>> +
>> +	rc = tpm_transmit_cmd(chip, buf.data, tpm_buf_length(&buf), 0,
>>   			      "attempting extend a PCR value");
>>
>> +	tpm_buf_destroy(&buf);
>> +
>>   	return rc;
>>   }
>>
>> diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
>> index 1660d74..2e47f4d 100644
>> --- a/drivers/char/tpm/tpm_eventlog.h
>> +++ b/drivers/char/tpm/tpm_eventlog.h
>> @@ -2,9 +2,12 @@
>>   #ifndef __TPM_EVENTLOG_H__
>>   #define __TPM_EVENTLOG_H__
>>
>> +#include <crypto/hash_info.h>
>> +
>>   #define TCG_EVENT_NAME_LEN_MAX	255
>>   #define MAX_TEXT_EVENT		1000	/* Max event string length */
>>   #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
>> +#define TPM2_ACTIVE_PCR_BANKS	3
>>
>>   #ifdef CONFIG_PPC64
>>   #define do_endian_conversion(x) be32_to_cpu(x)
>> @@ -73,6 +76,21 @@ enum tcpa_pc_event_ids {
>>   	HOST_TABLE_OF_DEVICES,
>>   };
>>
>> +/**
>> + * Digest structures for TPM 2.0 as defined in document
>> + * Trusted Platform Module Library Part 2: Structures, Family "2.0".
>> + */
>
> Please remove this comment
>
>> +
>> +struct tpmt_ha {
>> +	u16 alg_id;
>> +	u8 digest[SHA384_DIGEST_SIZE];
>> +} __packed;
>
> struct tpm2_hash
>
>> +struct tpml_digest_values {
>> +	u32 count;
>> +	struct tpmt_ha digests[TPM2_ACTIVE_PCR_BANKS];
>> +} __packed;
>
> Please remove this structure.

Sorry Jarkko, I didn't understand this comment.
Why do we want to remove this structure.

Thanks & Regards,
    - Nayna

>
>> +
>>   #if defined(CONFIG_ACPI)
>>   int tpm_read_log_acpi(struct tpm_chip *chip);
>>   #else
>> --
>> 2.5.0
>>
>
> /Jarkko
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active PCR banks
  2017-01-12 18:25   ` Jarkko Sakkinen
@ 2017-01-13  7:24     ` Nayna
  2017-01-13 16:45       ` Jarkko Sakkinen
  0 siblings, 1 reply; 12+ messages in thread
From: Nayna @ 2017-01-13  7:24 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel



On 01/12/2017 11:55 PM, Jarkko Sakkinen wrote:
> On Thu, Jan 12, 2017 at 11:58:09AM -0500, Nayna Jain wrote:
>> This patch implements the TPM 2.0 capability TPM_CAP_PCRS to
>> retrieve the active PCR banks from the TPM. This is needed
>> to enable extending all active banks as recommended by TPM 2.0
>> TCG Specification.
>>
>> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
>> ---
>>   drivers/char/tpm/tpm.h      |  4 +++
>>   drivers/char/tpm/tpm2-cmd.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
>>   2 files changed, 63 insertions(+)
>>
>> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
>> index 1ae9768..dddd573 100644
>> --- a/drivers/char/tpm/tpm.h
>> +++ b/drivers/char/tpm/tpm.h
>> @@ -127,6 +127,7 @@ enum tpm2_permanent_handles {
>>   };
>>
>>   enum tpm2_capabilities {
>> +	TPM2_CAP_PCRS		= 5,
>>   	TPM2_CAP_TPM_PROPERTIES = 6,
>>   };
>>
>> @@ -187,6 +188,8 @@ struct tpm_chip {
>>
>>   	const struct attribute_group *groups[3];
>>   	unsigned int groups_cnt;
>> +
>> +	u16 active_banks[7];
>>   #ifdef CONFIG_ACPI
>>   	acpi_handle acpi_dev_handle;
>>   	char ppi_version[TPM_PPI_VERSION_LEN + 1];
>> @@ -545,4 +548,5 @@ int tpm2_auto_startup(struct tpm_chip *chip);
>>   void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
>>   unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
>>   int tpm2_probe(struct tpm_chip *chip);
>> +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
>>   #endif
>> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
>> index 6eda239..87388921 100644
>> --- a/drivers/char/tpm/tpm2-cmd.c
>> +++ b/drivers/char/tpm/tpm2-cmd.c
>> @@ -83,6 +83,12 @@ struct tpm2_get_tpm_pt_out {
>>   	__be32	value;
>>   } __packed;
>>
>> +struct tpm2_tpms_pcr_selection {
>> +	__be16  hash_alg;
>> +	u8  size_of_select;
>> +	u8  pcr_select[3];
>> +} __packed;
>
> Please move this right before tpm2_get_pcr_allocation.
> Drop 'tpms_'.

Sure, will do this. But didn't understand why. I think all structs are 
defined in start of file..

Thanks & Regards,
    - Nayna

>
>> +
>>   struct tpm2_get_random_in {
>>   	__be16	size;
>>   } __packed;
>> @@ -993,8 +999,61 @@ int tpm2_auto_startup(struct tpm_chip *chip)
>>   		}
>>   	}
>>
>> +	rc = tpm2_get_pcr_allocation(chip);
>> +
>
> Please have this call in the commit where you actually use it
> Does not make any sense here
>
>>   out:
>>   	if (rc > 0)
>>   		rc = -ENODEV;
>>   	return rc;
>>   }
>> +
>> +/**
>> + * tpm2_get_pcr_allocation() - get TPM active PCR banks.
>> + *
>> + * @chip: TPM chip to use.
>> + *
>> + * Return: Same as with tpm_transmit_cmd.
>> + */
>> +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
>> +{
>> +	struct tpm2_tpms_pcr_selection pcr_selection;
>> +	struct tpm_buf buf;
>> +	void *marker;
>> +	unsigned int count = 0;
>> +	int rc;
>> +	int i;
>> +
>> +	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
>> +	if (rc)
>> +		return rc;
>> +
>> +	tpm_buf_append_u32(&buf, TPM2_CAP_PCRS);
>> +	tpm_buf_append_u32(&buf, 0);
>> +	tpm_buf_append_u32(&buf, 1);
>> +
>> +	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0,
>> +			      "get tpm pcr allocation");
>> +	if (rc < 0)
>> +		goto out;
>> +
>> +	count = be32_to_cpup(
>> +		(__be32 *) &buf.data[TPM_HEADER_SIZE + 5]);
>
> Please do not add a space after cast. This has been an issue in your
> previous patches too so try to do it right next time.
>
>> +
>> +	if (count > ARRAY_SIZE(chip->active_banks))
>> +		return -ENODEV;
>> +
>> +	marker = &buf.data[TPM_HEADER_SIZE + 9];
>> +	for (i = 0; i < count; i++) {
>> +		memcpy(&pcr_selection, marker, sizeof(pcr_selection));
>> +		chip->active_banks[i] = be16_to_cpu(pcr_selection.hash_alg);
>> +		marker = marker + sizeof(struct tpm2_tpms_pcr_selection);
>> +	}
>> +
>> +out:
>> +	if (count < ARRAY_SIZE(chip->active_banks))
>> +		chip->active_banks[count] = 0;
>> +
>> +	tpm_buf_destroy(&buf);
>> +
>> +	return rc;
>> +}
>> --
>> 2.5.0
>>
>
> /Jarkko
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks
  2017-01-13  7:14     ` Nayna
@ 2017-01-13 16:43       ` Jarkko Sakkinen
  0 siblings, 0 replies; 12+ messages in thread
From: Jarkko Sakkinen @ 2017-01-13 16:43 UTC (permalink / raw)
  To: Nayna
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel

On Fri, Jan 13, 2017 at 12:44:15PM +0530, Nayna wrote:
> 
> 
> On 01/12/2017 11:50 PM, Jarkko Sakkinen wrote:
> > On Thu, Jan 12, 2017 at 11:58:10AM -0500, Nayna Jain wrote:
> > > The current TPM 2.0 device driver extends only the SHA1 PCR bank
> > > but the TCG Specification[1] recommends extending all active PCR
> > > banks, to prevent malicious users from setting unused PCR banks with
> > > fake measurements and quoting them.
> > > 
> > > The existing in-kernel interface(tpm_pcr_extend()) expects only a
> > > SHA1 digest.  To extend all active PCR banks with differing
> > > digest sizes, the SHA1 digest is padded with trailing 0's as needed.
> > > 
> > > [1] TPM 2.0 Specification referred here is "TCG PC Client Specific
> > > Platform Firmware Profile for TPM 2.0"
> > > 
> > > Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
> > > ---
> > >   drivers/char/tpm/Kconfig         |  1 +
> > >   drivers/char/tpm/tpm-interface.c | 16 +++++++++-
> > >   drivers/char/tpm/tpm.h           |  3 +-
> > >   drivers/char/tpm/tpm2-cmd.c      | 68 +++++++++++++++++++++++-----------------
> > >   drivers/char/tpm/tpm_eventlog.h  | 18 +++++++++++
> > >   5 files changed, 75 insertions(+), 31 deletions(-)
> > > 
> > > diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> > > index 277186d..af985cc 100644
> > > --- a/drivers/char/tpm/Kconfig
> > > +++ b/drivers/char/tpm/Kconfig
> > > @@ -6,6 +6,7 @@ menuconfig TCG_TPM
> > >   	tristate "TPM Hardware Support"
> > >   	depends on HAS_IOMEM
> > >   	select SECURITYFS
> > > +	select CRYPTO_HASH_INFO
> > 
> > In the commit message you did not mention this.
> > 
> > >   	---help---
> > >   	  If you have a TPM security chip in your system, which
> > >   	  implements the Trusted Computing Group's specification,
> > > diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> > > index fecdd3f..e037dd2 100644
> > > --- a/drivers/char/tpm/tpm-interface.c
> > > +++ b/drivers/char/tpm/tpm-interface.c
> > > @@ -7,6 +7,7 @@
> > >    * Dave Safford <safford@watson.ibm.com>
> > >    * Reiner Sailer <sailer@watson.ibm.com>
> > >    * Kylene Hall <kjhall@us.ibm.com>
> > > + * Nayna Jain <nayna@linux.vnet.ibm.com>
> > 
> > Remove.
> > 
> > >    *
> > >    * Maintained by: <tpmdd-devel@lists.sourceforge.net>
> > >    *
> > > @@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = {
> > >   int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
> > >   {
> > >   	struct tpm_cmd_t cmd;
> > > +	int i;
> > >   	int rc;
> > >   	struct tpm_chip *chip;
> > > 
> > > @@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
> > >   		return -ENODEV;
> > > 
> > >   	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> > > -		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
> > > +		struct tpml_digest_values d_values;
> > > +
> > > +		memset(&d_values, 0, sizeof(d_values));
> > > +
> > > +		for (i = 0; (chip->active_banks[i] != 0) &&
> > > +		     (i < ARRAY_SIZE(chip->active_banks)); i++) {
> > > +			d_values.digests[i].alg_id = chip->active_banks[i];
> > > +			memcpy(d_values.digests[i].digest, hash,
> > > +			       TPM_DIGEST_SIZE);
> > > +			d_values.count++;
> > > +		}
> > > +
> > > +		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
> > >   		tpm_put_ops(chip);
> > >   		return rc;
> > >   	}
> > > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> > > index dddd573..dd82d58 100644
> > > --- a/drivers/char/tpm/tpm.h
> > > +++ b/drivers/char/tpm/tpm.h
> > > @@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
> > >   #endif
> > > 
> > >   int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
> > > -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
> > > +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> > > +		    struct tpml_digest_values *digests);
> > >   int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
> > >   int tpm2_seal_trusted(struct tpm_chip *chip,
> > >   		      struct trusted_key_payload *payload,
> > > diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> > > index 87388921..5027a54 100644
> > > --- a/drivers/char/tpm/tpm2-cmd.c
> > > +++ b/drivers/char/tpm/tpm2-cmd.c
> > > @@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in {
> > >   	__be32				pcr_idx;
> > >   	__be32				auth_area_size;
> > >   	struct tpm2_null_auth_area	auth_area;
> > > -	__be32				digest_cnt;
> > > -	__be16				hash_alg;
> > > -	u8				digest[TPM_DIGEST_SIZE];
> > > +	struct tpml_digest_values       digests;
> > >   } __packed;
> > > 
> > >   struct tpm2_get_tpm_pt_in {
> > > @@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
> > >   	return rc;
> > >   }
> > > 
> > > -#define TPM2_GET_PCREXTEND_IN_SIZE \
> > > -	(sizeof(struct tpm_input_header) + \
> > > -	 sizeof(struct tpm2_pcr_extend_in))
> > > -
> > > -static const struct tpm_input_header tpm2_pcrextend_header = {
> > > -	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
> > > -	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
> > > -	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
> > > -};
> > > -
> > >   /**
> > >    * tpm2_pcr_extend() - extend a PCR value
> > >    *
> > >    * @chip:	TPM chip to use.
> > >    * @pcr_idx:	index of the PCR.
> > > - * @hash:	hash value to use for the extend operation.
> > > + * @digests:	list of pcr banks and corresponding hash values to be extended.
> > >    *
> > >    * Return: Same as with tpm_transmit_cmd.
> > >    */
> > > -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
> > > +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> > > +		    struct tpml_digest_values *digests)
> > >   {
> > > -	struct tpm2_cmd cmd;
> > > +	struct tpm_buf buf;
> > > +	struct tpm2_null_auth_area auth_area;
> > >   	int rc;
> > > +	int i;
> > > +	int j;
> > > 
> > > -	cmd.header.in = tpm2_pcrextend_header;
> > > -	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
> > > -	cmd.params.pcrextend_in.auth_area_size =
> > > -		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
> > > -	cmd.params.pcrextend_in.auth_area.handle =
> > > -		cpu_to_be32(TPM2_RS_PW);
> > > -	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
> > > -	cmd.params.pcrextend_in.auth_area.attributes = 0;
> > > -	cmd.params.pcrextend_in.auth_area.auth_size = 0;
> > > -	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
> > > -	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
> > > -	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
> > > +	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
> > > +	if (rc)
> > > +		return rc;
> > > 
> > > -	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
> > > +	tpm_buf_append_u32(&buf, pcr_idx);
> > > +
> > > +	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_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, digests->count);
> > > +
> > > +	for (i = 0; i < digests->count; i++) {
> > > +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
> > > +			if (digests->digests[i].alg_id !=
> > > +			    tpm2_hash_map[j].tpm_id)
> > > +				continue;
> > > +
> > > +			tpm_buf_append_u16(&buf, digests->digests[i].alg_id);
> > > +			tpm_buf_append(&buf, (const unsigned char
> > > +					      *)&digests->digests[i].digest,
> > > +				hash_digest_size[tpm2_hash_map[j].crypto_id]);
> > > +		}
> > > +	}
> > > +
> > > +	rc = tpm_transmit_cmd(chip, buf.data, tpm_buf_length(&buf), 0,
> > >   			      "attempting extend a PCR value");
> > > 
> > > +	tpm_buf_destroy(&buf);
> > > +
> > >   	return rc;
> > >   }
> > > 
> > > diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
> > > index 1660d74..2e47f4d 100644
> > > --- a/drivers/char/tpm/tpm_eventlog.h
> > > +++ b/drivers/char/tpm/tpm_eventlog.h
> > > @@ -2,9 +2,12 @@
> > >   #ifndef __TPM_EVENTLOG_H__
> > >   #define __TPM_EVENTLOG_H__
> > > 
> > > +#include <crypto/hash_info.h>
> > > +
> > >   #define TCG_EVENT_NAME_LEN_MAX	255
> > >   #define MAX_TEXT_EVENT		1000	/* Max event string length */
> > >   #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
> > > +#define TPM2_ACTIVE_PCR_BANKS	3
> > > 
> > >   #ifdef CONFIG_PPC64
> > >   #define do_endian_conversion(x) be32_to_cpu(x)
> > > @@ -73,6 +76,21 @@ enum tcpa_pc_event_ids {
> > >   	HOST_TABLE_OF_DEVICES,
> > >   };
> > > 
> > > +/**
> > > + * Digest structures for TPM 2.0 as defined in document
> > > + * Trusted Platform Module Library Part 2: Structures, Family "2.0".
> > > + */
> > 
> > Please remove this comment
> > 
> > > +
> > > +struct tpmt_ha {
> > > +	u16 alg_id;
> > > +	u8 digest[SHA384_DIGEST_SIZE];
> > > +} __packed;
> > 
> > struct tpm2_hash
> > 
> > > +struct tpml_digest_values {
> > > +	u32 count;
> > > +	struct tpmt_ha digests[TPM2_ACTIVE_PCR_BANKS];
> > > +} __packed;
> > 
> > Please remove this structure.
> 
> Sorry Jarkko, I didn't understand this comment.
> Why do we want to remove this structure.

Well it is only used to pass two parameters.

> Thanks & Regards,
>    - Nayna

/Jarkko

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active PCR banks
  2017-01-13  7:24     ` Nayna
@ 2017-01-13 16:45       ` Jarkko Sakkinen
  0 siblings, 0 replies; 12+ messages in thread
From: Jarkko Sakkinen @ 2017-01-13 16:45 UTC (permalink / raw)
  To: Nayna
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel

On Fri, Jan 13, 2017 at 12:54:12PM +0530, Nayna wrote:
> 
> 
> On 01/12/2017 11:55 PM, Jarkko Sakkinen wrote:
> > On Thu, Jan 12, 2017 at 11:58:09AM -0500, Nayna Jain wrote:
> > > This patch implements the TPM 2.0 capability TPM_CAP_PCRS to
> > > retrieve the active PCR banks from the TPM. This is needed
> > > to enable extending all active banks as recommended by TPM 2.0
> > > TCG Specification.
> > > 
> > > Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
> > > ---
> > >   drivers/char/tpm/tpm.h      |  4 +++
> > >   drivers/char/tpm/tpm2-cmd.c | 59 +++++++++++++++++++++++++++++++++++++++++++++
> > >   2 files changed, 63 insertions(+)
> > > 
> > > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> > > index 1ae9768..dddd573 100644
> > > --- a/drivers/char/tpm/tpm.h
> > > +++ b/drivers/char/tpm/tpm.h
> > > @@ -127,6 +127,7 @@ enum tpm2_permanent_handles {
> > >   };
> > > 
> > >   enum tpm2_capabilities {
> > > +	TPM2_CAP_PCRS		= 5,
> > >   	TPM2_CAP_TPM_PROPERTIES = 6,
> > >   };
> > > 
> > > @@ -187,6 +188,8 @@ struct tpm_chip {
> > > 
> > >   	const struct attribute_group *groups[3];
> > >   	unsigned int groups_cnt;
> > > +
> > > +	u16 active_banks[7];
> > >   #ifdef CONFIG_ACPI
> > >   	acpi_handle acpi_dev_handle;
> > >   	char ppi_version[TPM_PPI_VERSION_LEN + 1];
> > > @@ -545,4 +548,5 @@ int tpm2_auto_startup(struct tpm_chip *chip);
> > >   void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type);
> > >   unsigned long tpm2_calc_ordinal_duration(struct tpm_chip *chip, u32 ordinal);
> > >   int tpm2_probe(struct tpm_chip *chip);
> > > +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip);
> > >   #endif
> > > diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> > > index 6eda239..87388921 100644
> > > --- a/drivers/char/tpm/tpm2-cmd.c
> > > +++ b/drivers/char/tpm/tpm2-cmd.c
> > > @@ -83,6 +83,12 @@ struct tpm2_get_tpm_pt_out {
> > >   	__be32	value;
> > >   } __packed;
> > > 
> > > +struct tpm2_tpms_pcr_selection {
> > > +	__be16  hash_alg;
> > > +	u8  size_of_select;
> > > +	u8  pcr_select[3];
> > > +} __packed;
> > 
> > Please move this right before tpm2_get_pcr_allocation.
> > Drop 'tpms_'.
> 
> Sure, will do this. But didn't understand why. I think all structs are
> defined in start of file..
> 
> Thanks & Regards,
>    - Nayna
> 
> > 
> > > +
> > >   struct tpm2_get_random_in {
> > >   	__be16	size;
> > >   } __packed;
> > > @@ -993,8 +999,61 @@ int tpm2_auto_startup(struct tpm_chip *chip)
> > >   		}
> > >   	}
> > > 
> > > +	rc = tpm2_get_pcr_allocation(chip);
> > > +
> > 
> > Please have this call in the commit where you actually use it
> > Does not make any sense here
> > 
> > >   out:
> > >   	if (rc > 0)
> > >   		rc = -ENODEV;
> > >   	return rc;
> > >   }
> > > +
> > > +/**
> > > + * tpm2_get_pcr_allocation() - get TPM active PCR banks.
> > > + *
> > > + * @chip: TPM chip to use.
> > > + *
> > > + * Return: Same as with tpm_transmit_cmd.
> > > + */
> > > +ssize_t tpm2_get_pcr_allocation(struct tpm_chip *chip)
> > > +{
> > > +	struct tpm2_tpms_pcr_selection pcr_selection;
> > > +	struct tpm_buf buf;
> > > +	void *marker;
> > > +	unsigned int count = 0;
> > > +	int rc;
> > > +	int i;
> > > +
> > > +	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_GET_CAPABILITY);
> > > +	if (rc)
> > > +		return rc;
> > > +
> > > +	tpm_buf_append_u32(&buf, TPM2_CAP_PCRS);
> > > +	tpm_buf_append_u32(&buf, 0);
> > > +	tpm_buf_append_u32(&buf, 1);
> > > +
> > > +	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0,
> > > +			      "get tpm pcr allocation");
> > > +	if (rc < 0)
> > > +		goto out;
> > > +
> > > +	count = be32_to_cpup(
> > > +		(__be32 *) &buf.data[TPM_HEADER_SIZE + 5]);
> > 
> > Please do not add a space after cast. This has been an issue in your
> > previous patches too so try to do it right next time.

It is only used internally by that function. I think this would
make sense for other structures too that are only used by one
function.

/Jarkko

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks
  2017-01-12 18:20   ` Jarkko Sakkinen
  2017-01-13  7:14     ` Nayna
@ 2017-01-17  7:53     ` Nayna
  2017-01-17 16:13       ` Jarkko Sakkinen
  1 sibling, 1 reply; 12+ messages in thread
From: Nayna @ 2017-01-17  7:53 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel



On 01/12/2017 11:50 PM, Jarkko Sakkinen wrote:
> On Thu, Jan 12, 2017 at 11:58:10AM -0500, Nayna Jain wrote:
>> The current TPM 2.0 device driver extends only the SHA1 PCR bank
>> but the TCG Specification[1] recommends extending all active PCR
>> banks, to prevent malicious users from setting unused PCR banks with
>> fake measurements and quoting them.
>>
>> The existing in-kernel interface(tpm_pcr_extend()) expects only a
>> SHA1 digest.  To extend all active PCR banks with differing
>> digest sizes, the SHA1 digest is padded with trailing 0's as needed.
>>
>> [1] TPM 2.0 Specification referred here is "TCG PC Client Specific
>> Platform Firmware Profile for TPM 2.0"
>>
>> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
>> ---
>>   drivers/char/tpm/Kconfig         |  1 +
>>   drivers/char/tpm/tpm-interface.c | 16 +++++++++-
>>   drivers/char/tpm/tpm.h           |  3 +-
>>   drivers/char/tpm/tpm2-cmd.c      | 68 +++++++++++++++++++++++-----------------
>>   drivers/char/tpm/tpm_eventlog.h  | 18 +++++++++++
>>   5 files changed, 75 insertions(+), 31 deletions(-)
>>
>> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
>> index 277186d..af985cc 100644
>> --- a/drivers/char/tpm/Kconfig
>> +++ b/drivers/char/tpm/Kconfig
>> @@ -6,6 +6,7 @@ menuconfig TCG_TPM
>>   	tristate "TPM Hardware Support"
>>   	depends on HAS_IOMEM
>>   	select SECURITYFS
>> +	select CRYPTO_HASH_INFO
>
> In the commit message you did not mention this.
>
>>   	---help---
>>   	  If you have a TPM security chip in your system, which
>>   	  implements the Trusted Computing Group's specification,
>> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
>> index fecdd3f..e037dd2 100644
>> --- a/drivers/char/tpm/tpm-interface.c
>> +++ b/drivers/char/tpm/tpm-interface.c
>> @@ -7,6 +7,7 @@
>>    * Dave Safford <safford@watson.ibm.com>
>>    * Reiner Sailer <sailer@watson.ibm.com>
>>    * Kylene Hall <kjhall@us.ibm.com>
>> + * Nayna Jain <nayna@linux.vnet.ibm.com>
>
> Remove.
>
>>    *
>>    * Maintained by: <tpmdd-devel@lists.sourceforge.net>
>>    *
>> @@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = {
>>   int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>>   {
>>   	struct tpm_cmd_t cmd;
>> +	int i;
>>   	int rc;
>>   	struct tpm_chip *chip;
>>
>> @@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>>   		return -ENODEV;
>>
>>   	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
>> -		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
>> +		struct tpml_digest_values d_values;
>> +
>> +		memset(&d_values, 0, sizeof(d_values));
>> +
>> +		for (i = 0; (chip->active_banks[i] != 0) &&
>> +		     (i < ARRAY_SIZE(chip->active_banks)); i++) {
>> +			d_values.digests[i].alg_id = chip->active_banks[i];
>> +			memcpy(d_values.digests[i].digest, hash,
>> +			       TPM_DIGEST_SIZE);
>> +			d_values.count++;
>> +		}
>> +
>> +		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
>>   		tpm_put_ops(chip);
>>   		return rc;
>>   	}
>> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
>> index dddd573..dd82d58 100644
>> --- a/drivers/char/tpm/tpm.h
>> +++ b/drivers/char/tpm/tpm.h
>> @@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
>>   #endif
>>
>>   int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
>> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
>> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
>> +		    struct tpml_digest_values *digests);
>>   int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
>>   int tpm2_seal_trusted(struct tpm_chip *chip,
>>   		      struct trusted_key_payload *payload,
>> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
>> index 87388921..5027a54 100644
>> --- a/drivers/char/tpm/tpm2-cmd.c
>> +++ b/drivers/char/tpm/tpm2-cmd.c
>> @@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in {
>>   	__be32				pcr_idx;
>>   	__be32				auth_area_size;
>>   	struct tpm2_null_auth_area	auth_area;
>> -	__be32				digest_cnt;
>> -	__be16				hash_alg;
>> -	u8				digest[TPM_DIGEST_SIZE];
>> +	struct tpml_digest_values       digests;
>>   } __packed;
>>
>>   struct tpm2_get_tpm_pt_in {
>> @@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
>>   	return rc;
>>   }
>>
>> -#define TPM2_GET_PCREXTEND_IN_SIZE \
>> -	(sizeof(struct tpm_input_header) + \
>> -	 sizeof(struct tpm2_pcr_extend_in))
>> -
>> -static const struct tpm_input_header tpm2_pcrextend_header = {
>> -	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
>> -	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
>> -	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
>> -};
>> -
>>   /**
>>    * tpm2_pcr_extend() - extend a PCR value
>>    *
>>    * @chip:	TPM chip to use.
>>    * @pcr_idx:	index of the PCR.
>> - * @hash:	hash value to use for the extend operation.
>> + * @digests:	list of pcr banks and corresponding hash values to be extended.
>>    *
>>    * Return: Same as with tpm_transmit_cmd.
>>    */
>> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
>> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
>> +		    struct tpml_digest_values *digests)
>>   {
>> -	struct tpm2_cmd cmd;
>> +	struct tpm_buf buf;
>> +	struct tpm2_null_auth_area auth_area;
>>   	int rc;
>> +	int i;
>> +	int j;
>>
>> -	cmd.header.in = tpm2_pcrextend_header;
>> -	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
>> -	cmd.params.pcrextend_in.auth_area_size =
>> -		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
>> -	cmd.params.pcrextend_in.auth_area.handle =
>> -		cpu_to_be32(TPM2_RS_PW);
>> -	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
>> -	cmd.params.pcrextend_in.auth_area.attributes = 0;
>> -	cmd.params.pcrextend_in.auth_area.auth_size = 0;
>> -	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
>> -	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
>> -	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
>> +	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
>> +	if (rc)
>> +		return rc;
>>
>> -	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
>> +	tpm_buf_append_u32(&buf, pcr_idx);
>> +
>> +	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_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, digests->count);
>> +
>> +	for (i = 0; i < digests->count; i++) {
>> +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
>> +			if (digests->digests[i].alg_id !=
>> +			    tpm2_hash_map[j].tpm_id)
>> +				continue;
>> +
>> +			tpm_buf_append_u16(&buf, digests->digests[i].alg_id);
>> +			tpm_buf_append(&buf, (const unsigned char
>> +					      *)&digests->digests[i].digest,
>> +				hash_digest_size[tpm2_hash_map[j].crypto_id]);
>> +		}
>> +	}
>> +
>> +	rc = tpm_transmit_cmd(chip, buf.data, tpm_buf_length(&buf), 0,
>>   			      "attempting extend a PCR value");
>>
>> +	tpm_buf_destroy(&buf);
>> +
>>   	return rc;
>>   }
>>
>> diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
>> index 1660d74..2e47f4d 100644
>> --- a/drivers/char/tpm/tpm_eventlog.h
>> +++ b/drivers/char/tpm/tpm_eventlog.h
>> @@ -2,9 +2,12 @@
>>   #ifndef __TPM_EVENTLOG_H__
>>   #define __TPM_EVENTLOG_H__
>>
>> +#include <crypto/hash_info.h>
>> +
>>   #define TCG_EVENT_NAME_LEN_MAX	255
>>   #define MAX_TEXT_EVENT		1000	/* Max event string length */
>>   #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
>> +#define TPM2_ACTIVE_PCR_BANKS	3
>>
>>   #ifdef CONFIG_PPC64
>>   #define do_endian_conversion(x) be32_to_cpu(x)
>> @@ -73,6 +76,21 @@ enum tcpa_pc_event_ids {
>>   	HOST_TABLE_OF_DEVICES,
>>   };
>>
>> +/**
>> + * Digest structures for TPM 2.0 as defined in document
>> + * Trusted Platform Module Library Part 2: Structures, Family "2.0".
>> + */
>
> Please remove this comment
>
>> +
>> +struct tpmt_ha {
>> +	u16 alg_id;
>> +	u8 digest[SHA384_DIGEST_SIZE];
>> +} __packed;
>
> struct tpm2_hash

struct tpm2_hash is already defined in tpm2-cmd.c as below

struct tpm2_hash {
         unsigned int crypto_id;
         unsigned int tpm_id;
};

Though, I think this probably needs a different name, probably as 
"struct tpm2_hash_ids_map" or just "struct tpm2_hash_ids"

and then I rename struct tpmt_ha as struct tpm2_hash.

If this sounds good, I will also rename existing tpm2_hash as different 
patch.

Thanks & Regards,
    - Nayna

>
>> +struct tpml_digest_values {
>> +	u32 count;
>> +	struct tpmt_ha digests[TPM2_ACTIVE_PCR_BANKS];
>> +} __packed;
>
> Please remove this structure.
>
>> +
>>   #if defined(CONFIG_ACPI)
>>   int tpm_read_log_acpi(struct tpm_chip *chip);
>>   #else
>> --
>> 2.5.0
>>
>
> /Jarkko
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks
  2017-01-17  7:53     ` Nayna
@ 2017-01-17 16:13       ` Jarkko Sakkinen
  2017-01-17 16:26         ` Nayna
  0 siblings, 1 reply; 12+ messages in thread
From: Jarkko Sakkinen @ 2017-01-17 16:13 UTC (permalink / raw)
  To: Nayna
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel

On Tue, Jan 17, 2017 at 01:23:44PM +0530, Nayna wrote:
> 
> 
> On 01/12/2017 11:50 PM, Jarkko Sakkinen wrote:
> > On Thu, Jan 12, 2017 at 11:58:10AM -0500, Nayna Jain wrote:
> > > The current TPM 2.0 device driver extends only the SHA1 PCR bank
> > > but the TCG Specification[1] recommends extending all active PCR
> > > banks, to prevent malicious users from setting unused PCR banks with
> > > fake measurements and quoting them.
> > > 
> > > The existing in-kernel interface(tpm_pcr_extend()) expects only a
> > > SHA1 digest.  To extend all active PCR banks with differing
> > > digest sizes, the SHA1 digest is padded with trailing 0's as needed.
> > > 
> > > [1] TPM 2.0 Specification referred here is "TCG PC Client Specific
> > > Platform Firmware Profile for TPM 2.0"
> > > 
> > > Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
> > > ---
> > >   drivers/char/tpm/Kconfig         |  1 +
> > >   drivers/char/tpm/tpm-interface.c | 16 +++++++++-
> > >   drivers/char/tpm/tpm.h           |  3 +-
> > >   drivers/char/tpm/tpm2-cmd.c      | 68 +++++++++++++++++++++++-----------------
> > >   drivers/char/tpm/tpm_eventlog.h  | 18 +++++++++++
> > >   5 files changed, 75 insertions(+), 31 deletions(-)
> > > 
> > > diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
> > > index 277186d..af985cc 100644
> > > --- a/drivers/char/tpm/Kconfig
> > > +++ b/drivers/char/tpm/Kconfig
> > > @@ -6,6 +6,7 @@ menuconfig TCG_TPM
> > >   	tristate "TPM Hardware Support"
> > >   	depends on HAS_IOMEM
> > >   	select SECURITYFS
> > > +	select CRYPTO_HASH_INFO
> > 
> > In the commit message you did not mention this.
> > 
> > >   	---help---
> > >   	  If you have a TPM security chip in your system, which
> > >   	  implements the Trusted Computing Group's specification,
> > > diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> > > index fecdd3f..e037dd2 100644
> > > --- a/drivers/char/tpm/tpm-interface.c
> > > +++ b/drivers/char/tpm/tpm-interface.c
> > > @@ -7,6 +7,7 @@
> > >    * Dave Safford <safford@watson.ibm.com>
> > >    * Reiner Sailer <sailer@watson.ibm.com>
> > >    * Kylene Hall <kjhall@us.ibm.com>
> > > + * Nayna Jain <nayna@linux.vnet.ibm.com>
> > 
> > Remove.
> > 
> > >    *
> > >    * Maintained by: <tpmdd-devel@lists.sourceforge.net>
> > >    *
> > > @@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = {
> > >   int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
> > >   {
> > >   	struct tpm_cmd_t cmd;
> > > +	int i;
> > >   	int rc;
> > >   	struct tpm_chip *chip;
> > > 
> > > @@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
> > >   		return -ENODEV;
> > > 
> > >   	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
> > > -		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
> > > +		struct tpml_digest_values d_values;
> > > +
> > > +		memset(&d_values, 0, sizeof(d_values));
> > > +
> > > +		for (i = 0; (chip->active_banks[i] != 0) &&
> > > +		     (i < ARRAY_SIZE(chip->active_banks)); i++) {
> > > +			d_values.digests[i].alg_id = chip->active_banks[i];
> > > +			memcpy(d_values.digests[i].digest, hash,
> > > +			       TPM_DIGEST_SIZE);
> > > +			d_values.count++;
> > > +		}
> > > +
> > > +		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
> > >   		tpm_put_ops(chip);
> > >   		return rc;
> > >   	}
> > > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
> > > index dddd573..dd82d58 100644
> > > --- a/drivers/char/tpm/tpm.h
> > > +++ b/drivers/char/tpm/tpm.h
> > > @@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
> > >   #endif
> > > 
> > >   int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
> > > -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
> > > +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> > > +		    struct tpml_digest_values *digests);
> > >   int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
> > >   int tpm2_seal_trusted(struct tpm_chip *chip,
> > >   		      struct trusted_key_payload *payload,
> > > diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> > > index 87388921..5027a54 100644
> > > --- a/drivers/char/tpm/tpm2-cmd.c
> > > +++ b/drivers/char/tpm/tpm2-cmd.c
> > > @@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in {
> > >   	__be32				pcr_idx;
> > >   	__be32				auth_area_size;
> > >   	struct tpm2_null_auth_area	auth_area;
> > > -	__be32				digest_cnt;
> > > -	__be16				hash_alg;
> > > -	u8				digest[TPM_DIGEST_SIZE];
> > > +	struct tpml_digest_values       digests;
> > >   } __packed;
> > > 
> > >   struct tpm2_get_tpm_pt_in {
> > > @@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
> > >   	return rc;
> > >   }
> > > 
> > > -#define TPM2_GET_PCREXTEND_IN_SIZE \
> > > -	(sizeof(struct tpm_input_header) + \
> > > -	 sizeof(struct tpm2_pcr_extend_in))
> > > -
> > > -static const struct tpm_input_header tpm2_pcrextend_header = {
> > > -	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
> > > -	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
> > > -	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
> > > -};
> > > -
> > >   /**
> > >    * tpm2_pcr_extend() - extend a PCR value
> > >    *
> > >    * @chip:	TPM chip to use.
> > >    * @pcr_idx:	index of the PCR.
> > > - * @hash:	hash value to use for the extend operation.
> > > + * @digests:	list of pcr banks and corresponding hash values to be extended.
> > >    *
> > >    * Return: Same as with tpm_transmit_cmd.
> > >    */
> > > -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
> > > +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> > > +		    struct tpml_digest_values *digests)
> > >   {
> > > -	struct tpm2_cmd cmd;
> > > +	struct tpm_buf buf;
> > > +	struct tpm2_null_auth_area auth_area;
> > >   	int rc;
> > > +	int i;
> > > +	int j;
> > > 
> > > -	cmd.header.in = tpm2_pcrextend_header;
> > > -	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
> > > -	cmd.params.pcrextend_in.auth_area_size =
> > > -		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
> > > -	cmd.params.pcrextend_in.auth_area.handle =
> > > -		cpu_to_be32(TPM2_RS_PW);
> > > -	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
> > > -	cmd.params.pcrextend_in.auth_area.attributes = 0;
> > > -	cmd.params.pcrextend_in.auth_area.auth_size = 0;
> > > -	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
> > > -	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
> > > -	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
> > > +	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
> > > +	if (rc)
> > > +		return rc;
> > > 
> > > -	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
> > > +	tpm_buf_append_u32(&buf, pcr_idx);
> > > +
> > > +	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_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, digests->count);
> > > +
> > > +	for (i = 0; i < digests->count; i++) {
> > > +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
> > > +			if (digests->digests[i].alg_id !=
> > > +			    tpm2_hash_map[j].tpm_id)
> > > +				continue;
> > > +
> > > +			tpm_buf_append_u16(&buf, digests->digests[i].alg_id);
> > > +			tpm_buf_append(&buf, (const unsigned char
> > > +					      *)&digests->digests[i].digest,
> > > +				hash_digest_size[tpm2_hash_map[j].crypto_id]);
> > > +		}
> > > +	}
> > > +
> > > +	rc = tpm_transmit_cmd(chip, buf.data, tpm_buf_length(&buf), 0,
> > >   			      "attempting extend a PCR value");
> > > 
> > > +	tpm_buf_destroy(&buf);
> > > +
> > >   	return rc;
> > >   }
> > > 
> > > diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
> > > index 1660d74..2e47f4d 100644
> > > --- a/drivers/char/tpm/tpm_eventlog.h
> > > +++ b/drivers/char/tpm/tpm_eventlog.h
> > > @@ -2,9 +2,12 @@
> > >   #ifndef __TPM_EVENTLOG_H__
> > >   #define __TPM_EVENTLOG_H__
> > > 
> > > +#include <crypto/hash_info.h>
> > > +
> > >   #define TCG_EVENT_NAME_LEN_MAX	255
> > >   #define MAX_TEXT_EVENT		1000	/* Max event string length */
> > >   #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
> > > +#define TPM2_ACTIVE_PCR_BANKS	3
> > > 
> > >   #ifdef CONFIG_PPC64
> > >   #define do_endian_conversion(x) be32_to_cpu(x)
> > > @@ -73,6 +76,21 @@ enum tcpa_pc_event_ids {
> > >   	HOST_TABLE_OF_DEVICES,
> > >   };
> > > 
> > > +/**
> > > + * Digest structures for TPM 2.0 as defined in document
> > > + * Trusted Platform Module Library Part 2: Structures, Family "2.0".
> > > + */
> > 
> > Please remove this comment
> > 
> > > +
> > > +struct tpmt_ha {
> > > +	u16 alg_id;
> > > +	u8 digest[SHA384_DIGEST_SIZE];
> > > +} __packed;
> > 
> > struct tpm2_hash
> 
> struct tpm2_hash is already defined in tpm2-cmd.c as below
> 
> struct tpm2_hash {
>         unsigned int crypto_id;
>         unsigned int tpm_id;
> };
> 
> Though, I think this probably needs a different name, probably as "struct
> tpm2_hash_ids_map" or just "struct tpm2_hash_ids"
> 
> and then I rename struct tpmt_ha as struct tpm2_hash.
> 
> If this sounds good, I will also rename existing tpm2_hash as different
> patch.
> 
> Thanks & Regards,
>    - Nayna

What if you just use tpm2_digest for the new structure?

/Jarkko

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks
  2017-01-17 16:13       ` Jarkko Sakkinen
@ 2017-01-17 16:26         ` Nayna
  0 siblings, 0 replies; 12+ messages in thread
From: Nayna @ 2017-01-17 16:26 UTC (permalink / raw)
  To: Jarkko Sakkinen
  Cc: tpmdd-devel, peterhuewe, tpmdd, jgunthorpe,
	linux-security-module, linux-kernel



On 01/17/2017 09:43 PM, Jarkko Sakkinen wrote:
> On Tue, Jan 17, 2017 at 01:23:44PM +0530, Nayna wrote:
>>
>>
>> On 01/12/2017 11:50 PM, Jarkko Sakkinen wrote:
>>> On Thu, Jan 12, 2017 at 11:58:10AM -0500, Nayna Jain wrote:
>>>> The current TPM 2.0 device driver extends only the SHA1 PCR bank
>>>> but the TCG Specification[1] recommends extending all active PCR
>>>> banks, to prevent malicious users from setting unused PCR banks with
>>>> fake measurements and quoting them.
>>>>
>>>> The existing in-kernel interface(tpm_pcr_extend()) expects only a
>>>> SHA1 digest.  To extend all active PCR banks with differing
>>>> digest sizes, the SHA1 digest is padded with trailing 0's as needed.
>>>>
>>>> [1] TPM 2.0 Specification referred here is "TCG PC Client Specific
>>>> Platform Firmware Profile for TPM 2.0"
>>>>
>>>> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
>>>> ---
>>>>    drivers/char/tpm/Kconfig         |  1 +
>>>>    drivers/char/tpm/tpm-interface.c | 16 +++++++++-
>>>>    drivers/char/tpm/tpm.h           |  3 +-
>>>>    drivers/char/tpm/tpm2-cmd.c      | 68 +++++++++++++++++++++++-----------------
>>>>    drivers/char/tpm/tpm_eventlog.h  | 18 +++++++++++
>>>>    5 files changed, 75 insertions(+), 31 deletions(-)
>>>>
>>>> diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig
>>>> index 277186d..af985cc 100644
>>>> --- a/drivers/char/tpm/Kconfig
>>>> +++ b/drivers/char/tpm/Kconfig
>>>> @@ -6,6 +6,7 @@ menuconfig TCG_TPM
>>>>    	tristate "TPM Hardware Support"
>>>>    	depends on HAS_IOMEM
>>>>    	select SECURITYFS
>>>> +	select CRYPTO_HASH_INFO
>>>
>>> In the commit message you did not mention this.
>>>
>>>>    	---help---
>>>>    	  If you have a TPM security chip in your system, which
>>>>    	  implements the Trusted Computing Group's specification,
>>>> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
>>>> index fecdd3f..e037dd2 100644
>>>> --- a/drivers/char/tpm/tpm-interface.c
>>>> +++ b/drivers/char/tpm/tpm-interface.c
>>>> @@ -7,6 +7,7 @@
>>>>     * Dave Safford <safford@watson.ibm.com>
>>>>     * Reiner Sailer <sailer@watson.ibm.com>
>>>>     * Kylene Hall <kjhall@us.ibm.com>
>>>> + * Nayna Jain <nayna@linux.vnet.ibm.com>
>>>
>>> Remove.
>>>
>>>>     *
>>>>     * Maintained by: <tpmdd-devel@lists.sourceforge.net>
>>>>     *
>>>> @@ -759,6 +760,7 @@ static const struct tpm_input_header pcrextend_header = {
>>>>    int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>>>>    {
>>>>    	struct tpm_cmd_t cmd;
>>>> +	int i;
>>>>    	int rc;
>>>>    	struct tpm_chip *chip;
>>>>
>>>> @@ -767,7 +769,19 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
>>>>    		return -ENODEV;
>>>>
>>>>    	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
>>>> -		rc = tpm2_pcr_extend(chip, pcr_idx, hash);
>>>> +		struct tpml_digest_values d_values;
>>>> +
>>>> +		memset(&d_values, 0, sizeof(d_values));
>>>> +
>>>> +		for (i = 0; (chip->active_banks[i] != 0) &&
>>>> +		     (i < ARRAY_SIZE(chip->active_banks)); i++) {
>>>> +			d_values.digests[i].alg_id = chip->active_banks[i];
>>>> +			memcpy(d_values.digests[i].digest, hash,
>>>> +			       TPM_DIGEST_SIZE);
>>>> +			d_values.count++;
>>>> +		}
>>>> +
>>>> +		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
>>>>    		tpm_put_ops(chip);
>>>>    		return rc;
>>>>    	}
>>>> diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
>>>> index dddd573..dd82d58 100644
>>>> --- a/drivers/char/tpm/tpm.h
>>>> +++ b/drivers/char/tpm/tpm.h
>>>> @@ -533,7 +533,8 @@ static inline void tpm_add_ppi(struct tpm_chip *chip)
>>>>    #endif
>>>>
>>>>    int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
>>>> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash);
>>>> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
>>>> +		    struct tpml_digest_values *digests);
>>>>    int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max);
>>>>    int tpm2_seal_trusted(struct tpm_chip *chip,
>>>>    		      struct trusted_key_payload *payload,
>>>> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
>>>> index 87388921..5027a54 100644
>>>> --- a/drivers/char/tpm/tpm2-cmd.c
>>>> +++ b/drivers/char/tpm/tpm2-cmd.c
>>>> @@ -64,9 +64,7 @@ struct tpm2_pcr_extend_in {
>>>>    	__be32				pcr_idx;
>>>>    	__be32				auth_area_size;
>>>>    	struct tpm2_null_auth_area	auth_area;
>>>> -	__be32				digest_cnt;
>>>> -	__be16				hash_alg;
>>>> -	u8				digest[TPM_DIGEST_SIZE];
>>>> +	struct tpml_digest_values       digests;
>>>>    } __packed;
>>>>
>>>>    struct tpm2_get_tpm_pt_in {
>>>> @@ -296,46 +294,58 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
>>>>    	return rc;
>>>>    }
>>>>
>>>> -#define TPM2_GET_PCREXTEND_IN_SIZE \
>>>> -	(sizeof(struct tpm_input_header) + \
>>>> -	 sizeof(struct tpm2_pcr_extend_in))
>>>> -
>>>> -static const struct tpm_input_header tpm2_pcrextend_header = {
>>>> -	.tag = cpu_to_be16(TPM2_ST_SESSIONS),
>>>> -	.length = cpu_to_be32(TPM2_GET_PCREXTEND_IN_SIZE),
>>>> -	.ordinal = cpu_to_be32(TPM2_CC_PCR_EXTEND)
>>>> -};
>>>> -
>>>>    /**
>>>>     * tpm2_pcr_extend() - extend a PCR value
>>>>     *
>>>>     * @chip:	TPM chip to use.
>>>>     * @pcr_idx:	index of the PCR.
>>>> - * @hash:	hash value to use for the extend operation.
>>>> + * @digests:	list of pcr banks and corresponding hash values to be extended.
>>>>     *
>>>>     * Return: Same as with tpm_transmit_cmd.
>>>>     */
>>>> -int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
>>>> +int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
>>>> +		    struct tpml_digest_values *digests)
>>>>    {
>>>> -	struct tpm2_cmd cmd;
>>>> +	struct tpm_buf buf;
>>>> +	struct tpm2_null_auth_area auth_area;
>>>>    	int rc;
>>>> +	int i;
>>>> +	int j;
>>>>
>>>> -	cmd.header.in = tpm2_pcrextend_header;
>>>> -	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
>>>> -	cmd.params.pcrextend_in.auth_area_size =
>>>> -		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
>>>> -	cmd.params.pcrextend_in.auth_area.handle =
>>>> -		cpu_to_be32(TPM2_RS_PW);
>>>> -	cmd.params.pcrextend_in.auth_area.nonce_size = 0;
>>>> -	cmd.params.pcrextend_in.auth_area.attributes = 0;
>>>> -	cmd.params.pcrextend_in.auth_area.auth_size = 0;
>>>> -	cmd.params.pcrextend_in.digest_cnt = cpu_to_be32(1);
>>>> -	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
>>>> -	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
>>>> +	rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_PCR_EXTEND);
>>>> +	if (rc)
>>>> +		return rc;
>>>>
>>>> -	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
>>>> +	tpm_buf_append_u32(&buf, pcr_idx);
>>>> +
>>>> +	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_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, digests->count);
>>>> +
>>>> +	for (i = 0; i < digests->count; i++) {
>>>> +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
>>>> +			if (digests->digests[i].alg_id !=
>>>> +			    tpm2_hash_map[j].tpm_id)
>>>> +				continue;
>>>> +
>>>> +			tpm_buf_append_u16(&buf, digests->digests[i].alg_id);
>>>> +			tpm_buf_append(&buf, (const unsigned char
>>>> +					      *)&digests->digests[i].digest,
>>>> +				hash_digest_size[tpm2_hash_map[j].crypto_id]);
>>>> +		}
>>>> +	}
>>>> +
>>>> +	rc = tpm_transmit_cmd(chip, buf.data, tpm_buf_length(&buf), 0,
>>>>    			      "attempting extend a PCR value");
>>>>
>>>> +	tpm_buf_destroy(&buf);
>>>> +
>>>>    	return rc;
>>>>    }
>>>>
>>>> diff --git a/drivers/char/tpm/tpm_eventlog.h b/drivers/char/tpm/tpm_eventlog.h
>>>> index 1660d74..2e47f4d 100644
>>>> --- a/drivers/char/tpm/tpm_eventlog.h
>>>> +++ b/drivers/char/tpm/tpm_eventlog.h
>>>> @@ -2,9 +2,12 @@
>>>>    #ifndef __TPM_EVENTLOG_H__
>>>>    #define __TPM_EVENTLOG_H__
>>>>
>>>> +#include <crypto/hash_info.h>
>>>> +
>>>>    #define TCG_EVENT_NAME_LEN_MAX	255
>>>>    #define MAX_TEXT_EVENT		1000	/* Max event string length */
>>>>    #define ACPI_TCPA_SIG		"TCPA"	/* 0x41504354 /'TCPA' */
>>>> +#define TPM2_ACTIVE_PCR_BANKS	3
>>>>
>>>>    #ifdef CONFIG_PPC64
>>>>    #define do_endian_conversion(x) be32_to_cpu(x)
>>>> @@ -73,6 +76,21 @@ enum tcpa_pc_event_ids {
>>>>    	HOST_TABLE_OF_DEVICES,
>>>>    };
>>>>
>>>> +/**
>>>> + * Digest structures for TPM 2.0 as defined in document
>>>> + * Trusted Platform Module Library Part 2: Structures, Family "2.0".
>>>> + */
>>>
>>> Please remove this comment
>>>
>>>> +
>>>> +struct tpmt_ha {
>>>> +	u16 alg_id;
>>>> +	u8 digest[SHA384_DIGEST_SIZE];
>>>> +} __packed;
>>>
>>> struct tpm2_hash
>>
>> struct tpm2_hash is already defined in tpm2-cmd.c as below
>>
>> struct tpm2_hash {
>>          unsigned int crypto_id;
>>          unsigned int tpm_id;
>> };
>>
>> Though, I think this probably needs a different name, probably as "struct
>> tpm2_hash_ids_map" or just "struct tpm2_hash_ids"
>>
>> and then I rename struct tpmt_ha as struct tpm2_hash.
>>
>> If this sounds good, I will also rename existing tpm2_hash as different
>> patch.
>>
>> Thanks & Regards,
>>     - Nayna
>
> What if you just use tpm2_digest for the new structure?

I can.

Thanks & Regards,
- Nayna


>
> /Jarkko
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-01-17 20:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-12 16:58 [PATCH v3 0/2] tpm: enhance TPM 2.0 extend function to support multiple PCR banks Nayna Jain
2017-01-12 16:58 ` [PATCH v3 1/2] tpm: implement TPM 2.0 capability to get active " Nayna Jain
2017-01-12 18:25   ` Jarkko Sakkinen
2017-01-13  7:24     ` Nayna
2017-01-13 16:45       ` Jarkko Sakkinen
2017-01-12 16:58 ` [PATCH v3 2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks Nayna Jain
2017-01-12 18:20   ` Jarkko Sakkinen
2017-01-13  7:14     ` Nayna
2017-01-13 16:43       ` Jarkko Sakkinen
2017-01-17  7:53     ` Nayna
2017-01-17 16:13       ` Jarkko Sakkinen
2017-01-17 16:26         ` Nayna

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).