From: Stefan Berger stefanb@linux.vnet.ibm.com
Implement tpm2_startup and tpm2_s3_resume and their dependencies.
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...
Power on: Figure 7 & 7.3.2 item 4. S3: Figure 9 & 7.3.2 item 4.
Signed-off-by: Stefan Berger stefanb@linux.vnet.ibm.com --- src/std/tcg.h | 20 ++++++++++++++++ src/tcgbios.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 91 insertions(+), 6 deletions(-)
diff --git a/src/std/tcg.h b/src/std/tcg.h index 91692e9..db1155d 100644 --- a/src/std/tcg.h +++ b/src/std/tcg.h @@ -362,4 +362,24 @@ struct tpm_res_sha1complete { #define TPM_PPI_OP_SET_OWNERINSTALL_TRUE 8 #define TPM_PPI_OP_SET_OWNERINSTALL_FALSE 9
+/* + * TPM 2 + */ + +#define TPM2_NO 0 +#define TPM2_YES 1 + +#define TPM2_SU_CLEAR 0x0000 +#define TPM2_SU_STATE 0x0001 + +/* TPM 2 command tags */ +#define TPM2_ST_NO_SESSIONS 0x8001 + +/* TPM 2 commands */ +#define TPM2_CC_SelfTest 0x143 +#define TPM2_CC_Startup 0x144 + +/* TPM 2 error codes */ +#define TPM2_RC_INITIALIZE 0x100 + #endif // tcg.h diff --git a/src/tcgbios.c b/src/tcgbios.c index 89af876..0d6cfdb 100644 --- a/src/tcgbios.c +++ b/src/tcgbios.c @@ -25,6 +25,10 @@ #include "util.h" // printf, get_keystroke #include "stacks.h" // wait_threads, reset
+/**************************************************************** + * TPM 1.2 commands + ****************************************************************/ + static const u8 Startup_ST_CLEAR[] = { 0x00, TPM_ST_CLEAR }; static const u8 Startup_ST_STATE[] = { 0x00, TPM_ST_STATE };
@@ -36,8 +40,17 @@ static const u8 PhysicalPresence_NOT_PRESENT_LOCK[] = { 0x00, 0x14 }; static const u8 CommandFlag_FALSE[1] = { 0x00 }; static const u8 CommandFlag_TRUE[1] = { 0x01 };
-typedef u8 tpm_ppi_code; +/**************************************************************** + * TPM 2 commands + ****************************************************************/ + +static const u8 Startup_SU_CLEAR[] = { 0x00, TPM2_SU_CLEAR}; +static const u8 Startup_SU_STATE[] = { 0x00, TPM2_SU_STATE};
+static const u8 TPM2_SelfTest_YES[] = { TPM2_YES }; /* full test */ + + +typedef u8 tpm_ppi_code;
/**************************************************************** * ACPI TCPA table interface @@ -191,12 +204,22 @@ tpm_build_and_send_cmd(u8 locty, u32 ordinal, const u8 *append, { struct { struct tpm_req_header trqh; - u8 cmd[2]; + u8 cmd[6]; } PACKED req = { .trqh.tag = cpu_to_be16(TPM_TAG_RQU_CMD), .trqh.totlen = cpu_to_be32(sizeof(req.trqh) + append_size), .trqh.ordinal = cpu_to_be32(ordinal), }; + + switch (TPM_version) { + case TPM_VERSION_1_2: + req.trqh.tag = cpu_to_be16(TPM_TAG_RQU_CMD); + break; + case TPM_VERSION_2: + req.trqh.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS); + break; + } + u8 obuffer[64]; struct tpm_rsp_header *trsh = (struct tpm_rsp_header *)obuffer; u32 obuffer_len = sizeof(obuffer); @@ -532,14 +555,47 @@ err_exit: }
static int +tpm2_startup(void) +{ + dprintf(DEBUG_tcg, "TCGBIOS: Starting with TPM2_Startup(SU_CLEAR)\n"); + int ret = tpm_build_and_send_cmd(0, TPM2_CC_Startup, + Startup_SU_CLEAR, + sizeof(Startup_SU_CLEAR), + TPM_DURATION_TYPE_SHORT); + + if (CONFIG_COREBOOT && ret == TPM2_RC_INITIALIZE) + /* with other firmware on the system the TPM may already have been + * initialized + */ + ret = 0; + + if (ret) + goto err_exit; + + ret = tpm_build_and_send_cmd(0, TPM2_CC_SelfTest, + TPM2_SelfTest_YES, + sizeof(TPM2_SelfTest_YES), + TPM_DURATION_TYPE_LONG); + if (ret) + goto err_exit; + + return 0; + +err_exit: + dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__); + + tpm_set_failure(); + return -1; +} + +static int tpm_startup(void) { switch (TPM_version) { case TPM_VERSION_1_2: return tpm12_startup(); case TPM_VERSION_2: - // FIXME: missing code - return -1; + return tpm2_startup(); }
return -1; @@ -697,8 +753,17 @@ tpm_s3_resume(void) TPM_DURATION_TYPE_SHORT); break; case TPM_VERSION_2: - // FIXME: missing code - ret = -1; + ret = tpm_build_and_send_cmd(0, TPM2_CC_Startup, + Startup_SU_STATE, + sizeof(Startup_SU_STATE), + TPM_DURATION_TYPE_SHORT); + if (ret) + goto err_exit; + + + ret = tpm_build_and_send_cmd(0, TPM2_CC_SelfTest, + TPM2_SelfTest_YES, sizeof(TPM2_SelfTest_YES), + TPM_DURATION_TYPE_LONG); break; }