On Sat, 23 Oct 2021 at 18:42, Heinrich Schuchardt <xypron.g...@gmx.de> wrote: > > > > On 10/22/21 13:24, Masahisa Kojima wrote: > > This commit adds the missing EFI_TCG2_PROTOCOL selftest > > and Measured Boot selftest in lib/efi_selftest. > > > > Signed-off-by: Masahisa Kojima <masahisa.koj...@linaro.org> > > --- > > lib/efi_selftest/Makefile | 10 + > > .../efi_selftest_miniapp_measuredboot.c | 93 ++ > > lib/efi_selftest/efi_selftest_tcg2.c | 804 +++++++++++++++++- > > 3 files changed, 906 insertions(+), 1 deletion(-) > > create mode 100644 lib/efi_selftest/efi_selftest_miniapp_measuredboot.c > > > > diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile > > index 9ff6e1760c..09950ee028 100644 > > --- a/lib/efi_selftest/Makefile > > +++ b/lib/efi_selftest/Makefile > > @@ -14,6 +14,8 @@ CFLAGS_efi_selftest_miniapp_exception.o := $(CFLAGS_EFI) > > -Os -ffreestanding > > CFLAGS_REMOVE_efi_selftest_miniapp_exception.o := $(CFLAGS_NON_EFI) > > CFLAGS_efi_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding > > CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI) > > +CFLAGS_efi_selftest_miniapp_measuredboot.o := $(CFLAGS_EFI) -Os > > -ffreestanding > > +CFLAGS_REMOVE_efi_selftest_miniapp_measuredboot.o := $(CFLAGS_NON_EFI) > > CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding > > CFLAGS_REMOVE_efi_selftest_miniapp_return.o := $(CFLAGS_NON_EFI) > > CFLAGS_initrddump_exit.o := $(CFLAGS_EFI) -Os -ffreestanding > > @@ -78,9 +80,11 @@ obj-$(CONFIG_EFI_ESRT) += efi_selftest_esrt.o > > targets += \ > > efi_miniapp_file_image_exception.h \ > > efi_miniapp_file_image_exit.h \ > > +efi_miniapp_file_image_measuredboot.h \ > > efi_miniapp_file_image_return.h \ > > efi_selftest_miniapp_exception.efi \ > > efi_selftest_miniapp_exit.efi \ > > +efi_selftest_miniapp_measuredboot.efi \ > > efi_selftest_miniapp_return.efi > > > > ifeq ($(CONFIG_GENERATE_ACPI_TABLE),) > > @@ -99,6 +103,10 @@ $(obj)/efi_miniapp_file_image_exit.h: > > $(obj)/efi_selftest_miniapp_exit.efi > > $(obj)/../../tools/file2include $(obj)/efi_selftest_miniapp_exit.efi > > > \ > > $(obj)/efi_miniapp_file_image_exit.h > > > > +$(obj)/efi_miniapp_file_image_measuredboot.h: > > $(obj)/efi_selftest_miniapp_measuredboot.efi > > + $(obj)/../../tools/file2include > > $(obj)/efi_selftest_miniapp_measuredboot.efi > \ > > + $(obj)/efi_miniapp_file_image_measuredboot.h > > + > > $(obj)/efi_miniapp_file_image_return.h: > > $(obj)/efi_selftest_miniapp_return.efi > > $(obj)/../../tools/file2include > > $(obj)/efi_selftest_miniapp_return.efi > \ > > $(obj)/efi_miniapp_file_image_return.h > > @@ -112,3 +120,5 @@ $(obj)/efi_selftest_loadimage.o: > > $(obj)/efi_miniapp_file_image_exit.h > > $(obj)/efi_selftest_startimage_exit.o: > > $(obj)/efi_miniapp_file_image_exit.h > > > > $(obj)/efi_selftest_startimage_return.o: > > $(obj)/efi_miniapp_file_image_return.h > > + > > +$(obj)/efi_selftest_tcg2.o: $(obj)/efi_miniapp_file_image_measuredboot.h > > diff --git a/lib/efi_selftest/efi_selftest_miniapp_measuredboot.c > > b/lib/efi_selftest/efi_selftest_miniapp_measuredboot.c > > Thank you for going the extra mile and adding the test. > > Which image is actually loaded seems to be irrelevant for the test. Can > we reuse an existing one, e.g. efi_miniapp_file_image_return.h? > > I guess the PCR related to the loaded image is not checked as it will > depend on the build tools and date.
Sorry, I'm doing wrong. Actually this selftest verifies the PE/COFF image measurement, so measuremt will be different depending on the build tools and date. # In my build environment, timestamp is set to all zero. To test the PE/COFF image measurement, I must prepare the static PE/COFF image. I plan to add efi_miniapp_file_image_measuredboot.h as a pre-compiled small static PE/COFF image for the measurement test, instead of adding efi_selftest_miniapp_measuredboot.c or reusing existing one. > > > new file mode 100644 > > index 0000000000..926713c1c2 > > --- /dev/null > > +++ b/lib/efi_selftest/efi_selftest_miniapp_measuredboot.c > > @@ -0,0 +1,93 @@ > > +// SPDX-License-Identifier: GPL-2.0+ > > +/* > > + * efi_selftest_miniapp_measuredboot > > + * > > + * Copyright (c) 2018 Heinrich Schuchardt > > + * Copyright (c) 2021 Masahisa Kojima > > + * > > + * This EFI application is run by the StartImage selftest. > > This is incorrect due to copy and paste. > > > + * It uses the Exit boot service to return and used for > > + * Measured Boot selftest. > > + */ > > + > > +#include <common.h> > > +#include <efi_selftest.h> > > + > > +static efi_guid_t loaded_image_protocol_guid = > > EFI_LOADED_IMAGE_PROTOCOL_GUID; > > + > > +/** > > + * check_loaded_image_protocol() - check image_base/image_size > > + * > > + * Try to open the loaded image protocol. Check that this function is > > located > > + * between image_base and image_base + image_size. > > + * > > + * @image_handle: handle of the loaded image > > + * @systable: system table > > + * @return: status code > > + */ > > +static efi_status_t EFIAPI check_loaded_image_protocol > > + (efi_handle_t image_handle, struct efi_system_table *systable) > > +{ > > + struct efi_simple_text_output_protocol *cout = systable->con_out; > > + struct efi_boot_services *boottime = systable->boottime; > > + struct efi_loaded_image *loaded_image_protocol; > > + efi_status_t ret; > > + > > + /* > > + * Open the loaded image protocol. > > + */ > > + ret = boottime->open_protocol > > + (image_handle, &loaded_image_protocol_guid, > > + (void **)&loaded_image_protocol, NULL, > > + NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); > > + if (ret != EFI_SUCCESS) { > > + cout->output_string(cout, > > + L"Could not open loaded image protocol"); > > + return ret; > > + } > > + if ((void *)check_loaded_image_protocol < > > + loaded_image_protocol->image_base || > > + (void *)check_loaded_image_protocol >= > > + loaded_image_protocol->image_base + > > + loaded_image_protocol->image_size) { > > + cout->output_string(cout, > > + L"Incorrect image_base or image_size\n"); > > + return EFI_NOT_FOUND; > > + } > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + * Entry point of the EFI application. > > + * > > + * @handle: handle of the loaded image > > + * @systable: system table > > + * @return: status code > > + */ > > +efi_status_t EFIAPI efi_main(efi_handle_t handle, > > + struct efi_system_table *systable) > > +{ > > + struct efi_simple_text_output_protocol *con_out = systable->con_out; > > + efi_status_t ret; > > + u16 text[] = EFI_ST_SUCCESS_STR; > > + > > + con_out->output_string(con_out, L"EFI application calling Exit\n"); > > + > > + if (check_loaded_image_protocol(handle, systable) != EFI_SUCCESS) { > > + con_out->output_string(con_out, > > + L"Loaded image protocol missing\n"); > > + ret = EFI_NOT_FOUND; > > + goto out; > > + } > > + > > + /* This return value is expected by the calling test */ > > + ret = EFI_UNSUPPORTED; > > +out: > > + systable->boottime->exit(handle, ret, sizeof(text), text); > > + > > + /* > > + * This statement should not be reached. > > + * To enable testing use a different return value. > > + */ > > + return EFI_SUCCESS; > > +} > > diff --git a/lib/efi_selftest/efi_selftest_tcg2.c > > b/lib/efi_selftest/efi_selftest_tcg2.c > > index 1399309cec..50de735f5e 100644 > > --- a/lib/efi_selftest/efi_selftest_tcg2.c > > +++ b/lib/efi_selftest/efi_selftest_tcg2.c > > @@ -9,10 +9,495 @@ > > > > #include <efi_selftest.h> > > #include <efi_tcg2.h> > > +/* Include containing the miniapp.efi application */ > > +#include "efi_miniapp_file_image_measuredboot.h" > > efi_miniapp_file_image_return.h As I said above, I will prepare static PE/COFF image only for the measurement purpose. > > > + > > +#include <linux/unaligned/access_ok.h> > > +#include <mapmem.h> > > +#include <smbios.h> > > +#include <tables_csum.h> > > > > static struct efi_boot_services *boottime; > > static const efi_guid_t guid_tcg2 = EFI_TCG2_PROTOCOL_GUID; > > > > +/* Block size of compressed disk image */ > > +#define COMPRESSED_DISK_IMAGE_BLOCK_SIZE 8 > > + > > +static efi_handle_t image_handle; > > +/* Decompressed file image */ > > +static u8 *image; > > + > > +/* One 8 byte block of the compressed disk image */ > > +struct line { > > + size_t addr; > > + char *line; > > +}; > > + > > +/* Compressed file image */ > > +struct compressed_file_image { > > + size_t length; > > + struct line lines[]; > > +}; > > + > > +static struct compressed_file_image img = EFI_ST_DISK_IMG; > > + > > +static struct efi_tcg2_event *efi_tcg2_event; > > + > > +static struct efi_runtime_services *runtime; > > +#define BOOT_NAME_1000 u"Boot1000" > > +#define BOOT_NAME_1001 u"Boot1001" > > +#define BOOT_NAME_1002 u"Boot1002" > > + > > +#define DEFAULT_ATTR (EFI_VARIABLE_NON_VOLATILE | \ > > + EFI_VARIABLE_BOOTSERVICE_ACCESS | \ > > + EFI_VARIABLE_RUNTIME_ACCESS) > > + > > +/* "efidebug boot add -b 1000 test1000 virtio 0:1 > > /EFI/debian/grubaa64.efi" */ > > +static const u8 boot_1000[] = { > > +0x01, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, > > +0x74, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x04, 0x14, 0x00, 0xb9, 0x73, > > +0x1d, 0xe6, 0x84, 0xa3, 0xcc, 0x4a, 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, > > +0x62, 0x8b, 0x01, 0x04, 0x15, 0x00, 0x92, 0x37, 0x29, 0x63, 0xf5, 0xad, > > +0x25, 0x93, 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e, 0x00, 0x04, > > +0x01, 0x2a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, > > +0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, > > +0x5a, 0x47, 0xc2, 0x35, 0x27, 0x44, 0x47, 0x9f, 0x01, 0x67, 0xfe, 0xfa, > > +0x1d, 0x06, 0xae, 0x02, 0x02, 0x04, 0x04, 0x36, 0x00, 0x5c, 0x00, 0x45, > > +0x00, 0x46, 0x00, 0x49, 0x00, 0x5c, 0x00, 0x64, 0x00, 0x65, 0x00, 0x62, > > +0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x5c, 0x00, 0x67, 0x00, 0x72, > > +0x00, 0x75, 0x00, 0x62, 0x00, 0x61, 0x00, 0x61, 0x00, 0x36, 0x00, 0x34, > > +0x00, 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x00, 0x00, 0x7f, > > +0xff, 0x04, 0x00 }; > > + > > +/* "efidebug boot add -b 1001 test1001 virtio 0:1 > > /EFI/debian/grubaa64.efi" */ > > +static const u8 boot_1001[] = { > > +0x01, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, > > +0x74, 0x00, 0x31, 0x00, 0x00, 0x00, 0x01, 0x04, 0x14, 0x00, 0xb9, 0x73, > > +0x1d, 0xe6, 0x84, 0xa3, 0xcc, 0x4a, 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, > > +0x62, 0x8b, 0x01, 0x04, 0x15, 0x00, 0x92, 0x37, 0x29, 0x63, 0xf5, 0xad, > > +0x25, 0x93, 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e, 0x00, 0x04, > > +0x01, 0x2a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, > > +0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, > > +0x5a, 0x47, 0xc2, 0x35, 0x27, 0x44, 0x47, 0x9f, 0x01, 0x67, 0xfe, 0xfa, > > +0x1d, 0x06, 0xae, 0x02, 0x02, 0x04, 0x04, 0x36, 0x00, 0x5c, 0x00, 0x45, > > +0x00, 0x46, 0x00, 0x49, 0x00, 0x5c, 0x00, 0x64, 0x00, 0x65, 0x00, 0x62, > > +0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x5c, 0x00, 0x67, 0x00, 0x72, > > +0x00, 0x75, 0x00, 0x62, 0x00, 0x61, 0x00, 0x61, 0x00, 0x36, 0x00, 0x34, > > +0x00, 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x00, 0x00, 0x7f, > > +0xff, 0x04, 0x00 }; > > + > > +/* "efidebug boot add -b 1002 test1002 virtio 0:1 > > /EFI/debian/grubaa64.efi" */ > > +static const u8 boot_1002[] = { > > +0x01, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, > > +0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x01, 0x04, 0x14, 0x00, 0xb9, 0x73, > > +0x1d, 0xe6, 0x84, 0xa3, 0xcc, 0x4a, 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, > > +0x62, 0x8b, 0x01, 0x04, 0x15, 0x00, 0x92, 0x37, 0x29, 0x63, 0xf5, 0xad, > > +0x25, 0x93, 0xb9, 0x9f, 0x4e, 0x0e, 0x45, 0x5c, 0x1b, 0x1e, 0x00, 0x04, > > +0x01, 0x2a, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, > > +0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, > > +0x5a, 0x47, 0xc2, 0x35, 0x27, 0x44, 0x47, 0x9f, 0x01, 0x67, 0xfe, 0xfa, > > +0x1d, 0x06, 0xae, 0x02, 0x02, 0x04, 0x04, 0x36, 0x00, 0x5c, 0x00, 0x45, > > +0x00, 0x46, 0x00, 0x49, 0x00, 0x5c, 0x00, 0x64, 0x00, 0x65, 0x00, 0x62, > > +0x00, 0x69, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x5c, 0x00, 0x67, 0x00, 0x72, > > +0x00, 0x75, 0x00, 0x62, 0x00, 0x61, 0x00, 0x61, 0x00, 0x36, 0x00, 0x34, > > +0x00, 0x2e, 0x00, 0x65, 0x00, 0x66, 0x00, 0x69, 0x00, 0x00, 0x00, 0x7f, > > +0xff, 0x04, 0x00}; > > + > > +/* "efidebug boot order 1002 1000 1001" */ > > +static u8 boot_order[] = {0x02, 0x10, 0x00, 0x10, 0x01, 0x10}; > > + > > +static void *orig_smbios_table; > > +static u64 dmi_addr = U32_MAX; > > +#define SMBIOS_ENTRY_HEADER_SIZE 0x20 > > +/* smbios table for the measurement test */ > > +static u8 smbios_table_test[] = { > > +0x5f, 0x53, 0x4d, 0x5f, 0x2c, 0x1f, 0x03, 0x00, 0x54, 0x00, 0x00, 0x00, > > +0x00, 0x00, 0x00, 0x00, 0x5f, 0x44, 0x4d, 0x49, 0x5f, 0xe4, 0x5c, 0x01, > > +0x20, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, > > +0x01, 0x02, 0x00, 0x00, 0x03, 0x00, 0x80, 0x08, 0x01, 0x00, 0x00, 0x00, > > +0x00, 0x00, 0x00, 0x0c, 0x15, 0x0a, 0xff, 0xff, 0x55, 0x2d, 0x42, 0x6f, > > +0x6f, 0x74, 0x00, 0x32, 0x30, 0x32, 0x31, 0x2e, 0x31, 0x30, 0x2d, 0x72, > > +0x63, 0x34, 0x2d, 0x30, 0x30, 0x30, 0x30, 0x35, 0x2d, 0x67, 0x37, 0x32, > > +0x37, 0x63, 0x33, 0x66, 0x33, 0x32, 0x35, 0x39, 0x2d, 0x64, 0x69, 0x72, > > +0x74, 0x79, 0x00, 0x31, 0x30, 0x2f, 0x30, 0x31, 0x2f, 0x32, 0x30, 0x32, > > +0x31, 0x00, 0x00, 0x01, 0x1b, 0x01, 0x00, 0x01, 0x02, 0x00, 0x03, 0x31, > > +0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, > > +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, > > +0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x50, 0x72, > > +0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, > > +0x37, 0x38, 0x00, 0x00, 0x02, 0x0e, 0x02, 0x00, 0x01, 0x02, 0x00, 0x04, > > +0x03, 0x01, 0x01, 0x01, 0x00, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, > > +0x6e, 0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x50, 0x72, > > +0x6f, 0x64, 0x75, 0x63, 0x74, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, > > +0x33, 0x33, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x00, > > +0x00, 0x03, 0x15, 0x03, 0x00, 0x01, 0x03, 0x00, 0x02, 0x03, 0x03, 0x03, > > +0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x6e, > > +0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, > > +0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, > > +0x00, 0x04, 0x30, 0x04, 0x00, 0x00, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, > > +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, > > +0x00, 0x01, 0x06, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x03, 0x04, > > +0x04, 0x04, 0x08, 0x00, 0x00, 0x02, 0x00, 0x08, 0x00, 0x08, 0x00, 0x01, > > +0x00, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x00, 0x31, 0x32, 0x33, > > +0x34, 0x35, 0x36, 0x37, 0x38, 0x00, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, > > +0x33, 0x33, 0x00, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x00, > > +0x00, 0x20, 0x0b, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > +0x00, 0x00, 0x7f, 0x04, 0x06, 0x00, 0x00, 0x00 > > +}; > > + > > +#define TPM2_CMD_BUF_SIZE 64 > > +/* TPM command is big endian */ > > +#define __MSB(x) ((x) >> 8) > > +#define __LSB(x) ((x) & 0xFF) > > +#define tpm_u16(x) __MSB(x), __LSB(x) > > +#define tpm_u32(x) tpm_u16((x) >> 16), tpm_u16((x) & 0xFFFF) > > +#define TPM2_PCR_READ_HEADER_SIZE 30 > > + > > +static u8 *pcrs; > > +static u8 expected_pcrs[EFI_TCG2_MAX_PCR_INDEX + > > 1][TPM2_SHA256_DIGEST_SIZE] = { > > + {0x91, 0x21, 0x37, 0xc7, 0x1a, 0x49, 0x19, 0xc8, > > + 0xf1, 0xfb, 0xa9, 0x84, 0x5c, 0x65, 0xa9, 0xdd, > > + 0x7b, 0xb9, 0xfe, 0xa1, 0xcd, 0x64, 0x49, 0xdd, > > + 0xed, 0xe2, 0x65, 0x82, 0xc5, 0x3e, 0xf4, 0xc4}, > > + > > + {0xf5, 0x79, 0xf3, 0x20, 0x62, 0x6e, 0x8b, 0x58, > > + 0x62, 0xa3, 0x4e, 0x2f, 0xb7, 0x10, 0xac, 0x34, > > + 0x4e, 0x68, 0x94, 0x37, 0x87, 0x29, 0xc4, 0xbe, > > + 0xa3, 0xc4, 0xd9, 0x14, 0x2b, 0x66, 0x79, 0x9b}, > > + > > + {0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, > > + 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, > > + 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, > > + 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, > > + > > + {0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, > > + 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, > > + 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, > > + 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, > > + > > + {0xbe, 0xea, 0xdc, 0xe0, 0x44, 0x5b, 0x5f, 0x14, > > + 0xef, 0x24, 0x5d, 0x13, 0x15, 0xfe, 0x41, 0x86, > > + 0xc2, 0xd5, 0xdc, 0x0d, 0x04, 0x2f, 0xd4, 0x04, > > + 0x0d, 0x02, 0x62, 0xc0, 0x34, 0x80, 0xee, 0xd5}, > > + > > + {0x3d, 0x45, 0x8c, 0xfe, 0x55, 0xcc, 0x03, 0xea, > > + 0x1f, 0x44, 0x3f, 0x15, 0x62, 0xbe, 0xec, 0x8d, > > + 0xf5, 0x1c, 0x75, 0xe1, 0x4a, 0x9f, 0xcf, 0x9a, > > + 0x72, 0x34, 0xa1, 0x3f, 0x19, 0x8e, 0x79, 0x69}, > > + > > + {0x8d, 0x28, 0xde, 0x72, 0x22, 0x3e, 0x88, 0x1a, > > + 0x37, 0xfa, 0x47, 0x12, 0x68, 0x45, 0xdf, 0x71, > > + 0x50, 0x8f, 0xab, 0x59, 0x50, 0x7b, 0x52, 0x32, > > + 0xa6, 0xaa, 0x03, 0x3d, 0x4e, 0x22, 0x89, 0xd7}, > > + > > + {0x96, 0x74, 0xae, 0xcd, 0x3f, 0x40, 0xb4, 0xa9, > > + 0x36, 0xae, 0x19, 0xc8, 0x84, 0x8a, 0xb9, 0x5a, > > + 0x87, 0x99, 0xd8, 0x89, 0x7f, 0xfc, 0x40, 0x48, > > + 0x05, 0x99, 0x65, 0x2e, 0x55, 0xd4, 0x93, 0x32}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > + > > + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, > > + > > + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, > > + > > + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, > > + > > + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, > > + > > + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, > > + > > + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, > > + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, > > + > > + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, > > + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, > > +}; > > + > > +struct boot_variable { > > + u16 name[16]; > > + u8 *buf; > > + efi_uintn_t size; > > + u32 attr; > > + const u8 *test_data; > > + efi_uintn_t test_data_size; > > +}; > > + > > +static struct boot_variable boot_variable_test[] = { > > + {u"BootOrder", NULL, 0, DEFAULT_ATTR, boot_order, > > sizeof(boot_order)}, > > + {BOOT_NAME_1000, NULL, 0, DEFAULT_ATTR, boot_1000, > > sizeof(boot_1000)}, > > + {BOOT_NAME_1001, NULL, 0, DEFAULT_ATTR, boot_1001, > > sizeof(boot_1001)}, > > + {BOOT_NAME_1002, NULL, 0, DEFAULT_ATTR, boot_1002, > > sizeof(boot_1002)}, > > +}; > > + > > +/* > > + * Decompress the disk image. > > + * > > + * @image decompressed disk image > > + * @return status code > > + */ > > +static efi_status_t decompress(u8 **image) > > +{ > > + u8 *buf; > > + size_t i; > > + size_t addr; > > + size_t len; > > + efi_status_t ret; > > + > > + ret = boottime->allocate_pool(EFI_LOADER_DATA, img.length, > > + (void **)&buf); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("Out of memory\n"); > > + return ret; > > + } > > + boottime->set_mem(buf, img.length, 0); > > + > > + for (i = 0; ; ++i) { > > + if (!img.lines[i].line) > > + break; > > + addr = img.lines[i].addr; > > + len = COMPRESSED_DISK_IMAGE_BLOCK_SIZE; > > + if (addr + len > img.length) > > + len = img.length - addr; > > + boottime->copy_mem(buf + addr, img.lines[i].line, len); > > + } > > + *image = buf; > > + return ret; > > +} > > + > > +/* > > + * Configure dummy boot variables. > > /** > * efi_status_t setup_boot_variable() - configure dummy boot variables > * > * Preexisting variable values are saved and will be restored by > * calling restore_boot_variable(). > * > > > + * > > + * @return status code > > + */ > > +static efi_status_t setup_boot_variable(void) > > +{ > > + efi_status_t ret; > > + u32 i; > > + efi_uintn_t size; > > + u8 dummy; > > This variable is superfluous. > > > + > > + for (i = 0; i < ARRAY_SIZE(boot_variable_test); i++) { > > + size = 1; > > Please, set size to 0. > > > + ret = runtime->get_variable(boot_variable_test[i].name, > > + &efi_global_variable_guid, > > + &boot_variable_test[i].attr, > > + &size, > > + &dummy); > > Instead of dummy you can use NULL if size = 0. > > > + if (ret == EFI_BUFFER_TOO_SMALL) { > > + /* Variable exists, save the current vaiable */ > > %s/vaiable/value/ > > > + boot_variable_test[i].size = size; > > + ret = boottime->allocate_pool(EFI_LOADER_DATA, > > + > > boot_variable_test[i].size, > > + (void > > **)&boot_variable_test[i].buf); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("fail to allocate buffer for > > boot variable\n"); > > In all other tests we use 'Failed to' > > %s/fail/Failed/ > > > + return ret; > > + } > > + ret = > > runtime->get_variable(boot_variable_test[i].name, > > + &efi_global_variable_guid, > > + > > &boot_variable_test[i].attr, > > + > > &boot_variable_test[i].size, > > + > > boot_variable_test[i].buf); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("fail to get current boot > > variable\n"); > > %s/fail/Failed/ > > > > + return ret; > > + } > > + } > > + > > + /* set boot variable for the measurement test */ > > + ret = runtime->set_variable(boot_variable_test[i].name, > > + &efi_global_variable_guid, > > + boot_variable_test[i].attr, > > + > > boot_variable_test[i].test_data_size, > > + boot_variable_test[i].test_data); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("### fail to set test boot > > variable(%d)n", i); > > %s/### fail/Failed/ > > > + return ret; > > + } > > + } > > + > > + return 0; > > +} > > + > > +/* > > /** > * efi_status_t restore_boot_variable() - restore original values > * > * Restore the variable values saved in setup_boot_variable(). > * > > > + * Restore original boot variables. > > + * > > + * @return status code > > + */ > > +efi_status_t restore_boot_variable(void) > > +{ > > + int i; > > + efi_status_t ret; > > + > > + for (i = 0; i < ARRAY_SIZE(boot_variable_test); i++) { > > + if (boot_variable_test[i].buf) { > > + ret = > > runtime->set_variable(boot_variable_test[i].name, > > + &efi_global_variable_guid, > > + > > boot_variable_test[i].attr, > > + > > boot_variable_test[i].size, > > + > > boot_variable_test[i].buf); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("### fail to restore boot > > variable\n"); > > + return ret; > > + } > > + ret = boottime->free_pool(boot_variable_test[i].buf); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("Failed to free boot > > variable\n"); > > + return ret; > > + } > > + } else { > > + /* delete the variable used only for testing */ > > + ret = > > runtime->set_variable(boot_variable_test[i].name, > > + &efi_global_variable_guid, > > + 0, 0, NULL); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("### fail to delete boot > > variable\n"); > > %s/### fail/Failed/ > > > + return ret; > > + } > > + } > > + } > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + * Find smbios table > > + * > > + * @systable system table > > + * @return status code > > + */ > > +static void *find_smbios_table(const struct efi_system_table *systable) > > +{ > > + u32 i; > > + > > + for (i = 0; i < systable->nr_tables; i++) { > > + if (!guidcmp(&smbios_guid, &systable->tables[i].guid)) > > + return systable->tables[i].table; > > + } > > + > > + return NULL; > > +} > > + > > +/** > > + * Prepare the dummy SMBIOS table > > + * > > + * @systable system table > > + * @return status code > > + */ > > +efi_status_t setup_smbios_table(const struct efi_system_table *systable) > > +{ > > + struct smbios_entry *se; > > + efi_status_t ret; > > + /* Map within the low 32 bits, to allow for 32bit SMBIOS tables */ > > + void *dmi; > > + char *istart; > > + int isize; > > + > > + if (sizeof(smbios_table_test) > EFI_PAGE_SIZE) > > + return EFI_OUT_OF_RESOURCES; > > + > > + orig_smbios_table = find_smbios_table(systable); > > + > > + /* Reserve 4kiB page for SMBIOS */ > > + ret = boottime->allocate_pages(EFI_ALLOCATE_MAX_ADDRESS, > > + EFI_RUNTIME_SERVICES_DATA, 1, &dmi_addr); > > + > > + if (ret != EFI_SUCCESS) { > > + /* Could not find space in lowmem, use highmem instead */ > > + ret = boottime->allocate_pages(EFI_ALLOCATE_ANY_PAGES, > > + EFI_RUNTIME_SERVICES_DATA, 1, > > + &dmi_addr); > > + > > + if (ret != EFI_SUCCESS) > > + return ret; > > + } > > + > > + dmi = (void *)(uintptr_t)dmi_addr; > > + se = dmi; > > + boottime->copy_mem(se, smbios_table_test, sizeof(smbios_table_test)); > > + > > + /* update smbios table start address */ > > + se->struct_table_address = (uintptr_t)((u8 *)dmi + > > SMBIOS_ENTRY_HEADER_SIZE); > > + > > + /* calculate checksums */ > > + istart = (char *)se + SMBIOS_INTERMEDIATE_OFFSET; > > + isize = sizeof(struct smbios_entry) - SMBIOS_INTERMEDIATE_OFFSET; > > + se->intermediate_checksum = table_compute_checksum(istart, isize); > > + se->checksum = table_compute_checksum(se, sizeof(struct > > smbios_entry)); > > + > > + /* Install SMBIOS information as configuration table */ > > + ret = boottime->install_configuration_table(&smbios_guid, dmi); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("Cannot install SMBIOS table\n"); > > + boottime->free_pages(dmi_addr, 1); > > + } > > + > > + return ret; > > +} > > + > > /** > > * efi_st_tcg2_setup() - setup test > > * > > @@ -23,7 +508,171 @@ static const efi_guid_t guid_tcg2 = > > EFI_TCG2_PROTOCOL_GUID; > > static int efi_st_tcg2_setup(const efi_handle_t img_handle, > > const struct efi_system_table *systable) > > { > > + efi_status_t ret; > > + struct uefi_image_load_event image_load_event; > > + > > + image_handle = img_handle; > > boottime = systable->boottime; > > + runtime = systable->runtime; > > + > > + /* Load the application image into memory */ > > + decompress(&image); > > + > > + ret = boottime->allocate_pool(EFI_LOADER_DATA, > > + sizeof(struct efi_tcg2_event) + > > + sizeof(struct uefi_image_load_event), > > + (void **)&efi_tcg2_event); > > + if (!efi_tcg2_event) > > + return EFI_ST_FAILURE; > > + > > + efi_tcg2_event->size = sizeof(struct efi_tcg2_event) + > > + sizeof(struct uefi_image_load_event); > > + efi_tcg2_event->header.header_size = sizeof(struct > > efi_tcg2_event_header); > > + efi_tcg2_event->header.header_version = 1; > > + efi_tcg2_event->header.pcr_index = 6; > > + efi_tcg2_event->header.event_type = EV_EFI_RUNTIME_SERVICES_DRIVER; > > + image_load_event.image_location_in_memory = 0x12345678; > > + image_load_event.image_length_in_memory = 0x300000; > > + image_load_event.image_link_time_address = 0x87654321; > > + image_load_event.length_of_device_path = 0; > > + boottime->copy_mem(efi_tcg2_event->event, &image_load_event, > > + sizeof(struct uefi_image_load_event)); > > + > > + ret = setup_boot_variable(); > > + if (ret != EFI_SUCCESS) > > + return EFI_ST_FAILURE; > > + > > + ret = setup_smbios_table(systable); > > + if (ret != EFI_SUCCESS) > > + return EFI_ST_FAILURE; > > + > > + ret = boottime->allocate_pool(EFI_LOADER_DATA, > > + (EFI_TCG2_MAX_PCR_INDEX + 1) * > > + TPM2_SHA256_DIGEST_SIZE, > > + (void **)&pcrs); > > + if (!pcrs) > > + return EFI_ST_FAILURE; > > + > > + boottime->set_mem(pcrs, (EFI_TCG2_MAX_PCR_INDEX + 1) * > > TPM2_SHA256_DIGEST_SIZE, 0); > > + > > + return EFI_ST_SUCCESS; > > +} > > + > > +/** > > + * Get manufacturer_id through submit_command API > > + * > > + * @tcg2 tcg2 protocol > > + * @manufacturer_id pointer to the manufacturer_id > > + * @return status code > > + */ > > +static efi_status_t get_manufacturer_id(struct efi_tcg2_protocol *tcg2, > > u32 *manufacturer_id) > > +{ > > + efi_status_t ret; > > + u8 cmd[TPM2_CMD_BUF_SIZE] = { > > + tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ > > + tpm_u32(22), /* Length */ > > + tpm_u32(TPM2_CC_GET_CAPABILITY), /* Command code */ > > + > > + tpm_u32(TPM2_CAP_TPM_PROPERTIES), /* Capability */ > > + tpm_u32(TPM2_PT_MANUFACTURER), /* Property */ > > + tpm_u32(1), /* Property count */ > > + }; > > + u8 resp[TPM2_CMD_BUF_SIZE]; > > + unsigned int value_off; > > + > > + ret = tcg2->submit_command(tcg2, 22, cmd, > > + TPM2_CMD_BUF_SIZE, resp); > > + if (ret != EFI_SUCCESS) > > + return ret; > > + > > + /* > > + * In the response buffer, the properties are located after the: > > + * tag (u16), response size (u32), response code (u32), > > + * YES/NO flag (u8), TPM_CAP (u32). > > + * The value is located after count (u32), property (u32). > > + */ > > + value_off = sizeof(u16) + sizeof(u32) + sizeof(u32) + > > + sizeof(u8) + sizeof(u32) + sizeof(u32) + sizeof(u32); > > + *manufacturer_id = get_unaligned_be32(&resp[value_off]); > > + > > + return ret; > > +} > > + > > +/** > > + * Read the PCR from the TPM device > > + * > > + * @tcg2 tcg2 protocol > > + * @idx pcr index to read > > + * @return status code > > + */ > > +static efi_status_t read_pcr(struct efi_tcg2_protocol *tcg2, u32 idx) > > +{ > > + efi_status_t ret; > > + u8 idx_array_sz = 3; /* support 24 PCRs */ > > This is a constant. > > #define IDX_ARRAY_SZ 3 > > You can move it close to the TPM2_CMD_BUF_SIZE definition. > > > + u32 cmd_len = 17 + idx_array_sz; > > + u8 cmd[TPM2_CMD_BUF_SIZE] = { > > + tpm_u16(TPM2_ST_NO_SESSIONS), /* TAG */ > > + tpm_u32(cmd_len), /* Length */ > > + tpm_u32(TPM2_CC_PCR_READ), /* Command code */ > > + /* TPML_PCR_SELECTION */ > > + tpm_u32(1), /* Number of selections */ > > + tpm_u16(TPM2_ALG_SHA256), /* Algorithm of the hash */ > > + idx_array_sz, /* Array size for selection */ > > + /* bitmap(idx), Selected PCR bitmap */ > > + }; > > + u8 resp[TPM2_CMD_BUF_SIZE]; > > + u32 pcr_sel_idx = idx / 8; > > + u8 pcr_sel_bit = BIT(idx % 8); > > + u8 *dst; > > + > > + cmd[17 + pcr_sel_idx] = pcr_sel_bit; > > + ret = tcg2->submit_command(tcg2, cmd_len, cmd, > > + TPM2_CMD_BUF_SIZE, resp); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("tcg2->submit_command fail to read PCR\n"); > > + return ret; > > + } > > + > > + dst = pcrs + (idx * TPM2_SHA256_DIGEST_SIZE); > > + boottime->copy_mem(dst, &resp[TPM2_PCR_READ_HEADER_SIZE], > > + TPM2_SHA256_DIGEST_SIZE); > > + > > + return ret; > > +} > > + > > +/** > > + * Compare the expected and actual pcrs > > + * > > + * @return status code > > + */ > > +static int validate_pcrs(void) > > +{ > > + u32 i; > > + u8 *expected = (u8 *)expected_pcrs; > > + u8 *result = pcrs; > > Making expected_pcrs and pcrs arrays with elements of size > TPM2_SHA256_DIGEST_SIZE can replace these pointers. > > > + > > + /* > > + * - Skip PCR[0] validation. PCR[0] contains U-Boot version > > measurement > > + * it contains the commit hash, so the measurement varies every > > build > > + * with different commit hash. > > + * - Skip PCR[7] validation. PCR[7] contains UEFI Secure Boot > > variables > > + * measurement. These variables can not be updated through > > efi_selftest and > > + * it varies depending on the platform. > > %s/it varies/vary/ > > > + */ > > + for (i = 0; i < (EFI_TCG2_MAX_PCR_INDEX + 1); i++) { > > for (i = 1; i < (EFI_TCG2_MAX_PCR_INDEX + 1); ++i) { > if (i != 7) > continue; > if (memcmp(pcr[i], expected_pcr[i], PM2_SHA256_DIGEST_SIZE)) { > if (memcmp(expected, result, TPM2_SHA256_DIGEST_SIZE)) { > efi_st_printf("PCR[%d] is not the expected value\n", i); > return EFI_ST_FAILURE; > } > } > } > > > + result = pcrs + (TPM2_SHA256_DIGEST_SIZE * i); > > + if (i == 0 || i == 7) { > > + expected += TPM2_SHA256_DIGEST_SIZE; > > + result += TPM2_SHA256_DIGEST_SIZE; > > + continue; /* skip validation */ > > + } > > + if (memcmp(expected, result, TPM2_SHA256_DIGEST_SIZE)) { > > + efi_st_printf("PCR[%d] is not the expected value\n", > > i); > > + return EFI_ST_FAILURE; > > + } > > + expected += TPM2_SHA256_DIGEST_SIZE; > > + result += TPM2_SHA256_DIGEST_SIZE; > > + } > > > > return EFI_ST_SUCCESS; > > } > > @@ -31,7 +680,8 @@ static int efi_st_tcg2_setup(const efi_handle_t > > img_handle, > > /** > > * efi_st_tcg2_execute() - execute test > > * > > - * Call the GetCapability service of the EFI_TCG2_PROTOCOL. > > + * Call EFI_TCG2_PROTOCOL services and check the > > + * Measured Boot behavior. > > * > > * Return: status code > > */ > > @@ -40,12 +690,22 @@ static int efi_st_tcg2_execute(void) > > struct efi_tcg2_protocol *tcg2; > > struct efi_tcg2_boot_service_capability capability; > > efi_status_t ret; > > + u32 active_pcr_banks; > > + u64 eventlog, eventlog_last_entry; > > + bool eventlog_truncated; > > + efi_handle_t handle; > > + efi_uintn_t exit_data_size = 0; > > + u16 *exit_data = NULL; > > + u32 i; > > + u32 manufacturer_id; > > > > ret = boottime->locate_protocol(&guid_tcg2, NULL, (void **)&tcg2); > > if (ret != EFI_SUCCESS) { > > efi_st_error("TCG2 protocol is not available.\n"); > > return EFI_ST_FAILURE; > > } > > + > > + /* EFI_TCG2_PROTOCOL.GetCapability test */ > > capability.size = sizeof(struct efi_tcg2_boot_service_capability) - 1; > > ret = tcg2->get_capability(tcg2, &capability); > > if (ret != EFI_BUFFER_TOO_SMALL) { > > @@ -64,12 +724,154 @@ static int efi_st_tcg2_execute(void) > > } > > efi_st_printf("TPM supports 0x%.8x event logs\n", > > capability.supported_event_logs); > > + > > + /* EFI_TCG2_PROTOCOL.GetActivePcrBanks test */ > > + ret = tcg2->get_active_pcr_banks(tcg2, &active_pcr_banks); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("tcg2->get_active_pcr_banks failed\n"); > > + return EFI_ST_FAILURE; > > + } > > + if (active_pcr_banks != capability.active_pcr_banks) { > > + efi_st_error("tcg2->get_active_pcr_banks return wrong > > value\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + /* EFI_TCG2_PROTOCOL.HashLogExtendEvent test */ > > + ret = tcg2->hash_log_extend_event(tcg2, EFI_TCG2_EXTEND_ONLY, > > + (uintptr_t)image, > > + img.length, efi_tcg2_event); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("tcg2->hash_log_extend_event(EXTEND_ONLY) > > failed\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + ret = tcg2->hash_log_extend_event(tcg2, PE_COFF_IMAGE, > > (uintptr_t)image, > > + img.length, efi_tcg2_event); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("tcg2->hash_log_extend_event(PE_COFF_IMAGE) > > failed\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + /* EFI_TCG2_PROTOCOL.SubmitCommand test */ > > + ret = get_manufacturer_id(tcg2, &manufacturer_id); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("get_manufacturer_id failed\n"); > > + return EFI_ST_FAILURE; > > + } > > + if (capability.manufacturer_id != manufacturer_id) { > > + efi_st_error("tcg2->submit_command test failed\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + /* tcg2_measure_pe_image test */ > > + ret = boottime->load_image(false, image_handle, NULL, image, > > + img.length, &handle); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("Failed to load image\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + /* measure ready_to_boot event(boot variables, smbios table, etc.) */ > > + /* TODO: add GPT measurement test */ > > lib/efi_selftest/efi_selftest_block_device.c shows how to setup a memory > based block device. Thank you for the information. I tried to copy efi_selftest_block_device but I encountered error. To test GPT measurement, I need to add the device path node having following type. dp->type == DEVICE_PATH_TYPE_MEDIA_DEVICE dp->sub_type == DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH If I added this node in the device path, boottime->connect_controller() returns EFI_NOT_FOUND and I'm investigating how to use connect_controller. For other comments, I will include fixes in the next version. Thanks, Masahisa Kojima > > > + ret = boottime->start_image(handle, &exit_data_size, &exit_data); > > + if (ret != EFI_UNSUPPORTED) { > > + efi_st_error("Wrong return value from application\n"); > > + return EFI_ST_FAILURE; > > + } > > + ret = boottime->free_pool(exit_data); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("Failed to free exit data\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + /* validate PCR read from the TPM device */ > > + for (i = 0; i < (EFI_TCG2_MAX_PCR_INDEX + 1); i++) { > > + ret = read_pcr(tcg2, i); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("read pcr error\n"); > > + return EFI_ST_FAILURE; > > + } > > + } > > + if (validate_pcrs()) { > > + efi_st_error("PCR validation failed\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + /* EFI_TCG2_PROTOCOL.GetEventLog test */ > > + ret = tcg2->get_eventlog(tcg2, TCG2_EVENT_LOG_FORMAT_TCG_2, &eventlog, > > + &eventlog_last_entry, &eventlog_truncated); > > + if (ret != EFI_SUCCESS) { > > + efi_st_error("tcg2->get_eventlog failed\n"); > > + return EFI_ST_FAILURE; > > + } > > + /* TODO: eventlog format check */ > > + > > return EFI_ST_SUCCESS; > > } > > > > +/* > > + * Tear down unit test. > > /** > * efi_st_tcg2_teardown() - tear down unit test > * > > Overall the design looks good to me. > > Best regards > > Heinrich > > > + * > > + * @return: EFI_ST_SUCCESS for success > > + */ > > +static int efi_st_tcg2_teardown(void) > > +{ > > + efi_status_t r = EFI_ST_SUCCESS; > > + > > + if (image) { > > + r = boottime->free_pool(image); > > + if (r != EFI_SUCCESS) { > > + efi_st_error("Failed to free image\n"); > > + return EFI_ST_FAILURE; > > + } > > + } > > + if (efi_tcg2_event) { > > + r = boottime->free_pool(efi_tcg2_event); > > + if (r != EFI_SUCCESS) { > > + efi_st_error("Failed to free efi_tcg2_event\n"); > > + return EFI_ST_FAILURE; > > + } > > + } > > + if (pcrs) { > > + r = boottime->free_pool(pcrs); > > + if (r != EFI_SUCCESS) { > > + efi_st_error("Failed to free pcr\n"); > > + return EFI_ST_FAILURE; > > + } > > + } > > + > > + r = restore_boot_variable(); > > + if (r != EFI_SUCCESS) { > > + efi_st_error("Failed to restore boot variables\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + /* > > + * Restore SMBIOS table > > + * If orig_smbios_table is NULL, calling install_configuration_table() > > + * removes dummy SMBIOS table form systab. > > + */ > > + r = boottime->install_configuration_table(&smbios_guid, > > orig_smbios_table); > > + if (r != EFI_SUCCESS) { > > + efi_st_error("Failed to restore SMBOIS table\n"); > > + return EFI_ST_FAILURE; > > + } > > + > > + if (dmi_addr) { > > + r = boottime->free_pages(dmi_addr, 1); > > + if (r != EFI_SUCCESS) { > > + efi_st_error("Failed to free dummy smbios table\n"); > > + return EFI_ST_FAILURE; > > + } > > + } > > + > > + return r; > > +} > > + > > EFI_UNIT_TEST(tcg2) = { > > .name = "tcg2", > > .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, > > .execute = efi_st_tcg2_execute, > > .setup = efi_st_tcg2_setup, > > + .teardown = efi_st_tcg2_teardown, > > }; > >