diff mbox series

tpmevlog: add tests for checking the UEFI_IMAGE_LOAD_EVENT Structure

Message ID 20221216054243.3427183-1-ivan.hu@canonical.com
State Accepted
Headers show
Series tpmevlog: add tests for checking the UEFI_IMAGE_LOAD_EVENT Structure | expand

Commit Message

Ivan Hu Dec. 16, 2022, 5:42 a.m. UTC
Buglink: https://bugs.launchpad.net/fwts/+bug/1999728

From the TCG PFP specification, the PCR 4 and event type(0x80000003)
EV_EFI_BOOT_SERVICES_APPLICATION, the event field MUST contain a
UEFI_IMAGE_LOAD_EVENT structure. Some buggy firmwares that haven't
implemented correct the DevicePath on the UEFI_IMAGE_LOAD_EVENT
structure or executing something, but the log entry is broken
that cause the measurements failed.

Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
---
 src/lib/include/fwts_tpm.h  |  9 ++++++++
 src/tpm/tpmevlog/tpmevlog.c | 42 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 50 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/src/lib/include/fwts_tpm.h b/src/lib/include/fwts_tpm.h
index 0d24a245..03daf714 100644
--- a/src/lib/include/fwts_tpm.h
+++ b/src/lib/include/fwts_tpm.h
@@ -172,6 +172,15 @@  typedef struct {
 */
 } __attribute__ ((packed)) fwts_tcg_pcr_event2;
 
+typedef uint64_t uefi_physical_address;
+typedef struct {
+    uefi_physical_address	image_location_in_memory;
+    uint64_t			image_len_in_memory;
+    uint64_t			image_link_time_address;
+    uint64_t			length_of_device_path;
+    uint8_t			device_path[0];
+} __attribute__ ((packed)) uefi_image_load_event;
+
 void fwts_tpm_data_hexdump(fwts_framework *fw, const uint8_t *data,
 	const size_t size, const char *str);
 uint8_t fwts_tpm_get_hash_size(const TPM2_ALG_ID hash);
diff --git a/src/tpm/tpmevlog/tpmevlog.c b/src/tpm/tpmevlog/tpmevlog.c
index cfc287ab..215cd7cc 100644
--- a/src/tpm/tpmevlog/tpmevlog.c
+++ b/src/tpm/tpmevlog/tpmevlog.c
@@ -25,6 +25,7 @@ 
 #include <fcntl.h>
 
 #include "fwts_tpm.h"
+#include "fwts_uefi.h"
 
 #define FWTS_TPM_LOG_DIR_PATH	"/sys/kernel/security"
 
@@ -149,6 +150,40 @@  static int tpmevlog_algid_check(fwts_framework *fw, const TPM2_ALG_ID hash)
 	return FWTS_OK;
 }
 
+static int tpmevlog_pcr_type_event_check(
+	fwts_framework *fw,
+	const uint32_t pcr,
+	const fwts_tpmlog_event_type event_type,
+	uint32_t event_size,
+	uint8_t *event)
+{
+
+	uefi_image_load_event *ev_image_load = (uefi_image_load_event *)event;
+
+	if (pcr == 4 && event_type == EV_EFI_BOOT_SERVICES_APPLICATION) {
+		if (event_size <= sizeof(uefi_image_load_event)) {
+			fwts_failed(fw, LOG_LEVEL_HIGH, "ImageLoadEventLength",
+					"The length of the event is %" PRIu32 " which"
+					" is smaller than the UEFI Image Load Event "
+					"structure that contains DevicePath "
+					"of PE/COFF image for PCR4 and type "
+					"EV_EFI_BOOT_SERVICES_APPLICATION.",
+					event_size);
+			return FWTS_ERROR;
+		}
+		if (ev_image_load->length_of_device_path <= sizeof(fwts_uefi_dev_path)) {
+			fwts_failed(fw, LOG_LEVEL_HIGH, "ImageLoadDevicePathLength",
+					"The length of the device path is %" PRIu64
+					" is smaller than DevicePath of PE/COFF image "
+					"for PCR4 and type EV_EFI_BOOT_SERVICES_APPLICATION.",
+					ev_image_load->length_of_device_path);
+			return FWTS_ERROR;
+		}
+	}
+
+	return FWTS_OK;
+}
+
 static int tpmevlog_v2_check(
 	fwts_framework *fw,
 	uint8_t *data,
@@ -335,6 +370,12 @@  static int tpmevlog_v2_check(
 					sizeof(event_size));
 			return FWTS_ERROR;
 		}
+
+		ret = tpmevlog_pcr_type_event_check(fw, pcr_event2->pcr_index,
+				pcr_event2->event_type,
+				event_size, pdata + sizeof(event_size));
+		if (ret != FWTS_OK)
+			return ret;
 		pdata += (event_size + sizeof(event_size));
 		len_remain -= (event_size + sizeof(event_size));
 
@@ -386,7 +427,6 @@  static int tpmevlog_check(fwts_framework *fw, uint8_t *data, size_t len)
 	return FWTS_OK;
 }
 
-
 static uint8_t *tpmevlog_load_file(const int fd, size_t *length)
 {
 	uint8_t *ptr = NULL, *tmp;