aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/std/tcg.h29
-rw-r--r--src/tcgbios.c59
2 files changed, 88 insertions, 0 deletions
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..f9c6f74 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)
{
@@ -366,6 +370,57 @@ tpm12_get_capability(u32 cap, u32 subcap, struct tpm_rsp_header *rsp, u32 rsize)
}
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;
+
+ u32 size = be32_to_cpu(trg->hdr.totlen) -
+ offsetof(struct tpm2_res_getcapability, data);
+ tpm20_pcr_selection = malloc_high(size);
+ if (tpm20_pcr_selection) {
+ memcpy(tpm20_pcr_selection, &trg->data, size);
+ tpm20_pcr_selection_size = size;
+ } else {
+ warn_noalloc();
+ ret = -1;
+ }
+
+ return ret;
+}
+
+static int
tpm12_determine_timeouts(void)
{
struct tpm_res_getcap_timeouts timeouts;
@@ -701,6 +756,10 @@ tpm20_startup(void)
if (ret)
goto err_exit;
+ ret = tpm20_get_pcrbanks();
+ if (ret)
+ goto err_exit;
+
return 0;
err_exit: