From f5c6e1d276040ffd44fa7fe3607ecfa6db2f8bca Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Mon, 2 Dec 2019 11:31:46 +0000 Subject: [PATCH] Add a new plugin that can parse the TPM event log Some devices do not have a stable PCR0 for the same firmware version, and I'd like to collect the TPM event log for affected machines to debug why. --- contrib/debian/fwupd.install | 1 + contrib/fwupd.spec.in | 2 + plugins/dell/fu-plugin-dell.c | 1 + plugins/meson.build | 1 + plugins/tpm-eventlog/README.md | 12 + plugins/tpm-eventlog/fu-plugin-tpm-eventlog.c | 51 +++ plugins/tpm-eventlog/fu-self-test.c | 73 +++++ plugins/tpm-eventlog/fu-tpm-eventlog-common.c | 153 +++++++++ plugins/tpm-eventlog/fu-tpm-eventlog-common.h | 49 +++ plugins/tpm-eventlog/fu-tpm-eventlog-device.c | 98 ++++++ plugins/tpm-eventlog/fu-tpm-eventlog-device.h | 17 + plugins/tpm-eventlog/fu-tpm-eventlog-parser.c | 290 ++++++++++++++++++ plugins/tpm-eventlog/fu-tpm-eventlog-parser.h | 34 ++ plugins/tpm-eventlog/fu-tpm-eventlog.c | 110 +++++++ plugins/tpm-eventlog/meson.build | 90 ++++++ .../tests/binary_bios_measurements-v1 | Bin 0 -> 10436 bytes .../tests/binary_bios_measurements-v2 | Bin 0 -> 40311 bytes plugins/tpm/fu-tpm-device.c | 1 + plugins/uefi/fu-plugin-uefi.c | 1 + po/POTFILES.in | 1 + 20 files changed, 985 insertions(+) create mode 100644 plugins/tpm-eventlog/README.md create mode 100644 plugins/tpm-eventlog/fu-plugin-tpm-eventlog.c create mode 100644 plugins/tpm-eventlog/fu-self-test.c create mode 100644 plugins/tpm-eventlog/fu-tpm-eventlog-common.c create mode 100644 plugins/tpm-eventlog/fu-tpm-eventlog-common.h create mode 100644 plugins/tpm-eventlog/fu-tpm-eventlog-device.c create mode 100644 plugins/tpm-eventlog/fu-tpm-eventlog-device.h create mode 100644 plugins/tpm-eventlog/fu-tpm-eventlog-parser.c create mode 100644 plugins/tpm-eventlog/fu-tpm-eventlog-parser.h create mode 100644 plugins/tpm-eventlog/fu-tpm-eventlog.c create mode 100644 plugins/tpm-eventlog/meson.build create mode 100644 plugins/tpm-eventlog/tests/binary_bios_measurements-v1 create mode 100644 plugins/tpm-eventlog/tests/binary_bios_measurements-v2 diff --git a/contrib/debian/fwupd.install b/contrib/debian/fwupd.install index 0c7c8f78d..dd31791be 100644 --- a/contrib/debian/fwupd.install +++ b/contrib/debian/fwupd.install @@ -12,6 +12,7 @@ usr/lib/*/fwupd usr/lib/*/fwupdagent usr/lib/*/fwupdoffline usr/lib/*/fwupdtool +usr/lib/*/fwupdtpmevlog usr/share/man/man1/* lib/systemd/system/* lib/systemd/system-preset/* diff --git a/contrib/fwupd.spec.in b/contrib/fwupd.spec.in index 80305034d..5a07dbfc9 100644 --- a/contrib/fwupd.spec.in +++ b/contrib/fwupd.spec.in @@ -249,6 +249,7 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom %{_libexecdir}/fwupd/fwupdtool %{_libexecdir}/fwupd/fwupdagent %{_libexecdir}/fwupd/fwupdoffline +%{_libexecdir}/fwupd/fwupdtpmevlog %if 0%{?have_uefi} %{_libexecdir}/fwupd/efi/*.efi %{_libexecdir}/fwupd/efi/*.efi.signed @@ -353,6 +354,7 @@ rm ${RPM_BUILD_ROOT}%{_sbindir}/flashrom %{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt.so %{_libdir}/fwupd-plugins-3/libfu_plugin_thunderbolt_power.so %{_libdir}/fwupd-plugins-3/libfu_plugin_tpm.so +%{_libdir}/fwupd-plugins-3/libfu_plugin_tpm_eventlog.so %if 0%{?have_uefi} %{_libdir}/fwupd-plugins-3/libfu_plugin_uefi.so %{_libdir}/fwupd-plugins-3/libfu_plugin_uefi_recovery.so diff --git a/plugins/dell/fu-plugin-dell.c b/plugins/dell/fu-plugin-dell.c index 67cf6b7a2..a9aba340c 100644 --- a/plugins/dell/fu-plugin-dell.c +++ b/plugins/dell/fu-plugin-dell.c @@ -732,6 +732,7 @@ fu_plugin_dell_detect_tpm (FuPlugin *plugin, GError **error) dev = fu_device_new (); fu_device_set_physical_id (dev, "DEVNAME=/dev/tpm0"); fu_device_add_instance_id (dev, tpm_guid_raw); + fu_device_add_instance_id (dev, "system-tpm"); fu_device_set_vendor (dev, "Dell Inc."); fu_device_set_name (dev, pretty_tpm_name); fu_device_set_summary (dev, "Platform TPM device"); diff --git a/plugins/meson.build b/plugins/meson.build index cce9b252a..f49f4bb86 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -31,6 +31,7 @@ subdir('csr') if get_option('plugin_tpm') and get_option('gudev') subdir('tpm') +subdir('tpm-eventlog') endif if get_option('plugin_emmc') and get_option('gudev') diff --git a/plugins/tpm-eventlog/README.md b/plugins/tpm-eventlog/README.md new file mode 100644 index 000000000..ce18d1613 --- /dev/null +++ b/plugins/tpm-eventlog/README.md @@ -0,0 +1,12 @@ +TPM Event Log Support +===================== + +Introduction +------------ + +The TPM Event Log records which events are registered for the PCR0 hash, which +may help in explaining why PCR0 values are differing for some firmware. + +The device exposed is not upgradable in any way and is just for debugging. +The created device will be a child device of the system TPM device, which may +or may not be upgradable. diff --git a/plugins/tpm-eventlog/fu-plugin-tpm-eventlog.c b/plugins/tpm-eventlog/fu-plugin-tpm-eventlog.c new file mode 100644 index 000000000..bcf372dff --- /dev/null +++ b/plugins/tpm-eventlog/fu-plugin-tpm-eventlog.c @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include "fu-hash.h" +#include "fu-plugin-vfuncs.h" + +#include "fu-tpm-eventlog-device.h" + +void +fu_plugin_init (FuPlugin *plugin) +{ + fu_plugin_set_build_hash (plugin, FU_BUILD_HASH); +} + +gboolean +fu_plugin_coldplug (FuPlugin *plugin, GError **error) +{ + gsize bufsz = 0; + const gchar *fn = "/sys/kernel/security/tpm0/binary_bios_measurements"; + g_autofree gchar *str = NULL; + g_autofree guint8 *buf = NULL; + g_autoptr(FuTpmEventlogDevice) dev = NULL; + + if (!g_file_get_contents (fn, (gchar **) &buf, &bufsz, error)) + return FALSE; + if (bufsz == 0) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_INVALID_FILE, + "failed to read data from %s", fn); + return FALSE; + } + dev = fu_tpm_eventlog_device_new (buf, bufsz, error); + if (dev == NULL) + return FALSE; + if (!fu_device_setup (FU_DEVICE (dev), error)) + return FALSE; + + /* add optional report metadata */ + str = fu_tpm_eventlog_device_report_metadata (dev); + g_debug ("using TPM event log report data of:\n%s", str); + fu_plugin_add_report_metadata (plugin, "TpmEventLog", str); + fu_plugin_device_add (plugin, FU_DEVICE (dev)); + return TRUE; +} + diff --git a/plugins/tpm-eventlog/fu-self-test.c b/plugins/tpm-eventlog/fu-self-test.c new file mode 100644 index 000000000..7d287ca31 --- /dev/null +++ b/plugins/tpm-eventlog/fu-self-test.c @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include + +#include "fu-tpm-eventlog-common.h" +#include "fu-tpm-eventlog-device.h" + +static void +fu_test_tpm_eventlog_parse_v1_func (void) +{ + gboolean ret; + gsize bufsz = 0; + g_autofree gchar *fn = NULL; + g_autofree guint8 *buf = NULL; + g_autofree gchar *str = NULL; + g_autoptr(FuTpmEventlogDevice) dev = NULL; + g_autoptr(GError) error = NULL; + + fn = g_build_filename (TESTDATADIR, "binary_bios_measurements-v1", NULL); + ret = g_file_get_contents (fn, (gchar **) &buf, &bufsz, &error); + g_assert_no_error (error); + g_assert_true (ret); + + dev = fu_tpm_eventlog_device_new (buf, bufsz, &error); + g_assert_no_error (error); + g_assert_nonnull (dev); + str = fu_device_to_string (FU_DEVICE (dev)); + g_print ("%s\n", str); + g_assert_nonnull (g_strstr_len (str, -1, "231f248f12ef9f38549f1bda7a859b781b5caab0")); + g_assert_nonnull (g_strstr_len (str, -1, "9069ca78e7450a285173431b3e52c5c25299e473")); +} + +static void +fu_test_tpm_eventlog_parse_v2_func (void) +{ + gboolean ret; + gsize bufsz = 0; + g_autofree gchar *fn = NULL; + g_autofree guint8 *buf = NULL; + g_autofree gchar *str = NULL; + g_autoptr(FuTpmEventlogDevice) dev = NULL; + g_autoptr(GError) error = NULL; + + fn = g_build_filename (TESTDATADIR, "binary_bios_measurements-v2", NULL); + ret = g_file_get_contents (fn, (gchar **) &buf, &bufsz, &error); + g_assert_no_error (error); + g_assert_true (ret); + + dev = fu_tpm_eventlog_device_new (buf, bufsz, &error); + g_assert_no_error (error); + g_assert_nonnull (dev); + str = fu_device_to_string (FU_DEVICE (dev)); + g_print ("%s\n", str); + g_assert_nonnull (g_strstr_len (str, -1, "19ce8e1347a709d2b485d519695e3ce10b939485")); + g_assert_nonnull (g_strstr_len (str, -1, "9069ca78e7450a285173431b3e52c5c25299e473")); + g_assert_nonnull (g_strstr_len (str, -1, "Boot Guard Measured")); +} + +int +main (int argc, char **argv) +{ + g_test_init (&argc, &argv, NULL); + g_log_set_fatal_mask (NULL, G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL); + g_test_add_func ("/tpm-eventlog/parse{v1}", fu_test_tpm_eventlog_parse_v1_func); + g_test_add_func ("/tpm-eventlog/parse{v2}", fu_test_tpm_eventlog_parse_v2_func); + return g_test_run (); +} diff --git a/plugins/tpm-eventlog/fu-tpm-eventlog-common.c b/plugins/tpm-eventlog/fu-tpm-eventlog-common.c new file mode 100644 index 000000000..21172de5c --- /dev/null +++ b/plugins/tpm-eventlog/fu-tpm-eventlog-common.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include "fu-tpm-eventlog-common.h" + +const gchar * +fu_tpm_eventlog_pcr_to_string (gint pcr) +{ + if (pcr == 0) + return "BIOS"; + if (pcr == 1) + return "BIOS Configuration"; + if (pcr == 2) + return "Option ROMs"; + if (pcr == 3) + return "Option ROM configuration"; + if (pcr == 4) + return "Initial program loader code"; + if (pcr == 5) + return "Initial program loader code configuration"; + if (pcr == 6) + return "State transitions and wake events"; + if (pcr == 7) + return "Platform manufacturer specifc measurements"; + if (pcr >= 8 && pcr <= 15) + return "Static operating system"; + if (pcr == 16) + return "Debug"; + if (pcr == 17) + return "Dynamic root of trust measurement and launch control policy"; + if (pcr >= 18 && pcr <= 22) + return "Trusted OS"; + if (pcr == 23) + return "Application support"; + return "Undefined"; +} + +const gchar * +fu_tpm_eventlog_hash_to_string (TPM2_ALG_ID hash_kind) +{ + if (hash_kind == TPM2_ALG_SHA1) + return "SHA1"; + if (hash_kind == TPM2_ALG_SHA256) + return "SHA256"; + if (hash_kind == TPM2_ALG_SHA384) + return "SHA384"; + if (hash_kind == TPM2_ALG_SHA512) + return "SHA512"; + return NULL; +} + +guint32 +fu_tpm_eventlog_hash_get_size (TPM2_ALG_ID hash_kind) +{ + if (hash_kind == TPM2_ALG_SHA1) + return TPM2_SHA1_DIGEST_SIZE; + if (hash_kind == TPM2_ALG_SHA256) + return TPM2_SHA256_DIGEST_SIZE; + if (hash_kind == TPM2_ALG_SHA384) + return TPM2_SHA384_DIGEST_SIZE; + if (hash_kind == TPM2_ALG_SHA512) + return TPM2_SHA512_DIGEST_SIZE; + return 0; +} + +const gchar * +fu_tpm_eventlog_item_kind_to_string (FuTpmEventlogItemKind event_type) +{ + if (event_type == EV_PREBOOT_CERT) + return "EV_PREBOOT_CERT"; + if (event_type == EV_POST_CODE) + return "EV_POST_CODE"; + if (event_type == EV_NO_ACTION) + return "EV_NO_ACTION"; + if (event_type == EV_SEPARATOR) + return "EV_SEPARATOR"; + if (event_type == EV_ACTION) + return "EV_ACTION"; + if (event_type == EV_EVENT_TAG) + return "EV_EVENT_TAG"; + if (event_type == EV_S_CRTM_CONTENTS) + return "EV_S_CRTM_CONTENTS"; + if (event_type == EV_S_CRTM_VERSION) + return "EV_S_CRTM_VERSION"; + if (event_type == EV_CPU_MICROCODE) + return "EV_CPU_MICROCODE"; + if (event_type == EV_PLATFORM_CONFIG_FLAGS) + return "EV_PLATFORM_CONFIG_FLAGS"; + if (event_type == EV_TABLE_OF_DEVICES) + return "EV_TABLE_OF_DEVICES"; + if (event_type == EV_COMPACT_HASH) + return "EV_COMPACT_HASH"; + if (event_type == EV_NONHOST_CODE) + return "EV_NONHOST_CODE"; + if (event_type == EV_NONHOST_CONFIG) + return "EV_NONHOST_CONFIG"; + if (event_type == EV_NONHOST_INFO) + return "EV_NONHOST_INFO"; + if (event_type == EV_OMIT_BOOT_DEVICE_EVENTS) + return "EV_OMIT_BOOT_DEVICE_EVENTS"; + if (event_type == EV_EFI_EVENT_BASE) + return "EV_EFI_EVENT_BASE"; + if (event_type == EV_EFI_VARIABLE_DRIVER_CONFIG) + return "EV_EFI_VARIABLE_DRIVER_CONFIG"; + if (event_type == EV_EFI_VARIABLE_BOOT) + return "EV_EFI_VARIABLE_BOOT"; + if (event_type == EV_EFI_BOOT_SERVICES_APPLICATION) + return "EV_BOOT_SERVICES_APPLICATION"; + if (event_type == EV_EFI_BOOT_SERVICES_DRIVER) + return "EV_EFI_BOOT_SERVICES_DRIVER"; + if (event_type == EV_EFI_RUNTIME_SERVICES_DRIVER) + return "EV_EFI_RUNTIME_SERVICES_DRIVER"; + if (event_type == EV_EFI_GPT_EVENT) + return "EV_EFI_GPT_EVENT"; + if (event_type == EV_EFI_ACTION) + return "EV_EFI_ACTION"; + if (event_type == EV_EFI_PLATFORM_FIRMWARE_BLOB) + return "EV_EFI_PLATFORM_FIRMWARE_BLOB"; + if (event_type == EV_EFI_HANDOFF_TABLES) + return "EV_EFI_HANDOFF_TABLES"; + if (event_type == EV_EFI_HCRTM_EVENT) + return "EV_EFI_HCRTM_EVENT"; + if (event_type == EV_EFI_VARIABLE_AUTHORITY) + return "EV_EFI_EFI_VARIABLE_AUTHORITY"; + return NULL; +} + +gchar * +fu_tpm_eventlog_blobstr (GBytes *blob) +{ + gboolean has_printable = FALSE; + gsize bufsz = 0; + const guint8 *buf = g_bytes_get_data (blob, &bufsz); + g_autoptr(GString) str = g_string_new (NULL); + + for (gsize i = 0; i < bufsz; i++) { + gchar chr = buf[i]; + if (g_ascii_isprint (chr)) { + g_string_append_c (str, chr); + has_printable = TRUE; + } else { + g_string_append_c (str, '.'); + } + } + if (!has_printable) + return NULL; + return g_string_free (g_steal_pointer (&str), FALSE); +} diff --git a/plugins/tpm-eventlog/fu-tpm-eventlog-common.h b/plugins/tpm-eventlog/fu-tpm-eventlog-common.h new file mode 100644 index 000000000..8c9cf0e77 --- /dev/null +++ b/plugins/tpm-eventlog/fu-tpm-eventlog-common.h @@ -0,0 +1,49 @@ + /* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#pragma once + +#include +#include + +#include "fu-plugin.h" + +typedef enum { + EV_PREBOOT_CERT = 0x00000000, + EV_POST_CODE = 0x00000001, + EV_NO_ACTION = 0x00000003, + EV_SEPARATOR = 0x00000004, + EV_ACTION = 0x00000005, + EV_EVENT_TAG = 0x00000006, + EV_S_CRTM_CONTENTS = 0x00000007, + EV_S_CRTM_VERSION = 0x00000008, + EV_CPU_MICROCODE = 0x00000009, + EV_PLATFORM_CONFIG_FLAGS = 0x0000000a, + EV_TABLE_OF_DEVICES = 0x0000000b, + EV_COMPACT_HASH = 0x0000000c, + EV_NONHOST_CODE = 0x0000000f, + EV_NONHOST_CONFIG = 0x00000010, + EV_NONHOST_INFO = 0x00000011, + EV_OMIT_BOOT_DEVICE_EVENTS = 0x00000012, + EV_EFI_EVENT_BASE = 0x80000000, + EV_EFI_VARIABLE_DRIVER_CONFIG = 0x80000001, + EV_EFI_VARIABLE_BOOT = 0x80000002, + EV_EFI_BOOT_SERVICES_APPLICATION = 0x80000003, + EV_EFI_BOOT_SERVICES_DRIVER = 0x80000004, + EV_EFI_RUNTIME_SERVICES_DRIVER = 0x80000005, + EV_EFI_GPT_EVENT = 0x80000006, + EV_EFI_ACTION = 0x80000007, + EV_EFI_PLATFORM_FIRMWARE_BLOB = 0x80000008, + EV_EFI_HANDOFF_TABLES = 0x80000009, + EV_EFI_HCRTM_EVENT = 0x80000010, + EV_EFI_VARIABLE_AUTHORITY = 0x800000e0 +} FuTpmEventlogItemKind; + +const gchar *fu_tpm_eventlog_pcr_to_string (gint pcr); +const gchar *fu_tpm_eventlog_hash_to_string (TPM2_ALG_ID hash_kind); +guint32 fu_tpm_eventlog_hash_get_size (TPM2_ALG_ID hash_kind); +const gchar *fu_tpm_eventlog_item_kind_to_string (FuTpmEventlogItemKind event_type); +gchar *fu_tpm_eventlog_blobstr (GBytes *blob); diff --git a/plugins/tpm-eventlog/fu-tpm-eventlog-device.c b/plugins/tpm-eventlog/fu-tpm-eventlog-device.c new file mode 100644 index 000000000..6960a711e --- /dev/null +++ b/plugins/tpm-eventlog/fu-tpm-eventlog-device.c @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include + +#include "fu-common.h" + +#include "fu-tpm-eventlog-device.h" +#include "fu-tpm-eventlog-parser.h" + +struct _FuTpmEventlogDevice { + FuDevice parent_instance; + GPtrArray *items; +}; + +G_DEFINE_TYPE (FuTpmEventlogDevice, fu_tpm_eventlog_device, FU_TYPE_DEVICE) + +static void +fu_tpm_eventlog_device_to_string (FuDevice *device, guint idt, GString *str) +{ + FuTpmEventlogDevice *self = FU_TPM_EVENTLOG_DEVICE (device); + if (self->items->len > 0) { + fu_common_string_append_kv (str, idt, "Items", NULL); + for (guint i = 0; i < self->items->len; i++) { + FuTpmEventlogItem *item = g_ptr_array_index (self->items, i); + fu_tpm_eventlog_item_to_string (item, idt + 1, str); + } + } +} + +gchar * +fu_tpm_eventlog_device_report_metadata (FuTpmEventlogDevice *self) +{ + GString *str = g_string_new (""); + for (guint i = 0; i < self->items->len; i++) { + FuTpmEventlogItem *item = g_ptr_array_index (self->items, i); + g_autofree gchar *blobstr = fu_tpm_eventlog_blobstr (item->blob); + g_string_append_printf (str, "0x%08x %s", item->kind, item->checksum_sha1); + if (blobstr != NULL) + g_string_append_printf (str, " [%s]", blobstr); + g_string_append (str, "\n"); + } + if (str->len > 0) + g_string_truncate (str, str->len - 1); + return g_string_free (str, FALSE); +} + +static void +fu_tpm_eventlog_device_init (FuTpmEventlogDevice *self) +{ + fu_device_set_name (FU_DEVICE (self), "Event Log"); + fu_device_add_flag (FU_DEVICE (self), FWUPD_DEVICE_FLAG_INTERNAL); + fu_device_set_physical_id (FU_DEVICE (self), "DEVNAME=/dev/tpm0"); + fu_device_set_logical_id (FU_DEVICE (self), "eventlog"); + fu_device_add_parent_guid (FU_DEVICE (self), "system-tpm"); + fu_device_add_instance_id (FU_DEVICE (self), "system-tpm-eventlog"); +} + +static void +fu_tpm_eventlog_device_finalize (GObject *object) +{ + FuTpmEventlogDevice *self = FU_TPM_EVENTLOG_DEVICE (object); + + g_ptr_array_unref (self->items); + + G_OBJECT_CLASS (fu_tpm_eventlog_device_parent_class)->finalize (object); +} + +static void +fu_tpm_eventlog_device_class_init (FuTpmEventlogDeviceClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + FuDeviceClass *klass_device = FU_DEVICE_CLASS (klass); + object_class->finalize = fu_tpm_eventlog_device_finalize; + klass_device->to_string = fu_tpm_eventlog_device_to_string; +} + +FuTpmEventlogDevice * +fu_tpm_eventlog_device_new (const guint8 *buf, gsize bufsz, GError **error) +{ + g_autoptr(FuTpmEventlogDevice) self = NULL; + + g_return_val_if_fail (buf != NULL, NULL); + + /* create object */ + self = g_object_new (FU_TYPE_TPM_EVENTLOG_DEVICE, NULL); + self->items = fu_tpm_eventlog_parser_new (buf, bufsz, + FU_TPM_EVENTLOG_PARSER_FLAG_NONE, + error); + if (self->items == NULL) + return NULL; + return FU_TPM_EVENTLOG_DEVICE (g_steal_pointer (&self)); +} diff --git a/plugins/tpm-eventlog/fu-tpm-eventlog-device.h b/plugins/tpm-eventlog/fu-tpm-eventlog-device.h new file mode 100644 index 000000000..a77e9a657 --- /dev/null +++ b/plugins/tpm-eventlog/fu-tpm-eventlog-device.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#pragma once + +#include "fu-plugin.h" + +#define FU_TYPE_TPM_EVENTLOG_DEVICE (fu_tpm_eventlog_device_get_type ()) +G_DECLARE_FINAL_TYPE (FuTpmEventlogDevice, fu_tpm_eventlog_device, FU, TPM_EVENTLOG_DEVICE, FuDevice) + +FuTpmEventlogDevice *fu_tpm_eventlog_device_new (const guint8 *buf, + gsize bufsz, + GError **error); +gchar *fu_tpm_eventlog_device_report_metadata (FuTpmEventlogDevice *self); diff --git a/plugins/tpm-eventlog/fu-tpm-eventlog-parser.c b/plugins/tpm-eventlog/fu-tpm-eventlog-parser.c new file mode 100644 index 000000000..0b59383b3 --- /dev/null +++ b/plugins/tpm-eventlog/fu-tpm-eventlog-parser.c @@ -0,0 +1,290 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include "config.h" + +#include + +#include "fu-common.h" + +#include "fu-tpm-eventlog-parser.h" + +#define FU_TPM_EVENTLOG_V1_IDX_PCR 0x00 +#define FU_TPM_EVENTLOG_V1_IDX_TYPE 0x04 +#define FU_TPM_EVENTLOG_V1_IDX_DIGEST 0x08 +#define FU_TPM_EVENTLOG_V1_IDX_EVENT_SIZE 0x1c +#define FU_TPM_EVENTLOG_V1_SIZE 0x20 + +#define FU_TPM_EVENTLOG_V2_HDR_IDX_SIGNATURE 0x00 +#define FU_TPM_EVENTLOG_V2_HDR_IDX_PLATFORM_CLASS 0x10 +#define FU_TPM_EVENTLOG_V2_HDR_IDX_SPEC_VERSION_MINOR 0x14 +#define FU_TPM_EVENTLOG_V2_HDR_IDX_SPEC_VERSION_MAJOR 0X15 +#define FU_TPM_EVENTLOG_V2_HDR_IDX_SPEC_ERRATA 0x16 +#define FU_TPM_EVENTLOG_V2_HDR_IDX_UINTN_SIZE 0x17 +#define FU_TPM_EVENTLOG_V2_HDR_IDX_NUMBER_OF_ALGS 0x18 + +#define FU_TPM_EVENTLOG_V2_HDR_SIGNATURE "Spec ID Event03" + +#define FU_TPM_EVENTLOG_V2_IDX_PCR 0x00 +#define FU_TPM_EVENTLOG_V2_IDX_TYPE 0x04 +#define FU_TPM_EVENTLOG_V2_IDX_DIGEST_COUNT 0x08 +#define FU_TPM_EVENTLOG_V2_SIZE 0x0c + +static void +fu_tpm_eventlog_parser_item_free (FuTpmEventlogItem *item) +{ + g_bytes_unref (item->blob); + g_free (item->checksum_sha1); + g_free (item->checksum_sha256); + g_free (item); +} + +void +fu_tpm_eventlog_item_to_string (FuTpmEventlogItem *item, guint idt, GString *str) +{ + const gchar *tmp; + g_autofree gchar *blobstr = fu_tpm_eventlog_blobstr (item->blob); + g_autofree gchar *pcrstr = g_strdup_printf ("%s (%u)", + fu_tpm_eventlog_pcr_to_string (item->pcr), + item->pcr); + fu_common_string_append_kv (str, idt, "PCR", pcrstr); + fu_common_string_append_kx (str, idt, "Type", item->kind); + tmp = fu_tpm_eventlog_item_kind_to_string (item->kind); + if (tmp != NULL) + fu_common_string_append_kv (str, idt, "Description", tmp);; + fu_common_string_append_kv (str, idt, "ChecksumSha1", item->checksum_sha1); + if (item->checksum_sha256 != NULL) + fu_common_string_append_kv (str, idt, "ChecksumSha256", item->checksum_sha256); + if (blobstr != NULL) + fu_common_string_append_kv (str, idt, "BlobStr", blobstr); +} + +static gchar * +fu_tpm_eventlog_read_strhex_safe (const guint8 *buf, + gsize bufsz, + gsize offset, + gsize length, + GError **error) +{ + g_autoptr(GString) csum = g_string_new (NULL); + g_autofree guint8 *digest = g_malloc0 (length); + if (!fu_memcpy_safe (digest, length, 0x0, /* dst */ + buf, bufsz, offset, /* src */ + length, error)) + return FALSE; + for (guint i = 0; i < length; i++) + g_string_append_printf (csum, "%02x", digest[i]); + return g_string_free (g_steal_pointer (&csum), FALSE); +} + +static GPtrArray * +fu_tpm_eventlog_parser_parse_blob_v2 (const guint8 *buf, gsize bufsz, + FuTpmEventlogParserFlags flags, + GError **error) +{ + guint32 hdrsz = 0x0; + g_autoptr(GPtrArray) items = NULL; + + /* advance over the header block */ + if (!fu_common_read_uint32_safe (buf, bufsz, + FU_TPM_EVENTLOG_V1_IDX_EVENT_SIZE, + &hdrsz, G_LITTLE_ENDIAN, error)) + return NULL; + items = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_tpm_eventlog_parser_item_free); + for (gsize idx = FU_TPM_EVENTLOG_V1_SIZE + hdrsz; idx < bufsz;) { + guint32 pcr = 0; + guint32 event_type = 0; + guint32 digestcnt = 0; + guint32 datasz = 0; + g_autofree gchar *checksum_sha1 = NULL; + g_autofree gchar *checksum_sha256 = NULL; + + /* read entry */ + if (!fu_common_read_uint32_safe (buf, bufsz, + idx + FU_TPM_EVENTLOG_V2_IDX_PCR, + &pcr, G_LITTLE_ENDIAN, error)) + return NULL; + if (!fu_common_read_uint32_safe (buf, bufsz, + idx + FU_TPM_EVENTLOG_V2_IDX_TYPE, + &event_type, G_LITTLE_ENDIAN, error)) + return NULL; + if (!fu_common_read_uint32_safe (buf, bufsz, + idx + FU_TPM_EVENTLOG_V2_IDX_DIGEST_COUNT, + &digestcnt, G_LITTLE_ENDIAN, error)) + return NULL; + + /* read checksum block */ + idx += FU_TPM_EVENTLOG_V2_SIZE; + for (guint i = 0; i < digestcnt; i++) { + guint16 alg_type = 0; + guint32 alg_size = 0; + + /* get checksum type */ + if (!fu_common_read_uint16_safe (buf, bufsz, idx, + &alg_type, G_LITTLE_ENDIAN, error)) + return NULL; + alg_size = fu_tpm_eventlog_hash_get_size (alg_type); + if (alg_size == 0) { + g_set_error (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "hash algorithm 0x%x size not known", + alg_type); + return NULL; + } + + /* build checksum */ + idx += sizeof(alg_type); + if (alg_type == TPM2_ALG_SHA1 || + flags & FU_TPM_EVENTLOG_PARSER_FLAG_ALL_ALGS) { + g_autofree gchar *csum_tmp = NULL; + csum_tmp = fu_tpm_eventlog_read_strhex_safe (buf, + bufsz, + idx, + alg_size, + error); + if (csum_tmp == NULL) + return NULL; + + /* save this for analysis */ + if (alg_type == TPM2_ALG_SHA1) + checksum_sha1 = g_steal_pointer (&csum_tmp); + else if (alg_type == TPM2_ALG_SHA256) + checksum_sha256 = g_steal_pointer (&csum_tmp); + } + + /* next block */ + idx += alg_size; + } + + /* read data block */ + if (!fu_common_read_uint32_safe (buf, bufsz, idx, + &datasz, G_LITTLE_ENDIAN, error)) + return NULL; + if (datasz > 1024 * 1024) { + g_set_error_literal (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "event log item too large"); + return NULL; + } + + /* save blob if PCR=0 */ + idx += sizeof(datasz); + if (pcr == ESYS_TR_PCR0 || + flags & FU_TPM_EVENTLOG_PARSER_FLAG_ALL_PCRS) { + FuTpmEventlogItem *item; + g_autofree guint8 *data = NULL; + + /* build item */ + data = g_malloc0 (datasz); + if (!fu_memcpy_safe (data, datasz, 0x0, /* dst */ + buf, bufsz, idx, datasz, /* src */ + error)) + return NULL; + + /* not normally required */ + if (g_getenv ("FWUPD_TPM_EVENTLOG_VERBOSE") != NULL) { + fu_common_dump_full (G_LOG_DOMAIN, "Event Data", + data, datasz, 20, + FU_DUMP_FLAGS_SHOW_ASCII); + } + item = g_new0 (FuTpmEventlogItem, 1); + item->pcr = pcr; + item->kind = event_type; + item->checksum_sha1 = g_steal_pointer (&checksum_sha1); + item->checksum_sha256 = g_steal_pointer (&checksum_sha256); + item->blob = g_bytes_new_take (g_steal_pointer (&data), datasz); + g_ptr_array_add (items, item); + } + + /* next entry */ + idx += datasz; + } + + /* success */ + return g_steal_pointer (&items); +} + +GPtrArray * +fu_tpm_eventlog_parser_new (const guint8 *buf, gsize bufsz, + FuTpmEventlogParserFlags flags, + GError **error) +{ + gchar sig[] = FU_TPM_EVENTLOG_V2_HDR_SIGNATURE; + g_autoptr(GPtrArray) items = NULL; + + g_return_val_if_fail (buf != NULL, NULL); + + /* look for TCG v2 signature */ + if (!fu_memcpy_safe ((guint8 *) sig, sizeof(sig), 0x0, /* dst */ + buf, bufsz, FU_TPM_EVENTLOG_V1_SIZE, /* src */ + sizeof(sig), error)) + return NULL; + if (g_strcmp0 (sig, FU_TPM_EVENTLOG_V2_HDR_SIGNATURE) == 0) + return fu_tpm_eventlog_parser_parse_blob_v2 (buf, bufsz, flags, error); + + /* assume v1 structure */ + items = g_ptr_array_new_with_free_func ((GDestroyNotify) fu_tpm_eventlog_parser_item_free); + for (gsize idx = 0; idx < bufsz; idx += FU_TPM_EVENTLOG_V1_SIZE) { + guint32 datasz = 0; + guint32 pcr = 0; + guint32 event_type = 0; + if (!fu_common_read_uint32_safe (buf, bufsz, + idx + FU_TPM_EVENTLOG_V1_IDX_PCR, + &pcr, G_LITTLE_ENDIAN, error)) + return NULL; + if (!fu_common_read_uint32_safe (buf, bufsz, + idx + FU_TPM_EVENTLOG_V1_IDX_TYPE, + &event_type, G_LITTLE_ENDIAN, error)) + return NULL; + if (!fu_common_read_uint32_safe (buf, bufsz, + idx + FU_TPM_EVENTLOG_V1_IDX_EVENT_SIZE, + &datasz, G_LITTLE_ENDIAN, error)) + return NULL; + if (datasz > 1024 * 1024) { + g_set_error_literal (error, + FWUPD_ERROR, + FWUPD_ERROR_NOT_SUPPORTED, + "event log item too large"); + return NULL; + } + if (pcr == ESYS_TR_PCR0 || + flags & FU_TPM_EVENTLOG_PARSER_FLAG_ALL_PCRS) { + FuTpmEventlogItem *item; + g_autofree gchar *csum = NULL; + g_autofree guint8 *data = NULL; + + /* build checksum */ + csum = fu_tpm_eventlog_read_strhex_safe (buf, bufsz, + idx + FU_TPM_EVENTLOG_V1_IDX_DIGEST, + TPM2_SHA1_DIGEST_SIZE, + error); + if (csum == NULL) + return NULL; + + /* build item */ + data = g_malloc0 (datasz); + if (!fu_memcpy_safe (data, datasz, 0x0, /* dst */ + buf, bufsz, idx + FU_TPM_EVENTLOG_V1_SIZE, datasz, /* src */ + error)) + return NULL; + item = g_new0 (FuTpmEventlogItem, 1); + item->pcr = pcr; + item->kind = event_type; + item->checksum_sha1 = g_steal_pointer (&csum); + item->blob = g_bytes_new_take (g_steal_pointer (&data), datasz); + g_ptr_array_add (items, item); + + /* not normally required */ + if (g_getenv ("FWUPD_TPM_EVENTLOG_VERBOSE") != NULL) + fu_common_dump_bytes (G_LOG_DOMAIN, "Event Data", item->blob); + } + idx += datasz; + } + return g_steal_pointer (&items); + +} diff --git a/plugins/tpm-eventlog/fu-tpm-eventlog-parser.h b/plugins/tpm-eventlog/fu-tpm-eventlog-parser.h new file mode 100644 index 000000000..d951c46c7 --- /dev/null +++ b/plugins/tpm-eventlog/fu-tpm-eventlog-parser.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#pragma once + +#include "fu-plugin.h" + +#include "fu-tpm-eventlog-common.h" + +typedef struct { + guint8 pcr; + FuTpmEventlogItemKind kind; + gchar *checksum_sha1; + gchar *checksum_sha256; + GBytes *blob; +} FuTpmEventlogItem; + +typedef enum { + FU_TPM_EVENTLOG_PARSER_FLAG_NONE = 0, + FU_TPM_EVENTLOG_PARSER_FLAG_ALL_PCRS = 1 << 0, + FU_TPM_EVENTLOG_PARSER_FLAG_ALL_ALGS = 1 << 1, + FU_TPM_EVENTLOG_PARSER_FLAG_LAST +} FuTpmEventlogParserFlags; + +GPtrArray *fu_tpm_eventlog_parser_new (const guint8 *buf, + gsize bufsz, + FuTpmEventlogParserFlags flags, + GError **error); +void fu_tpm_eventlog_item_to_string (FuTpmEventlogItem *item, + guint idt, + GString *str); diff --git a/plugins/tpm-eventlog/fu-tpm-eventlog.c b/plugins/tpm-eventlog/fu-tpm-eventlog.c new file mode 100644 index 000000000..ebd3256e5 --- /dev/null +++ b/plugins/tpm-eventlog/fu-tpm-eventlog.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2019 Richard Hughes + * + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#define G_LOG_DOMAIN "FuTpmEventlog" + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "fu-tpm-eventlog-parser.h" + +static gint +fu_tmp_eventlog_sort_cb (gconstpointer a, gconstpointer b) +{ + FuTpmEventlogItem *item_a = *((FuTpmEventlogItem **) a); + FuTpmEventlogItem *item_b = *((FuTpmEventlogItem **) b); + if (item_a->pcr > item_b->pcr) + return 1; + if (item_a->pcr < item_b->pcr) + return -1; + return 0; +} + +static gboolean +fu_tmp_eventlog_process (const gchar *fn, gint pcr, GError **error) +{ + gsize bufsz = 0; + g_autofree guint8 *buf = NULL; + g_autoptr(GPtrArray) items = NULL; + g_autoptr(GString) str = g_string_new (NULL); + + /* parse this */ + if (!g_file_get_contents (fn, (gchar **) &buf, &bufsz, error)) + return FALSE; + items = fu_tpm_eventlog_parser_new (buf, bufsz, + FU_TPM_EVENTLOG_PARSER_FLAG_ALL_ALGS | + FU_TPM_EVENTLOG_PARSER_FLAG_ALL_PCRS, + error); + if (items == NULL) + return FALSE; + g_ptr_array_sort (items, fu_tmp_eventlog_sort_cb); + + for (guint i = 0; i < items->len; i++) { + FuTpmEventlogItem *item = g_ptr_array_index (items, i); + if (pcr >= 0 && item->pcr != pcr) + continue; + fu_tpm_eventlog_item_to_string (item, 0, str); + g_string_append (str, "\n"); + } + + /* success */ + g_print ("%s", str->str); + return TRUE; +} + +int +main (int argc, char *argv[]) +{ + const gchar *fn; + gboolean verbose = FALSE; + gint pcr = -1; + g_autoptr(GError) error = NULL; + g_autoptr(GOptionContext) context = g_option_context_new (NULL); + const GOptionEntry options[] = { + { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, + /* TRANSLATORS: command line option */ + _("Show extra debugging information"), NULL }, + { "pcr", 'p', 0, G_OPTION_ARG_INT, &pcr, + /* TRANSLATORS: command line option */ + _("Only show single PCR value"), NULL }, + { NULL} + }; + + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, FWUPD_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + /* TRANSLATORS: program name */ + g_option_context_add_main_entries (context, options, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) { + /* TRANSLATORS: the user didn't read the man page */ + g_print ("%s: %s\n", _("Failed to parse arguments"), + error->message); + return EXIT_FAILURE; + } + + /* set verbose? */ + if (verbose) { + g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); + g_setenv ("FWUPD_TPM_EVENTLOG_VERBOSE", "1", FALSE); + } + + /* allow user to chose a local file */ + fn = argc <= 1 ? "/sys/kernel/security/tpm0/binary_bios_measurements" : argv[1]; + if (!fu_tmp_eventlog_process (fn, pcr, &error)) { + /* TRANSLATORS: failed to read measurements file */ + g_printerr ("%s: %s\n", _("Failed to parse file"), + error->message); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/plugins/tpm-eventlog/meson.build b/plugins/tpm-eventlog/meson.build new file mode 100644 index 000000000..b8acf26fa --- /dev/null +++ b/plugins/tpm-eventlog/meson.build @@ -0,0 +1,90 @@ +cargs = ['-DG_LOG_DOMAIN="FuPluginTpmEventlog"'] + +shared_module('fu_plugin_tpm_eventlog', + fu_hash, + sources : [ + 'fu-plugin-tpm-eventlog.c', + 'fu-tpm-eventlog-common.c', + 'fu-tpm-eventlog-device.c', + 'fu-tpm-eventlog-parser.c', + ], + include_directories : [ + root_incdir, + fwupd_incdir, + fwupdplugin_incdir, + ], + install : true, + install_dir: plugin_dir, + link_with : [ + fwupdplugin, + fwupd, + ], + c_args : cargs, + dependencies : [ + plugin_deps, + tpm2tss, + ], +) + +if get_option('tests') + testdatadir = join_paths(meson.current_source_dir(), 'tests') + cargs += '-DTESTDATADIR="' + testdatadir + '"' + e = executable( + 'tpm-eventlog-self-test', + fu_hash, + sources : [ + 'fu-self-test.c', + 'fu-tpm-eventlog-common.c', + 'fu-tpm-eventlog-device.c', + 'fu-tpm-eventlog-parser.c', + ], + include_directories : [ + root_incdir, + fwupd_incdir, + fwupdplugin_incdir, + ], + link_with : [ + fwupdplugin, + fwupd, + ], + dependencies : [ + plugin_deps, + tpm2tss, + ], + c_args : cargs + ) + test('tpm-eventlog-self-test', e) +endif + +fwupdtpmevlog = executable( + 'fwupdtpmevlog', + sources : [ + 'fu-tpm-eventlog.c', + 'fu-tpm-eventlog-common.c', + 'fu-tpm-eventlog-parser.c', + ], + include_directories : [ + root_incdir, + fwupd_incdir, + fwupdplugin_incdir, + ], + dependencies : [ + plugin_deps, + tpm2tss, + ], + link_with : [ + fwupd, + fwupdplugin, + ], + install : true, + install_dir : join_paths(libexecdir, 'fwupd') +) + +run_target('fuzz-tpm-eventlog', + command: [ + join_paths(meson.source_root(), 'contrib/afl-fuzz.py'), + '-i', join_paths(meson.current_source_dir(), 'tests'), + '-o', join_paths(meson.current_build_dir(), 'findings'), + fwupdtpmevlog, + ], +) diff --git a/plugins/tpm-eventlog/tests/binary_bios_measurements-v1 b/plugins/tpm-eventlog/tests/binary_bios_measurements-v1 new file mode 100644 index 0000000000000000000000000000000000000000..0618456e968779145ef4e5aeaab9ffe04a393643 GIT binary patch literal 10436 zcmdT}2V4``^Iw_@r=qBUg1Vj!Jp&1$DnWXY5{hC0jZ3l#QIcQ^0v13lU;$A?ggZgy zEMUP-5!5^71P%*$hYhTNilxTO6vP#LrXx0p6*3b+!5F*%Ph5>Ui~UQdPo z+3L!&H@hDAiJ~d_#ZG)f;sH=gLRdgYX;`^L+)f~{IFg} zh5~qqD-gjECL%$E;OT@2z(5MY+Z$Rx<)G0 z5AjmS$ZT7EzPDr6s)+JYoT{|d*W2T^&KlQ^j85~VGQ7Y-bxH|-+m;h`Rrmd6szC)c zqd;#$&fPmuld2;_>n79EU3Zl6Of&Mu({nbhDM9~z3 zc~FzCGP-I4WkeBDGy(NSZe>)ntB#4k$l1s~;QTKE+a8GEIJ_V__&Y9OWZ1lWi|h`Z zNY`vFZ13audwvep8_XFZ8$BSMgEqW(UXx^hYW5zCeE)J%QQO+wX+>_x+~sxhe+=gvRw|UTiKeLHTU=>KQ zQ2m}^^?ROlTI&eiJ^g;nlEcSxdn;p6CNqkHTvpN97i^8_8>Z{b6t%|?SPoLG`Eo

?8RXHWL{L^tQK4Y^o);Npr>V2$C?)wiptS(tCtUKqQvl?P$#5|S8hE~t) zDq>!GHF$E?v{QMT!Uh#fo-1SR8s4ANG~JeS*QDm!m44INqT!gOvRw{lJ;PF;S-SN8 zh2`|(K2MfEFClT1vFe`{*RDU3e9viItz%I6V~$(eJv9RBaa3Cc8altkqL|ZVkx&tu`}3*@s9EefYfv=WT=jk1lIW@-?uV z?^+=i+#un`>TNKn9l3sYLwth$OIu!Iwnl1Y{6sKuvfO9lYsY%mV**mG#o0@EUzvF? zWKVCfq4L3Y8VSD6;LAtY2p8cXYKlwl4>d3bhY3LVko|&$aEcfQ8;g`g&h`K2DK!j< zbF#Bvk+kYbR_&<4OVj63_-}uyTUiUtNQpbUlishwd-u>QO^&rcdBRc+uXWM~qU_1e za>WIODq7XEfL?|r<0Kpj-Ke;T3FuZxOFY!nr7o7S{3{PaBG}{O?mJ|if7RRbm2tNH zjCGoq&u{jwibf%{42DAbsU?wAJ1|op**JdcSsw)b#}`h)_yxrz&R>1&WUXzCx>q4( zfyQrirWukG8m57{t_4_LPYfY5xa5_b4(d7!1fq~YGynx?C^8H&LX45&$OvR4f+~<~ zo9Z?%_&Xr|)l=r9yj#;!7|*U5g#b0XBK461Ad_S!$dSkh{7{HlG3c$hAmCXb>=z>< zfFh?t5g!BtGZ;t&s1=Ori9{(wa&)DVQE9!>wR+GPSyt=raQepCp2@ zDDZUxq2z+l!E+kGa0Wdh4OxQN65hjze$gD@kq}F8XMqn1u>dlyfz2df4HJAQ;4d~p zMa%&@70g-yDhohi3wV|R1dPCgJsfNopdRv7CND}Yc-yOV`H;M-^0monKesZM%-#(- zy7X>x-$#Nuc**UR`kqY44+Z|g0kQ!21_LzEzr<3>nH_o&yhW73jV6#{-_S0ye37Q*Ol*uaODwZ)oS!?ppKeT5V<=4^T4<2Uwr7 z!j8~G)d~vm7u41SnSlfX`%q$45JW>~3{qngb!vs~e4hmUGht7oYl2rt=%we)iSjrR ze)Xr?;srC5JsLQF=~2d5-qFI_KC`yAyiI5g+c=&78C~Rki?T;4VAbK(sf!zk5En4g zoi>8jAv+Vv$DQ{UvIc0ojqp^~X8XAD&TNkthp*VuwM(zhd4Hg=++ZP)^C{2BE2XM7 zwuEOUfVY?+5dAoaJgCXokNkod58Y;d-P`wIX3mL6$%VNpq2@=MO`^XR_}&rUI=w*5 zG1s}%lGbxo9J{Cj)BbBzQB(HH7RlQiJ05;V_aATD|Jcr_ZYDS0&0q8xuQ-A^c&U2D zNv4V;$XG`ZFCN4inFG4+6iPi5Iy=ZE+i_3PNP5!5f;TF@sgxKT4o;nv?3fe%bjX|0 z>cdY_xAj~h=WZ3Eex*X1${sp7Y|fh#x56j?QxbptRqWr_z0(4=^jsmAZWa1e^mO%* zhO$EC`^@@oc^&q&neq}fSoJK!ep`)Q&lPg*Rw2q)dPrSaA;UVg1-s%j4Xjfxu6n#f zkCVzD9N6&2iR$Hvau0$OOo7#=^t7d=BdB=7~B+M1*shn3yZzqimsohdK!a zVw4^M2LLHisXq6@3pIt+>~l1-m*UUTz?%OhIdJ|Xe{fcQ zXkiGsvF!BapQoHO;#PS*00u$d`8ftmhn-vqprunv_J9Yma`1UbZ#%Jxe-D3vD_Qot zsam@@Ul`_;nD0Bs@WA9u=o@&&$-cdf%b5@xUM8Z6XGgxR8CdLvz4n&I@lGzkw>YwNt^4i;_UuX*L`jm z5f3SDhx=}LUiGhEynkl)%FjLLys}Z7dcliM@2J1%Z+PiD=OSbO_TnWmIN~A2?U))O z@2&n-9lF{dJ>z}gf}uq|d$X?Ac}M(n1aXk!cIZlD?Oz24!eEYoyo@`LDJ(saX^{VL zZd&rflEPHS8)KdGz?@-0sVl_Hi0(Y;gumCq8@SZf`XZMdHHZU8H8l_`!-+ehVK6|N zCw=;pK>p5-NRXuiX_7=H4Q_CfN_pc63SrmSf~gWqY)Sf7t$ySrYrlLS5`VNG>{x~ zBhOuVJgdf(Y%*qSoFx!qW>7HBk3{Dxq*b_2F&Wmd zqjud+Tgob0(V3zS%39cDC{zd+U@QjY`I1nD$d*K}#%G5k6Q?+Z)t2^pnOjZYr`2Cs zWH73vz-1#UYua^t-?n%2rl#3<^ioe;eBMWy8v1~RvoT4ym}ZGlFe--IuxwdW3riad zTdE~y&7_#K$xLgEX-y_sno>NL-czc7Mu|zW=oxqqXx(YrCq67Z-9fl!QgBS;~mXI^bw zr&s+~8Z$ZNd-96p-?LLcL*Z#b=AwoDP-RrOmSQds2cQg*I654sL6a4ri@ewNi_^a}c?PzY>WSKL z$|T$lgHQ0&EEQ~8BdpI;q9*pysTw-3?Uk#QZdKCFVajY=zKADap}xZSB|+KMTe@kVO$mq=PTBu&$20Rti6&_ zY4bDM69SHMc4bE0{$$p6*0F-uzYDT#v5AigNBCXbYMOH8bm~6%e*`5}KUs1lB3x+7 zWOI~~YGRzv*t68OpBRS2_TD77-b)R75i?X-oNN<_z=UE3D2xjAdDaq3%{|9Gr`LFn z_A{MA%cMA5Q>h6uMm$Pvu3-A67<}aDaj#(kT_<|Lrifbp;~76TOeF^?t0=-TAu|jm zk@x}nH@@HT9C}yEL)O=C7DXH#Y5R73ft0} zO18wzZP}eQ@0%Snyx6w!e1*E}uBVfKbx6J2>=>kR6rQOo7D(n8HrDCPZ}Ll1WX{6C z!eUwj|M}Z}Nf)iR`>UbwwMPN;6@G!62Wms1l1Vm}=1z)rD%x{iza}~E=^-J_efp7& z8)omeM^aQpE4mBDLR`qlf!oC*!p*c9Gdx{rY%7cn`U?sP!&w-~0y8%!*_yLLNo*Ti zTQ-havDlUrR471&xJbgor99>s#R|vCmLzK%CYfYmg;|qAt=X2KEx}kUTa0DJw6H*h zVVqEOk%S9&1ckZ>e3tn>+d|FMvpd*YlBC{?QPJ+Jl1eg{hlYzl^efnwPuuG`);L>j zdCr_ge`tjy^?5R!3lE4D4(vi7dN=B3e0+;u$JMn9A6*NJT=M*CXxA1}^wllondQ;* z@U#H!#22%4>*JmwPu$X1sq8uO7E+;aM9uVjj}t2PpB(tOIrLcGj-Y0j#xigQpwL&* z2%$4UO%f~?Ne>i!Fg|RCQ4?^?V8+5D%|tBBd;-V}Ca9Jobg_(9{#zgdQy_B$q6ncN z6c>_kHkU+kCcBU*6dPxBiH>%cJwY)5LRv=~?$t2eXye0JWY|laj|T*76!eH=z{-my zLYxs1j)~aQ&4dj&ezdKK^OmZX-y(Qc2X!;Afm}3fd#}MQ2nE^ zPz<&+Vl147g)zBO6;V`SppG^kF2Z}FfD$X4tE0^f!?=97c);bvTZ9jnDHMnVY_XXW z@QWGDIUa|-*c2$IvrMtN?Y*rHCNij z|Cc(*{U0XwC1>5qnOa!j`gk+x&_IveQx3`r)ESV0(IPR={|#@-#=Mcy9Jx+75ltt$fhx)A3Xot-kfZ-c|Lu& zN+BQ;Jd(@81&Sc}rb4jfWXnsZ2#vj$Y_rs!*^wBxdT1t*UTRk+-HkvupQ z^NE*K>0a|cRdW#duU>ct5wfd!e@xPnU{=!=+erwg<tFQPOm&T?)| zeaPQkJO2ikkJhayxUBJEd35>LoPfl+CnIs5$(<)4)B~l%{@Br6?vQ!tid7V4fxqsN z3;X3xl-6T-5CZhT|Id0-ewxFHDA{%?ExIz(h&s4xN6h&-bJ#B& vAVx4AXz{u~xG?4NIEs~Onh+axO6$JWn(SPioWTyy!v?+2|9GW52@vEz%Vs0w literal 0 HcmV?d00001 diff --git a/plugins/tpm-eventlog/tests/binary_bios_measurements-v2 b/plugins/tpm-eventlog/tests/binary_bios_measurements-v2 new file mode 100644 index 0000000000000000000000000000000000000000..5aacd4197a15cee3c201acbe77bfc98d00411e40 GIT binary patch literal 40311 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

5y*bf4$P?~a>aJj!5lMf_ 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 = fu_uefi_bgrt_new (); fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_RUN_AFTER, "upower"); + fu_plugin_add_rule (plugin, FU_PLUGIN_RULE_METADATA_SOURCE, "tpm_eventlog"); fu_plugin_add_compile_version (plugin, "com.redhat.efivar", EFIVAR_LIBRARY_VERSION); fu_plugin_set_build_hash (plugin, FU_BUILD_HASH); } diff --git a/po/POTFILES.in b/po/POTFILES.in index 7494ccf29..1c13355c7 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,6 +2,7 @@ data/remotes.d/lvfs.metainfo.xml data/remotes.d/lvfs-testing.metainfo.xml policy/org.freedesktop.fwupd.policy.in plugins/dfu/dfu-tool.c +plugins/tpm-eventlog/fu-tpm-eventlog.c plugins/uefi/fu-plugin-uefi.c plugins/uefi/fu-uefi-tool.c src/fu-agent.c