mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
boot: report missing GetActivePcrBanks() call in formware as UINT32_MAX PCR bank mask
Fixes: #39150
This commit is contained in:
@@ -198,8 +198,8 @@ uint32_t tpm_get_active_pcr_banks(void) {
|
||||
|
||||
/* GetActivePcrBanks() was added only in version 1.1 of the spec */
|
||||
if (version.Major < 1 || (version.Major == 1 && version.Minor < 1)) {
|
||||
log_debug("TCG protocol too old for GetActivePcrBanks(), claiming no active banks.");
|
||||
return 0;
|
||||
log_debug("TCG protocol too old for GetActivePcrBanks(), returning wildcard bank information.");
|
||||
return UINT32_MAX;
|
||||
}
|
||||
|
||||
uint32_t active_pcr_banks = 0;
|
||||
|
||||
@@ -525,10 +525,15 @@ int efi_get_boot_options(uint16_t **ret_options) {
|
||||
|
||||
int efi_get_active_pcr_banks(uint32_t *ret) {
|
||||
#if ENABLE_EFI
|
||||
static uint32_t cache = UINT32_MAX;
|
||||
static uint32_t cache = 0;
|
||||
static bool cache_valid = false;
|
||||
int r;
|
||||
|
||||
if (cache == UINT32_MAX) {
|
||||
/* Returns the enabled PCR banks as bitmask, as reported by firmware. If the bitmask is returned as
|
||||
* UINT32_MAX, the firmware supports the TCG protocol, but in a version too old to report this
|
||||
* information. */
|
||||
|
||||
if (!cache_valid) {
|
||||
_cleanup_free_ char *active_pcr_banks = NULL;
|
||||
r = efi_get_variable_string(EFI_LOADER_VARIABLE_STR("LoaderTpm2ActivePcrBanks"), &active_pcr_banks);
|
||||
if (r < 0)
|
||||
@@ -539,22 +544,29 @@ int efi_get_active_pcr_banks(uint32_t *ret) {
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to parse LoaderTpm2ActivePcrBanks variable: %m");
|
||||
|
||||
/* EFI TPM protocol uses different bit values for the hash algorithms, let's convert */
|
||||
static const struct {
|
||||
uint32_t efi;
|
||||
uint32_t tcg;
|
||||
} table[] = {
|
||||
{ EFI_TCG2_BOOT_HASH_ALG_SHA1, 1U << TPM2_ALG_SHA1 },
|
||||
{ EFI_TCG2_BOOT_HASH_ALG_SHA256, 1U << TPM2_ALG_SHA256 },
|
||||
{ EFI_TCG2_BOOT_HASH_ALG_SHA384, 1U << TPM2_ALG_SHA384 },
|
||||
{ EFI_TCG2_BOOT_HASH_ALG_SHA512, 1U << TPM2_ALG_SHA512 },
|
||||
};
|
||||
if (efi_bits == UINT32_MAX)
|
||||
/* UINT32_MAX means that the firmware API doesn't implement GetActivePcrBanks() and caller must guess */
|
||||
cache = UINT32_MAX;
|
||||
else {
|
||||
/* EFI TPM protocol uses different bit values for the hash algorithms, let's convert */
|
||||
static const struct {
|
||||
uint32_t efi;
|
||||
uint32_t tcg;
|
||||
} table[] = {
|
||||
{ EFI_TCG2_BOOT_HASH_ALG_SHA1, 1U << TPM2_ALG_SHA1 },
|
||||
{ EFI_TCG2_BOOT_HASH_ALG_SHA256, 1U << TPM2_ALG_SHA256 },
|
||||
{ EFI_TCG2_BOOT_HASH_ALG_SHA384, 1U << TPM2_ALG_SHA384 },
|
||||
{ EFI_TCG2_BOOT_HASH_ALG_SHA512, 1U << TPM2_ALG_SHA512 },
|
||||
};
|
||||
|
||||
uint32_t tcg_bits = 0;
|
||||
FOREACH_ELEMENT(t, table)
|
||||
SET_FLAG(tcg_bits, t->tcg, efi_bits & t->efi);
|
||||
uint32_t tcg_bits = 0;
|
||||
FOREACH_ELEMENT(t, table)
|
||||
SET_FLAG(tcg_bits, t->tcg, efi_bits & t->efi);
|
||||
|
||||
cache = tcg_bits;
|
||||
cache = tcg_bits;
|
||||
}
|
||||
|
||||
cache_valid = true;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
|
||||
@@ -2705,7 +2705,9 @@ int tpm2_get_best_pcr_bank(
|
||||
|
||||
/* If variable is not set use guesswork below */
|
||||
log_debug("Boot loader didn't set the LoaderTpm2ActivePcrBanks EFI variable, we have to guess the used PCR banks.");
|
||||
} else {
|
||||
} else if (efi_banks == UINT32_MAX)
|
||||
log_debug("Boot loader set the LoaderTpm2ActivePcrBanks EFI variable to indicate that the GetActivePcrBanks() API is not available in the firmware. We have to guess the used PCR banks.");
|
||||
else {
|
||||
if (BIT_SET(efi_banks, TPM2_ALG_SHA256))
|
||||
*ret = TPM2_ALG_SHA256;
|
||||
else if (BIT_SET(efi_banks, TPM2_ALG_SHA1))
|
||||
@@ -2812,7 +2814,9 @@ int tpm2_get_good_pcr_banks(
|
||||
|
||||
/* If the variable is not set we have to guess via the code below */
|
||||
log_debug("Boot loader didn't set the LoaderTpm2ActivePcrBanks EFI variable, we have to guess the used PCR banks.");
|
||||
} else {
|
||||
} else if (efi_banks == UINT32_MAX)
|
||||
log_debug("Boot loader set the LoaderTpm2ActivePcrBanks EFI variable to indicate that the GetActivePcrBanks() API is not available in the firmware. We have to guess the used PCR banks.");
|
||||
else {
|
||||
FOREACH_ARRAY(hash, tpm2_hash_algorithms, TPM2_N_HASH_ALGORITHMS) {
|
||||
if (!BIT_SET(efi_banks, *hash))
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user