From: Michał Żygowski <michal.zygow...@3mdeb.com> Signed-off-by: Michał Żygowski <michal.zygow...@3mdeb.com> Signed-off-by: Krystian Hebel <krystian.he...@3mdeb.com> Signed-off-by: Sergii Dmytruk <sergii.dmyt...@3mdeb.com> --- grub-core/loader/slaunch/txt.c | 68 +++++++++++++++++++++++++++++++++- include/grub/i386/txt.h | 33 +++++++++++++++++ 2 files changed, 100 insertions(+), 1 deletion(-)
diff --git a/grub-core/loader/slaunch/txt.c b/grub-core/loader/slaunch/txt.c index 7040c4159..3b36e0ca4 100644 --- a/grub-core/loader/slaunch/txt.c +++ b/grub-core/loader/slaunch/txt.c @@ -503,6 +503,32 @@ grub_set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr) return GRUB_ERR_NONE; } +void +grub_txt_init_tpm_event_log (void *buf, grub_size_t size) +{ + struct grub_txt_event_log_container *elog; + + if (buf == NULL || size < sizeof (*elog)) + return; + + /* For TPM 2.0 just clear the area, only TPM 1.2 requires initialization. */ + grub_memset (buf, 0, size); + + if (grub_get_tpm_ver () != GRUB_TPM_12) + return; + + elog = (struct grub_txt_event_log_container *) buf; + + grub_memcpy ((void *) elog->signature, EVTLOG_SIGNATURE, sizeof (elog->signature)); + elog->container_ver_major = EVTLOG_CNTNR_MAJOR_VER; + elog->container_ver_minor = EVTLOG_CNTNR_MINOR_VER; + elog->pcr_event_ver_major = EVTLOG_EVT_MAJOR_VER; + elog->pcr_event_ver_minor = EVTLOG_EVT_MINOR_VER; + elog->size = size; + elog->pcr_events_offset = sizeof (*elog); + elog->next_event_offset = sizeof (*elog); +} + static void set_txt_info_ptr (struct grub_slaunch_params *slparams, struct grub_txt_os_mle_data *os_mle_data) @@ -524,6 +550,7 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header struct grub_txt_os_mle_data *os_mle_data; struct grub_txt_os_sinit_data *os_sinit_data; struct grub_txt_heap_end_element *heap_end_element; + struct grub_txt_heap_tpm_event_log_element *heap_tpm_event_log_element; struct grub_txt_heap_event_log_pointer2_1_element *heap_event_log_pointer2_1_element; #ifdef GRUB_MACHINE_EFI struct grub_acpi_rsdp_v20 *rsdp; @@ -637,10 +664,31 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header sinit_caps = grub_txt_get_sinit_capabilities (sinit); + grub_dprintf ("slaunch", "SINIT capabilities 0x%08x\n", sinit_caps); + /* CBnT bits 5:4 must be 11b, since D/A mapping is the only one supported. */ os_sinit_data->capabilities = GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE | GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE; + if (grub_get_tpm_ver () == GRUB_TPM_20) + { + if ((sinit_caps & os_sinit_data->capabilities) != os_sinit_data->capabilities) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("Details/authorities PCR usage is not supported")); + } + else + { + if (!(sinit_caps & GRUB_TXT_CAPS_TPM_12_AUTH_PCR_USAGE)) + { + grub_dprintf ("slaunch", "Details/authorities PCR usage is not supported. Trying legacy"); + if (sinit_caps & GRUB_TXT_CAPS_TPM_12_NO_LEGACY_PCR_USAGE) + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("Not a single PCR usage available in SINIT capabilities")); + + os_sinit_data->capabilities = 0; + } + } + /* Choose monitor RLP wakeup mechanism first. */ if (sinit_caps & GRUB_TXT_CAPS_MONITOR_SUPPORT) os_sinit_data->capabilities |= GRUB_TXT_CAPS_MONITOR_SUPPORT; @@ -653,9 +701,27 @@ init_txt_heap (struct grub_slaunch_params *slparams, struct grub_txt_acm_header os_sinit_data->capabilities |= GRUB_TXT_CAPS_ECX_PT_SUPPORT; if (grub_get_tpm_ver () == GRUB_TPM_12) - return grub_error (GRUB_ERR_BAD_DEVICE, N_("TPM 1.2 is not supported")); + { + grub_dprintf ("slaunch", "TPM 1.2 detected\n"); + grub_dprintf ("slaunch", "Setting up TXT HEAP TPM event log element\n"); + os_sinit_data->flags = GRUB_TXT_PCR_EXT_MAX_PERF_POLICY; + os_sinit_data->version = OS_SINIT_DATA_TPM_12_VER; + + heap_tpm_event_log_element = + (struct grub_txt_heap_tpm_event_log_element *) os_sinit_data->ext_data_elts; + heap_tpm_event_log_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_TPM_EVENT_LOG_PTR; + heap_tpm_event_log_element->size = sizeof (*heap_tpm_event_log_element); + heap_tpm_event_log_element->event_log_phys_addr = slparams->tpm_evt_log_base; + + heap_end_element = (struct grub_txt_heap_end_element *) + ((grub_addr_t) heap_tpm_event_log_element + heap_tpm_event_log_element->size); + heap_end_element->type = GRUB_TXT_HEAP_EXTDATA_TYPE_END; + heap_end_element->size = sizeof (*heap_end_element); + } else { + grub_dprintf ("slaunch", "TPM 2.0 detected\n"); + grub_dprintf ("slaunch", "Setting up TXT HEAP TPM event log element\n"); if (!(sinit_caps & GRUB_TXT_CAPS_TPM_20_EVTLOG_SUPPORT)) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("original TXT TPM 2.0 event log format is not supported")); diff --git a/include/grub/i386/txt.h b/include/grub/i386/txt.h index 01668045f..d4a6d1cd1 100644 --- a/include/grub/i386/txt.h +++ b/include/grub/i386/txt.h @@ -22,6 +22,7 @@ #define GRUB_TXT_H 1 #include <grub/i386/mmio.h> +#include <grub/tpm.h> /* Intel TXT Software Developers Guide */ @@ -636,6 +637,36 @@ struct grub_smx_parameters grub_uint32_t txt_feature_ext_flags; } GRUB_PACKED; +/* Structures and constants used for TPM 1.2 event log initialization */ +struct grub_tpm12_pcr_event +{ + grub_uint32_t pcr_index; + grub_uint32_t type; + grub_uint8_t digest[SHA1_DIGEST_SIZE]; + grub_uint32_t data_size; + grub_uint8_t data[]; +} GRUB_PACKED; + +#define EVTLOG_SIGNATURE "TXT Event Container" +#define EVTLOG_CNTNR_MAJOR_VER 1 +#define EVTLOG_CNTNR_MINOR_VER 0 +#define EVTLOG_EVT_MAJOR_VER 1 +#define EVTLOG_EVT_MINOR_VER 0 + +struct grub_txt_event_log_container +{ + grub_uint8_t signature[20]; + grub_uint8_t reserved[12]; + grub_uint8_t container_ver_major; + grub_uint8_t container_ver_minor; + grub_uint8_t pcr_event_ver_major; + grub_uint8_t pcr_event_ver_minor; + grub_uint32_t size; + grub_uint32_t pcr_events_offset; + grub_uint32_t next_event_offset; + struct grub_tpm12_pcr_event pcr_events[]; +} GRUB_PACKED; + static inline void grub_txt_getsec_parameters (grub_uint32_t index, grub_uint32_t *eax_out, grub_uint32_t *ebx_out, grub_uint32_t *ecx_out) @@ -662,6 +693,8 @@ extern grub_err_t grub_txt_verify_platform (void); extern grub_err_t grub_txt_prepare_cpu (void); extern grub_err_t grub_set_mtrrs_for_acmod (struct grub_txt_acm_header *hdr); +extern void grub_txt_init_tpm_event_log (void *buf, grub_size_t size); + extern grub_uint32_t grub_txt_get_mle_ptab_size (grub_uint32_t mle_size); extern void grub_txt_setup_mle_ptab (struct grub_slaunch_params *slparams); -- 2.47.1 _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel