:: commit 8515b9a47fa74da4ee59763c605c1ab8d62d9a65

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

parents: b35885ef46

lib/tpm, protos: Embed the measured value in event descriptions

diff --git a/common/lib/misc.c b/common/lib/misc.c
index de7f50a0..00c78489 100644
--- a/common/lib/misc.c
+++ b/common/lib/misc.c
@@ -119,7 +119,7 @@ size_t get_trailing_zeros(uint64_t val) {
 }
 
 void *get_device_tree_blob(const char *config, size_t extra_size,
-                           const char *measure_label) {
+                           bool measure) {
     int ret;
 
     size_t size = 0;
@@ -155,9 +155,9 @@ void *get_device_tree_blob(const char *config, size_t extra_size,
             }
 
 #if defined (UEFI)
-            if (measure_label != NULL) {
+            if (measure) {
                 tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                            dtb, size, measure_label);
+                            dtb, size, "dtb_path: ", dtb_path);
             }
 #endif
 
@@ -173,9 +173,9 @@ void *get_device_tree_blob(const char *config, size_t extra_size,
             if (memcmp(&cur_table->VendorGuid, &dtb_guid, sizeof(EFI_GUID)))
                 continue;
             size = fdt_totalsize(cur_table->VendorTable);
-            if (measure_label != NULL) {
+            if (measure) {
                 tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                            cur_table->VendorTable, size, measure_label);
+                            cur_table->VendorTable, size, "efi_dtb", NULL);
             }
             dtb = ext_mem_alloc(size);
             ret = fdt_open_into(cur_table->VendorTable, dtb, size);
@@ -187,7 +187,7 @@ void *get_device_tree_blob(const char *config, size_t extra_size,
         }
     }
 #else
-    (void)measure_label;
+    (void)measure;
 #endif
 
     if (extra_size == 0) {
diff --git a/common/lib/misc.h b/common/lib/misc.h
index 394449dc..c5a20c1d 100644
--- a/common/lib/misc.h
+++ b/common/lib/misc.h
@@ -30,8 +30,7 @@ bool efi_exit_boot_services(void);
 bool is_efi_serial_present(void);
 #endif
 
-void *get_device_tree_blob(const char *config, size_t extra_size,
-                           const char *measure_label);
+void *get_device_tree_blob(const char *config, size_t extra_size, bool measure);
 
 extern struct volume *boot_volume;
 
diff --git a/common/lib/tpm.c b/common/lib/tpm.c
index a3d06bc8..1d9a6e39 100644
--- a/common/lib/tpm.c
+++ b/common/lib/tpm.c
@@ -99,12 +99,14 @@ bool tpm_present(void) {
 
 void tpm_measure(uint32_t pcr, uint32_t event_type,
                  const void *data, size_t data_size,
-                 const char *description) {
+                 const char *desc_prefix, const char *desc_value) {
     if (!measured_boot || data == NULL) {
         return;
     }
 
-    size_t desc_len = description != NULL ? strlen(description) : 0;
+    size_t prefix_len = desc_prefix != NULL ? strlen(desc_prefix) : 0;
+    size_t value_len = desc_value != NULL ? strlen(desc_value) : 0;
+    size_t desc_len = prefix_len + value_len + 1;
 
     if (tcg2 != NULL) {
         size_t event_size = offsetof(EFI_TCG2_EVENT, Event) + desc_len;
@@ -115,8 +117,11 @@ void tpm_measure(uint32_t pcr, uint32_t event_type,
         event->Header.HeaderVersion = 1;
         event->Header.PCRIndex = pcr;
         event->Header.EventType = event_type;
-        if (desc_len > 0) {
-            memcpy(event->Event, description, desc_len);
+        if (prefix_len > 0) {
+            memcpy(event->Event, desc_prefix, prefix_len);
+        }
+        if (value_len > 0) {
+            memcpy(event->Event + prefix_len, desc_value, value_len);
         }
 
         EFI_STATUS status = tcg2->HashLogExtendEvent(
@@ -147,8 +152,11 @@ void tpm_measure(uint32_t pcr, uint32_t event_type,
         event->Header.HeaderVersion = EFI_CC_EVENT_HEADER_VERSION;
         event->Header.MrIndex = mr_index;
         event->Header.EventType = event_type;
-        if (desc_len > 0) {
-            memcpy(event->Event, description, desc_len);
+        if (prefix_len > 0) {
+            memcpy(event->Event, desc_prefix, prefix_len);
+        }
+        if (value_len > 0) {
+            memcpy(event->Event + prefix_len, desc_value, value_len);
         }
 
         status = cc->HashLogExtendEvent(
diff --git a/common/lib/tpm.h b/common/lib/tpm.h
index 2929029f..87b061d7 100644
--- a/common/lib/tpm.h
+++ b/common/lib/tpm.h
@@ -23,7 +23,7 @@ bool tpm_present(void);
 
 void tpm_measure(uint32_t pcr, uint32_t event_type,
                  const void *data, size_t data_size,
-                 const char *description);
+                 const char *desc_prefix, const char *desc_value);
 
 // Capture the firmware TCG2 event log into bootloader-reclaimable memory
 // and expose the raw event stream. `format` receives the TCG event log
diff --git a/common/menu.c b/common/menu.c
index 98ae2556..d11ac1ac 100644
--- a/common/menu.c
+++ b/common/menu.c
@@ -1193,7 +1193,7 @@ noreturn void _menu(bool first_run) {
     const char *raw = config_get_raw(&raw_size);
     if (raw != NULL) {
         tpm_measure(TPM_PCR_BOOT_AUTH, TPM_EV_IPL,
-                    raw, raw_size, "Limine config");
+                    raw, raw_size, "limine_cfg", NULL);
     }
 #endif
 
diff --git a/common/protos/limine.c b/common/protos/limine.c
index cbdea610..06b73999 100644
--- a/common/protos/limine.c
+++ b/common/protos/limine.c
@@ -460,7 +460,7 @@ noreturn void limine_load(char *config, char *cmdline) {
 #if defined (UEFI)
     if (cmdline != NULL) {
         tpm_measure(TPM_PCR_BOOT_AUTH, TPM_EV_IPL,
-                    cmdline, strlen(cmdline), "Limine cmdline");
+                    cmdline, strlen(cmdline), "cmdline: ", cmdline);
     }
 #endif
 
@@ -525,7 +525,7 @@ noreturn void limine_load(char *config, char *cmdline) {
 
 #if defined (UEFI)
     tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                kernel, kernel_file->size, "Limine executable");
+                kernel, kernel_file->size, "path: ", kernel_path);
 #endif
 
     char *kaslr_s = config_get_value(config, 0, "KASLR");
@@ -1180,7 +1180,7 @@ FEAT_START
         break; // next feature
     }
 
-    void *dtb = get_device_tree_blob(config, 0, "Limine DTB");
+    void *dtb = get_device_tree_blob(config, 0, true);
 
     if (dtb) {
         // Delete all /memory@... nodes.
@@ -1361,18 +1361,18 @@ FEAT_START
             }
             continue;
         }
-        if (module_path_allocated) {
-            pmm_free(module_path, 1024);
-        }
-
         struct limine_file *l = &modules[final_module_count++];
         *l = get_file(f, module_cmdline);
 
 #if defined (UEFI)
         tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                    f->fd, f->size, "Limine module");
+                    f->fd, f->size, "module_path: ", module_path);
 #endif
 
+        if (module_path_allocated) {
+            pmm_free(module_path, 1024);
+        }
+
         fclose(f);
     }
 
diff --git a/common/protos/linux_risc.c b/common/protos/linux_risc.c
index 9b15e023..4f483f14 100644
--- a/common/protos/linux_risc.c
+++ b/common/protos/linux_risc.c
@@ -156,10 +156,11 @@ static void load_module(struct boot_param *p, char *config) {
         fread(modules[i], p->module_base + offset, 0, module_size);
         fclose(modules[i]);
 
+        char *module_path = config_get_value(config, i, "MODULE_PATH");
+
         tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                    p->module_base + offset, module_size, "Linux initrd");
+                    p->module_base + offset, module_size, "module_path: ", module_path);
 
-        char *module_path = config_get_value(config, i, "MODULE_PATH");
         printv("linux: loaded module `%s` at %p, size %U\n", module_path,
                p->module_base + offset, (uint64_t)module_size);
         offset += module_size;
@@ -469,11 +470,11 @@ noreturn void linux_load(char *config, char *cmdline) {
     struct boot_param p;
     memset(&p, 0, sizeof(p));
     p.cmdline = cmdline;
-    p.dtb = get_device_tree_blob(config, 0x1000, "Linux DTB");
+    p.dtb = get_device_tree_blob(config, 0x1000, true);
 
     if (cmdline != NULL) {
         tpm_measure(TPM_PCR_BOOT_AUTH, TPM_EV_IPL,
-                    cmdline, strlen(cmdline), "Linux cmdline");
+                    cmdline, strlen(cmdline), "cmdline: ", cmdline);
     }
 
     struct file_handle *kernel_file;
@@ -526,7 +527,7 @@ noreturn void linux_load(char *config, char *cmdline) {
     printv("linux: loaded kernel `%s` at %p, size %U\n", kernel_path, p.kernel_base, (uint64_t)p.kernel_size);
 
     tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                p.kernel_base, p.kernel_size, "Linux kernel");
+                p.kernel_base, p.kernel_size, "path: ", kernel_path);
 
     load_module(&p, config);
 
diff --git a/common/protos/linux_x86.c b/common/protos/linux_x86.c
index 01b809e9..b76fbd4d 100644
--- a/common/protos/linux_x86.c
+++ b/common/protos/linux_x86.c
@@ -296,7 +296,7 @@ noreturn void linux_load(char *config, char *cmdline) {
 #if defined (UEFI)
     if (cmdline != NULL) {
         tpm_measure(TPM_PCR_BOOT_AUTH, TPM_EV_IPL,
-                    cmdline, strlen(cmdline), "Linux cmdline");
+                    cmdline, strlen(cmdline), "cmdline: ", cmdline);
     }
 #endif
 
@@ -425,7 +425,7 @@ noreturn void linux_load(char *config, char *cmdline) {
 
 #if defined (UEFI)
     tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                kernel_file->fd, kernel_file->size, "Linux kernel");
+                kernel_file->fd, kernel_file->size, "path: ", kernel_path);
 #endif
 
     fclose(kernel_file);
@@ -517,7 +517,7 @@ noreturn void linux_load(char *config, char *cmdline) {
 
 #if defined (UEFI)
         tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                    (void *)_modules_mem_base, modules[i]->size, "Linux initrd");
+                    (void *)_modules_mem_base, modules[i]->size, "module_path: ", module_path);
 #endif
 
         _modules_mem_base += modules[i]->size;
diff --git a/common/protos/multiboot1.c b/common/protos/multiboot1.c
index 9d811263..fdd08afa 100644
--- a/common/protos/multiboot1.c
+++ b/common/protos/multiboot1.c
@@ -59,7 +59,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
 #if defined (UEFI)
     if (cmdline != NULL) {
         tpm_measure(TPM_PCR_BOOT_AUTH, TPM_EV_IPL,
-                    cmdline, strlen(cmdline), "Multiboot1 cmdline");
+                    cmdline, strlen(cmdline), "cmdline: ", cmdline);
     }
 #endif
 
@@ -86,7 +86,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
 
 #if defined (UEFI)
     tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                kernel, kernel_file_size, "Multiboot1 kernel");
+                kernel, kernel_file_size, "path: ", kernel_path);
 #endif
 
     fclose(kernel_file);
@@ -363,7 +363,7 @@ noreturn void multiboot1_load(char *config, char *cmdline) {
 
 #if defined (UEFI)
             tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                        module_addr, f->size, "Multiboot1 module");
+                        module_addr, f->size, "module_path: ", module_path);
 #endif
 
             if (!elsewhere_append(true /* flexible target */,
diff --git a/common/protos/multiboot2.c b/common/protos/multiboot2.c
index 4a60f522..d6677d01 100644
--- a/common/protos/multiboot2.c
+++ b/common/protos/multiboot2.c
@@ -79,7 +79,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
 #if defined (UEFI)
     if (cmdline != NULL) {
         tpm_measure(TPM_PCR_BOOT_AUTH, TPM_EV_IPL,
-                    cmdline, strlen(cmdline), "Multiboot2 cmdline");
+                    cmdline, strlen(cmdline), "cmdline: ", cmdline);
     }
 #endif
 
@@ -106,7 +106,7 @@ noreturn void multiboot2_load(char *config, char* cmdline) {
 
 #if defined (UEFI)
     tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                kernel, kernel_file_size, "Multiboot2 kernel");
+                kernel, kernel_file_size, "path: ", kernel_path);
 #endif
 
     fclose(kernel_file);
@@ -667,7 +667,7 @@ reloc_fail:
 
 #if defined (UEFI)
         tpm_measure(TPM_PCR_LOADED_IMAGES, TPM_EV_IPL,
-                    module_addr, f->size, "Multiboot2 module");
+                    module_addr, f->size, "module_path: ", module_path);
 #endif
 
         if (!elsewhere_append(true /* flexible target */,
diff --git a/common/sys/cpu_riscv.c b/common/sys/cpu_riscv.c
index 70210622..d0be6818 100644
--- a/common/sys/cpu_riscv.c
+++ b/common/sys/cpu_riscv.c
@@ -313,7 +313,7 @@ void init_riscv(const char *config) {
     if (!prioritise_dtb && acpi_get_rsdp()) {
         init_riscv_acpi();
     } else {
-        riscv_fdt = get_device_tree_blob(config, 0, NULL);
+        riscv_fdt = get_device_tree_blob(config, 0, false);
         if (riscv_fdt != NULL) {
             init_riscv_fdt(riscv_fdt);
         } else {
diff --git a/common/sys/smp.c b/common/sys/smp.c
index feb68c87..bceef5ea 100644
--- a/common/sys/smp.c
+++ b/common/sys/smp.c
@@ -798,7 +798,7 @@ struct limine_mp_info *init_smp(const char *config,
         return info;
 
     // No RSDP means no ACPI, try device trees in that case.
-    void *dtb = get_device_tree_blob(config, 0, NULL);
+    void *dtb = get_device_tree_blob(config, 0, false);
     if (dtb) {
         info = try_dtb_smp(dtb,
                            cpu_count, bsp_mpidr, pagemap,
@@ -1212,7 +1212,7 @@ struct limine_mp_info *init_smp(size_t *cpu_count, uint32_t *bsp_phys_id,
     if (acpi_get_rsdp() && (info = try_acpi_smp(cpu_count, bsp_phys_id, pagemap, hhdm_offset)))
         return info;
 
-    void *dtb = get_device_tree_blob(NULL, 0, NULL);
+    void *dtb = get_device_tree_blob(NULL, 0, false);
     if (dtb) {
         info = try_dtb_smp(dtb, cpu_count, bsp_phys_id, pagemap, hhdm_offset);
         pmm_free(dtb, fdt_totalsize(dtb));
tab: 248 wrap: offon