diff --git a/TODO b/TODO
index 0f738b95bf..07701ee7df 100644
--- a/TODO
+++ b/TODO
@@ -205,9 +205,6 @@ Features:
2nd key derived from volume key of the user, with which to wrap all
keys. maintain keys in kernel keyring if possible.
-* add ConditionSecurity=stub-measured or so that checks if we are booted with
- systemd-stub and its measurements
-
* sd-boot should probably measure its configuration file to PCR 5 at boot, as
per TCG PC Client Platform Firmware Profile Spec.
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index ae470ee96e..fa867dba1a 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -1479,11 +1479,67 @@
ConditionSecurity=
ConditionSecurity= may be used to check whether the given
- security technology is enabled on the system. Currently, the recognized values are
- selinux, apparmor, tomoyo,
- ima, smack, audit,
- uefi-secureboot, tpm2 and cvm.
- The test may be negated by prepending an exclamation mark.
+ security technology is enabled on the system. Currently, the following values are recognized:
+
+
+ Recognized security technologies
+
+
+
+
+
+
+
+ Value
+ Description
+
+
+
+
+ selinux
+ SELinux MAC
+
+
+ apparmor
+ AppArmor MAC
+
+
+ tomoyo
+ Tomoyo MAC
+
+
+ smack
+ SMACK MAC
+
+
+ ima
+ Integrity Measurement Architecture (IMA)
+
+
+ audit
+ Linux Audit Framework
+
+
+ uefi-secureboot
+ UEFI SecureBoot
+
+
+ tpm2
+ Trusted Platform Module 2.0 (TPM2)
+
+
+ cvm
+ Confidential virtual machine (SEV/TDX)
+
+
+ measured-uki
+ Unified Kernel Image with PCR 11 Measurements, as per systemd-stub7.
+
+
+
+
+
+ The test may be negated by prepending an exclamation mark.
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index a7577d8113..1c3f29e613 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -824,7 +824,7 @@ static int measure_volume_key(
return 0;
}
- r = efi_stub_measured(LOG_WARNING);
+ r = efi_measured_uki(LOG_WARNING);
if (r < 0)
return r;
if (r == 0) {
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index 0a30f8c9c9..5a5c05df0c 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -650,7 +650,7 @@ static int add_mount(
}
if (flags & MOUNT_PCRFS) {
- r = efi_stub_measured(LOG_WARNING);
+ r = efi_measured_uki(LOG_WARNING);
if (r == 0)
log_debug("Kernel stub did not measure kernel image into PCR, skipping userspace measurement, too.");
else if (r > 0) {
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index 2bcb887a82..d774740622 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -106,7 +106,7 @@ static int add_cryptsetup(
* assignment, under the assumption that people who are fine to use sd-stub with its PCR
* assignments are also OK with our PCR 15 use here. */
- r = efi_stub_measured(LOG_WARNING);
+ r = efi_measured_uki(LOG_WARNING);
if (r == 0)
log_debug("Will not measure volume key of volume '%s', not booted via systemd-stub with measurements enabled.", id);
else if (r > 0) {
diff --git a/src/pcrextend/pcrextend.c b/src/pcrextend/pcrextend.c
index 358bee72b0..8c5631babb 100644
--- a/src/pcrextend/pcrextend.c
+++ b/src/pcrextend/pcrextend.c
@@ -351,7 +351,7 @@ static int run(int argc, char *argv[]) {
length = strlen(word);
/* Skip logic if sd-stub is not used, after all PCR 11 might have a very different purpose then. */
- r = efi_stub_measured(LOG_ERR);
+ r = efi_measured_uki(LOG_ERR);
if (r < 0)
return r;
if (r == 0) {
diff --git a/src/shared/condition.c b/src/shared/condition.c
index 06fcd71be5..d3446e8a9d 100644
--- a/src/shared/condition.c
+++ b/src/shared/condition.c
@@ -28,6 +28,7 @@
#include "cpu-set-util.h"
#include "creds-util.h"
#include "efi-api.h"
+#include "efi-loader.h"
#include "env-file.h"
#include "env-util.h"
#include "extract-word.h"
@@ -692,6 +693,8 @@ static int condition_test_security(Condition *c, char **env) {
return has_tpm2();
if (streq(c->parameter, "cvm"))
return detect_confidential_virtualization() > 0;
+ if (streq(c->parameter, "measured-uki"))
+ return efi_measured_uki(LOG_DEBUG);
return false;
}
diff --git a/src/shared/efi-loader.c b/src/shared/efi-loader.c
index 7cbd69bfb0..0822364535 100644
--- a/src/shared/efi-loader.c
+++ b/src/shared/efi-loader.c
@@ -238,11 +238,15 @@ int efi_stub_get_features(uint64_t *ret) {
return 0;
}
-int efi_stub_measured(int log_level) {
+int efi_measured_uki(int log_level) {
_cleanup_free_ char *pcr_string = NULL;
+ static int cached = -1;
unsigned pcr_nr;
int r;
+ if (cached >= 0)
+ return cached;
+
/* Checks if we are booted on a kernel with sd-stub which measured the kernel into PCR 11. Or in
* other words, if we are running on a TPM enabled UKI.
*
@@ -253,16 +257,16 @@ int efi_stub_measured(int log_level) {
r = getenv_bool_secure("SYSTEMD_FORCE_MEASURE"); /* Give user a chance to override the variable test,
* for debugging purposes */
if (r >= 0)
- return r;
+ return (cached = r);
if (r != -ENXIO)
log_debug_errno(r, "Failed to parse $SYSTEMD_FORCE_MEASURE, ignoring: %m");
if (!is_efi_boot())
- return 0;
+ return (cached = 0);
r = efi_get_variable_string(EFI_LOADER_VARIABLE(StubPcrKernelImage), &pcr_string);
if (r == -ENOENT)
- return 0;
+ return (cached = 0);
if (r < 0)
return log_full_errno(log_level, r,
"Failed to get StubPcrKernelImage EFI variable: %m");
@@ -276,7 +280,7 @@ int efi_stub_measured(int log_level) {
"Kernel stub measured kernel image into PCR %u, which is different than expected %i.",
pcr_nr, TPM2_PCR_KERNEL_BOOT);
- return 1;
+ return (cached = 1);
}
int efi_loader_get_config_timeout_one_shot(usec_t *ret) {
diff --git a/src/shared/efi-loader.h b/src/shared/efi-loader.h
index 834362292a..c878eea72f 100644
--- a/src/shared/efi-loader.h
+++ b/src/shared/efi-loader.h
@@ -18,7 +18,7 @@ int efi_loader_get_entries(char ***ret);
int efi_loader_get_features(uint64_t *ret);
int efi_stub_get_features(uint64_t *ret);
-int efi_stub_measured(int log_level);
+int efi_measured_uki(int log_level);
int efi_loader_get_config_timeout_one_shot(usec_t *ret);
int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat);
@@ -45,7 +45,7 @@ static inline int efi_stub_get_features(uint64_t *ret) {
return -EOPNOTSUPP;
}
-static inline int efi_stub_measured(int log_level) {
+static inline int efi_measured_uki(int log_level) {
return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP),
"Compiled without support for EFI");
}
diff --git a/units/systemd-pcrfs-root.service.in b/units/systemd-pcrfs-root.service.in
index d7941fc1f6..11dc747194 100644
--- a/units/systemd-pcrfs-root.service.in
+++ b/units/systemd-pcrfs-root.service.in
@@ -15,8 +15,7 @@ Conflicts=shutdown.target
After=systemd-pcrmachine.service
Before=shutdown.target
ConditionPathExists=!/etc/initrd-release
-ConditionSecurity=tpm2
-ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+ConditionSecurity=measured-uki
[Service]
Type=oneshot
diff --git a/units/systemd-pcrfs@.service.in b/units/systemd-pcrfs@.service.in
index 9ada988f5b..fbaec4b999 100644
--- a/units/systemd-pcrfs@.service.in
+++ b/units/systemd-pcrfs@.service.in
@@ -16,8 +16,7 @@ Conflicts=shutdown.target
After=%i.mount systemd-pcrfs-root.service
Before=shutdown.target
ConditionPathExists=!/etc/initrd-release
-ConditionSecurity=tpm2
-ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+ConditionSecurity=measured-uki
[Service]
Type=oneshot
diff --git a/units/systemd-pcrmachine.service.in b/units/systemd-pcrmachine.service.in
index 9088a66acf..fb7d3ce601 100644
--- a/units/systemd-pcrmachine.service.in
+++ b/units/systemd-pcrmachine.service.in
@@ -14,8 +14,7 @@ DefaultDependencies=no
Conflicts=shutdown.target
Before=sysinit.target shutdown.target
ConditionPathExists=!/etc/initrd-release
-ConditionSecurity=tpm2
-ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+ConditionSecurity=measured-uki
[Service]
Type=oneshot
diff --git a/units/systemd-pcrphase-initrd.service.in b/units/systemd-pcrphase-initrd.service.in
index 357c7c5869..b337d602ba 100644
--- a/units/systemd-pcrphase-initrd.service.in
+++ b/units/systemd-pcrphase-initrd.service.in
@@ -14,8 +14,7 @@ DefaultDependencies=no
Conflicts=shutdown.target initrd-switch-root.target
Before=sysinit.target cryptsetup-pre.target cryptsetup.target shutdown.target initrd-switch-root.target systemd-sysext.service
ConditionPathExists=/etc/initrd-release
-ConditionSecurity=tpm2
-ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+ConditionSecurity=measured-uki
[Service]
Type=oneshot
diff --git a/units/systemd-pcrphase-sysinit.service.in b/units/systemd-pcrphase-sysinit.service.in
index 5ca986fdf7..08f73973be 100644
--- a/units/systemd-pcrphase-sysinit.service.in
+++ b/units/systemd-pcrphase-sysinit.service.in
@@ -15,8 +15,7 @@ Conflicts=shutdown.target
After=sysinit.target
Before=basic.target shutdown.target
ConditionPathExists=!/etc/initrd-release
-ConditionSecurity=tpm2
-ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+ConditionSecurity=measured-uki
[Service]
Type=oneshot
diff --git a/units/systemd-pcrphase.service.in b/units/systemd-pcrphase.service.in
index 88d41c2c5d..c94ad756d4 100644
--- a/units/systemd-pcrphase.service.in
+++ b/units/systemd-pcrphase.service.in
@@ -13,8 +13,7 @@ Documentation=man:systemd-pcrphase.service(8)
After=remote-fs.target remote-cryptsetup.target
Before=systemd-user-sessions.service
ConditionPathExists=!/etc/initrd-release
-ConditionSecurity=tpm2
-ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+ConditionSecurity=measured-uki
[Service]
Type=oneshot