* [PATCH] bli: set LoaderTpm2ActivePcrBanks runtime variable
@ 2025-07-18 22:20 luca.boccassi
0 siblings, 0 replies; 4+ messages in thread
From: luca.boccassi @ 2025-07-18 22:20 UTC (permalink / raw)
To: grub-devel
From: Luca Boccassi <luca.boccassi@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.boccassi@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..7f5c48d9c 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);
+ if (!tpm)
+ {
+ 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);
+ if (status != GRUB_EFI_SUCCESS)
+ return 0; /* Assume none available if the call fails */
+ }
+
+ return active_pcr_banks;
+}
diff --git a/include/grub/tpm.h b/include/grub/tpm.h
index d09783dac..fd0956b39 100644
--- a/include/grub/tpm.h
+++ b/include/grub/tpm.h
@@ -39,6 +39,7 @@
grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size,
grub_uint8_t pcr, const char *description);
int grub_tpm_present (void);
+grub_uint32_t grub_tpm2_active_pcr_banks (void);
static inline bool
grub_is_tpm_fail_fatal (void)
--
2.47.2
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH] bli: set LoaderTpm2ActivePcrBanks runtime variable
@ 2025-07-18 22:46 luca.boccassi
2025-07-25 13:38 ` Daniel Kiper
0 siblings, 1 reply; 4+ messages in thread
From: luca.boccassi @ 2025-07-18 22:46 UTC (permalink / raw)
To: grub-devel
From: Luca Boccassi <luca.boccassi@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.boccassi@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);
+ if (!tpm)
+ {
+ 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);
+ if (status != GRUB_EFI_SUCCESS)
+ return 0; /* Assume none available if the call fails */
+ }
+
+ return active_pcr_banks;
+}
diff --git a/include/grub/tpm.h b/include/grub/tpm.h
index d09783dac..fd0956b39 100644
--- a/include/grub/tpm.h
+++ b/include/grub/tpm.h
@@ -39,6 +39,7 @@
grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size,
grub_uint8_t pcr, const char *description);
int grub_tpm_present (void);
+grub_uint32_t grub_tpm2_active_pcr_banks (void);
static inline bool
grub_is_tpm_fail_fatal (void)
--
2.47.2
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] bli: set LoaderTpm2ActivePcrBanks runtime variable
2025-07-18 22:46 luca.boccassi
@ 2025-07-25 13:38 ` Daniel Kiper
2025-07-25 13:54 ` Luca Boccassi
0 siblings, 1 reply; 4+ messages in thread
From: Daniel Kiper @ 2025-07-25 13:38 UTC (permalink / raw)
To: luca.boccassi; +Cc: grub-devel
On Fri, Jul 18, 2025 at 11:46:52PM +0100, luca.boccassi@gmail.com wrote:
> From: Luca Boccassi <luca.boccassi@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.boccassi@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
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] bli: set LoaderTpm2ActivePcrBanks runtime variable
2025-07-25 13:38 ` Daniel Kiper
@ 2025-07-25 13:54 ` Luca Boccassi
0 siblings, 0 replies; 4+ messages in thread
From: Luca Boccassi @ 2025-07-25 13:54 UTC (permalink / raw)
To: Daniel Kiper; +Cc: grub-devel
On Fri, 25 Jul 2025 at 14:38, Daniel Kiper <dkiper@net-space.pl> wrote:
>
> On Fri, Jul 18, 2025 at 11:46:52PM +0100, luca.boccassi@gmail.com wrote:
> > From: Luca Boccassi <luca.boccassi@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.boccassi@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
Thanks, had just copy/pasted from above, sent v2.
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-07-25 13:58 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-18 22:20 [PATCH] bli: set LoaderTpm2ActivePcrBanks runtime variable luca.boccassi
-- strict thread matches above, loose matches on Subject: below --
2025-07-18 22:46 luca.boccassi
2025-07-25 13:38 ` Daniel Kiper
2025-07-25 13:54 ` Luca Boccassi
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).