linux-integrity.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
  • * Re: [PATCH v2, RESEND 2/3] tpm: modify tpm_pcr_read() definition to pass TPM hash algorithms
           [not found] ` <20180917093820.20500-3-roberto.sassu@huawei.com>
           [not found]   ` <411432db-ea57-a537-05d3-0b53008bef27@huawei.com>
    @ 2018-09-25 13:27   ` Jarkko Sakkinen
      1 sibling, 0 replies; 9+ messages in thread
    From: Jarkko Sakkinen @ 2018-09-25 13:27 UTC (permalink / raw)
      To: Roberto Sassu; +Cc: linux-integrity, linux-security-module, linux-kernel
    
    On Mon, 2018-09-17 at 11:38 +0200, Roberto Sassu wrote:
    > Currently the TPM driver allows other kernel subsystems to read only the
    > SHA1 PCR bank. This patch modifies the parameters of tpm_pcr_read() and
    > tpm2_pcr_read() to pass an array of tpm_digest structures, which contains
    > the desired hash algorithms. Initially, the array size is limited to 1.
    > 
    > Due to the API change, IMA functions have been modified.
    > 
    > Signed-off-by: Roberto Sassu <roberto.sassu@huawei.com>
    > ---
    >  drivers/char/tpm/tpm-interface.c    | 13 +++++++++----
    >  drivers/char/tpm/tpm.h              |  3 ++-
    >  drivers/char/tpm/tpm2-cmd.c         | 17 +++++++++++------
    >  include/linux/tpm.h                 |  6 ++++--
    >  security/integrity/ima/ima_crypto.c | 10 +++++-----
    >  5 files changed, 31 insertions(+), 18 deletions(-)
    > 
    > diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-
    > interface.c
    > index 645c9aa7677a..81872880b5f1 100644
    > --- a/drivers/char/tpm/tpm-interface.c
    > +++ b/drivers/char/tpm/tpm-interface.c
    > @@ -976,21 +976,26 @@ EXPORT_SYMBOL_GPL(tpm_is_tpm2);
    >   * tpm_pcr_read - read a PCR value from SHA1 bank
    >   * @chip:	a &struct tpm_chip instance, %NULL for the default chip
    >   * @pcr_idx:	the PCR to be retrieved
    > - * @res_buf:	the value of the PCR
    > + * @count:	number of digests passed
    > + * @digests:	list of pcr banks and buffers current PCR values are
    > written to
    >   *
    >   * Return: same as with tpm_transmit_cmd()
    >   */
    > -int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
    > +int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u32 count,
    > +		 struct tpm_digest *digests)
    >  {
    >  	int rc;
    >  
    > +	if (count != 1)
    > +		return -EINVAL;
    > +
    >  	chip = tpm_find_get_ops(chip);
    >  	if (!chip)
    >  		return -ENODEV;
    >  	if (chip->flags & TPM_CHIP_FLAG_TPM2)
    > -		rc = tpm2_pcr_read(chip, pcr_idx, res_buf);
    > +		rc = tpm2_pcr_read(chip, pcr_idx, count, digests);
    >  	else
    > -		rc = tpm_pcr_read_dev(chip, pcr_idx, res_buf);
    > +		rc = tpm_pcr_read_dev(chip, pcr_idx, digests[0].digest);
    >  	tpm_put_ops(chip);
    >  	return rc;
    >  }
    > diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
    > index b928ba44d864..9479e1ae1b4c 100644
    > --- a/drivers/char/tpm/tpm.h
    > +++ b/drivers/char/tpm/tpm.h
    > @@ -564,7 +564,8 @@ static inline u32 tpm2_rc_value(u32 rc)
    >  	return (rc & BIT(7)) ? rc & 0xff : rc;
    >  }
    >  
    > -int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
    > +int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u32 count,
    > +		  struct tpm_digest *digests);
    >  int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, u32 count,
    >  		    struct tpm_digest *digests);
    >  int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max);
    > diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
    > index 2d7397b8a0d1..601d67c76c1e 100644
    > --- a/drivers/char/tpm/tpm2-cmd.c
    > +++ b/drivers/char/tpm/tpm2-cmd.c
    > @@ -179,11 +179,13 @@ struct tpm2_pcr_read_out {
    >   * tpm2_pcr_read() - read a PCR value
    >   * @chip:	TPM chip to use.
    >   * @pcr_idx:	index of the PCR to read.
    > - * @res_buf:	buffer to store the resulting hash.
    > + * @count:	number of digests passed.
    > + * @digests:	list of pcr banks and buffers current PCR values are
    > written to.
    >   *
    >   * Return: Same as with tpm_transmit_cmd.
    >   */
    > -int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
    > +int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u32 count,
    > +		  struct tpm_digest *digests)
    >  {
    >  	int rc;
    >  	struct tpm_buf buf;
    > @@ -192,6 +194,8 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8
    > *res_buf)
    >  
    >  	if (pcr_idx >= TPM2_PLATFORM_PCR)
    >  		return -EINVAL;
    > +	if (count > 1)
    > +		return -EINVAL;
    >  
    >  	rc = tpm_buf_init(&buf, TPM2_ST_NO_SESSIONS, TPM2_CC_PCR_READ);
    >  	if (rc)
    > @@ -200,16 +204,17 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8
    > *res_buf)
    >  	pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7);
    >  
    >  	tpm_buf_append_u32(&buf, 1);
    > -	tpm_buf_append_u16(&buf, TPM_ALG_SHA1);
    > +	tpm_buf_append_u16(&buf, count ? digests[0].alg_id : TPM_ALG_SHA1);
    >  	tpm_buf_append_u8(&buf, TPM2_PCR_SELECT_MIN);
    >  	tpm_buf_append(&buf, (const unsigned char *)pcr_select,
    >  		       sizeof(pcr_select));
    >  
    >  	rc = tpm_transmit_cmd(chip, NULL, buf.data, PAGE_SIZE, 0, 0,
    > -			res_buf ? "attempting to read a pcr value" : NULL);
    > -	if (rc == 0 && res_buf) {
    > +			      count ? "attempting to read a pcr value" :
    > NULL);
    > +	if (rc == 0 && count) {
    >  		out = (struct tpm2_pcr_read_out *)&buf.data[TPM_HEADER_SIZE];
    > -		memcpy(res_buf, out->digest, SHA1_DIGEST_SIZE);
    > +		memcpy(digests[0].digest, out->digest,
    > +		       be16_to_cpu(out->digest_size));
    >  	}
    >  
    >  	tpm_buf_destroy(&buf);
    > diff --git a/include/linux/tpm.h b/include/linux/tpm.h
    > index 71d7bbf5f690..ac9fc47f4494 100644
    > --- a/include/linux/tpm.h
    > +++ b/include/linux/tpm.h
    > @@ -71,7 +71,8 @@ struct tpm_class_ops {
    >  #if defined(CONFIG_TCG_TPM) || defined(CONFIG_TCG_TPM_MODULE)
    >  
    >  extern int tpm_is_tpm2(struct tpm_chip *chip);
    > -extern int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf);
    > +extern int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u32 count,
    > +			struct tpm_digest *digests);
    >  extern int tpm_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8
    > *hash);
    >  extern int tpm_send(struct tpm_chip *chip, void *cmd, size_t buflen);
    >  extern int tpm_get_random(struct tpm_chip *chip, u8 *data, size_t max);
    > @@ -87,7 +88,8 @@ static inline int tpm_is_tpm2(struct tpm_chip *chip)
    >  {
    >  	return -ENODEV;
    >  }
    > -static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u8
    > *res_buf)
    > +static inline int tpm_pcr_read(struct tpm_chip *chip, int pcr_idx, u32 count,
    > +			       struct tpm_digest *digests)
    >  {
    >  	return -ENODEV;
    >  }
    > diff --git a/security/integrity/ima/ima_crypto.c
    > b/security/integrity/ima/ima_crypto.c
    > index 7e7e7e7c250a..4c94cf810d15 100644
    > --- a/security/integrity/ima/ima_crypto.c
    > +++ b/security/integrity/ima/ima_crypto.c
    > @@ -629,12 +629,12 @@ int ima_calc_buffer_hash(const void *buf, loff_t len,
    >  	return calc_buffer_shash(buf, len, hash);
    >  }
    >  
    > -static void __init ima_pcrread(int idx, u8 *pcr)
    > +static void __init ima_pcrread(int idx, struct tpm_digest *d)
    >  {
    >  	if (!ima_tpm_chip)
    >  		return;
    >  
    > -	if (tpm_pcr_read(ima_tpm_chip, idx, pcr) != 0)
    > +	if (tpm_pcr_read(ima_tpm_chip, idx, 1, d) != 0)
    >  		pr_err("Error Communicating to TPM chip\n");
    >  }
    >  
    > @@ -644,7 +644,7 @@ static void __init ima_pcrread(int idx, u8 *pcr)
    >  static int __init ima_calc_boot_aggregate_tfm(char *digest,
    >  					      struct crypto_shash *tfm)
    >  {
    > -	u8 pcr_i[TPM_DIGEST_SIZE];
    > +	struct tpm_digest d = {.alg_id = TPM_ALG_SHA1};
    >  	int rc, i;
    >  	SHASH_DESC_ON_STACK(shash, tfm);
    >  
    > @@ -657,9 +657,9 @@ static int __init ima_calc_boot_aggregate_tfm(char
    > *digest,
    >  
    >  	/* cumulative sha1 over tpm registers 0-7 */
    >  	for (i = TPM_PCR0; i < TPM_PCR8; i++) {
    > -		ima_pcrread(i, pcr_i);
    > +		ima_pcrread(i, &d);
    >  		/* now accumulate with current aggregate */
    > -		rc = crypto_shash_update(shash, pcr_i, TPM_DIGEST_SIZE);
    > +		rc = crypto_shash_update(shash, d.digest, TPM_DIGEST_SIZE);
    >  	}
    >  	if (!rc)
    >  		crypto_shash_final(shash, digest);
    
    The change would be good if there was a patch in the series that would
    use arrays larger than one. The principle is that something added only
    at the point when it is taken use of. You should remove @count for now.
    
    /Jarkko
    
    ^ permalink raw reply	[flat|nested] 9+ messages in thread
  • [parent not found: <20180917093820.20500-4-roberto.sassu@huawei.com>]
  • * Re: [PATCH v2, RESEND 0/3] tpm: retrieve digest size of unknown algorithms from TPM
           [not found] <20180917093820.20500-1-roberto.sassu@huawei.com>
           [not found] ` <20180917093820.20500-3-roberto.sassu@huawei.com>
           [not found] ` <20180917093820.20500-4-roberto.sassu@huawei.com>
    @ 2018-09-26 14:40 ` Mimi Zohar
      2018-09-26 18:03   ` Mimi Zohar
      2 siblings, 1 reply; 9+ messages in thread
    From: Mimi Zohar @ 2018-09-26 14:40 UTC (permalink / raw)
      To: Roberto Sassu, jarkko.sakkinen
      Cc: linux-integrity, linux-security-module, linux-kernel
    
    On Mon, 2018-09-17 at 11:38 +0200, Roberto Sassu wrote:
    > Resending to maintainer with correct mailing lists in CC.
    > 
    > The TPM driver currently relies on the crypto subsystem to determine the
    > digest size of supported TPM algorithms. In the future, TPM vendors might
    > implement new algorithms in their chips, and those algorithms might not
    > be supported by the crypto subsystem.
    > 
    > Usually, vendors provide patches for the new hardware, and likely
    > the crypto subsystem will be updated before the new algorithm is
    > introduced. However, old kernels might be updated later, after patches
    > are included in the mainline kernel. This would leave the opportunity
    > for attackers to misuse PCRs, as PCR banks with an unknown algorithm
    > are not extended.
    > 
    > This patch set provides a long term solution for this issue. If a TPM
    > algorithm is not known by the crypto subsystem, the TPM driver retrieves
    > the digest size from the TPM with a PCR read. All the PCR banks are
    > extended, even if the algorithm is not yet supported by the crypto
    > subsystem.
    
    Other than checking the digest size before copying the pcrread buffer,
    the patches look good.  Please add my Ack on all 3 patches.
    
    (New address) Acked-by: Mimi Zohar <zohar@linux.ibm.com>
    
    Thanks!
    
    Mimi
    
    ^ permalink raw reply	[flat|nested] 9+ messages in thread

  • end of thread, other threads:[~2018-09-27 20:09 UTC | newest]
    
    Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
    -- links below jump to the message on this page --
         [not found] <20180917093820.20500-1-roberto.sassu@huawei.com>
         [not found] ` <20180917093820.20500-3-roberto.sassu@huawei.com>
         [not found]   ` <411432db-ea57-a537-05d3-0b53008bef27@huawei.com>
    2018-09-21 13:59     ` [PATCH v2, RESEND 2/3] tpm: modify tpm_pcr_read() definition to pass TPM hash algorithms Mimi Zohar
    2018-09-21 21:57     ` Jarkko Sakkinen
    2018-09-25 13:27   ` Jarkko Sakkinen
         [not found] ` <20180917093820.20500-4-roberto.sassu@huawei.com>
    2018-09-25 14:00   ` [PATCH v2, RESEND 3/3] tpm: retrieve digest size of unknown algorithms with PCR read Jarkko Sakkinen
    2018-09-26 14:40 ` [PATCH v2, RESEND 0/3] tpm: retrieve digest size of unknown algorithms from TPM Mimi Zohar
    2018-09-26 18:03   ` Mimi Zohar
    2018-09-27  6:50     ` Roberto Sassu
    2018-09-27 13:43       ` Mimi Zohar
    2018-09-27 13:50       ` Jarkko Sakkinen
    

    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).