aboutsummaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_tcg2.c
diff options
context:
space:
mode:
authorMasahisa Kojima <masahisa.kojima@linaro.org>2021-10-26 17:27:24 +0900
committerHeinrich Schuchardt <heinrich.schuchardt@canonical.com>2021-10-26 17:58:14 +0200
commit3d49ee8510d38e7fd087c7250a3f4392a38bf0dd (patch)
treee0f5d9398fb5072d38c354438ac6ce30ffeaff05 /lib/efi_loader/efi_tcg2.c
parenta45dac1785564e1cbb876c44f3b56b05c974584e (diff)
downloadu-boot-3d49ee8510d38e7fd087c7250a3f4392a38bf0dd.zip
u-boot-3d49ee8510d38e7fd087c7250a3f4392a38bf0dd.tar.gz
u-boot-3d49ee8510d38e7fd087c7250a3f4392a38bf0dd.tar.bz2
efi_loader: add SMBIOS table measurement
TCG PC Client Platform Firmware Profile Specification requires to measure the SMBIOS table that contains static configuration information (e.g. Platform Manufacturer Enterprise Number assigned by IANA, platform model number, Vendor and Device IDs for each SMBIOS table). The device- and environment-dependent information such as serial number is cleared to zero or space character for the measurement. Existing smbios_string() function returns pointer to the string with const qualifier, but exisintg use case is updating version string and const qualifier must be removed. This commit removes const qualifier from smbios_string() return value and reuses to clear the strings for the measurement. This commit also fixes the following compiler warning: lib/smbios-parser.c:59:39: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] const struct smbios_header *header = (struct smbios_header *)entry->struct_table_address; Signed-off-by: Masahisa Kojima <masahisa.kojima@linaro.org>
Diffstat (limited to 'lib/efi_loader/efi_tcg2.c')
-rw-r--r--lib/efi_loader/efi_tcg2.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
index b6f8f99..da589d01 100644
--- a/lib/efi_loader/efi_tcg2.c
+++ b/lib/efi_loader/efi_tcg2.c
@@ -15,6 +15,7 @@
#include <efi_tcg2.h>
#include <log.h>
#include <malloc.h>
+#include <smbios.h>
#include <version_string.h>
#include <tpm-v2.h>
#include <u-boot/hash-checksum.h>
@@ -1453,6 +1454,81 @@ error:
}
/**
+ * tcg2_measure_smbios() - measure smbios table
+ *
+ * @dev: TPM device
+ * @entry: pointer to the smbios_entry structure
+ *
+ * Return: status code
+ */
+static efi_status_t
+tcg2_measure_smbios(struct udevice *dev,
+ const struct smbios_entry *entry)
+{
+ efi_status_t ret;
+ struct smbios_header *smbios_copy;
+ struct smbios_handoff_table_pointers2 *event = NULL;
+ u32 event_size;
+
+ /*
+ * TCG PC Client PFP Spec says
+ * "SMBIOS structures that contain static configuration information
+ * (e.g. Platform Manufacturer Enterprise Number assigned by IANA,
+ * platform model number, Vendor and Device IDs for each SMBIOS table)
+ * that is relevant to the security of the platform MUST be measured".
+ * Device dependent parameters such as serial number are cleared to
+ * zero or spaces for the measurement.
+ */
+ event_size = sizeof(struct smbios_handoff_table_pointers2) +
+ FIELD_SIZEOF(struct efi_configuration_table, guid) +
+ entry->struct_table_length;
+ event = calloc(1, event_size);
+ if (!event) {
+ ret = EFI_OUT_OF_RESOURCES;
+ goto out;
+ }
+
+ event->table_description_size = sizeof(SMBIOS_HANDOFF_TABLE_DESC);
+ memcpy(event->table_description, SMBIOS_HANDOFF_TABLE_DESC,
+ sizeof(SMBIOS_HANDOFF_TABLE_DESC));
+ put_unaligned_le64(1, &event->number_of_tables);
+ guidcpy(&event->table_entry[0].guid, &smbios_guid);
+ smbios_copy = (struct smbios_header *)((uintptr_t)&event->table_entry[0].table);
+ memcpy(&event->table_entry[0].table,
+ (void *)((uintptr_t)entry->struct_table_address),
+ entry->struct_table_length);
+
+ smbios_prepare_measurement(entry, smbios_copy);
+
+ ret = tcg2_measure_event(dev, 1, EV_EFI_HANDOFF_TABLES2, event_size,
+ (u8 *)event);
+ if (ret != EFI_SUCCESS)
+ goto out;
+
+out:
+ free(event);
+
+ return ret;
+}
+
+/**
+ * find_smbios_table() - find smbios table
+ *
+ * Return: pointer to the smbios table
+ */
+static void *find_smbios_table(void)
+{
+ u32 i;
+
+ for (i = 0; i < systab.nr_tables; i++) {
+ if (!guidcmp(&smbios_guid, &systab.tables[i].guid))
+ return systab.tables[i].table;
+ }
+
+ return NULL;
+}
+
+/**
* efi_tcg2_measure_efi_app_invocation() - measure efi app invocation
*
* Return: status code
@@ -1463,6 +1539,7 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(void)
u32 pcr_index;
struct udevice *dev;
u32 event = 0;
+ struct smbios_entry *entry;
if (tcg2_efi_app_invoked)
return EFI_SUCCESS;
@@ -1481,6 +1558,13 @@ efi_status_t efi_tcg2_measure_efi_app_invocation(void)
if (ret != EFI_SUCCESS)
goto out;
+ entry = (struct smbios_entry *)find_smbios_table();
+ if (entry) {
+ ret = tcg2_measure_smbios(dev, entry);
+ if (ret != EFI_SUCCESS)
+ goto out;
+ }
+
for (pcr_index = 0; pcr_index <= 7; pcr_index++) {
ret = tcg2_measure_event(dev, pcr_index, EV_SEPARATOR,
sizeof(event), (u8 *)&event);