→ **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
[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);
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.");