[SeaBIOS] [RFC PATCH v1 8/9] tpm: Implement tpm2_menu
Stefan Berger
stefanb at us.ibm.com
Fri Jan 15 20:44:38 CET 2016
From: Stefan Berger <stefanb at linux.vnet.ibm.com>
In the TPM 2 menu we currently only allow to run the TPM2_Clear operation.
For this we follow the TCG Physical Presence Interface Specification
to be found here:
http://www.trustedcomputinggroup.org/resources/tcg_physical_presence_interface_specification
Table 3 shows the 'Clear' operation and the sequence of commands to send.
Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
---
src/std/tcg.h | 17 +++++++++
src/tcgbios.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 135 insertions(+), 1 deletion(-)
diff --git a/src/std/tcg.h b/src/std/tcg.h
index d45c7f6..dd860e6 100644
--- a/src/std/tcg.h
+++ b/src/std/tcg.h
@@ -382,6 +382,8 @@ struct tpm_res_sha1complete {
#define TPM2_ST_SESSIONS 0x8002
/* TPM 2 commands */
+#define TPM2_CC_Clear 0x126
+#define TPM2_CC_ClearControl 0x127
#define TPM2_CC_HierarchyChangeAuth 0x129
#define TPM2_CC_SelfTest 0x143
#define TPM2_CC_Startup 0x144
@@ -443,4 +445,19 @@ struct tpm2_req_extend {
struct tpm2_digest_value digest;
} PACKED;
+struct tpm2_req_clearcontrol {
+ struct tpm_req_header hdr;
+ u32 authhandle;
+ u32 authblocksize;
+ struct tpm2_authblock authblock;
+ u8 disable;
+} PACKED;
+
+struct tpm2_req_clear {
+ struct tpm_req_header hdr;
+ u32 authhandle;
+ u32 authblocksize;
+ struct tpm2_authblock authblock;
+} PACKED;
+
#endif // tcg.h
diff --git a/src/tcgbios.c b/src/tcgbios.c
index 627a374..356cef9 100644
--- a/src/tcgbios.c
+++ b/src/tcgbios.c
@@ -1429,6 +1429,89 @@ tpm12_process_cfg(tpm_ppi_code msgCode, int verbose)
}
static int
+tpm2_clearcontrol(u8 disable, int 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;
+ u32 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)
+ return -1;
+
+ return 0;
+}
+
+static int
+tpm2_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;
+ u32 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)
+ return -1;
+
+ return 0;
+}
+
+static int
+tpm2_process_cfg(tpm_ppi_code msgCode, int verbose)
+{
+ int ret = 0;
+
+ switch (msgCode) {
+ case TPM_PPI_OP_NOOP: /* no-op */
+ break;
+
+ case TPM_PPI_OP_CLEAR:
+ ret = tpm2_clearcontrol(0, verbose);
+ if (ret)
+ dprintf(DEBUG_tcg,
+ "TCGBIOS: tpm2_clearcontrol failed\n");
+ if (!ret) {
+ ret = tpm2_clear();
+ if (ret) {
+ dprintf(DEBUG_tcg,
+ "TCGBIOS: tpm2_clear failed\n");
+ }
+ }
+ break;
+ }
+
+ if (ret)
+ printf("Op %d: An error occurred: 0x%x\n", msgCode, ret);
+
+ return ret;
+}
+
+static int
tpm12_get_tpm_state(void)
{
int state = 0;
@@ -1602,6 +1685,40 @@ tpm12_menu(void)
}
}
+static void
+tpm2_menu(void)
+{
+ int scan_code;
+ tpm_ppi_code msgCode;
+
+ for (;;) {
+ printf("1. Clear TPM\n");
+
+ printf("\nIf no change is desired or if this menu was reached by "
+ "mistake, press ESC to\n"
+ "reboot the machine.\n");
+
+ msgCode = TPM_PPI_OP_NOOP;
+
+ while ((scan_code = get_keystroke(1000)) == ~0)
+ ;
+
+ switch (scan_code) {
+ case 1:
+ // ESC
+ reset();
+ break;
+ case 2:
+ msgCode = TPM_PPI_OP_CLEAR;
+ break;
+ default:
+ continue;
+ }
+
+ tpm2_process_cfg(msgCode, 0);
+ }
+}
+
void
tpm_menu(void)
{
@@ -1617,7 +1734,7 @@ tpm_menu(void)
tpm12_menu();
break;
case TPM_VERSION_2:
- // FIXME: missing code
+ tpm2_menu();
break;
}
}
--
2.4.3
More information about the SeaBIOS
mailing list