[SeaBIOS] [PATCH 1/5] Deactivate TPM in case of failure

Stefan Berger stefanb at us.ibm.com
Thu Nov 12 16:14:44 CET 2015


From: Stefan Berger <stefanb at linux.vnet.ibm.com>

Temporarily deactivate the TPM in case of failure of TPM commands
and failure to log measurements. Introduce the tpm_set_failure()
function replacing occurrences of 'tpm_state.tpm_working = 0' and
invoke it in error paths.

Temporarily deactivating the TPM means that it will be active again
upon reboot.

Signed-off-by: Stefan Berger <stefanb at linux.vnet.ibm.com>
---
 src/tcgbios.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------
 src/tcgbios.h |  1 +
 2 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/src/tcgbios.c b/src/tcgbios.c
index 0995482..2f69318 100644
--- a/src/tcgbios.c
+++ b/src/tcgbios.c
@@ -64,6 +64,10 @@ static u8 evt_separator[] = {0xff,0xff,0xff,0xff};
 
 /* local function prototypes */
 
+static u32 build_and_send_cmd(u8 locty, u32 ordinal,
+                   const u8 *append, u32 append_size,
+                   u8 *resbuffer, u32 return_size, u32 *returnCode,
+                   enum tpmDurationType to_t);
 static u32 tpm_calling_int19h(void);
 static u32 tpm_add_event_separators(void);
 static u32 tpm_start_option_rom_scan(void);
@@ -138,6 +142,31 @@ has_working_tpm(void)
     return tpm_state.tpm_working;
 }
 
+static void
+tpm_set_failure(void)
+{
+    u32 returnCode;
+
+    /* we will try to deactivate the TPM now - ignoring all errors */
+    build_and_send_cmd(0, TPM_ORD_PhysicalPresence,
+                       PhysicalPresence_CMD_ENABLE,
+                       sizeof(PhysicalPresence_CMD_ENABLE),
+                       NULL, 0, &returnCode,
+                       TPM_DURATION_TYPE_SHORT);
+
+    build_and_send_cmd(0, TPM_ORD_PhysicalPresence,
+                       PhysicalPresence_PRESENT,
+                       sizeof(PhysicalPresence_PRESENT),
+                       NULL, 0, &returnCode,
+                       TPM_DURATION_TYPE_SHORT);
+
+    build_and_send_cmd(0, TPM_ORD_SetTempDeactivated,
+                       NULL, 0, NULL, 0, &returnCode,
+                       TPM_DURATION_TYPE_SHORT);
+
+    tpm_state.tpm_working = 0;
+}
+
 static struct tcpa_descriptor_rev2 *
 find_tcpa_by_rsdp(struct rsdp_descriptor *rsdp)
 {
@@ -425,7 +454,7 @@ determine_timeouts(void)
 err_exit:
     dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
 
-    tpm_state.tpm_working = 0;
+    tpm_set_failure();
     if (rc)
         return rc;
     return TCG_TCG_COMMAND_ERROR;
@@ -495,7 +524,7 @@ tpm_startup(void)
 err_exit:
     dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
 
-    tpm_state.tpm_working = 0;
+    tpm_set_failure();
     if (rc)
         return rc;
     return TCG_TCG_COMMAND_ERROR;
@@ -555,7 +584,7 @@ tpm_prepboot(void)
 err_exit:
     dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
 
-    tpm_state.tpm_working = 0;
+    tpm_set_failure();
 }
 
 static int
@@ -659,7 +688,7 @@ tpm_sha1_calc(const u8 *data, u32 length, u8 *hash)
 err_exit:
     dprintf(DEBUG_tcg, "TCGBIOS: TPM SHA1 malfunctioning.\n");
 
-    tpm_state.tpm_working = 0;
+    tpm_set_failure();
     if (rc)
         return rc;
     return TCG_TCG_COMMAND_ERROR;
@@ -695,19 +724,28 @@ tpm_extend_acpi_log(void *entry_ptr, u16 *entry_count)
     u8 *log_area_start_address_next = NULL;
     struct pcpes *pcpes = (struct pcpes *)entry_ptr;
 
+    if (!has_working_tpm())
+        return TCG_GENERAL_ERROR;
+
     get_lasa_last_ptr(entry_count, &log_area_start_address_next);
 
     dprintf(DEBUG_tcg, "TCGBIOS: LASA_BASE = %p, LASA_NEXT = %p\n",
             log_area_start_address_base, log_area_start_address_next);
 
-    if (log_area_start_address_next == NULL || log_area_minimum_length == 0)
+    if (log_area_start_address_next == NULL || log_area_minimum_length == 0) {
+        tpm_set_failure();
+
         return TCG_PC_LOGOVERFLOW;
+    }
 
     size = pcpes->eventdatasize + offsetof(struct pcpes, event);
 
     if ((log_area_start_address_next + size - log_area_start_address_base) >
         log_area_minimum_length) {
         dprintf(DEBUG_tcg, "TCGBIOS: LOG OVERFLOW: size = %d\n", size);
+
+        tpm_set_failure();
+
         return TCG_PC_LOGOVERFLOW;
     }
 
@@ -1476,5 +1514,5 @@ tpm_s3_resume(void)
 err_exit:
     dprintf(DEBUG_tcg, "TCGBIOS: TPM malfunctioning (line %d).\n", __LINE__);
 
-    tpm_state.tpm_working = 0;
+    tpm_set_failure();
 }
diff --git a/src/tcgbios.h b/src/tcgbios.h
index 4b7eaab..b0c20ad 100644
--- a/src/tcgbios.h
+++ b/src/tcgbios.h
@@ -56,6 +56,7 @@
 #define TPM_ORD_PhysicalDisable          0x00000070
 #define TPM_ORD_SetOwnerInstall          0x00000071
 #define TPM_ORD_PhysicalSetDeactivated   0x00000072
+#define TPM_ORD_SetTempDeactivated       0x00000073
 #define TPM_ORD_Startup                  0x00000099
 #define TPM_ORD_PhysicalPresence         0x4000000a
 #define TPM_ORD_Extend                   0x00000014
-- 
2.4.3




More information about the SeaBIOS mailing list