[SeaBIOS] [PATCH 3/3] tpm: Support 2.0 TPM devices connected to a TIS host

Stephen Douthit stephend at silicom-usa.com
Mon Feb 26 21:37:34 CET 2018


tis_get_tpm_version() was returning the interface version, which is always
1.2 since tis_probe() would have failed if the interface wasn't TIS.

New version check is based on the tpm2_probe() function from the Linux
tpm_tis driver.

Signed-off-by: Stephen Douthit <stephend at silicom-usa.com>
Tested-by: Stephen Douthit <stephend at silicom-usa.com>
---
 src/hw/tpm_drivers.c | 21 +++++++++++++++------
 src/std/tcg.h        |  1 +
 src/tcgbios.c        |  2 +-
 src/tcgbios.h        |  4 ++++
 4 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/src/hw/tpm_drivers.c b/src/hw/tpm_drivers.c
index 789d70a..32c34df 100644
--- a/src/hw/tpm_drivers.c
+++ b/src/hw/tpm_drivers.c
@@ -11,6 +11,7 @@
 #include "config.h" // CONFIG_TPM_TIS_SHA1THRESHOLD
 #include "hw/tpm_drivers.h" // struct tpm_driver
 #include "std/tcg.h" // TCG_RESPONSE_TIMEOUT
+#include "tcgbios.h" // tpm20_getcapability
 #include "output.h" // warn_timeout
 #include "stacks.h" // yield
 #include "string.h" // memcpy
@@ -119,7 +120,7 @@ static u32 tis_probe(void)
     if ((didvid != 0) && (didvid != 0xffffffff))
         rc = 1;
 
-    /* TPM 2 has an interface register */
+    /* Low 32 bits of CRB interface register overlap TIS interface register */
     u32 ifaceid = readl(TIS_REG(0, TIS_REG_IFACE_ID));
 
     if ((ifaceid & 0xf) != 0xf) {
@@ -142,13 +143,21 @@ static u32 tis_probe(void)
 
 static TPMVersion tis_get_tpm_version(void)
 {
-    /* TPM 2 has an interface register */
-    u32 ifaceid = readl(TIS_REG(0, TIS_REG_IFACE_ID));
+    u8 buffer[128];
+    int ret;
+    struct tpm2_res_getcapability *trg =
+      (struct tpm2_res_getcapability *)&buffer;
+
+    ret = tpm20_getcapability(TPM2_CAP_TPM_PROPERTIES, cpu_to_be32(0x100),
+                              cpu_to_be32(1), &trg->hdr, sizeof(buffer));
+    if (ret == TPM2_RC_INITIALIZE)
+        return TPM_VERSION_2;
+    else if (ret)
+        return TPM_VERSION_NONE;
 
-    if ((ifaceid & 0xf) == 0) {
-        /* TPM 2 */
+    if (cpu_to_be32(trg->hdr.tag) == TPM2_ST_NO_SESSIONS)
         return TPM_VERSION_2;
-    }
+
     return TPM_VERSION_1_2;
 }
 
diff --git a/src/std/tcg.h b/src/std/tcg.h
index 09a92d8..4c07493 100644
--- a/src/std/tcg.h
+++ b/src/std/tcg.h
@@ -357,6 +357,7 @@ struct tpm_res_sha1complete {
 
 /* TPM 2 Capabilities */
 #define TPM2_CAP_PCRS               0x00000005
+#define TPM2_CAP_TPM_PROPERTIES     0x00000006
 
 /* TPM 2 data structures */
 
diff --git a/src/tcgbios.c b/src/tcgbios.c
index 40b3028..b86bf64 100644
--- a/src/tcgbios.c
+++ b/src/tcgbios.c
@@ -381,7 +381,7 @@ tpm_simple_cmd(u8 locty, u32 ordinal
     return ret;
 }
 
-static int
+int
 tpm20_getcapability(u32 capability, u32 property, u32 count,
                     struct tpm_rsp_header *rsp, u32 rsize)
 {
diff --git a/src/tcgbios.h b/src/tcgbios.h
index 32fb941..9fc711a 100644
--- a/src/tcgbios.h
+++ b/src/tcgbios.h
@@ -1,6 +1,7 @@
 #ifndef TCGBIOS_H
 #define TCGBIOS_H
 
+#include "std/tcg.h" // struct tpm_rsp_header
 #include "types.h"
 
 struct bregs;
@@ -15,5 +16,8 @@ void tpm_add_cdrom_catalog(const u8 *addr, u32 length);
 void tpm_option_rom(const void *addr, u32 len);
 int tpm_can_show_menu(void);
 void tpm_menu(void);
+int
+tpm20_getcapability(u32 capability, u32 property, u32 count,
+                    struct tpm_rsp_header *rsp, u32 rsize);
 
 #endif /* TCGBIOS_H */
-- 
2.14.3




More information about the SeaBIOS mailing list