diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index ece1c11cd5..193eebde0c 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -2339,7 +2339,7 @@ static EFI_STATUS image_start( loaded_image->LoadOptionsSize = strsize16(options); /* Try to log any options to the TPM, especially to catch manually edited options */ - (void) tpm_log_load_options(options); + (void) tpm_log_load_options(options, NULL); } efivar_set_time_usec(LOADER_GUID, L"LoaderTimeExecUSec", 0); diff --git a/src/boot/efi/cpio.c b/src/boot/efi/cpio.c index 6905e07c85..693b3816a4 100644 --- a/src/boot/efi/cpio.c +++ b/src/boot/efi/cpio.c @@ -436,7 +436,8 @@ EFI_STATUS pack_cpio( tpm_pcr[i], POINTER_TO_PHYSICAL_ADDRESS(buffer), buffer_size, - tpm_description); + tpm_description, + NULL); if (err != EFI_SUCCESS) log_error_stall(L"Unable to add initrd TPM measurement for PCR %u (%s), ignoring: %r", tpm_pcr[i], tpm_description, err); } diff --git a/src/boot/efi/measure.c b/src/boot/efi/measure.c index 7108554681..9041896f5b 100644 --- a/src/boot/efi/measure.c +++ b/src/boot/efi/measure.c @@ -141,43 +141,79 @@ bool tpm_present(void) { return tcg2_interface_check() || tcg1_interface_check(); } -EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description) { - EFI_TCG *tpm1; +EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description, bool *ret_measured) { EFI_TCG2 *tpm2; + EFI_STATUS err; assert(description); - /* PCR disabled */ - if (pcrindex == UINT32_MAX) + /* If EFI_SUCCESS is returned, will initialize ret_measured to true if we actually measured + * something, or false if measurement was turned off. */ + + if (pcrindex == UINT32_MAX) { /* PCR disabled? */ + if (ret_measured) + *ret_measured = false; + return EFI_SUCCESS; + } tpm2 = tcg2_interface_check(); if (tpm2) - return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description); + err = tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description); + else { + EFI_TCG *tpm1; - tpm1 = tcg1_interface_check(); - if (tpm1) - return tpm1_measure_to_pcr_and_event_log(tpm1, pcrindex, buffer, buffer_size, description); + tpm1 = tcg1_interface_check(); + if (tpm1) + err = tpm1_measure_to_pcr_and_event_log(tpm1, pcrindex, buffer, buffer_size, description); + else { + /* No active TPM found, so don't return an error */ - /* No active TPM found, so don't return an error */ - return EFI_SUCCESS; + if (ret_measured) + *ret_measured = false; + + return EFI_SUCCESS; + } + } + + if (err == EFI_SUCCESS && ret_measured) + *ret_measured = true; + + return err; } -EFI_STATUS tpm_log_load_options(const char16_t *load_options) { +EFI_STATUS tpm_log_event_ascii(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char *description, bool *ret_measured) { + _cleanup_free_ char16_t *c = NULL; + + if (description) + c = xstra_to_str(description); + + return tpm_log_event(pcrindex, buffer, buffer_size, c, ret_measured); +} + +EFI_STATUS tpm_log_load_options(const char16_t *load_options, bool *ret_measured) { + int measured = -1; EFI_STATUS err; /* Measures a load options string into the TPM2, i.e. the kernel command line */ for (UINTN i = 0; i < 2; i++) { uint32_t pcr = i == 0 ? TPM_PCR_INDEX_KERNEL_PARAMETERS : TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT; + bool m; - err = tpm_log_event(pcr, - POINTER_TO_PHYSICAL_ADDRESS(load_options), - strsize16(load_options), load_options); + if (pcr == UINT32_MAX) /* Skip this one, if it's invalid, so that our 'measured' return value is not corrupted by it */ + continue; + + err = tpm_log_event(pcr, POINTER_TO_PHYSICAL_ADDRESS(load_options), strsize16(load_options), load_options, &m); if (err != EFI_SUCCESS) return log_error_status_stall(err, L"Unable to add load options (i.e. kernel command) line measurement to PCR %u: %r", pcr, err); + + measured = measured < 0 ? m : (measured && m); } + if (ret_measured) + *ret_measured = measured < 0 ? false : measured; + return EFI_SUCCESS; } diff --git a/src/boot/efi/measure.h b/src/boot/efi/measure.h index af1cc62cdd..5da160f8c8 100644 --- a/src/boot/efi/measure.h +++ b/src/boot/efi/measure.h @@ -22,8 +22,9 @@ #if ENABLE_TPM bool tpm_present(void); -EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description); -EFI_STATUS tpm_log_load_options(const char16_t *cmdline); +EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description, bool *ret_measured); +EFI_STATUS tpm_log_event_ascii(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char *description, bool *ret_measured); +EFI_STATUS tpm_log_load_options(const char16_t *cmdline, bool *ret_measured); #else @@ -31,11 +32,21 @@ static inline bool tpm_present(void) { return false; } -static inline EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description) { +static inline EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description, bool *ret_measured) { + if (ret_measured) + *ret_measured = false; return EFI_SUCCESS; } -static inline EFI_STATUS tpm_log_load_options(const char16_t *cmdline) { +static inline EFI_STATUS tpm_log_event_ascii(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char *description, bool *ret_measured) { + if (ret_measured) + *ret_measured = false; + return EFI_SUCCESS; +} + +static inline EFI_STATUS tpm_log_load_options(const char16_t *cmdline, bool *ret_measured) { + if (ret_measured) + *ret_measured = false; return EFI_SUCCESS; } diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 83badd96cd..7f43678cb1 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -223,7 +223,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { * duplicates what we already did in the boot menu, if that was already used. However, since * we want the boot menu to support an EFI binary, and want to this stub to be usable from * any boot menu, let's measure things anyway. */ - (void) tpm_log_load_options(loaded_image->LoadOptions); + (void) tpm_log_load_options(loaded_image->LoadOptions, NULL); } export_variables(loaded_image);