From: Stefan Berger stefanb@linux.vnet.ibm.com
Implement TPM 2's set failure.
We follow this specification:
TCG PC Client Specific Platform Firmware Profile for TPM 2.0 Systems Revision 1.0 Version 21
It can be found on this page:
http://www.trustedcomputinggroup.org/resources/specifications_in_public_revi...
Make the TPM unavailable for OS-present applications following 6.2 item 2.d.i .
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/std/tcg.h | 12 ++++++++++++ src/tcgbios.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-)
diff --git a/src/std/tcg.h b/src/std/tcg.h index dd860e6..8466b14 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -372,7 +372,9 @@ struct tpm_res_sha1complete { #define TPM2_SU_CLEAR 0x0000 #define TPM2_SU_STATE 0x0001
+#define TPM2_RH_OWNER 0x40000001 #define TPM2_RS_PW 0x40000009 +#define TPM2_RH_ENDORSEMENT 0x4000000b #define TPM2_RH_PLATFORM 0x4000000c
#define TPM2_ALG_SHA1 0x0004 @@ -382,6 +384,7 @@ struct tpm_res_sha1complete { #define TPM2_ST_SESSIONS 0x8002
/* TPM 2 commands */ +#define TPM2_CC_HierarchyControl 0x121 #define TPM2_CC_Clear 0x126 #define TPM2_CC_ClearControl 0x127 #define TPM2_CC_HierarchyChangeAuth 0x129 @@ -460,4 +463,13 @@ struct tpm2_req_clear { struct tpm2_authblock authblock; } PACKED;
+struct tpm2_req_hierarchycontrol { + struct tpm_req_header hdr; + u32 authhandle; + u32 authblocksize; + struct tpm2_authblock authblock; + u32 enable; + u8 state; +} PACKED; + #endif // tcg.h diff --git a/src/tcgbios.c b/src/tcgbios.c index 356cef9..f1ea023 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -239,6 +239,35 @@ tpm_build_and_send_cmd(u8 locty, u32 ordinal, const u8 *append, return ret; }
+static int +tpm2_hierarchycontrol(u32 hierarchy, u8 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; + u32 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) + return -1; + + return 0; +} + static void tpm_set_failure(void) { @@ -253,7 +282,8 @@ tpm_set_failure(void) NULL, 0, TPM_DURATION_TYPE_SHORT); break; case TPM_VERSION_2: - // FIXME: missing code + tpm2_hierarchycontrol(TPM2_RH_ENDORSEMENT, TPM2_NO); + tpm2_hierarchycontrol(TPM2_RH_OWNER, TPM2_NO); break; }