]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
units: measure a separator event into PCR 9 after completing NvPCR initialization
authorLennart Poettering <lennart@poettering.net>
Thu, 13 Nov 2025 13:47:57 +0000 (14:47 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 14 Nov 2025 21:22:39 +0000 (22:22 +0100)
We do this in a separate service (rather than inside of
systemd-tpm2-setup), since we want failures of this measurement to
result in an instant reboot, like for most our measurements.

Failures to initialize nvpcrs, or allocate an SRK are somewhat OK (and
more likely), as long as this separator communicates clearly where they
have to have taken place, if they worked.

docs/TPM2_PCR_MEASUREMENTS.md
man/rules/meson.build
man/systemd-pcrphase.service.xml
src/shared/tpm2-util.c
src/shared/tpm2-util.h
units/meson.build
units/systemd-pcrnvdone.service.in [new file with mode: 0644]

index 7b29069a7ea2a5dcabead27192d2f69aa74a19f7..b05739a8c724dffda06cd8f3826361fb2a58880c 100644 (file)
@@ -260,6 +260,15 @@ colon-separated strings, identifying the file system type, UUID, label as well
 as the GPT partition entry UUID, entry type UUID and entry label (in UTF-8,
 without trailing NUL bytes).
 
+### PCR 9, NvPCR initialization separator
+
+After completion of `systemd-tpm2-setup.service` (which initializes all NvPCRs
+and measures their initial state) at arly boot the `systemd-pcrnvdone.service`
+service will measure a separator event into PCR 9, isolating the early-boot
+NvPCR initializations from any later additions.
+
+→ **Measured hash** covers the string `nvpcr-separator`.
+
 ## PCR/NvPCR Measurements Made by `systemd-cryptsetup` (Userspace)
 
 ### PCR 15, volume key
index 26eddb77912f06c7ff437704d98fae957fed94f1..6ffc088453fff9a36e66371e70eb8c7964b35b68 100644 (file)
@@ -1106,6 +1106,7 @@ manpages = [
    'systemd-pcrfs-root.service',
    'systemd-pcrfs@.service',
    'systemd-pcrmachine.service',
+   'systemd-pcrnvdone.service',
    'systemd-pcrphase-initrd.service',
    'systemd-pcrphase-sysinit.service'],
   'ENABLE_BOOTLOADER HAVE_OPENSSL HAVE_TPM2'],
index 7832e10f85a7b3737efa4cd49e8053e28556e30d..1d543fe403d2dfa5ce4d103599abc7561ee0887c 100644 (file)
@@ -24,6 +24,7 @@
     <refname>systemd-pcrproduct.service</refname>
     <refname>systemd-pcrfs-root.service</refname>
     <refname>systemd-pcrfs@.service</refname>
+    <refname>systemd-pcrnvdone.service</refname>
     <refname>systemd-pcrextend</refname>
     <refpurpose>Measure boot phases, machine ID, product UUID and file system identity into TPM PCRs and NvPCRs</refpurpose>
   </refnamediv>
@@ -35,6 +36,7 @@
     <para><filename>systemd-pcrmachine.service</filename></para>
     <para><filename>systemd-pcrfs-root.service</filename></para>
     <para><filename>systemd-pcrfs@.service</filename></para>
+    <para><filename>systemd-pcrnvdone.service</filename></para>
     <para><filename>/usr/lib/systemd/systemd-pcrextend</filename> <optional><replaceable>STRING</replaceable></optional></para>
   </refsynopsisdiv>
 
@@ -54,6 +56,9 @@
     product UUID (as provided by one of SMBIOS, Devicetree, …) into a NvPCR named
     <literal>hardware</literal>.</para>
 
+    <para><filename>systemd-pcrnvdone.service</filename> is a system service that measures a separator event
+    into PCR 9 once all NvPCRs have completed initialization.</para>
+
     <para><filename>systemd-pcrfs-root.service</filename> and <filename>systemd-pcrfs@.service</filename> are
     services that measure file system identity information (i.e. mount point, file system type, label and
     UUID, partition label and UUID) into PCR 15. <filename>systemd-pcrfs-root.service</filename> does so for
index ad61fd1d8bdaa2e9248a7ce37c73a3c368f71c64..1603b5f3169e3495b47b8c25b6f69a174a4cf955 100644 (file)
@@ -6420,13 +6420,14 @@ static int json_dispatch_tpm2_algorithm(const char *name, sd_json_variant *varia
 }
 
 static const char* tpm2_userspace_event_type_table[_TPM2_USERSPACE_EVENT_TYPE_MAX] = {
-        [TPM2_EVENT_PHASE]      = "phase",
-        [TPM2_EVENT_FILESYSTEM] = "filesystem",
-        [TPM2_EVENT_VOLUME_KEY] = "volume-key",
-        [TPM2_EVENT_MACHINE_ID] = "machine-id",
-        [TPM2_EVENT_PRODUCT_ID] = "product-id",
-        [TPM2_EVENT_KEYSLOT]    = "keyslot",
-        [TPM2_EVENT_NVPCR_INIT] = "nvpcr-init",
+        [TPM2_EVENT_PHASE]           = "phase",
+        [TPM2_EVENT_FILESYSTEM]      = "filesystem",
+        [TPM2_EVENT_VOLUME_KEY]      = "volume-key",
+        [TPM2_EVENT_MACHINE_ID]      = "machine-id",
+        [TPM2_EVENT_PRODUCT_ID]      = "product-id",
+        [TPM2_EVENT_KEYSLOT]         = "keyslot",
+        [TPM2_EVENT_NVPCR_INIT]      = "nvpcr-init",
+        [TPM2_EVENT_NVPCR_SEPARATOR] = "nvpcr-separator",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(tpm2_userspace_event_type, Tpm2UserspaceEventType);
index 8dfe87af0706f6dc9eab7656b6cb0ecc635ca01b..59b7ed9984f882aa5f67e3302668a5a73ac77960 100644 (file)
@@ -145,6 +145,7 @@ typedef enum Tpm2UserspaceEventType {
         TPM2_EVENT_PRODUCT_ID,
         TPM2_EVENT_KEYSLOT,
         TPM2_EVENT_NVPCR_INIT,
+        TPM2_EVENT_NVPCR_SEPARATOR,
         _TPM2_USERSPACE_EVENT_TYPE_MAX,
         _TPM2_USERSPACE_EVENT_TYPE_INVALID = -EINVAL,
 } Tpm2UserspaceEventType;
index bd788f6d0b671f6c2935c06dbb7c09d1ed9e9386..8e5b645f9166ef93c424db9b1f0f9fbb38c974cf 100644 (file)
@@ -581,6 +581,11 @@ units = [
           'conditions' : ['ENABLE_BOOTLOADER', 'HAVE_OPENSSL', 'HAVE_TPM2'],
           'symlinks' : ['sysinit.target.wants/'],
         },
+        {
+          'file' : 'systemd-pcrnvdone.service.in',
+          'conditions' : ['ENABLE_BOOTLOADER', 'HAVE_OPENSSL', 'HAVE_TPM2'],
+          'symlinks' : ['sysinit.target.wants/'],
+        },
         {
           'file' : 'systemd-tpm2-clear.service.in',
           'conditions' : ['ENABLE_BOOTLOADER', 'HAVE_OPENSSL', 'HAVE_TPM2'],
diff --git a/units/systemd-pcrnvdone.service.in b/units/systemd-pcrnvdone.service.in
new file mode 100644 (file)
index 0000000..e0dd9a8
--- /dev/null
@@ -0,0 +1,24 @@
+#  SPDX-License-Identifier: LGPL-2.1-or-later
+#
+#  This file is part of systemd.
+#
+#  systemd is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU Lesser General Public License as published by
+#  the Free Software Foundation; either version 2.1 of the License, or
+#  (at your option) any later version.
+
+[Unit]
+Description=TPM PCR NvPCR Initialization Separator
+Documentation=man:systemd-pcrnvdone.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-tpm2-setup-early.service systemd-tpm2-setup.service
+Before=sysinit.target shutdown.target
+ConditionSecurity=measured-uki
+ConditionPathExists=!/etc/initrd-release
+FailureAction=reboot-force
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart={{LIBEXECDIR}}/systemd-pcrextend --graceful --pcr=kernel-initrd --event-type=nvpcr-separator nvpcr-separator