On 11/7/21 11:16, Heinrich Schuchardt wrote:
On 11/4/21 11:45, Masahisa Kojima wrote:
This commit adds the missing EFI_TCG2_PROTOCOL selftest
and Measured Boot selftest in lib/efi_selftest.

This selftest includes PE/COFF image measurement test,
some PCR values are different in each architecture.
With that, this commit also adds the pre-build efi application
for PE/COFF image measurement test for 32-bit arm, arm64,
ia32, x86_64, riscv32 and riscv64.

Please, add some information about the includes here:

* From which C code were they compiled?
* State that the precompiled form is needed due the problem of
reproducible builds.


Signed-off-by: Masahisa Kojima <masahisa.koj...@linaro.org>
---
  lib/efi_selftest/efi_miniapp_tcg2_arm.h     | 152 ++++
  lib/efi_selftest/efi_miniapp_tcg2_arm64.h   | 207 +++++
  lib/efi_selftest/efi_miniapp_tcg2_ia32.h    | 177 ++++
  lib/efi_selftest/efi_miniapp_tcg2_riscv32.h | 173 ++++
  lib/efi_selftest/efi_miniapp_tcg2_riscv64.h | 189 ++++
  lib/efi_selftest/efi_miniapp_tcg2_x86_64.h  | 178 ++++
  lib/efi_selftest/efi_selftest_tcg2.c        | 941 +++++++++++++++++++-
  7 files changed, 2016 insertions(+), 1 deletion(-)
  create mode 100644 lib/efi_selftest/efi_miniapp_tcg2_arm.h
  create mode 100644 lib/efi_selftest/efi_miniapp_tcg2_arm64.h
  create mode 100644 lib/efi_selftest/efi_miniapp_tcg2_ia32.h
  create mode 100644 lib/efi_selftest/efi_miniapp_tcg2_riscv32.h
  create mode 100644 lib/efi_selftest/efi_miniapp_tcg2_riscv64.h
  create mode 100644 lib/efi_selftest/efi_miniapp_tcg2_x86_64.h

diff --git a/lib/efi_selftest/efi_miniapp_tcg2_arm.h b/lib/efi_selftest/efi_miniapp_tcg2_arm.h
new file mode 100644
index 0000000000..37ce1a0ce5
--- /dev/null
+++ b/lib/efi_selftest/efi_miniapp_tcg2_arm.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ *  Non-zero 8 byte strings of a disk image
+ *
+ *  Generated with tools/file2include

Please, edit the headers of the includes and describe from which C code
the EFI binaries were compiled.

To me it looks like lib/efi_selftest/efi_miniapp_file_image_exit.c.

How about:

+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * This file contains a precompiled EFI binary built from
+ * lib/efi_selftest/efi_miniapp_file_image_exit.c and converted to an
include
+ * using tools/file2include. It is used to testing the EFI_TCG2_PROTOCOL.
+ * The precompiled form is needed to avoid the problem of reproducible
builds.
+ */

Best regards

Heinrich

+ */

<snip/>

+
+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)},
+};
+
+/*
+ * efi_status_t decompress() - 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;
+}
+
+/*
+ * 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;
+
+    for (i = 0; i < ARRAY_SIZE(boot_variable_test); i++) {
+        size = 0;
+        ret = runtime->get_variable(boot_variable_test[i].name,
+                        &efi_global_variable_guid,
+                        &boot_variable_test[i].attr,
+                        &size,
+                        NULL);
+        if (ret == EFI_BUFFER_TOO_SMALL) {
+            /* Variable exists, save the current 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("Failed to allocate buffer for boot variable\n");
+                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("Failed to get current boot variable\n");
+                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("Failed to set test boot variable(%d)n", i);
+            return ret;
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * efi_status_t restore_boot_variable() - restore original values
+ *
+ * Restore the variable values saved in setup_boot_variable().
+ *
+ * @return    status code
+ */
+static 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("Failed 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("Failed to delete boot variable\n");
+                return ret;
+            }
+        }
+    }
+
+    return EFI_SUCCESS;
+}
+
+/**
+ * void *find_smbios_table() - 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;
+}
+
+/**
+ * efi_status_t setup_smbios_table() - Prepare the dummy SMBIOS table
+ *
+ * @systable    system table
+ * @return    status code
+ */
+static 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 +617,193 @@ 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);
+
+    /* setup expected PCRs per architecture */
+    boottime->copy_mem(&expected_pcrs[4], &expected_pcrs_per_arch[0], TPM2_SHA256_DIGEST_SIZE); +    boottime->copy_mem(&expected_pcrs[6], &expected_pcrs_per_arch[1], TPM2_SHA256_DIGEST_SIZE);
+
+    return EFI_ST_SUCCESS;
+}
+
+/**
+ * efi_status_t get_manufacturer_id() - 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;
+}
+
+/**
+ * efi_status_t get_manufacturer_id_buffer_small() - call submit_command with small resp buffer
+ *
+ * @tcg2        tcg2 protocol
+ * @manufacturer_id    pointer to the manufacturer_id
+ * @return        status code
+ */
+static efi_status_t get_manufacturer_id_buffer_small(struct efi_tcg2_protocol *tcg2)
+{
+    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[1]; /* set smaller buffer than expected */
+
+    ret = tcg2->submit_command(tcg2, 22, cmd, 1, resp);
+
+    return ret;
+}
+
+/**
+ * efi_status_t read_pcr() - 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;
+    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);
+
+    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;
+    }
+
+    boottime->copy_mem(pcrs[idx], &resp[TPM2_PCR_READ_HEADER_SIZE],
+               TPM2_SHA256_DIGEST_SIZE);
+
+    return ret;
+}
+
+/**
+ * int validate_pcrs() - Compare the expected and actual pcrs
+ *
+ * @return    status code
+ */
+static int validate_pcrs(void)
+{
+    u32 i;
+
+    /*
+     *  - 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
+     *    vary depending on the platform.
+     *  - Skip PCR[17..22] validation, they are not used in TCG PC Client
+     *    Platform Firmware Profile Specification
+     */
+    for (i = 1; i < (EFI_TCG2_MAX_PCR_INDEX + 1); i++) {
+        if (i == 7 || (i > 16 && i < 23))
+            continue; /* skip validation */
+
+        if (memcmp(pcrs[i], expected_pcrs[i], TPM2_SHA256_DIGEST_SIZE)) {
+            efi_st_error("PCR[%d] is not the expected value\n", i);
+            return EFI_ST_FAILURE;
+        }
+    }

      return EFI_ST_SUCCESS;
  }
@@ -31,7 +811,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 +821,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;

Is this really a failure? It could simply be that no TPM chip or emulation is available. We could imply write a warning and exit with EFI_SUCCESS. But as described below we have to make the test "onrequest" let's leave this now as iss

      }
+
+    /* 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 +855,160 @@ 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_buffer_small(tcg2);
+    if (ret != EFI_OUT_OF_RESOURCES) {
+        efi_st_error("get_manufacturer_id buffer too small failed\n");
+        return EFI_ST_FAILURE;
+    }
+
+    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 */
+    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;
  }

+/*
+ * efi_st_tcg2_teardown() - Tear down unit test
+ *
+ * @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,

Please add:

.on_request = true,

because we have to execute tpm2 startup TPM2_SU_CLEAR before it can succeed.

Best regards

Heinrich

  };

Reply via email to