[SeaBIOS] [RFC PATCH 1/2] tcgbios: Add physical presence interface support

Stefan Berger stefanb at linux.vnet.ibm.com
Thu Jan 11 15:57:01 CET 2018


Add support for TPM 1.2 and TPM 2 physical presence interface
(PPI). A shared memory structure is located at 0xffff 0000 -
0xffff 00ff that SeaBIOS initializes unless it has already
been intialized and then searches for a code it is supposed
to act upon. A code typically requires that one or more TPM
commands are being sent.

The underlying spec can be accessed from this page here:

https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/

Version 1.20 is implemented.

Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
---
 src/post.c    |  4 ++++
 src/std/tcg.h | 18 ++++++++++++++++++
 src/tcgbios.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/tcgbios.h |  3 +++
 4 files changed, 86 insertions(+)

diff --git a/src/post.c b/src/post.c
index f93106a..f451013 100644
--- a/src/post.c
+++ b/src/post.c
@@ -201,6 +201,7 @@ maininit(void)
 
     // Setup platform devices.
     platform_hardware_setup();
+    tpm_ppi_init();
 
     // Start hardware initialization (if threads allowed during optionroms)
     if (threads_during_optionroms())
@@ -220,6 +221,9 @@ maininit(void)
     // Run option roms
     optionrom_setup();
 
+    // Process user-requested TPM state change
+    tpm_ppi_process();
+
     // Allow user to modify overall boot order.
     interactive_bootmenu();
     wait_threads();
diff --git a/src/std/tcg.h b/src/std/tcg.h
index 09a92d8..0aeafe8 100644
--- a/src/std/tcg.h
+++ b/src/std/tcg.h
@@ -551,4 +551,22 @@ struct pcctes_romex
 #define TPM_PPI_OP_SET_OWNERINSTALL_TRUE 8
 #define TPM_PPI_OP_SET_OWNERINSTALL_FALSE 9
 
+#define TPM_PPI_ADDR_BASE  0xffff0000
+
+struct tpm_ppi {
+    u8 ppin;            // 1 = initialized
+    u32 ppip;           // not used
+    u32 pprp;           // response from TPM; set by BIOS
+    u32 pprq;           // opcode; set by ACPI
+    u32 pprm;           // parameter for opcode; set by ACPI
+    u32 lppr;           // last opcode; set by BIOS
+    u32 fret;           // not used
+    u8 res1;            // reserved
+    u32 res[4];         // reserved
+    u32 fail;           // set by BIOS (0 = success)
+} PACKED;
+
+void tpm_ppi_init(void);
+void tpm_ppi_process(void);
+
 #endif // tcg.h
diff --git a/src/tcgbios.c b/src/tcgbios.c
index 40b3028..2adca71 100644
--- a/src/tcgbios.c
+++ b/src/tcgbios.c
@@ -1774,6 +1774,18 @@ tpm20_process_cfg(tpm_ppi_code msgCode, int verbose)
 }
 
 static int
+tpm_process_cfg(tpm_ppi_code msgCode, int verbose)
+{
+    switch (TPM_version) {
+    case TPM_VERSION_1_2:
+        return tpm12_process_cfg(msgCode, verbose);
+    case TPM_VERSION_2:
+        return tpm20_process_cfg(msgCode, verbose);
+    }
+    return -1;
+}
+
+static int
 tpm12_get_tpm_state(void)
 {
     int state = 0;
@@ -2012,3 +2024,52 @@ tpm_can_show_menu(void)
     }
     return 0;
 }
+
+static struct tpm_ppi *tp;
+static u8 next_step; /* next opcode to execute after reboot */
+
+void
+tpm_ppi_init(void)
+{
+    tp = (struct tpm_ppi *)TPM_PPI_ADDR_BASE;
+
+    dprintf(DEBUG_tcg, "TCGBIOS: TPM PPI struct at %p\n", tp);
+
+    if (!tp->ppin) {
+        tp->ppin = 1;
+        tp->pprq = 0;
+        tp->lppr = 0;
+        tp->fail = 0;
+    }
+}
+
+void
+tpm_ppi_process(void)
+{
+   tpm_ppi_code op;
+
+   if (tp) {
+        op = tp->pprq;
+        if (!op) {
+            /* intermediate step after a reboot? */
+            op = next_step;
+        } else {
+            /* last full opcode */
+            tp->lppr = op;
+        }
+        if (op) {
+            /*
+             * Reset the opcode so we don't permanently reboot upon
+             * code 3 (Activate).
+             */
+            tp->pprq = 0;
+
+            printf("Processing TPM PPI opcode %d\n", op);
+            tp->fail = (tpm_process_cfg(op, 0) != 0);
+            if (tp->fail)
+                tp->pprp = 0x0badc0de;
+            else
+                tp->pprp = 0;
+        }
+   }
+}
diff --git a/src/tcgbios.h b/src/tcgbios.h
index 32fb941..52b86f2 100644
--- a/src/tcgbios.h
+++ b/src/tcgbios.h
@@ -16,4 +16,7 @@ void tpm_option_rom(const void *addr, u32 len);
 int tpm_can_show_menu(void);
 void tpm_menu(void);
 
+void tpm_ppi_init(void);
+void tpm_ppi_process(void);
+
 #endif /* TCGBIOS_H */
-- 
2.5.5




More information about the SeaBIOS mailing list