commands/bli: Set UINT32_MAX in LoaderTpm2ActivePcrBanks if TPM2 present but no banks protocol

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 <luca.boccassi@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
This commit is contained in:
Luca Boccassi 2025-12-10 23:47:53 +00:00 committed by Daniel Kiper
parent c0669af6a8
commit 9b2c8ae5d2

View File

@ -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 (grub_uint32_t) (tpm2_active_pcr_banks = 0);
if (protocol_version == 1)
return 0; /* We report TPM2 status */
return (grub_uint32_t) (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 (grub_uint32_t) (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 (grub_uint32_t) (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 (grub_uint32_t) (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 (grub_uint32_t) (tpm2_active_pcr_banks = GRUB_UINT_MAX);
return active_pcr_banks;
status = tpm->get_active_pcr_banks (tpm, &active_pcr_banks);
if (status != GRUB_EFI_SUCCESS)
return (grub_uint32_t) (tpm2_active_pcr_banks = 0); /* Assume none available if the call fails. */
return (grub_uint32_t) (tpm2_active_pcr_banks = active_pcr_banks);
}