description : 'path to the EFI lib directory')
option('efi-includedir', type : 'string', value : '/usr/include/efi',
description : 'path to the EFI header directory')
+option('efi-tpm-pcr-compat', type : 'boolean', value : 'false',
+ description : 'Measure kernel command line also into TPM PCR 8 (in addition to 12)')
option('sbat-distro', type : 'string', value : 'auto',
description : 'SBAT distribution ID, e.g. fedora, or auto for autodetection')
option('sbat-distro-generation', type : 'integer', value : 1,
const CHAR8 *target_dir_prefix,
UINT32 dir_mode,
UINT32 access_mode,
- UINT32 tpm_pcr,
+ const UINT32 tpm_pcr[],
+ UINTN n_tpm_pcr,
const CHAR16 *tpm_description,
void **ret_buffer,
UINTN *ret_buffer_size) {
assert(loaded_image);
assert(target_dir_prefix);
+ assert(tpm_pcr || n_tpm_pcr == 0);
assert(ret_buffer);
assert(ret_buffer_size);
if (EFI_ERROR(err))
return log_error_status_stall(err, L"Failed to pack cpio trailer: %r");
- err = tpm_log_event(
- tpm_pcr,
- POINTER_TO_PHYSICAL_ADDRESS(buffer),
- buffer_size,
- tpm_description);
- if (EFI_ERROR(err))
- log_error_stall(L"Unable to add initrd TPM measurement for PCR %u (%s), ignoring: %r", tpm_pcr, tpm_description, err);
+ for (UINTN i = 0; i < n_tpm_pcr; i++) {
+ err = tpm_log_event(
+ tpm_pcr[i],
+ POINTER_TO_PHYSICAL_ADDRESS(buffer),
+ buffer_size,
+ tpm_description);
+ if (EFI_ERROR(err))
+ log_error_stall(L"Unable to add initrd TPM measurement for PCR %u (%s), ignoring: %r", tpm_pcr[i], tpm_description, err);
+ }
*ret_buffer = TAKE_PTR(buffer);
*ret_buffer_size = buffer_size;
const CHAR8 *target_dir_prefix,
UINT32 dir_mode,
UINT32 access_mode,
- UINT32 tpm_pcr,
+ const UINT32 tpm_pcr[],
+ UINTN n_tpm_pcr,
const CHAR16 *tpm_description,
void **ret_buffer,
UINTN *ret_buffer_size);
assert(description);
+ /* PCR disabled */
+ if (pcrindex == UINT32_MAX)
+ return EFI_SUCCESS;
+
tpm2 = tcg2_interface_check();
if (tpm2)
return tpm2_measure_to_pcr_and_event_log(tpm2, pcrindex, buffer, buffer_size, description);
/* Measures a load options string into the TPM2, i.e. the kernel command line */
- err = tpm_log_event(TPM_PCR_INDEX_KERNEL_PARAMETERS,
- POINTER_TO_PHYSICAL_ADDRESS(load_options),
- StrSize(load_options), load_options);
- if (EFI_ERROR(err))
- return log_error_status_stall(err, L"Unable to add load options (i.e. kernel command) line measurement: %r", err);
+ for (UINTN i = 0; i < 2; i++) {
+ UINT32 pcr = i == 0 ? TPM_PCR_INDEX_KERNEL_PARAMETERS : TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT;
+
+ err = tpm_log_event(pcr,
+ POINTER_TO_PHYSICAL_ADDRESS(load_options),
+ StrSize(load_options), load_options);
+ if (EFI_ERROR(err))
+ return log_error_status_stall(err, L"Unable to add load options (i.e. kernel command) line measurement to PCR %u: %r", pcr, err);
+ }
return EFI_SUCCESS;
}
#include <efi.h>
+/* This TPM PCR is where we extend the kernel command line and any passed credentials here. */
+#define TPM_PCR_INDEX_KERNEL_PARAMETERS 12U
+
+/* We used to write the the kernel command line/credentials into PCR 8, in systemd <= 250. Let's provide for
+ * some compatibility. (Remove in 2023!) */
+#if EFI_TPM_PCR_COMPAT
+#define TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT 8U
+#else
+#define TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT UINT32_MAX
+#endif
+
+/* This TPM PCR is where most Linux infrastructure extends the initrd binary images into, and so do we. */
+#define TPM_PCR_INDEX_INITRD 4U
+
#if ENABLE_TPM
BOOLEAN tpm_present(void);
efi_conf = configuration_data()
efi_conf.set_quoted('EFI_MACHINE_TYPE_NAME', efi_arch[0])
efi_conf.set10('ENABLE_TPM', get_option('tpm'))
+efi_conf.set10('EFI_TPM_PCR_COMPAT', get_option('efi-tpm-pcr-compat'))
foreach ctype : ['color-normal', 'color-entry', 'color-highlight', 'color-edit']
c = get_option('efi-' + ctype).split(',')
(const CHAR8*) ".extra/credentials",
/* dir_mode= */ 0500,
/* access_mode= */ 0400,
- /* tpm_pcr= */ TPM_PCR_INDEX_KERNEL_PARAMETERS,
+ /* tpm_pcr= */ (UINT32[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
+ /* n_tpm_pcr= */ 2,
L"Credentials initrd",
&credential_initrd,
&credential_initrd_size);
(const CHAR8*) ".extra/global_credentials",
/* dir_mode= */ 0500,
/* access_mode= */ 0400,
- /* tpm_pcr= */ TPM_PCR_INDEX_KERNEL_PARAMETERS,
+ /* tpm_pcr= */ (UINT32[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
+ /* n_tpm_pcr= */ 2,
L"Global credentials initrd",
&global_credential_initrd,
&global_credential_initrd_size);
(const CHAR8*) ".extra/sysext",
/* dir_mode= */ 0555,
/* access_mode= */ 0444,
- /* tpm_pcr= */ TPM_PCR_INDEX_INITRD,
+ /* tpm_pcr= */ (UINT32[]) { TPM_PCR_INDEX_INITRD },
+ /* n_tpm_pcr= */ 1,
L"System extension initrd",
&sysext_initrd,
&sysext_initrd_size);
#include "string-util-fundamental.h"
-/* This TPM PCR is where most Linux infrastructure extends the kernel command line into, and so do we. We also extend
- * any passed credentials here. */
-#define TPM_PCR_INDEX_KERNEL_PARAMETERS 8
-
-/* This TPM PCR is where most Linux infrastructure extends the initrd binary images into, and so do we. */
-#define TPM_PCR_INDEX_INITRD 4
-
#define offsetof(type, member) __builtin_offsetof(type, member)
#define UINTN_MAX (~(UINTN)0)