On Tue, Jul 19, 2016 at 01:41:54PM -0400, Stefan Berger wrote:
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);
It's necessary to check the result of malloc_high() for NULL. (Otherwise, the memcpy could overwrite the memory at address zero, which is the real-mode IDT.)
-Kevin