[SLOF] [PATCH v4 23/33] tpm2: implement 2nd part of tpm20_start()
Stefan Berger
stefanb at linux.vnet.ibm.com
Thu Dec 12 07:27:18 AEDT 2019
Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
---
lib/libtpm/tcgbios.c | 69 ++++++++++++++++++++++++++++++++++++++++
lib/libtpm/tcgbios_int.h | 31 ++++++++++++++++++
2 files changed, 100 insertions(+)
diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index cd5e13c..3f1dca8 100644
--- a/lib/libtpm/tcgbios.c
+++ b/lib/libtpm/tcgbios.c
@@ -104,6 +104,9 @@ static void probe_tpm(void)
tpm_state.tpm_working = tpm_state.tpm_found;
}
+static uint32_t tpm20_pcr_selection_size;
+static struct tpml_pcr_selection *tpm20_pcr_selection;
+
/****************************************************************
* TPM hardware command wrappers
****************************************************************/
@@ -154,6 +157,68 @@ tpm_simple_cmd(uint8_t locty, uint32_t ordinal, int param_size, uint16_t param,
return ret;
}
+static int
+tpm20_getcapability(uint32_t capability, uint32_t property, uint32_t count,
+ struct tpm_rsp_header *rsp, uint32_t 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),
+ };
+
+ uint32_t 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("TCGBIOS: Return value from sending TPM2_CC_GetCapability = 0x%08x\n",
+ ret);
+
+ return ret;
+}
+
+static int
+tpm20_get_pcrbanks(void)
+{
+ uint8_t buffer[128];
+ uint32_t size;
+ 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;
+
+ /* defend against (broken) TPM sending packets that are too short */
+ uint32_t resplen = be32_to_cpu(trg->hdr.totlen);
+ if (resplen <= offset_of(struct tpm2_res_getcapability, data))
+ return -1;
+
+ size = resplen - offset_of(struct tpm2_res_getcapability, data);
+ /* we need a valid tpml_pcr_selection up to and including sizeOfSelect*/
+ if (size < offset_of(struct tpml_pcr_selection, selections) +
+ offset_of(struct tpms_pcr_selection, pcrSelect))
+ return -1;
+
+ tpm20_pcr_selection = SLOF_alloc_mem(size);
+ if (tpm20_pcr_selection) {
+ memcpy(tpm20_pcr_selection, &trg->data, size);
+ tpm20_pcr_selection_size = size;
+ } else {
+ printf("TCGBIOS: Failed to allocated %u bytes.\n", size);
+ ret = -1;
+ }
+
+ return ret;
+}
+
static int tpm12_get_capability(uint32_t cap, uint32_t subcap,
struct tpm_rsp_header *rsp, uint32_t rsize)
{
@@ -451,6 +516,10 @@ static int tpm20_startup(void)
if (ret)
goto err_exit;
+ ret = tpm20_get_pcrbanks();
+ if (ret)
+ goto err_exit;
+
return 0;
err_exit:
diff --git a/lib/libtpm/tcgbios_int.h b/lib/libtpm/tcgbios_int.h
index aeba9d9..581424f 100644
--- a/lib/libtpm/tcgbios_int.h
+++ b/lib/libtpm/tcgbios_int.h
@@ -218,6 +218,12 @@ struct tpm_rsp_getcap_buffersize {
#define TPM2_CC_HierarchyControl 0x121
#define TPM2_CC_SelfTest 0x143
#define TPM2_CC_Startup 0x144
+#define TPM2_CC_GetCapability 0x17a
+
+/* TPM 2 Capabilities */
+#define TPM2_CAP_PCRS 0x00000005
+
+/* TPM 2 data structures */
struct tpm2_authblock {
uint32_t handle;
@@ -235,4 +241,29 @@ struct tpm2_req_hierarchycontrol {
uint8_t state;
} __attribute__((packed));
+struct tpm2_req_getcapability {
+ struct tpm_req_header hdr;
+ uint32_t capability;
+ uint32_t property;
+ uint32_t propertycount;
+} __attribute__((packed));
+
+struct tpm2_res_getcapability {
+ struct tpm_rsp_header hdr;
+ uint8_t moreData;
+ uint32_t capability;
+ uint8_t data[0]; /* capability dependent data */
+} __attribute__((packed));
+
+struct tpms_pcr_selection {
+ uint16_t hashAlg;
+ uint8_t sizeOfSelect;
+ uint8_t pcrSelect[0];
+} __attribute__((packed));
+
+struct tpml_pcr_selection {
+ uint32_t count;
+ struct tpms_pcr_selection selections[0];
+} __attribute__((packed));
+
#endif /* TCGBIOS_INT_H */
--
2.17.1
More information about the SLOF
mailing list