diff mbox series

[v4,21/33] tpm2: support TPM2 in tpm_set_failure

Message ID 20191211202728.127996-22-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     | 45 +++++++++++++++++++++++++++++++++++++---
 lib/libtpm/tcgbios_int.h | 27 ++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/lib/libtpm/tcgbios.c b/lib/libtpm/tcgbios.c
index 6762bcc..f41db64 100644
--- a/lib/libtpm/tcgbios.c
+++ b/lib/libtpm/tcgbios.c
@@ -245,6 +245,37 @@  static int tpm_extend(uint8_t *hash, uint32_t pcrindex)
 	return 0;
 }
 
+static int tpm20_hierarchycontrol(uint32_t hierarchy, uint8_t state)
+{
+	/* we will try to deactivate the TPM now - ignoring all errors */
+	struct tpm2_req_hierarchycontrol trh = {
+		.hdr.tag = cpu_to_be16(TPM2_ST_SESSIONS),
+		.hdr.totlen = cpu_to_be32(sizeof(trh)),
+		.hdr.ordinal = cpu_to_be32(TPM2_CC_HierarchyControl),
+		.authhandle = cpu_to_be32(TPM2_RH_PLATFORM),
+		.authblocksize = cpu_to_be32(sizeof(trh.authblock)),
+		.authblock = {
+			.handle = cpu_to_be32(TPM2_RS_PW),
+			.noncesize = cpu_to_be16(0),
+			.contsession = TPM2_YES,
+			.pwdsize = cpu_to_be16(0),
+		},
+		.enable = cpu_to_be32(hierarchy),
+		.state = state,
+	};
+	struct tpm_rsp_header rsp;
+	uint32_t resp_length = sizeof(rsp);
+	int ret = tpmhw_transmit(0, &trh.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_HierarchyControl = 0x%08x\n",
+		ret);
+
+	return ret;
+}
+
 /****************************************************************
  * Setup and Measurements
  ****************************************************************/
@@ -259,9 +290,17 @@  bool tpm_is_working(void)
 
 static void tpm_set_failure(void)
 {
-	/* we will try to deactivate the TPM now - ignoring all errors */
-	tpm_simple_cmd(0, TPM_ORD_SET_TEMP_DEACTIVATED,
-		       0, 0, TPM_DURATION_TYPE_SHORT);
+	switch (TPM_version) {
+	case TPM_VERSION_1_2:
+		/* we will try to deactivate the TPM now - ignoring all errors */
+		tpm_simple_cmd(0, TPM_ORD_SET_TEMP_DEACTIVATED,
+			       0, 0, TPM_DURATION_TYPE_SHORT);
+		break;
+	case TPM_VERSION_2:
+		tpm20_hierarchycontrol(TPM2_RH_ENDORSEMENT, TPM2_NO);
+		tpm20_hierarchycontrol(TPM2_RH_OWNER, TPM2_NO);
+		break;
+	}
 
 	tpm_state.tpm_working = false;
 }
diff --git a/lib/libtpm/tcgbios_int.h b/lib/libtpm/tcgbios_int.h
index 473de3a..7e9d0f2 100644
--- a/lib/libtpm/tcgbios_int.h
+++ b/lib/libtpm/tcgbios_int.h
@@ -199,8 +199,35 @@  struct tpm_rsp_getcap_buffersize {
  * TPM v2.0 hardware commands
  ****************************************************************/
 
+#define TPM2_NO                     0
+#define TPM2_YES                    1
+
+#define TPM2_RH_OWNER               0x40000001
+#define TPM2_RS_PW                  0x40000009
+#define TPM2_RH_ENDORSEMENT         0x4000000b
+#define TPM2_RH_PLATFORM            0x4000000c
+
 /* TPM 2 command tags */
 #define TPM2_ST_NO_SESSIONS         0x8001
 #define TPM2_ST_SESSIONS            0x8002
 
+/* TPM 2 commands */
+#define TPM2_CC_HierarchyControl    0x121
+
+struct tpm2_authblock {
+	uint32_t handle;
+	uint16_t noncesize;  /* always 0 */
+	uint8_t contsession; /* always TPM2_YES */
+	uint16_t pwdsize;    /* always 0 */
+} __attribute__((packed));
+
+struct tpm2_req_hierarchycontrol {
+	struct tpm_req_header hdr;
+	uint32_t authhandle;
+	uint32_t authblocksize;
+	struct tpm2_authblock authblock;
+	uint32_t enable;
+	uint8_t state;
+} __attribute__((packed));
+
 #endif /* TCGBIOS_INT_H */