mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
tpm2-setup: measure information about NvPCR initialization to PCR 9
This locks down NvPCR initilization a bit more: we'll measure each initialization of an NvPCR into PCR 9, thus chaining the NvPCRs to the PCR set. After all NvPCRs are initialized we measure a barrier into PCR 9 as well. This ensures that later additions of NvPCRs are clearly recognizable and distuingishable from those done at boot.
This commit is contained in:
@@ -199,6 +199,22 @@ initrd" in UTF-16.
|
||||
→ **Measured hash** covers the per-UKI sysext cpio archive (which is generated
|
||||
on-the-fly by `systemd-stub`).
|
||||
|
||||
## PCR Measurements Made by `systemd-tpm2-setup` (Userspace)
|
||||
|
||||
### PCR 9, NvPCR Initializations
|
||||
|
||||
The `systemd-tpm2-setup.service` service initializes any NvPCRs defined via
|
||||
`*.nvpcr` files. For each initialized NvPCR it will measure an event into PCR
|
||||
9.
|
||||
|
||||
→ **Measured hash** covers the string `nvpcr-init:`, suffixed by the NvPCR
|
||||
name, suffixed by `:0x`, suffixed by the NV Index handle (formatted in
|
||||
hexadecimal), suffixed by a colon, suffixed by the hash function used, in
|
||||
lowercase (i.e. `sha256` or so), suffixed by a colon, and finally suffixed by
|
||||
the state of the NvPCR after its initialization with the anchor measurement, in
|
||||
hexadecimal. Example:
|
||||
`nvpcr-init:hardware:0x1d10200:sha256:de3857f637c61e82f02e3722e1b207585fe9711045d863238904be8db10683f2`
|
||||
|
||||
## PCR/NvPCR Measurements Made by `systemd-pcrextend` (Userspace)
|
||||
|
||||
### PCR 11, boot phases
|
||||
|
||||
@@ -6426,6 +6426,7 @@ static const char* tpm2_userspace_event_type_table[_TPM2_USERSPACE_EVENT_TYPE_MA
|
||||
[TPM2_EVENT_MACHINE_ID] = "machine-id",
|
||||
[TPM2_EVENT_PRODUCT_ID] = "product-id",
|
||||
[TPM2_EVENT_KEYSLOT] = "keyslot",
|
||||
[TPM2_EVENT_NVPCR_INIT] = "nvpcr-init",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP(tpm2_userspace_event_type, Tpm2UserspaceEventType);
|
||||
@@ -7368,6 +7369,37 @@ int tpm2_nvpcr_initialize(
|
||||
return log_debug_errno(r, "Failed to write anchor file: %m");
|
||||
|
||||
tpm2_userspace_log_clean(log_fd);
|
||||
log_fd = safe_close(log_fd);
|
||||
|
||||
/* Now also measure the initialization into PCR 9, so that there's a trace of it in regular PCRs. You
|
||||
* might wonder why PCR 9? Well, we have very few PCRs available, and PCR 9 appears to be the least
|
||||
* bad for this. It typically contains stuff that in our world is hard to predict anyway
|
||||
* (i.e. possibly some overly verbose Grub stuff, as well as all initrds – those generated on-the-fly
|
||||
* and those prepared beforehand – mangled into one), quite differently from all other PCRs we could
|
||||
* use. Moreover PCR 11 already contains most stuff from PCR 9, as it contains the same data
|
||||
* (i.e. initrds) in a more sensible fashion, clearly separated from on-the-fly generated ones. Note
|
||||
* that we only do all this measurement stuff if we are booted as UKI, and hence when PCR 11 is
|
||||
* available, but PCR 9 is not predictable. */
|
||||
_cleanup_strv_free_ char **banks = NULL;
|
||||
r = tpm2_get_good_pcr_banks_strv(c, UINT32_C(1) << TPM2_PCR_KERNEL_INITRD, &banks);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not verify PCR banks: %m");
|
||||
|
||||
_cleanup_free_ char *word = NULL;
|
||||
if (asprintf(&word, "nvpcr-init:%s:0x%x:%s:%s", name, p.nv_index, tpm2_hash_alg_to_string(p.algorithm), h) < 0)
|
||||
return log_oom();
|
||||
|
||||
r = tpm2_pcr_extend_bytes(
|
||||
c,
|
||||
banks,
|
||||
TPM2_PCR_KERNEL_INITRD,
|
||||
&IOVEC_MAKE_STRING(word),
|
||||
/* secret= */ NULL,
|
||||
TPM2_EVENT_NVPCR_INIT,
|
||||
word);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Could not extend PCR %i: %m", TPM2_PCR_KERNEL_INITRD);
|
||||
|
||||
return 1;
|
||||
#else /* HAVE_OPENSSL */
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "OpenSSL support is disabled.");
|
||||
|
||||
@@ -144,6 +144,7 @@ typedef enum Tpm2UserspaceEventType {
|
||||
TPM2_EVENT_MACHINE_ID,
|
||||
TPM2_EVENT_PRODUCT_ID,
|
||||
TPM2_EVENT_KEYSLOT,
|
||||
TPM2_EVENT_NVPCR_INIT,
|
||||
_TPM2_USERSPACE_EVENT_TYPE_MAX,
|
||||
_TPM2_USERSPACE_EVENT_TYPE_INVALID = -EINVAL,
|
||||
} Tpm2UserspaceEventType;
|
||||
|
||||
Reference in New Issue
Block a user