Commit Graph
30 Commits
Author SHA1 Message Date
Vitaly Kuznetsov 4820d57eee TEST-70-TPM2: Test the key_file + tpm2-device= combo
When key_file is passed along with tpm2-device= to systemd-cryptsetup, the
logic is to try the blob as a TPM blob first, and then fall back to trying the
file as a regular key file. Check that this fallback works.
2026-05-04 12:22:03 +02:00
Vitaly Kuznetsov bd9971cd25 cryptsetup: avoid a segfault when a keyfile is passed along with a TPM device
When a keyfile is passed with tpm2-device=, e.g.,

 systemd-cryptsetup attach test_data /vol /my-pass tpm2-device=auto

the logic in attach_luks_or_plain_or_bitlk_by_tpm2() tries to process it as a
TPM blob first. This did not work properly because it passes n_blobs=1 to
acquire_tpm2_key(), and the key_file is only read when n_blobs == 0. As a
result, the code ends up calling tpm2_unseal(..., blobs=NULL, n_blobs=1, ...).

Before commit 5c6aad9 ("cryptsetup-tokens: Print tpm2-primary-alg: only when it
is known"), the segfault was not observed because tpm2_unseal() was bailing out
early when primary_alg == 0. However, after that change, it attempts to process
the blob (which is NULL) and crashes.

Fix this logic by passing n_blobs=0 to acquire_tpm2_key() so that it actually
reads the key_file. Additionally, assert 'blobs' in tpm2_unseal() as a
safeguard.

Fixes #41867
2026-05-04 12:22:03 +02:00
Vitaly Kuznetsov 2299a37e28 sysext: provide a cmdline kill switch for the sysext/confext merging logic
While it is possible to disable sysext/confext merging in the main system
with 'systemctl disable', sysext/confext are always merged in the initrd,
both by systemd-{sys,conf}ext-initrd.service and by
systemd-{sys,conf}ext-sysroot.service and especially the latter can be
unexpected. Provide kernel cmdline options systemd.{sys,conf}ext=0 and
rd.systemd.{sys,conf}ext=0 covering all options.
2026-04-07 09:51:03 +02:00
Vitaly Kuznetsov c70b17daad sysext: provide systemd-{sysext,confext}-sysroot.service services
The new services are used to activate system and configuration extensions
for the main system from the initrd, this allows to overcome the limitation
that sysext/confext cannot be used to update the resources which are required
in the earliest boot of the system (before systemd-sysext/systemd-confext
start).
2026-04-07 09:50:59 +02:00
Vitaly Kuznetsov f778f08fae NEWS: fix sysext/confext configuration file names in v259
/etc/systemd/systemd-{confext,sysext}.conf are likely just leftovers
from an older in-development version of the feature.
2026-04-07 09:22:29 +02:00
Vitaly Kuznetsov a06992dd16 measure: make tpm_log_tagged_event() measure CC as well
tpm_log_tagged_event() only measures the event to the TPM while
tpm_log_ipl_event() measures the event both to the TPM and CC. Fix the
inconsistency.

Note, this is a potentially breaking change for TDX guests as systemd will
now measure more stuff to the MRTD/RTMRs, reference values for attestation may
need to be adjusted.

Found by Claude Code Review.
2026-03-18 12:35:21 +00:00
Vitaly Kuznetsov 4883ef8aae cryptsetup-tokens: Print tpm2-primary-alg: only when it is known
When 'tpm2-primary-alg' is missing in LUKS JSON token, the output of
'cryptsetup luksDump' is always:

	tpm2-primary-alg: ecc

because tpm2_parse_luks2_json() returns the default (TPM2_ALG_ECC). This can be
misleading and wrong. Make tpm2_parse_luks2_json() return the reality and move
the default to tpm2_unseal().
2026-02-27 14:22:22 +01:00
Vitaly Kuznetsov 295affa3f7 cryptenroll: Save primary algorithm type to the LUKS token
'tpm2-primary-alg' field is currently unset in LUKS JSON token both for the
case when SRK was used for enrolling (--tpm2-device-key=) and for the case when
SRK was obtained/generated (--tpm2-device=). While this information is not
really needed for unsealing (the sealed object itself has key type in it), it
may be convenient to see key type in e.g. 'cryptsetup luksDump' in the
situations where key type matters. Since 'tpm2-primary-alg' is already defined,
just set it properly in all cases.
2026-02-27 14:01:10 +01:00
Vitaly Kuznetsov 7a4b51ce4c TEST-58-REPART: Add a test for fstab/crypttab inclusion
Check that generated fstab/crypt are generated early and thus can
be put to the created volume.
2026-01-30 13:21:57 +01:00
Vitaly Kuznetsov 307785960b repart: Restore early generation of fstab/crypttab
Commit 15b1c33 ("repart: Generate fstab and crypttab late") moved
fstab/crypttab generation to the late stage but this introduced a regression:
it may be necessary to include fstab and crypttab into the generated partition
(e.g. with CopyFiles=). This is incompatible with 'fixate-volume-key' option as
it is impossible to capture LUKS volume key before it gets created but all the
rest should work fine.

Generate crypttab twice: early and late to capture possible changes. There's no
need to do the same for fstab for now, so keep the status quo.
2026-01-30 13:21:57 +01:00
Vitaly Kuznetsov 398acccb2a TEST-58-REPART: Add a test for fixate_folume_key
The test checks that the expected hash is correctly recorded to the
generated crypttab and also checks that systemd-cryptsetup handles
the option correctly.
2026-01-19 17:50:25 +01:00
Vitaly Kuznetsov 4754289ddf repart: Add fixate_volume_key crypttab option generation
Add an option to capture the expected LUKS volume key hash and
record it to the generated crypttab.
2026-01-19 17:50:25 +01:00
Vitaly Kuznetsov 69fab29ec4 cryptsetup: Add fixate-volume-key option to pin the expected volume key hash
The expected hash (SHA265 HMAC signature) uses the exact same algorithm which
is used to calculate sha256 PCR bank digest when 'tpm2-measure-pcr=' is used.
2026-01-19 17:49:39 +01:00
Vitaly Kuznetsov f99f843f24 tpm2-util: make tpm2_pcr_extend_bytes() declaration match its implementation
tpm2_pcr_extend_bytes() has differences in parameter names between the
declaration and the implementation, in particular, 'event' in the header is
named 'event_type' in the implementation.
2026-01-19 13:52:33 +01:00
Vitaly Kuznetsov 15b1c334df repart: Generate fstab and crypttab late
The immediate need for the change is to allow to capture the expected
LUKS volume key hash and record it to the generated crypttab but it
also seems to make sense to not generate crypttab/fstab before we know
that partition creation succeeded as fstab/crypttab entries are bogus
otherwise.
2026-01-19 11:29:00 +01:00
Vitaly Kuznetsov 9e78b1e817 TODO: add unimplemented Integrity= systemd-repart options 2025-12-18 09:12:54 +01:00
Vitaly Kuznetsov bb09cc02bd TEST-50-DISSECT: test 'encrypted' and 'encryptedwithintegrity' policies
Test the newly introduced 'encryptedwithintegrity' image policy and verify
that it's different from 'encrypted' one.
2025-12-18 09:12:54 +01:00
Vitaly Kuznetsov 771085291d dissect-image: introduce 'encryptedwithintegrity' policy
LUKS2 supports built-in integrity checking which may come very handy to
mitigate partial rollback attacks on the storage when only some specific
parts are restored to some old encrypted state. Specific use-cases like
Confidential VMs may want to mandate the usage of feature e.g. on the root
volume. Introduce "encryptedwithintegrity" image policy to support that.

Note, due to the current libcryptsetup limitations, checking whether the
feature is enabled or not for the 'file' case (e.g. DDI image as a raw file)
requires setting up a loop device. To avoid that and keep dissect fully
functional when working unpriviliged, implement a minimal custom LUKS header
parser.
2025-12-18 09:12:54 +01:00
Vitaly Kuznetsov cb2bc7575a TEST-58-REPART: add testcase for LUKS2 integrity
Create an encrypted partition with LUKS2 integrity checking enabled, verify
that dm-integrity mapping appears.
2025-12-18 09:12:54 +01:00
Vitaly Kuznetsov 1a4a34287f repart: add basic support for LUKS2 integrity verification
Authenticated disk encryption is experimentally supported by cryptsetup since
v2.0.0 and allows for automatic dm-integrity setup for LUKS devices. Add
support for the mode to systemd-repart. Currently, the option can only be used
in 'online' mode as libcryptsetup does not support creating integrity data
without the use of in-kernel dm-integrity infrastructure.

Integrity=/IntegrityAlgorithm= are added in the anticipation of other integrity
protection options, e.g. enabling dm-integrity for a plain unencrypted
partition.
2025-12-18 09:12:49 +01:00
Vitaly Kuznetsov 8d07a8d6b1 sysext: Support global sysext/confext
Load global sysext/confext from /.extra/global_{sysext,confext} which
systemd-stub puts there from ESP/loader/credentials/*.{sysext,confext}.raw.
Global extensions are handled the exact same way as per-UKI ones.
2025-07-11 13:08:26 +02:00
Vitaly Kuznetsov 9f7e3820e9 stub: Support global sysext/confext
Systemd-stub support loading addons, credentials, system and configuration
extensions from ESP and while addons and credentials can be both global and
per-UKI, sysext/confext are only per-UKI.

Add support for loading ESP/loader/credentials/*.{sysext,confext}.raw to
systemd-stub.

Note: for backwards compatibility reasons, per-UKI sysexts can also be
*.raw (not only *.sysext.raw) but as global extensions are new, there's
no need to bring this legacy there.
2025-07-11 13:08:15 +02:00
Vitaly Kuznetsov 821b453170 man/systemd-sysext: list ephemeral/ephemeral-import in the list of options
ephemeral/ephemeral-import are described as possible '--mutable' options but
not present in the list. Note, "systemd-sysext --help" lists them correctly.
2025-06-30 18:03:07 +01:00
Vitaly Kuznetsov f501830595 man: mention "overlay" as a possible option for systemd.volatile
systemd.volatile=overlay is described in the text below, however, it
is missing in the enclosed list of possible options in the beginning.
2025-04-08 02:29:29 +09:00
Vitaly Kuznetsov 803a392471 stub: restore random seed update logic
Commit 201e0d53bd ("stub: split out random seed part out of run()")
looks like refactoring but apparently it changed the logic when random
seed is refreshed in the ESP completely. Previously, process_random_seed()
was called when either:
- sd-stub was not present (LoaderFeatures var is unset) OR
- sd-stub was present but EFI_LOADER_FEATURE_RANDOM_SEED flag was unset.
Post-change, refresh_random_seed() bails under the exact same conditions (no
sd-stub or EFI_LOADER_FEATURE_RANDOM_SEED is unset) and thus
process_random_seed() is NOT called.

Restore the original logic. efivar_get_uint64_le()'s return value doesn't
require checking: loader_features is initialized to 0 and in case of failure it
stays untouched.
2024-08-28 05:10:06 +09:00
Vitaly Kuznetsov df94b28366 kernel-install/60-ukify: do not rebuild existing UKIs
In case kernel-install is called to install what's already a UKI, 60-ukify
must be skipped. E.g. when distro shipped and signed UKI is being installed,
it is counter-productive to try to rebuild it with ukify. Also, the existing
script is not ready to handle UKIs with embedded initramfs.

Note, it is already possible to disable 60-ukify by setting
KERNEL_INSTALL_UKI_GENERATOR to something but in case it is not set, 60-ukify
assumes it should run.
2024-03-26 03:01:30 +09:00
Vitaly Kuznetsov ce8dc0bd6b man: fix UKI filename suffix in 'tries' description
Boot Loader Type #2 entries (UKIs in $BOOT/EFI/Linux/) have '.efi' suffix,
not '.conf'.
2023-05-26 17:04:37 +02:00
Vitaly Kuznetsov b4e5c103be man: /usr/lib/systemd/random-seed -> /usr/lib/systemd/systemd-random-seed
/usr/lib/systemd/random-seed is not a thing.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
2023-04-25 17:05:28 +02:00
Vitaly Kuznetsov 155c51293d shared/tpm2-util: Fix "Error: Esys invalid ESAPI handle (40000001)" warning
systemd-cryptenroll complains (but succeeds!) upon binding to a signed PCR
policy:

$ systemd-cryptenroll --unlock-key-file=/tmp/passphrase --tpm2-device=auto
  --tpm2-public-key=... --tpm2-signature=..." /tmp/tmp.img

ERROR:esys:src/tss2-esys/esys_iutil.c:394:iesys_handle_to_tpm_handle() Error: Esys invalid ESAPI handle (40000001).
WARNING:esys:src/tss2-esys/esys_iutil.c:415:iesys_is_platform_handle() Convert handle from TPM2_RH to ESYS_TR, got: 0x40000001
ERROR:esys:src/tss2-esys/esys_iutil.c:394:iesys_handle_to_tpm_handle() Error: Esys invalid ESAPI handle (40000001).
WARNING:esys:src/tss2-esys/esys_iutil.c:415:iesys_is_platform_handle() Convert handle from TPM2_RH to ESYS_TR, got: 0x4000000
New TPM2 token enrolled as key slot 1.

The problem seems to be that Esys_LoadExternal() function from tpm2-tss
expects a 'ESYS_TR_RH*' constant specifying the requested hierarchy and not
a 'TPM2_RH_*' one (see Esys_LoadExternal() -> Esys_LoadExternal_Async() ->
iesys_handle_to_tpm_handle() call chain).

It all works because Esys_LoadExternal_Async() falls back to using the
supplied values when iesys_handle_to_tpm_handle() fails:

    r = iesys_handle_to_tpm_handle(hierarchy, &tpm_hierarchy);
    if (r != TSS2_RC_SUCCESS) {
        ...
        tpm_hierarchy = hierarchy;
    }

Note, TPM2_RH_OWNER was used on purpose to support older tpm2-tss versions
(pre https://github.com/tpm2-software/tpm2-tss/pull/1531), use meson magic
to preserve compatibility.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
2022-11-16 21:45:57 +01:00
Vitaly Kuznetsov 019243553d measure: fix section names in 'objcopy' example in systemd-measure man
A copy paste error has crippled in the objcopy example in 'systemd-measure'
manual,  "--change-section-vma" should reference the section being added,
not ".splash". When used as-is, the resulting UKI is unbootable.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
2022-11-14 12:31:33 +01:00