From fdb9805d6884090fd7bf62dbdf9c858692e55fb4 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Wed, 4 Sep 2019 10:57:30 +0200 Subject: security/tpm/tss/tcg-2.0: Add multi digits support to tlcl_extend() To support multi digists the tlcl_extend() for TPM2 expects TPML_DIGEST_VALUE pointer as input argument. BUG=N/A TEST=Build binary and verified logging on Facebook FBG-1701 Change-Id: I8d86c41c23e4e93a84e0527d7cddcfd30d5d8394 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/33252 Tested-by: build bot (Jenkins) Reviewed-by: Lance Zhao --- src/security/tpm/tspi/tspi.c | 23 +++++++++++ src/security/tpm/tss/tcg-2.0/tss.c | 58 +++++++++++++++++++++++---- src/security/tpm/tss/tcg-2.0/tss_structures.h | 20 ++++++--- 3 files changed, 88 insertions(+), 13 deletions(-) (limited to 'src/security') diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c index 4698a4dc8c..4cf371196e 100644 --- a/src/security/tpm/tspi/tspi.c +++ b/src/security/tpm/tspi/tspi.c @@ -4,6 +4,7 @@ * Copyright (c) 2013 The Chromium OS Authors. All rights reserved. * Copyright 2017 Facebook Inc. * Copyright 2018 Siemens AG + * Copyright 2019 Eltan B.V. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,6 +21,7 @@ #include #include #include +#include #if CONFIG(VBOOT) #include #include @@ -209,7 +211,28 @@ uint32_t tpm_extend_pcr(int pcr, enum vb2_hash_algorithm digest_algo, if (!digest) return TPM_E_IOERROR; +#if CONFIG(TPM2) + TPML_DIGEST_VALUES tpml_digests; + + tpml_digests.count = 1; + switch (digest_algo) { + case VB2_HASH_SHA1: + tpml_digests.digests[0].hashAlg = TPM_ALG_SHA1; + memcpy(tpml_digests.digests[0].digest.sha1, + digest, sizeof(TPMU_HA)); + break; + case VB2_HASH_SHA256: + tpml_digests.digests[0].hashAlg = TPM_ALG_SHA256; + memcpy(tpml_digests.digests[0].digest.sha256, + digest, sizeof(TPMU_HA)); + break; + default: + return TPM_E_IOERROR; + } + result = tlcl_extend(pcr, (uint8_t *)&tpml_digests, NULL); +#else result = tlcl_extend(pcr, digest, NULL); +#endif if (result != TPM_SUCCESS) return result; diff --git a/src/security/tpm/tss/tcg-2.0/tss.c b/src/security/tpm/tss/tcg-2.0/tss.c index 16e40fe569..fab334f798 100644 --- a/src/security/tpm/tss/tcg-2.0/tss.c +++ b/src/security/tpm/tss/tcg-2.0/tss.c @@ -127,24 +127,68 @@ uint32_t tlcl_assert_physical_presence(void) } /* - * The caller will provide the digest in a 32 byte buffer, let's consider it a - * sha256 digest. + * The caller will provide the digest in a 32 byte buffer */ uint32_t tlcl_extend(int pcr_num, const uint8_t *in_digest, uint8_t *out_digest) { struct tpm2_pcr_extend_cmd pcr_ext_cmd; struct tpm2_response *response; + int i; + TPML_DIGEST_VALUES *tpml_digests; pcr_ext_cmd.pcrHandle = HR_PCR + pcr_num; - pcr_ext_cmd.digests.count = 1; - pcr_ext_cmd.digests.digests[0].hashAlg = TPM_ALG_SHA256; - memcpy(pcr_ext_cmd.digests.digests[0].digest.sha256, in_digest, - sizeof(pcr_ext_cmd.digests.digests[0].digest.sha256)); + tpml_digests = (TPML_DIGEST_VALUES *)in_digest; + pcr_ext_cmd.digests.count = tpml_digests->count; + + for (i = 0; i < tpml_digests->count ; i++) { + pcr_ext_cmd.digests.digests[i].hashAlg = + tpml_digests->digests[i].hashAlg; + switch (tpml_digests->digests[i].hashAlg) { + case TPM_ALG_SHA1: + memcpy(pcr_ext_cmd.digests.digests[i].digest.sha1, + tpml_digests->digests[i].digest.sha1, + sizeof(TPMU_HA)); + break; + case TPM_ALG_SHA256: + memcpy(pcr_ext_cmd.digests.digests[i].digest.sha256, + tpml_digests->digests[i].digest.sha256, + sizeof(TPMU_HA)); + break; + case TPM_ALG_SHA384: + memcpy(pcr_ext_cmd.digests.digests[i].digest.sha384, + tpml_digests->digests[i].digest.sha384, + sizeof(TPMU_HA)); + break; + case TPM_ALG_SHA512: + memcpy(pcr_ext_cmd.digests.digests[i].digest.sha512, + tpml_digests->digests[i].digest.sha512, + sizeof(TPMU_HA)); + break; + case TPM_ALG_SM3_256: + memcpy(pcr_ext_cmd.digests.digests[i].digest.sm3_256, + tpml_digests->digests[i].digest.sm3_256, + sizeof(TPMU_HA)); + break; + } + } response = tpm_process_command(TPM2_PCR_Extend, &pcr_ext_cmd); - printk(BIOS_INFO, "%s: response is %x\n", + /* + * Check if we are invalidating the pcrs, ignore the error if this is + * the case + */ + if ((tpml_digests->count == 1) && + (tpml_digests->digests[0].hashAlg == TPM_ALG_ERROR) && + response && (response->hdr.tpm_code & ~TPM_RC_N_MASK) == + (TPM_RC_P | TPM_RC_HASH)) { + printk(BIOS_SPEW, "%s: TPM_RC_HASH returned this is" + " expected\n", __func__); + return TPM_SUCCESS; + } + + printk(BIOS_INFO, "%s: response is 0x%x\n", __func__, response ? response->hdr.tpm_code : -1); if (!response || response->hdr.tpm_code) return TPM_E_IOERROR; diff --git a/src/security/tpm/tss/tcg-2.0/tss_structures.h b/src/security/tpm/tss/tcg-2.0/tss_structures.h index 6a017bbb9d..1530613226 100644 --- a/src/security/tpm/tss/tcg-2.0/tss_structures.h +++ b/src/security/tpm/tss/tcg-2.0/tss_structures.h @@ -97,6 +97,12 @@ struct tpm_header { space is defined by the lower 16 bits. */ #define TPM_CC_VENDOR_BIT_MASK 0x20000000 +/* Table 15 - TPM_RC Constants (Actions) */ +#define RC_FMT1 (TPM_RC)(0x080) +#define TPM_RC_HASH (TPM_RC)(RC_FMT1 + 0x003) +#define TPM_RC_P (TPM_RC)(0x040) +#define TPM_RC_N_MASK (TPM_RC)(0xF00) + /* Startup values. */ #define TPM_SU_CLEAR 0 #define TPM_SU_STATE 1 @@ -311,12 +317,13 @@ typedef union { TPM2B b; } TPM2B_MAX_NV_BUFFER; -/* - * This is a union, but as of now we support just one digest - sha256, so - * there is just one element. - */ +/* Table 66 - TPMU_HA Union */ typedef union { - uint8_t sha256[SHA256_DIGEST_SIZE]; + uint8_t sha1[SHA1_DIGEST_SIZE]; + uint8_t sha256[SHA256_DIGEST_SIZE]; + uint8_t sm3_256[SM3_256_DIGEST_SIZE]; + uint8_t sha384[SHA384_DIGEST_SIZE]; + uint8_t sha512[SHA512_DIGEST_SIZE]; } TPMU_HA; typedef struct { @@ -324,9 +331,10 @@ typedef struct { TPMU_HA digest; } TPMT_HA; +/* Table 96 -- TPML_DIGEST_VALUES Structure */ typedef struct { uint32_t count; - TPMT_HA digests[1]; /* Limit max number of hashes to 1. */ + TPMT_HA digests[HASH_COUNT]; } TPML_DIGEST_VALUES; struct nv_read_response { -- cgit v1.2.3