aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStefan Berger <stefanb@linux.vnet.ibm.com>2016-02-02 13:09:12 -0500
committerKevin O'Connor <kevin@koconnor.net>2016-02-05 20:47:37 -0500
commitf53b93b402a6b9b90c73e43f44b7cedba10e33b5 (patch)
treef0663e3bc1df94ec299c8c0f444cb8e27c0ecb6d /src
parent1d37d521d34a791f7c4e0b229ab4e7edf5b43b16 (diff)
downloadseabios-hppa-f53b93b402a6b9b90c73e43f44b7cedba10e33b5.zip
seabios-hppa-f53b93b402a6b9b90c73e43f44b7cedba10e33b5.tar.gz
seabios-hppa-f53b93b402a6b9b90c73e43f44b7cedba10e33b5.tar.bz2
tpm: Implement tpm20_startup and tpm20_s3_resume
Implement tpm20_startup and tpm20_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_review 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>
Diffstat (limited to 'src')
-rw-r--r--src/std/tcg.h20
-rw-r--r--src/tcgbios.c91
2 files changed, 105 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 6be1966..0b40a8f 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,53 @@ err_exit:
}
static int
+tpm20_startup(void)
+{
+ int ret = tpm_build_and_send_cmd(0, TPM2_CC_Startup,
+ Startup_SU_CLEAR,
+ sizeof(Startup_SU_CLEAR),
+ TPM_DURATION_TYPE_SHORT);
+
+ dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_Startup(SU_CLEAR) = 0x%08x\n",
+ ret);
+
+ 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);
+
+ dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_SelfTest = 0x%08x\n",
+ ret);
+
+ 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 tpm20_startup();
}
return -1;
}
@@ -694,8 +756,25 @@ 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);
+
+ dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_Startup(SU_STATE) = 0x%08x\n",
+ ret);
+
+ 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);
+
+ dprintf(DEBUG_tcg, "TCGBIOS: Return value from sending TPM2_CC_SelfTest() = 0x%08x\n",
+ ret);
+
break;
}