diff mbox

[tpmdd-devel,2/2] tpm: enhance TPM 2.0 PCR extend to support multiple banks

Message ID 1475979357-1167-3-git-send-email-nayna@linux.vnet.ibm.com
State New
Headers show

Commit Message

Nayna Oct. 9, 2016, 2:15 a.m. UTC
Like TPM 1.2, the current device driver for TPM 2.0 supports
extending only to the SHA1 PCR bank. But the TPM 2.0 supports multiple
PCR banks and the specification recommends extending to all active PCR
banks, this patch enhances the existing device driver support for
TPM 2.0 extend function and its in-kernel interface to extend to all
active PCR banks.

The existing in-kernel 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 trailing 0's as needed.

Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
---
 drivers/char/tpm/tpm-interface.c | 17 ++++++++--
 drivers/char/tpm/tpm2-cmd.c      | 71 ++++++++++++++++++++++++++--------------
 drivers/char/tpm/tpm2.h          | 18 ++++++++++
 3 files changed, 79 insertions(+), 27 deletions(-)

Comments

Tomas Winkler Oct. 9, 2016, 6:28 a.m. UTC | #1
> Like TPM 1.2, the current device driver for TPM 2.0 supports extending only to
> the SHA1 PCR bank. But the TPM 2.0 supports multiple PCR banks and the
> specification recommends extending to all active PCR banks, this patch
> enhances the existing device driver support for TPM 2.0 extend function and
> its in-kernel interface to extend to all active PCR banks.
> 
> The existing in-kernel 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 trailing 0's as needed.
> 
> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
> ---
>  drivers/char/tpm/tpm-interface.c | 17 ++++++++--
>  drivers/char/tpm/tpm2-cmd.c      | 71 ++++++++++++++++++++++++++------------
> --
>  drivers/char/tpm/tpm2.h          | 18 ++++++++++
>  3 files changed, 79 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-
> interface.c
> index 7743e8a..5dd5005 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>
>   *
> @@ -32,6 +33,7 @@
>  #include <linux/pm_runtime.h>
> 
>  #include "tpm.h"
> +#include "tpm2.h"
>  #include "tpm_eventlog.h"
> 
>  #define TPM_MAX_ORDINAL 243
> @@ -752,7 +754,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 rc;
> +	int i, rc;
>  	struct tpm_chip *chip;
> 
>  	chip = tpm_chip_find_get(chip_num);
> @@ -760,7 +762,18 @@ 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; i < chip->no_of_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++;
> +		}

This is tpm2 only feature so  I suggest to create a function inside tpm2-chip.c instead of  open coding  it here.
This will probably also prevent all this code movement. 


> +		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
>  		tpm_put_ops(chip);
>  		return rc;
>  	}
> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index c597cf3c..8ba2992 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -16,6 +16,7 @@
>   */
> 
>  #include "tpm.h"
> +#include "tpm2.h"
>  #include <crypto/hash_info.h>
>  #include <keys/trusted-type.h>
> 
> @@ -53,22 +54,6 @@ struct tpm2_pcr_read_out {
>  	u8	digest[TPM_DIGEST_SIZE];
>  } __packed;
> 
> -struct tpm2_null_auth_area {
> -	__be32			handle;
> -	__be16			nonce_size;
> -	u8			attributes;
> -	__be16			auth_size;
> -} __packed;
> -
> -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];
> -} __packed;
> -
>  struct tpm2_get_tpm_pt_in {
>  	__be32	cap_id;
>  	__be32	property_id;
> @@ -300,38 +285,74 @@ int tpm2_pcr_read(struct tpm_chip *chip, int
> pcr_idx, u8 *res_buf)
> 
>  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.
> + * @chip:		TPM chip to use.
> + * @pcr_idx:		index of the PCR.
> + * @digest_values:	list of hash values to be extended.
>   *
>   * 0 is returned when the operation is successful. If a negative number is
>   * returned it remarks a POSIX error code. If a positive number is returned
>   * it remarks a TPM error.
>   */
> -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 *digest_list)
>  {
>  	struct tpm2_cmd cmd;
> -	int rc;
> +	int i, j, rc;
> +	void *marker;
> +	size_t size;
> +	u32 halg_size;
> +	u16 halg;
> 
>  	cmd.header.in = tpm2_pcrextend_header;
> +	size = sizeof(struct tpm_input_header);
> +
>  	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
> +	size = size + sizeof(cmd.params.pcrextend_in.pcr_idx);
> +
>  	cmd.params.pcrextend_in.auth_area_size =
>  		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
> +	size = size + sizeof(cmd.params.pcrextend_in.auth_area_size);
> +
>  	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);
> +	size = size + sizeof(cmd.params.pcrextend_in.auth_area);
> +
> +	cmd.params.pcrextend_in.digests.count =
> +		cpu_to_be32(digest_list->count);
> +	size = size + sizeof(cmd.params.pcrextend_in.digests.count);
> +	marker = &cmd.params.pcrextend_in.digests.digests[0];
> +
> +	for (i = 0; i < digest_list->count; i++) {
> +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
> +
> +			if (digest_list->digests[i].alg_id !=
> +			    tpm2_hash_map[j].tpm_id)
> +				continue;
> +
> +			halg_size = sizeof(digest_list->digests[i].alg_id);
> +			halg = cpu_to_be16(digest_list->digests[i].alg_id);
> +			memcpy(marker, &halg, halg_size);
> +			marker = marker + halg_size;
> +			size = size + halg_size;
> +
> +			memcpy(marker, &digest_list->digests[i].digest,
> +			       hash_digest_size[tpm2_hash_map[j].crypto_id]);
> +			marker = marker +
> +
> 	hash_digest_size[tpm2_hash_map[j].crypto_id];
> +			size = size +
> +
> 	hash_digest_size[tpm2_hash_map[j].crypto_id];
> +		}
> +	}
> 
> +	cmd.header.in.length = cpu_to_be32(size);
>  	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
>  			      "attempting extend a PCR value");
> 
> diff --git a/drivers/char/tpm/tpm2.h b/drivers/char/tpm/tpm2.h index
> 919fb05..0b1a107 100644
> --- a/drivers/char/tpm/tpm2.h
> +++ b/drivers/char/tpm/tpm2.h
> @@ -74,6 +74,22 @@ struct tcg_pcr_event2 {
>  	struct tcg_event_field		event;
>  } __packed;
> 
> +/* Auth Area Structure. */
> +struct tpm2_null_auth_area {
> +	__be32		handle;
> +	__be16		nonce_size;
> +	u8		attributes;
> +	__be16		auth_size;
> +} __packed;
> +
> +/* Crypto agile extend format. */
> +struct tpm2_pcr_extend_in {
> +	__be32				pcr_idx;
> +	__be32				auth_area_size;
> +	struct tpm2_null_auth_area	auth_area;
> +	struct tpml_digest_values	digests;
> +} __packed;
> +
>  struct tpm2_get_cap_in {
>  	__be32 cap_id;
>  	__be32 property_id;
> @@ -108,6 +124,8 @@ struct tpm2_get_cap_out {  extern const struct
> seq_operations tpm2_binary_b_measurments_seqops;
> 
>  extern int tpm2_get_active_pcr_banks(struct tpm_chip *chip);
> +extern int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> +			   struct tpml_digest_values *digest_values);
>  extern int tpm2_get_capability(struct tpm_chip *chip, struct
> tpm2_get_cap_in
>  	*cap_in, struct tpm2_get_cap_out *cap_out);
> 
> --
> 2.5.0
> 
> 
> ------------------------------------------------------------------------------
> Check out the vibrant tech community on one of the world's most
> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
> _______________________________________________
> tpmdd-devel mailing list
> tpmdd-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/tpmdd-devel

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Jarkko Sakkinen Oct. 9, 2016, 9:06 a.m. UTC | #2
On Sat, Oct 08, 2016 at 10:15:57PM -0400, Nayna Jain wrote:
> Like TPM 1.2, the current device driver for TPM 2.0 supports
> extending only to the SHA1 PCR bank. But the TPM 2.0 supports multiple
> PCR banks and the specification recommends extending to all active PCR
> banks, this patch enhances the existing device driver support for
> TPM 2.0 extend function and its in-kernel interface to extend to all
> active PCR banks.
> 
> The existing in-kernel 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 trailing 0's as needed.
> 
> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
> ---
>  drivers/char/tpm/tpm-interface.c | 17 ++++++++--
>  drivers/char/tpm/tpm2-cmd.c      | 71 ++++++++++++++++++++++++++--------------
>  drivers/char/tpm/tpm2.h          | 18 ++++++++++
>  3 files changed, 79 insertions(+), 27 deletions(-)

I'll ignore this commit because:

1. This is not used anywhere.
2. Does not apply to upstream.

/Jarkko

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Jarkko Sakkinen Oct. 9, 2016, 10:24 a.m. UTC | #3
On Sat, Oct 08, 2016 at 10:15:57PM -0400, Nayna Jain wrote:
> Like TPM 1.2, the current device driver for TPM 2.0 supports
> extending only to the SHA1 PCR bank. But the TPM 2.0 supports multiple
> PCR banks and the specification recommends extending to all active PCR
> banks, this patch enhances the existing device driver support for
> TPM 2.0 extend function and its in-kernel interface to extend to all
> active PCR banks.
> 
> The existing in-kernel 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 trailing 0's as needed.
> 
> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>

Please use struct tpm_buf for variable size stuff. You can see example
from trusted keys code in tpm2-cmd.c how to work on it.

/Jarkko

> ---
>  drivers/char/tpm/tpm-interface.c | 17 ++++++++--
>  drivers/char/tpm/tpm2-cmd.c      | 71 ++++++++++++++++++++++++++--------------
>  drivers/char/tpm/tpm2.h          | 18 ++++++++++
>  3 files changed, 79 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index 7743e8a..5dd5005 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>
>   *
> @@ -32,6 +33,7 @@
>  #include <linux/pm_runtime.h>
>  
>  #include "tpm.h"
> +#include "tpm2.h"
>  #include "tpm_eventlog.h"
>  
>  #define TPM_MAX_ORDINAL 243
> @@ -752,7 +754,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 rc;
> +	int i, rc;
>  	struct tpm_chip *chip;
>  
>  	chip = tpm_chip_find_get(chip_num);
> @@ -760,7 +762,18 @@ 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; i < chip->no_of_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/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
> index c597cf3c..8ba2992 100644
> --- a/drivers/char/tpm/tpm2-cmd.c
> +++ b/drivers/char/tpm/tpm2-cmd.c
> @@ -16,6 +16,7 @@
>   */
>  
>  #include "tpm.h"
> +#include "tpm2.h"
>  #include <crypto/hash_info.h>
>  #include <keys/trusted-type.h>
>  
> @@ -53,22 +54,6 @@ struct tpm2_pcr_read_out {
>  	u8	digest[TPM_DIGEST_SIZE];
>  } __packed;
>  
> -struct tpm2_null_auth_area {
> -	__be32			handle;
> -	__be16			nonce_size;
> -	u8			attributes;
> -	__be16			auth_size;
> -} __packed;
> -
> -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];
> -} __packed;
> -
>  struct tpm2_get_tpm_pt_in {
>  	__be32	cap_id;
>  	__be32	property_id;
> @@ -300,38 +285,74 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
>  
>  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.
> + * @chip:		TPM chip to use.
> + * @pcr_idx:		index of the PCR.
> + * @digest_values:	list of hash values to be extended.
>   *
>   * 0 is returned when the operation is successful. If a negative number is
>   * returned it remarks a POSIX error code. If a positive number is returned
>   * it remarks a TPM error.
>   */
> -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 *digest_list)
>  {
>  	struct tpm2_cmd cmd;
> -	int rc;
> +	int i, j, rc;
> +	void *marker;
> +	size_t size;
> +	u32 halg_size;
> +	u16 halg;
>  
>  	cmd.header.in = tpm2_pcrextend_header;
> +	size = sizeof(struct tpm_input_header);
> +
>  	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
> +	size = size + sizeof(cmd.params.pcrextend_in.pcr_idx);
> +
>  	cmd.params.pcrextend_in.auth_area_size =
>  		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
> +	size = size + sizeof(cmd.params.pcrextend_in.auth_area_size);
> +
>  	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);
> +	size = size + sizeof(cmd.params.pcrextend_in.auth_area);
> +
> +	cmd.params.pcrextend_in.digests.count =
> +		cpu_to_be32(digest_list->count);
> +	size = size + sizeof(cmd.params.pcrextend_in.digests.count);
> +	marker = &cmd.params.pcrextend_in.digests.digests[0];
> +
> +	for (i = 0; i < digest_list->count; i++) {
> +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
> +
> +			if (digest_list->digests[i].alg_id !=
> +			    tpm2_hash_map[j].tpm_id)
> +				continue;
> +
> +			halg_size = sizeof(digest_list->digests[i].alg_id);
> +			halg = cpu_to_be16(digest_list->digests[i].alg_id);
> +			memcpy(marker, &halg, halg_size);
> +			marker = marker + halg_size;
> +			size = size + halg_size;
> +
> +			memcpy(marker, &digest_list->digests[i].digest,
> +			       hash_digest_size[tpm2_hash_map[j].crypto_id]);
> +			marker = marker +
> +				hash_digest_size[tpm2_hash_map[j].crypto_id];
> +			size = size +
> +				hash_digest_size[tpm2_hash_map[j].crypto_id];
> +		}
> +	}
>  
> +	cmd.header.in.length = cpu_to_be32(size);
>  	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
>  			      "attempting extend a PCR value");
>  
> diff --git a/drivers/char/tpm/tpm2.h b/drivers/char/tpm/tpm2.h
> index 919fb05..0b1a107 100644
> --- a/drivers/char/tpm/tpm2.h
> +++ b/drivers/char/tpm/tpm2.h
> @@ -74,6 +74,22 @@ struct tcg_pcr_event2 {
>  	struct tcg_event_field		event;
>  } __packed;
>  
> +/* Auth Area Structure. */
> +struct tpm2_null_auth_area {
> +	__be32		handle;
> +	__be16		nonce_size;
> +	u8		attributes;
> +	__be16		auth_size;
> +} __packed;
> +
> +/* Crypto agile extend format. */
> +struct tpm2_pcr_extend_in {
> +	__be32				pcr_idx;
> +	__be32				auth_area_size;
> +	struct tpm2_null_auth_area	auth_area;
> +	struct tpml_digest_values	digests;
> +} __packed;
> +
>  struct tpm2_get_cap_in {
>  	__be32 cap_id;
>  	__be32 property_id;
> @@ -108,6 +124,8 @@ struct tpm2_get_cap_out {
>  extern const struct seq_operations tpm2_binary_b_measurments_seqops;
>  
>  extern int tpm2_get_active_pcr_banks(struct tpm_chip *chip);
> +extern int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
> +			   struct tpml_digest_values *digest_values);
>  extern int tpm2_get_capability(struct tpm_chip *chip, struct tpm2_get_cap_in
>  	*cap_in, struct tpm2_get_cap_out *cap_out);
>  
> -- 
> 2.5.0
> 

------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Nayna Oct. 12, 2016, 4:50 p.m. UTC | #4
On 10/09/2016 11:58 AM, Winkler, Tomas wrote:
>> Like TPM 1.2, the current device driver for TPM 2.0 supports extending only to
>> the SHA1 PCR bank. But the TPM 2.0 supports multiple PCR banks and the
>> specification recommends extending to all active PCR banks, this patch
>> enhances the existing device driver support for TPM 2.0 extend function and
>> its in-kernel interface to extend to all active PCR banks.
>>
>> The existing in-kernel 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 trailing 0's as needed.
>>
>> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
>> ---
>>   drivers/char/tpm/tpm-interface.c | 17 ++++++++--
>>   drivers/char/tpm/tpm2-cmd.c      | 71 ++++++++++++++++++++++++++------------
>> --
>>   drivers/char/tpm/tpm2.h          | 18 ++++++++++
>>   3 files changed, 79 insertions(+), 27 deletions(-)
>>
>> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-
>> interface.c
>> index 7743e8a..5dd5005 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>
>>    *
>> @@ -32,6 +33,7 @@
>>   #include <linux/pm_runtime.h>
>>
>>   #include "tpm.h"
>> +#include "tpm2.h"
>>   #include "tpm_eventlog.h"
>>
>>   #define TPM_MAX_ORDINAL 243
>> @@ -752,7 +754,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 rc;
>> +	int i, rc;
>>   	struct tpm_chip *chip;
>>
>>   	chip = tpm_chip_find_get(chip_num);
>> @@ -760,7 +762,18 @@ 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; i < chip->no_of_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++;
>> +		}
>
> This is tpm2 only feature so  I suggest to create a function inside tpm2-chip.c instead of  open coding  it here.
> This will probably also prevent all this code movement.

Thanks Tomas for reviewing, will look at this.
And I think you meant inside tpm2-cmd.c ?

Thanks & Regards,
    - Nayna


>
>
>> +		rc = tpm2_pcr_extend(chip, pcr_idx, &d_values);
>>   		tpm_put_ops(chip);
>>   		return rc;
>>   	}
>> diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
>> index c597cf3c..8ba2992 100644
>> --- a/drivers/char/tpm/tpm2-cmd.c
>> +++ b/drivers/char/tpm/tpm2-cmd.c
>> @@ -16,6 +16,7 @@
>>    */
>>
>>   #include "tpm.h"
>> +#include "tpm2.h"
>>   #include <crypto/hash_info.h>
>>   #include <keys/trusted-type.h>
>>
>> @@ -53,22 +54,6 @@ struct tpm2_pcr_read_out {
>>   	u8	digest[TPM_DIGEST_SIZE];
>>   } __packed;
>>
>> -struct tpm2_null_auth_area {
>> -	__be32			handle;
>> -	__be16			nonce_size;
>> -	u8			attributes;
>> -	__be16			auth_size;
>> -} __packed;
>> -
>> -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];
>> -} __packed;
>> -
>>   struct tpm2_get_tpm_pt_in {
>>   	__be32	cap_id;
>>   	__be32	property_id;
>> @@ -300,38 +285,74 @@ int tpm2_pcr_read(struct tpm_chip *chip, int
>> pcr_idx, u8 *res_buf)
>>
>>   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.
>> + * @chip:		TPM chip to use.
>> + * @pcr_idx:		index of the PCR.
>> + * @digest_values:	list of hash values to be extended.
>>    *
>>    * 0 is returned when the operation is successful. If a negative number is
>>    * returned it remarks a POSIX error code. If a positive number is returned
>>    * it remarks a TPM error.
>>    */
>> -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 *digest_list)
>>   {
>>   	struct tpm2_cmd cmd;
>> -	int rc;
>> +	int i, j, rc;
>> +	void *marker;
>> +	size_t size;
>> +	u32 halg_size;
>> +	u16 halg;
>>
>>   	cmd.header.in = tpm2_pcrextend_header;
>> +	size = sizeof(struct tpm_input_header);
>> +
>>   	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
>> +	size = size + sizeof(cmd.params.pcrextend_in.pcr_idx);
>> +
>>   	cmd.params.pcrextend_in.auth_area_size =
>>   		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
>> +	size = size + sizeof(cmd.params.pcrextend_in.auth_area_size);
>> +
>>   	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);
>> +	size = size + sizeof(cmd.params.pcrextend_in.auth_area);
>> +
>> +	cmd.params.pcrextend_in.digests.count =
>> +		cpu_to_be32(digest_list->count);
>> +	size = size + sizeof(cmd.params.pcrextend_in.digests.count);
>> +	marker = &cmd.params.pcrextend_in.digests.digests[0];
>> +
>> +	for (i = 0; i < digest_list->count; i++) {
>> +		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
>> +
>> +			if (digest_list->digests[i].alg_id !=
>> +			    tpm2_hash_map[j].tpm_id)
>> +				continue;
>> +
>> +			halg_size = sizeof(digest_list->digests[i].alg_id);
>> +			halg = cpu_to_be16(digest_list->digests[i].alg_id);
>> +			memcpy(marker, &halg, halg_size);
>> +			marker = marker + halg_size;
>> +			size = size + halg_size;
>> +
>> +			memcpy(marker, &digest_list->digests[i].digest,
>> +			       hash_digest_size[tpm2_hash_map[j].crypto_id]);
>> +			marker = marker +
>> +
>> 	hash_digest_size[tpm2_hash_map[j].crypto_id];
>> +			size = size +
>> +
>> 	hash_digest_size[tpm2_hash_map[j].crypto_id];
>> +		}
>> +	}
>>
>> +	cmd.header.in.length = cpu_to_be32(size);
>>   	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
>>   			      "attempting extend a PCR value");
>>
>> diff --git a/drivers/char/tpm/tpm2.h b/drivers/char/tpm/tpm2.h index
>> 919fb05..0b1a107 100644
>> --- a/drivers/char/tpm/tpm2.h
>> +++ b/drivers/char/tpm/tpm2.h
>> @@ -74,6 +74,22 @@ struct tcg_pcr_event2 {
>>   	struct tcg_event_field		event;
>>   } __packed;
>>
>> +/* Auth Area Structure. */
>> +struct tpm2_null_auth_area {
>> +	__be32		handle;
>> +	__be16		nonce_size;
>> +	u8		attributes;
>> +	__be16		auth_size;
>> +} __packed;
>> +
>> +/* Crypto agile extend format. */
>> +struct tpm2_pcr_extend_in {
>> +	__be32				pcr_idx;
>> +	__be32				auth_area_size;
>> +	struct tpm2_null_auth_area	auth_area;
>> +	struct tpml_digest_values	digests;
>> +} __packed;
>> +
>>   struct tpm2_get_cap_in {
>>   	__be32 cap_id;
>>   	__be32 property_id;
>> @@ -108,6 +124,8 @@ struct tpm2_get_cap_out {  extern const struct
>> seq_operations tpm2_binary_b_measurments_seqops;
>>
>>   extern int tpm2_get_active_pcr_banks(struct tpm_chip *chip);
>> +extern int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
>> +			   struct tpml_digest_values *digest_values);
>>   extern int tpm2_get_capability(struct tpm_chip *chip, struct
>> tpm2_get_cap_in
>>   	*cap_in, struct tpm2_get_cap_out *cap_out);
>>
>> --
>> 2.5.0
>>
>>
>> ------------------------------------------------------------------------------
>> Check out the vibrant tech community on one of the world's most
>> engaging tech sites, SlashDot.org! http://sdm.link/slashdot
>> _______________________________________________
>> tpmdd-devel mailing list
>> tpmdd-devel@lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/tpmdd-devel
>


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
Tomas Winkler Oct. 12, 2016, 7:02 p.m. UTC | #5
> 
> 
> On 10/09/2016 11:58 AM, Winkler, Tomas wrote:
> >> Like TPM 1.2, the current device driver for TPM 2.0 supports
> >> extending only to the SHA1 PCR bank. But the TPM 2.0 supports
> >> multiple PCR banks and the specification recommends extending to all
> >> active PCR banks, this patch enhances the existing device driver
> >> support for TPM 2.0 extend function and its in-kernel interface to extend to
> all active PCR banks.
> >>
> >> The existing in-kernel 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 trailing 0's as needed.
> >>
> >> Signed-off-by: Nayna Jain <nayna@linux.vnet.ibm.com>
> >> ---
> >>   drivers/char/tpm/tpm-interface.c | 17 ++++++++--
> >>   drivers/char/tpm/tpm2-cmd.c      | 71 ++++++++++++++++++++++++++-------
> -----
> >> --
> >>   drivers/char/tpm/tpm2.h          | 18 ++++++++++
> >>   3 files changed, 79 insertions(+), 27 deletions(-)
> >>
> >> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-
> >> interface.c index 7743e8a..5dd5005 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>
> >>    *
> >> @@ -32,6 +33,7 @@
> >>   #include <linux/pm_runtime.h>
> >>
> >>   #include "tpm.h"
> >> +#include "tpm2.h"
> >>   #include "tpm_eventlog.h"
> >>
> >>   #define TPM_MAX_ORDINAL 243
> >> @@ -752,7 +754,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 rc;
> >> +	int i, rc;
> >>   	struct tpm_chip *chip;
> >>
> >>   	chip = tpm_chip_find_get(chip_num); @@ -760,7 +762,18 @@ 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; i < chip->no_of_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++;
> >> +		}
> >
> > This is tpm2 only feature so  I suggest to create a function inside tpm2-chip.c
> instead of  open coding  it here.
> > This will probably also prevent all this code movement.
> 
> Thanks Tomas for reviewing, will look at this.
> And I think you meant inside tpm2-cmd.c ?

Right.
Tomas 


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most 
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
diff mbox

Patch

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 7743e8a..5dd5005 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>
  *
@@ -32,6 +33,7 @@ 
 #include <linux/pm_runtime.h>
 
 #include "tpm.h"
+#include "tpm2.h"
 #include "tpm_eventlog.h"
 
 #define TPM_MAX_ORDINAL 243
@@ -752,7 +754,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 rc;
+	int i, rc;
 	struct tpm_chip *chip;
 
 	chip = tpm_chip_find_get(chip_num);
@@ -760,7 +762,18 @@  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; i < chip->no_of_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/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index c597cf3c..8ba2992 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -16,6 +16,7 @@ 
  */
 
 #include "tpm.h"
+#include "tpm2.h"
 #include <crypto/hash_info.h>
 #include <keys/trusted-type.h>
 
@@ -53,22 +54,6 @@  struct tpm2_pcr_read_out {
 	u8	digest[TPM_DIGEST_SIZE];
 } __packed;
 
-struct tpm2_null_auth_area {
-	__be32			handle;
-	__be16			nonce_size;
-	u8			attributes;
-	__be16			auth_size;
-} __packed;
-
-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];
-} __packed;
-
 struct tpm2_get_tpm_pt_in {
 	__be32	cap_id;
 	__be32	property_id;
@@ -300,38 +285,74 @@  int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
 
 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.
+ * @chip:		TPM chip to use.
+ * @pcr_idx:		index of the PCR.
+ * @digest_values:	list of hash values to be extended.
  *
  * 0 is returned when the operation is successful. If a negative number is
  * returned it remarks a POSIX error code. If a positive number is returned
  * it remarks a TPM error.
  */
-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 *digest_list)
 {
 	struct tpm2_cmd cmd;
-	int rc;
+	int i, j, rc;
+	void *marker;
+	size_t size;
+	u32 halg_size;
+	u16 halg;
 
 	cmd.header.in = tpm2_pcrextend_header;
+	size = sizeof(struct tpm_input_header);
+
 	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
+	size = size + sizeof(cmd.params.pcrextend_in.pcr_idx);
+
 	cmd.params.pcrextend_in.auth_area_size =
 		cpu_to_be32(sizeof(struct tpm2_null_auth_area));
+	size = size + sizeof(cmd.params.pcrextend_in.auth_area_size);
+
 	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);
+	size = size + sizeof(cmd.params.pcrextend_in.auth_area);
+
+	cmd.params.pcrextend_in.digests.count =
+		cpu_to_be32(digest_list->count);
+	size = size + sizeof(cmd.params.pcrextend_in.digests.count);
+	marker = &cmd.params.pcrextend_in.digests.digests[0];
+
+	for (i = 0; i < digest_list->count; i++) {
+		for (j = 0; j < ARRAY_SIZE(tpm2_hash_map); j++) {
+
+			if (digest_list->digests[i].alg_id !=
+			    tpm2_hash_map[j].tpm_id)
+				continue;
+
+			halg_size = sizeof(digest_list->digests[i].alg_id);
+			halg = cpu_to_be16(digest_list->digests[i].alg_id);
+			memcpy(marker, &halg, halg_size);
+			marker = marker + halg_size;
+			size = size + halg_size;
+
+			memcpy(marker, &digest_list->digests[i].digest,
+			       hash_digest_size[tpm2_hash_map[j].crypto_id]);
+			marker = marker +
+				hash_digest_size[tpm2_hash_map[j].crypto_id];
+			size = size +
+				hash_digest_size[tpm2_hash_map[j].crypto_id];
+		}
+	}
 
+	cmd.header.in.length = cpu_to_be32(size);
 	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
 			      "attempting extend a PCR value");
 
diff --git a/drivers/char/tpm/tpm2.h b/drivers/char/tpm/tpm2.h
index 919fb05..0b1a107 100644
--- a/drivers/char/tpm/tpm2.h
+++ b/drivers/char/tpm/tpm2.h
@@ -74,6 +74,22 @@  struct tcg_pcr_event2 {
 	struct tcg_event_field		event;
 } __packed;
 
+/* Auth Area Structure. */
+struct tpm2_null_auth_area {
+	__be32		handle;
+	__be16		nonce_size;
+	u8		attributes;
+	__be16		auth_size;
+} __packed;
+
+/* Crypto agile extend format. */
+struct tpm2_pcr_extend_in {
+	__be32				pcr_idx;
+	__be32				auth_area_size;
+	struct tpm2_null_auth_area	auth_area;
+	struct tpml_digest_values	digests;
+} __packed;
+
 struct tpm2_get_cap_in {
 	__be32 cap_id;
 	__be32 property_id;
@@ -108,6 +124,8 @@  struct tpm2_get_cap_out {
 extern const struct seq_operations tpm2_binary_b_measurments_seqops;
 
 extern int tpm2_get_active_pcr_banks(struct tpm_chip *chip);
+extern int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx,
+			   struct tpml_digest_values *digest_values);
 extern int tpm2_get_capability(struct tpm_chip *chip, struct tpm2_get_cap_in
 	*cap_in, struct tpm2_get_cap_out *cap_out);