@@ -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;
}
@@ -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 */
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(-)