On Fri, Jul 18, 2025 at 11:46:52PM +0100, luca.bocca...@gmail.com wrote:
> From: Luca Boccassi <luca.bocca...@gmail.com>
>
> It turns out checking from userspace is not 100% reliable to figure out 
> whether
> the firmware had TPM2 support enabled or not. For example with EDK2 arm64, the
> default upstream build config bundles TPM2 support with SecureBoot support,
> so if the latter is disabled, TPM2 is also unavailable. But still, the ACPI
> TPM2 table is created just as if it was enabled. So 
> /sys/firmware/acpi/tables/TPM2
> exists and looks correct, but there are no measurements, neither the firmware
> nor the loader/stub can do them, and 
> /sys/kernel/security/tpm0/binary_bios_measurements
> does not exist. So userspace cannot really tell what was going on in UEFI 
> mode.
>
> The loader can use the apposite UEFI protocol to check, which is a more
> definitive answer. Export the bitmask with the list of active banks as-is.
> If it's not 0, then in userspace we can be sure a working TPM2 was available 
> in
> UEFI mode.
>
> Signed-off-by: Luca Boccassi <luca.bocca...@gmail.com>
> ---
> systemd-boot and systemd-stub v258 (current main) set this variable, and
> userspace portion consumes it to be able to tell what was available in the
> firmware context.
>
>  grub-core/commands/bli.c     | 23 +++++++++++++++++++++++
>  grub-core/commands/efi/tpm.c | 32 ++++++++++++++++++++++++++++++++
>  include/grub/tpm.h           |  1 +
>  3 files changed, 56 insertions(+)
>
> diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c
> index 298c5f70a..38f52f87a 100644
> --- a/grub-core/commands/bli.c
> +++ b/grub-core/commands/bli.c
> @@ -28,6 +28,7 @@
>  #include <grub/misc.h>
>  #include <grub/mm.h>
>  #include <grub/partition.h>
> +#include <grub/tpm.h>
>  #include <grub/types.h>
>
>  GRUB_MOD_LICENSE ("GPLv3+");
> @@ -127,12 +128,34 @@ set_loader_device_part_uuid (void)
>    return status;
>  }
>
> +static grub_err_t
> +set_loader_active_pcr_banks (void)
> +{
> +  grub_efi_uint32_t active_pcr_banks;
> +  char *active_pcr_banks_str;
> +  grub_err_t status;
> +
> +  active_pcr_banks = grub_tpm2_active_pcr_banks();
> +  active_pcr_banks_str = grub_xasprintf ("0x%08x", active_pcr_banks);
> +  if (active_pcr_banks_str == NULL)
> +    return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate active 
> PCR banks string"));
> +
> +  status = grub_efi_set_variable_to_string ("LoaderTpm2ActivePcrBanks",
> +                                          &bli_vendor_guid,
> +                                          active_pcr_banks_str,
> +                                          
> GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
> +                                          GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
> +  grub_free (active_pcr_banks_str);
> +  return status;
> +}
> +
>  GRUB_MOD_INIT (bli)
>  {
>    grub_efi_set_variable_to_string ("LoaderInfo", &bli_vendor_guid, 
> PACKAGE_STRING,
>                                  GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
>                                  GRUB_EFI_VARIABLE_RUNTIME_ACCESS);
>    set_loader_device_part_uuid ();
> +  set_loader_active_pcr_banks ();
>    /* No error here is critical, other than being logged */
>    grub_print_error ();
>  }
> diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
> index cbac69866..e2351f9cd 100644
> --- a/grub-core/commands/efi/tpm.c
> +++ b/grub-core/commands/efi/tpm.c
> @@ -332,3 +332,35 @@ grub_tpm_present (void)
>        return grub_tpm2_present (tpm);
>      }
>  }
> +
> +grub_uint32_t
> +grub_tpm2_active_pcr_banks (void)
> +{
> +  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;
> +
> +  if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
> +    return 0;
> +
> +  if (protocol_version == 1)
> +    return 0; /* We report TPM2 status */
> +
> +  tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
> +        GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);

Wrong indention. GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL should start under
"t" from tpm_handle.

> +  if (!tpm)

tpm == NULL

> +    {
> +      grub_dprintf ("tpm", "Cannot open TPM2 protocol\n");
> +      return 0;
> +    }
> +
> +  if (grub_tpm2_present (tpm))
> +    {
> +      grub_efi_status_t status = tpm->get_active_pcr_banks (tpm, 
> &active_pcr_banks);

Missing empty line...

> +      if (status != GRUB_EFI_SUCCESS)
> +     return 0; /* Assume none available if the call fails */

Seems like wrong indention again...

Anyway, if you fix these minor issues you can add my RB...

Daniel

_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to