From: Luca Boccassi <[email protected]> The implementation in sd-boot was changed to return UINT32_MAX when the EFI environment detects a working TPM2, but with an older firmware that doesn't implement the protocol to get the list of active banks. This allows distinguishing with the case where there is no working TPM2, in which case userspace just gives up, and instead lets userspace try to figure it out later.
Fixes: f326c5c47 (commands/bli: Set LoaderTpm2ActivePcrBanks runtime variable) Signed-off-by: Luca Boccassi <[email protected]> --- Follow-up for previous change to keep in sync with userspace tools expectations: https://github.com/systemd/systemd/commit/b2b8fb810509442ceca33555d47a04ff527b3da7 grub-core/commands/efi/tpm.c | 65 ++++++++++++++---------------------- 1 file changed, 25 insertions(+), 40 deletions(-) diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c index 7b493c890..c76dfbec9 100644 --- a/grub-core/commands/efi/tpm.c +++ b/grub-core/commands/efi/tpm.c @@ -39,7 +39,7 @@ static grub_uint8_t grub_tpm_version; static grub_int8_t tpm1_present = -1; static grub_int8_t tpm2_present = -1; -static grub_int8_t tpm2_pcr_banks_reporting_present = -1; +static grub_efi_int64_t tpm2_active_pcr_banks = -1; static grub_efi_boolean_t grub_tpm1_present (grub_efi_tpm_protocol_t *tpm) @@ -90,34 +90,6 @@ grub_tpm2_present (grub_efi_tpm2_protocol_t *tpm) return (grub_efi_boolean_t) tpm2_present; } -static grub_efi_boolean_t -grub_tpm2_pcr_banks_reporting_present (grub_efi_tpm2_protocol_t *tpm) -{ - grub_efi_status_t status; - EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; - - caps.Size = (grub_uint8_t) sizeof (caps); - - if (tpm2_pcr_banks_reporting_present != -1) - return (grub_efi_boolean_t) tpm2_pcr_banks_reporting_present; - - if (!grub_tpm2_present (tpm)) - return (grub_efi_boolean_t) (tpm2_pcr_banks_reporting_present = 0); - - status = tpm->get_capability (tpm, &caps); - - if (status != GRUB_EFI_SUCCESS || caps.StructureVersion.Major < 1 - || (caps.StructureVersion.Major == 1 && caps.StructureVersion.Minor < 1)) - tpm2_pcr_banks_reporting_present = 0; - else - tpm2_pcr_banks_reporting_present = 1; - - grub_dprintf ("tpm", "tpm2 PCR banks reporting%s present\n", - tpm2_pcr_banks_reporting_present ? "" : " NOT"); - - return (grub_efi_boolean_t) tpm2_pcr_banks_reporting_present; -} - static grub_efi_boolean_t grub_tpm_handle_find (grub_efi_handle_t *tpm_handle, grub_efi_uint8_t *protocol_version) @@ -365,32 +337,45 @@ grub_tpm_present (void) grub_uint32_t grub_tpm2_active_pcr_banks (void) { + EFI_TCG2_BOOT_SERVICE_CAPABILITY caps; grub_efi_handle_t tpm_handle; grub_efi_uint8_t protocol_version; grub_efi_tpm2_protocol_t *tpm; - grub_efi_uint32_t active_pcr_banks = 0; + grub_efi_uint32_t active_pcr_banks; + grub_efi_status_t status; + + if (tpm2_active_pcr_banks >= 0) + return (grub_uint32_t) tpm2_active_pcr_banks; if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) - return 0; + return (tpm2_active_pcr_banks = 0); if (protocol_version == 1) - return 0; /* We report TPM2 status */ + return (tpm2_active_pcr_banks = 0); /* We report TPM2 status */ tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (tpm == NULL) { grub_dprintf ("tpm", "Cannot open TPM2 protocol\n"); - return 0; + return (tpm2_active_pcr_banks = 0); } - if (grub_tpm2_pcr_banks_reporting_present (tpm)) - { - grub_efi_status_t status = tpm->get_active_pcr_banks (tpm, &active_pcr_banks); + if (!grub_tpm2_present (tpm)) + return (tpm2_active_pcr_banks = 0); - if (status != GRUB_EFI_SUCCESS) - return 0; /* Assume none available if the call fails. */ - } + caps.Size = (grub_uint8_t) sizeof (caps); + status = tpm->get_capability (tpm, &caps); + if (status != GRUB_EFI_SUCCESS) + return (tpm2_active_pcr_banks = 0); + if (caps.StructureVersion.Major < 1 + || (caps.StructureVersion.Major == 1 && caps.StructureVersion.Minor < 1)) + /* There's a working TPM2 but without querying protocol, let userspace figure it out */ + return (tpm2_active_pcr_banks = GRUB_UINT_MAX); + + status = tpm->get_active_pcr_banks (tpm, &active_pcr_banks); + if (status != GRUB_EFI_SUCCESS) + return (tpm2_active_pcr_banks = 0); /* Assume none available if the call fails. */ - return active_pcr_banks; + return (grub_uint32_t) (tpm2_active_pcr_banks = active_pcr_banks); } -- 2.47.3 _______________________________________________ Grub-devel mailing list [email protected] https://lists.gnu.org/mailman/listinfo/grub-devel
