From: Lennart Poettering Date: Thu, 13 Nov 2025 13:47:57 +0000 (+0100) Subject: units: measure a separator event into PCR 9 after completing NvPCR initialization X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=867e64737a1761e313c371abfb43ab2c04b9e568;p=thirdparty%2Fsystemd.git units: measure a separator event into PCR 9 after completing NvPCR initialization 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. --- diff --git a/docs/TPM2_PCR_MEASUREMENTS.md b/docs/TPM2_PCR_MEASUREMENTS.md index 7b29069a7ea..b05739a8c72 100644 --- a/docs/TPM2_PCR_MEASUREMENTS.md +++ b/docs/TPM2_PCR_MEASUREMENTS.md @@ -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 diff --git a/man/rules/meson.build b/man/rules/meson.build index 26eddb77912..6ffc088453f 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -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'], diff --git a/man/systemd-pcrphase.service.xml b/man/systemd-pcrphase.service.xml index 7832e10f85a..1d543fe403d 100644 --- a/man/systemd-pcrphase.service.xml +++ b/man/systemd-pcrphase.service.xml @@ -24,6 +24,7 @@ systemd-pcrproduct.service systemd-pcrfs-root.service systemd-pcrfs@.service + systemd-pcrnvdone.service systemd-pcrextend Measure boot phases, machine ID, product UUID and file system identity into TPM PCRs and NvPCRs @@ -35,6 +36,7 @@ systemd-pcrmachine.service systemd-pcrfs-root.service systemd-pcrfs@.service + systemd-pcrnvdone.service /usr/lib/systemd/systemd-pcrextend STRING @@ -54,6 +56,9 @@ product UUID (as provided by one of SMBIOS, Devicetree, …) into a NvPCR named hardware. + systemd-pcrnvdone.service is a system service that measures a separator event + into PCR 9 once all NvPCRs have completed initialization. + systemd-pcrfs-root.service and systemd-pcrfs@.service 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. systemd-pcrfs-root.service does so for diff --git a/src/shared/tpm2-util.c b/src/shared/tpm2-util.c index ad61fd1d8bd..1603b5f3169 100644 --- a/src/shared/tpm2-util.c +++ b/src/shared/tpm2-util.c @@ -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); diff --git a/src/shared/tpm2-util.h b/src/shared/tpm2-util.h index 8dfe87af070..59b7ed9984f 100644 --- a/src/shared/tpm2-util.h +++ b/src/shared/tpm2-util.h @@ -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; diff --git a/units/meson.build b/units/meson.build index bd788f6d0b6..8e5b645f916 100644 --- a/units/meson.build +++ b/units/meson.build @@ -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 index 00000000000..e0dd9a88209 --- /dev/null +++ b/units/systemd-pcrnvdone.service.in @@ -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