[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