Implement tpm20_get_capability and retrieve the PCR Bank configuration from the TPM using this function.
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/std/tcg.h | 29 +++++++++++++++++++++++++++++ src/tcgbios.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+)
diff --git a/src/std/tcg.h b/src/std/tcg.h index c59f671..d60ee09 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -394,12 +394,16 @@ struct tpm_res_sha1complete { #define TPM2_CC_SelfTest 0x143 #define TPM2_CC_Startup 0x144 #define TPM2_CC_StirRandom 0x146 +#define TPM2_CC_GetCapability 0x17a #define TPM2_CC_GetRandom 0x17b #define TPM2_CC_PCR_Extend 0x182
/* TPM 2 error codes */ #define TPM2_RC_INITIALIZE 0x100
+/* TPM 2 Capabilities */ +#define TPM2_CAP_PCRS 0x00000005 + /* TPM 2 data structures */
struct tpm2b_stir { @@ -475,6 +479,31 @@ struct tpm2_req_hierarchycontrol { u8 state; } PACKED;
+struct tpm2_req_getcapability { + struct tpm_req_header hdr; + u32 capability; + u32 property; + u32 propertycount; +} PACKED; + +struct tpm2_res_getcapability { + struct tpm_rsp_header hdr; + u8 moreData; + u32 capability; + u8 data[0]; /* capability dependent data */ +} PACKED; + +struct tpms_pcr_selection { + u16 hashAlg; + u8 sizeOfSelect; + u8 pcrSelect[0]; +} PACKED; + +struct tpml_pcr_selection { + u32 count; + struct tpms_pcr_selection selections[0]; +} PACKED; + /* TPM 2 log entry */
struct tpml_digest_values_sha1 { diff --git a/src/tcgbios.c b/src/tcgbios.c index 334d99b..a79b880 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -24,6 +24,7 @@ #include "tcgbios.h"// tpm_*, prototypes #include "util.h" // printf, get_keystroke #include "stacks.h" // wait_threads, reset +#include "malloc.h" // malloc_high
/**************************************************************** * TPM 1.2 commands @@ -76,6 +77,9 @@ static int TPM_has_physical_presence;
static TPMVersion TPM_version;
+static u32 tpm20_pcr_selection_size; +static struct tpml_pcr_selection *tpm20_pcr_selection; + static struct tcpa_descriptor_rev2 * find_tcpa_by_rsdp(struct rsdp_descriptor *rsdp) { @@ -669,6 +673,51 @@ err_exit: }
static int +tpm20_getcapability(u32 capability, u32 property, u32 count, + struct tpm_rsp_header *rsp, u32 rsize) +{ + struct tpm2_req_getcapability trg = { + .hdr.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS), + .hdr.totlen = cpu_to_be32(sizeof(trg)), + .hdr.ordinal = cpu_to_be32(TPM2_CC_GetCapability), + .capability = cpu_to_be32(capability), + .property = cpu_to_be32(property), + .propertycount = cpu_to_be32(count), + }; + + u32 resp_size = rsize; + int ret = tpmhw_transmit(0, &trg.hdr, rsp, &resp_size, + TPM_DURATION_TYPE_SHORT); + ret = (ret || + rsize < be32_to_cpu(rsp->totlen)) ? -1 : be32_to_cpu(rsp->errcode); + + dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_GetCapability = 0x%08x\n", + ret); + + return ret; +} + +static int +tpm20_get_pcrbanks(void) +{ + u8 buffer[128]; + struct tpm2_res_getcapability *trg = + (struct tpm2_res_getcapability *)&buffer; + + int ret = tpm20_getcapability(TPM2_CAP_PCRS, 0, 8, &trg->hdr, + sizeof(buffer)); + if (ret) + return ret; + + tpm20_pcr_selection_size = be32_to_cpu(trg->hdr.totlen) - + offsetof(struct tpm2_res_getcapability, data); + tpm20_pcr_selection = malloc_high(tpm20_pcr_selection_size); + memcpy(tpm20_pcr_selection, &trg->data, tpm20_pcr_selection_size); + + return 0; +} + +static int tpm20_startup(void) { tpm20_set_timeouts(); @@ -701,6 +750,10 @@ tpm20_startup(void) if (ret) goto err_exit;
+ ret = tpm20_get_pcrbanks(); + if (ret) + goto err_exit; + return 0;
err_exit: