diff mbox series

[v4,27/33] tpm2: Implement tpm20_process_cfg, tpm20_clear, and tpm20_clearcontrol

Message ID 20191211202728.127996-28-stefanb@linux.vnet.ibm.com
State Superseded
Headers show
Series Add vTPM support to SLOF | expand

Commit Message

Stefan Berger Dec. 11, 2019, 8:27 p.m. UTC
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 lib/libtpm/tcgbios.c     | 82 +++++++++++++++++++++++++++++++++++++++-
 lib/libtpm/tcgbios_int.h | 17 +++++++++
 2 files changed, 98 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index 02b5ba8..ea00c9f 100644
--- a/lib/libtpm/tcgbios.c
+++ b/lib/libtpm/tcgbios.c
@@ -1266,13 +1266,93 @@  static int tpm12_process_cfg(tpm_ppi_op ppi_op, bool verbose)
 	return ret;
 }
 
+static int
+tpm20_clearcontrol(uint8_t disable, bool verbose)
+{
+	struct tpm2_req_clearcontrol trc = {
+		.hdr.tag     = cpu_to_be16(TPM2_ST_SESSIONS),
+		.hdr.totlen  = cpu_to_be32(sizeof(trc)),
+		.hdr.ordinal = cpu_to_be32(TPM2_CC_ClearControl),
+		.authhandle = cpu_to_be32(TPM2_RH_PLATFORM),
+		.authblocksize = cpu_to_be32(sizeof(trc.authblock)),
+		.authblock = {
+			.handle = cpu_to_be32(TPM2_RS_PW),
+			.noncesize = cpu_to_be16(0),
+			.contsession = TPM2_YES,
+			.pwdsize = cpu_to_be16(0),
+		},
+		.disable = disable,
+	};
+	struct tpm_rsp_header rsp;
+	uint32_t resp_length = sizeof(rsp);
+	int ret = tpmhw_transmit(0, &trc.hdr, &rsp, &resp_length,
+				 TPM_DURATION_TYPE_SHORT);
+	if (ret || resp_length != sizeof(rsp) || rsp.errcode)
+		ret = -1;
+
+	dprintf("TCGBIOS: Return value from sending TPM2_CC_ClearControl = 0x%08x\n",
+		ret);
+
+	return ret;
+}
+
+static int
+tpm20_clear(void)
+{
+	struct tpm2_req_clear trq = {
+		.hdr.tag	 = cpu_to_be16(TPM2_ST_SESSIONS),
+		.hdr.totlen  = cpu_to_be32(sizeof(trq)),
+		.hdr.ordinal = cpu_to_be32(TPM2_CC_Clear),
+		.authhandle = cpu_to_be32(TPM2_RH_PLATFORM),
+		.authblocksize = cpu_to_be32(sizeof(trq.authblock)),
+		.authblock = {
+			.handle = cpu_to_be32(TPM2_RS_PW),
+			.noncesize = cpu_to_be16(0),
+			.contsession = TPM2_YES,
+			.pwdsize = cpu_to_be16(0),
+		},
+	};
+	struct tpm_rsp_header rsp;
+	uint32_t resp_length = sizeof(rsp);
+	int ret = tpmhw_transmit(0, &trq.hdr, &rsp, &resp_length,
+				 TPM_DURATION_TYPE_MEDIUM);
+	if (ret || resp_length != sizeof(rsp) || rsp.errcode)
+		ret = -1;
+
+	dprintf("TCGBIOS: Return value from sending TPM2_CC_Clear = 0x%08x\n",
+		ret);
+
+	return ret;
+}
+
+static int tpm20_process_cfg(tpm_ppi_op msgCode, bool verbose)
+{
+	int ret = 0;
+
+	switch (msgCode) {
+	case TPM_PPI_OP_NOOP: /* no-op */
+		break;
+
+	case TPM_PPI_OP_CLEAR:
+		ret = tpm20_clearcontrol(false, verbose);
+		if (!ret)
+			ret = tpm20_clear();
+		break;
+	}
+
+	if (ret)
+		dprintf("Op %d: An error occurred: 0x%x\n", msgCode, ret);
+
+	return ret;
+}
+
 uint32_t tpm_process_opcode(uint8_t op, bool verbose)
 {
 	switch (TPM_version) {
 	case TPM_VERSION_1_2:
 		return tpm12_process_cfg(op, verbose);
 	case TPM_VERSION_2:
-		break;
+		return tpm20_process_cfg(op, verbose);
 	}
 	return TCGBIOS_GENERAL_ERROR;
 }
diff --git a/lib/libtpm/tcgbios_int.h b/lib/libtpm/tcgbios_int.h
index 3aab7ed..3dc7199 100644
--- a/lib/libtpm/tcgbios_int.h
+++ b/lib/libtpm/tcgbios_int.h
@@ -276,6 +276,8 @@  struct tpm_rsp_getcap_buffersize {
 
 /* TPM 2 commands */
 #define TPM2_CC_HierarchyControl    0x121
+#define TPM2_CC_Clear               0x126
+#define TPM2_CC_ClearControl        0x127
 #define TPM2_CC_SelfTest            0x143
 #define TPM2_CC_Startup             0x144
 #define TPM2_CC_GetCapability       0x17a
@@ -301,6 +303,21 @@  struct tpm2_req_extend {
 	uint8_t digest[0];
 } __attribute__((packed));
 
+struct tpm2_req_clearcontrol {
+	struct tpm_req_header hdr;
+	uint32_t authhandle;
+	uint32_t authblocksize;
+	struct tpm2_authblock authblock;
+	uint8_t disable;
+} __attribute__((packed));
+
+struct tpm2_req_clear {
+	struct tpm_req_header hdr;
+	uint32_t authhandle;
+	uint32_t authblocksize;
+	struct tpm2_authblock authblock;
+} __attribute__((packed));
+
 struct tpm2_req_hierarchycontrol {
 	struct tpm_req_header hdr;
 	uint32_t authhandle;