]> xenbits.xensource.com Git - seabios.git/commitdiff
tpm: Implement tpm20_startup and tpm20_s3_resume
authorStefan Berger <stefanb@linux.vnet.ibm.com>
Tue, 2 Feb 2016 18:09:12 +0000 (13:09 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sat, 6 Feb 2016 01:47:37 +0000 (20:47 -0500)
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>
src/std/tcg.h
src/tcgbios.c

index 91692e919c0ced563126dd7450db0f2988190197..db1155d10ad86b2ca87687fca421e94fcaaa7088 100644 (file)
@@ -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
index 6be19665d6c34288b850bde9482fb7e4ba34e471..0b40a8fde051aa557b565aff6eec5f93f2d6a1bd 100644 (file)
 #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);
@@ -531,6 +554,46 @@ err_exit:
     return -1;
 }
 
+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)
 {
@@ -538,8 +601,7 @@ tpm_startup(void)
     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;
     }