:: commit 9d2a5d10ca7b539886aa7ad24d7c545864276b78

Mintsuki <mintsuki@protonmail.com> — 2026-04-30 17:16

parents: 60bbcb9ba4

lib/tpm: Walk EFI_CC_FINAL_EVENTS_TABLE on confidential computing platforms

diff --git a/common/lib/tpm.c b/common/lib/tpm.c
index 53ed40fe..ce6f8a02 100644
--- a/common/lib/tpm.c
+++ b/common/lib/tpm.c
@@ -308,4 +308,25 @@ void tpm_release_event_log(void) {
     }
 }
 
+void *tpm_get_final_events_table(void) {
+    EFI_GUID guid;
+    if (tcg2 != NULL) {
+        EFI_GUID tcg2_guid = EFI_TCG2_FINAL_EVENTS_TABLE_GUID;
+        guid = tcg2_guid;
+    } else if (cc != NULL) {
+        EFI_GUID cc_guid = EFI_CC_FINAL_EVENTS_TABLE_GUID;
+        guid = cc_guid;
+    } else {
+        return NULL;
+    }
+
+    for (UINTN i = 0; i < gST->NumberOfTableEntries; i++) {
+        if (memcmp(&gST->ConfigurationTable[i].VendorGuid,
+                   &guid, sizeof(EFI_GUID)) == 0) {
+            return gST->ConfigurationTable[i].VendorTable;
+        }
+    }
+    return NULL;
+}
+
 #endif
diff --git a/common/lib/tpm.h b/common/lib/tpm.h
index 91d81a81..94e5c065 100644
--- a/common/lib/tpm.h
+++ b/common/lib/tpm.h
@@ -41,6 +41,13 @@ void tpm_release_event_log(void);
 // digest lists. Returns 0 on malformed input.
 uint32_t tpm_calc_event_size(const void *event, const void *header);
 
+// Locate the firmware's final-events table for the active measurement
+// protocol (EFI_TCG2_FINAL_EVENTS_TABLE_GUID for TCG2, or
+// EFI_CC_FINAL_EVENTS_TABLE_GUID for CC). Both tables share the same
+// {Version, NumberOfEvents, Events[]} layout. Returns NULL if no TPM/CC
+// interface is active or the table isn't present.
+void *tpm_get_final_events_table(void);
+
 #endif
 
 #endif
diff --git a/common/protos/linux.c b/common/protos/linux.c
index ae1346fe..4f08b52a 100644
--- a/common/protos/linux.c
+++ b/common/protos/linux.c
@@ -34,19 +34,12 @@ void linux_install_efi_tpm_event_log(void) {
         return;
     }
 
-    // Walk the firmware's EFI_TCG2_FINAL_EVENTS_TABLE so the kernel can
-    // deduplicate any pre-boot events firmware migrated there.
+    // Walk the firmware's final-events table so the kernel can deduplicate
+    // any pre-boot events firmware migrated there. The table is selected
+    // by the active measurement protocol (TCG2 vs CC).
     uint32_t final_events_preboot_size = 0;
     if (format > EFI_TCG2_EVENT_LOG_FORMAT_TCG_1_2) {
-        EFI_TCG2_FINAL_EVENTS_TABLE *final_events = NULL;
-        EFI_GUID final_events_guid = EFI_TCG2_FINAL_EVENTS_TABLE_GUID;
-        for (UINTN i = 0; i < gST->NumberOfTableEntries; i++) {
-            if (memcmp(&gST->ConfigurationTable[i].VendorGuid,
-                       &final_events_guid, sizeof(EFI_GUID)) == 0) {
-                final_events = gST->ConfigurationTable[i].VendorTable;
-                break;
-            }
-        }
+        EFI_TCG2_FINAL_EVENTS_TABLE *final_events = tpm_get_final_events_table();
         if (final_events != NULL && final_events->NumberOfEvents > 0) {
             const uint8_t *base = final_events->Events;
             uint64_t remaining = final_events->NumberOfEvents;
tab: 248 wrap: offon