@@ -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);
@@ -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;
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(-)