From 94d745c42c389ac2de89ca5b5e300678b9c23f84 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Fri, 15 May 2026 12:16:01 +0000 Subject: [PATCH] cryptsetup: dlopen libcryptsetup in tokens This avoids having to subpackage the tokens separately. If they link directly against libcryptsetup, package manager will automatically add a dependency on libcryptsetup to the package containing the tokens. With this change, the tokens can ship in the main systemd package without necessarily pulling in libcryptsetup. It also makes things more consistent. Once we also do the same for pam, any direct linking will be limited to just libc, which for example simplifies writing tests for ensuring we don't link unnecessarily as we don't have to add exceptions for the cryptsetup tokens. This actually drops the dependency on cryptsetup-libs for the fedora/centos/opensuse systemd-udev package so install it explicitly in the initrd now to keep the tests working. --- .../mkosi.conf.d/centos-fedora.conf | 1 + mkosi/mkosi.initrd.conf/mkosi.conf.d/opensuse.conf | 1 + .../cryptsetup-token-systemd-fido2.c | 14 +++++++++++++- .../cryptsetup-token-systemd-pkcs11.c | 14 +++++++++++++- .../cryptsetup-token-systemd-tpm2.c | 14 +++++++++++++- .../cryptsetup-tokens/cryptsetup-token-util.h | 13 ++++++------- src/cryptsetup/cryptsetup-tokens/meson.build | 8 ++++---- src/shared/cryptsetup-util.c | 2 ++ src/shared/cryptsetup-util.h | 1 + 9 files changed, 54 insertions(+), 14 deletions(-) diff --git a/mkosi/mkosi.initrd.conf/mkosi.conf.d/centos-fedora.conf b/mkosi/mkosi.initrd.conf/mkosi.conf.d/centos-fedora.conf index e753749dc4..ab64813060 100644 --- a/mkosi/mkosi.initrd.conf/mkosi.conf.d/centos-fedora.conf +++ b/mkosi/mkosi.initrd.conf/mkosi.conf.d/centos-fedora.conf @@ -8,6 +8,7 @@ Distribution=|fedora PrepareScripts=%D/mkosi/mkosi.conf.d/centos-fedora/systemd.prepare Packages= coreutils + cryptsetup-libs policycoreutils swtpm-tools tpm2-tools diff --git a/mkosi/mkosi.initrd.conf/mkosi.conf.d/opensuse.conf b/mkosi/mkosi.initrd.conf/mkosi.conf.d/opensuse.conf index c30d970c85..b863f7b2d1 100644 --- a/mkosi/mkosi.initrd.conf/mkosi.conf.d/opensuse.conf +++ b/mkosi/mkosi.initrd.conf/mkosi.conf.d/opensuse.conf @@ -9,6 +9,7 @@ Packages= btrfs-progs coreutils kmod + libcryptsetup12 policycoreutils tpm2.0-tools diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-fido2.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-fido2.c index a2804e033a..0265b2d5a0 100644 --- a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-fido2.c +++ b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-fido2.c @@ -2,6 +2,7 @@ #include #include +#include #include "sd-json.h" @@ -37,8 +38,12 @@ _public_ int cryptsetup_token_open_pin( assert(pin || pin_size == 0); assert(token >= 0); + r = dlopen_cryptsetup(LOG_DEBUG); + if (r < 0) + return r; + /* This must not fail at this moment (internal error) */ - r = crypt_token_json_get(cd, token, &json); + r = sym_crypt_token_json_get(cd, token, &json); /* Use assert_se() here to avoid emitting warning with -DNDEBUG */ assert_se(token == r); assert(json); @@ -98,6 +103,9 @@ _public_ void cryptsetup_token_dump( assert(json); + if (dlopen_cryptsetup(LOG_DEBUG) < 0) + return; + r = parse_luks2_fido2_data(cd, json, &rp_id, &salt, &salt_size, &cid, &cid_size, &required); if (r < 0) return (void) crypt_log_debug_errno(cd, r, "Failed to parse " TOKEN_NAME " metadata: %m."); @@ -162,6 +170,10 @@ _public_ int cryptsetup_token_validate( assert(json); + r = dlopen_cryptsetup(LOG_DEBUG); + if (r < 0) + return r; + r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL); if (r < 0) return crypt_log_debug_errno(cd, r, "Could not parse " TOKEN_NAME " json object: %m."); diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-pkcs11.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-pkcs11.c index 16cf910fe6..e99fcfea85 100644 --- a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-pkcs11.c +++ b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-pkcs11.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #include "sd-json.h" @@ -36,8 +37,12 @@ _public_ int cryptsetup_token_open_pin( assert(pin || pin_size == 0); assert(token >= 0); + r = dlopen_cryptsetup(LOG_DEBUG); + if (r < 0) + return r; + /* This must not fail at this moment (internal error) */ - r = crypt_token_json_get(cd, token, &json); + r = sym_crypt_token_json_get(cd, token, &json); /* Use assert_se() here to avoid emitting warning with -DNDEBUG */ assert_se(token == r); assert(json); @@ -89,6 +94,9 @@ _public_ void cryptsetup_token_dump( _cleanup_free_ char *pkcs11_uri = NULL, *key_str = NULL; _cleanup_free_ void *pkcs11_key = NULL; + if (dlopen_cryptsetup(LOG_DEBUG) < 0) + return; + r = parse_luks2_pkcs11_data(cd, json, &pkcs11_uri, &pkcs11_key, &pkcs11_key_size); if (r < 0) return (void) crypt_log_debug_errno(cd, r, "Failed to parse " TOKEN_NAME " metadata: %m."); @@ -115,6 +123,10 @@ _public_ int cryptsetup_token_validate( sd_json_variant *w; _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; + r = dlopen_cryptsetup(LOG_DEBUG); + if (r < 0) + return r; + r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL); if (r < 0) return crypt_log_debug_errno(cd, r, "Could not parse " TOKEN_NAME " json object: %m."); diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c index 58dc37c5bf..ad14942622 100644 --- a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c +++ b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-systemd-tpm2.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include +#include #include "alloc-util.h" #include "cryptsetup-token.h" @@ -60,8 +61,12 @@ _public_ int cryptsetup_token_open_pin( assert(ret_password); assert(ret_password_len); + r = dlopen_cryptsetup(LOG_DEBUG); + if (r < 0) + return r; + /* This must not fail at this moment (internal error) */ - r = crypt_token_json_get(cd, token, &json); + r = sym_crypt_token_json_get(cd, token, &json); assert(token == r); assert(json); @@ -186,6 +191,9 @@ _public_ void cryptsetup_token_dump( assert(json); + if (dlopen_cryptsetup(LOG_DEBUG) < 0) + return; + r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL); if (r < 0) return (void) crypt_log_debug_errno(cd, r, "Failed to parse " TOKEN_NAME " JSON object: %m"); @@ -275,6 +283,10 @@ _public_ int cryptsetup_token_validate( assert(json); + r = dlopen_cryptsetup(LOG_DEBUG); + if (r < 0) + return r; + r = sd_json_parse(json, SD_JSON_PARSE_MUST_BE_OBJECT, &v, /* reterr_line= */ NULL, /* reterr_column= */ NULL); if (r < 0) return crypt_log_debug_errno(cd, r, "Could not parse " TOKEN_NAME " json object: %m"); diff --git a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.h b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.h index 68b09fc458..c6a7d25f39 100644 --- a/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.h +++ b/src/cryptsetup/cryptsetup-tokens/cryptsetup-token-util.h @@ -2,22 +2,21 @@ #pragma once -#include - +#include "cryptsetup-util.h" #include "shared-forward.h" /* crypt_dump() internal indentation magic */ #define CRYPT_DUMP_LINE_SEP "\n\t " -#define crypt_log_debug(cd, ...) crypt_logf(cd, CRYPT_LOG_DEBUG, __VA_ARGS__) -#define crypt_log_error(cd, ...) crypt_logf(cd, CRYPT_LOG_ERROR, __VA_ARGS__) -#define crypt_log_verbose(cd, ...) crypt_logf(cd, CRYPT_LOG_VERBOSE, __VA_ARGS__) -#define crypt_log(cd, ...) crypt_logf(cd, CRYPT_LOG_NORMAL, __VA_ARGS__) +#define crypt_log_debug(cd, ...) sym_crypt_logf(cd, CRYPT_LOG_DEBUG, __VA_ARGS__) +#define crypt_log_error(cd, ...) sym_crypt_logf(cd, CRYPT_LOG_ERROR, __VA_ARGS__) +#define crypt_log_verbose(cd, ...) sym_crypt_logf(cd, CRYPT_LOG_VERBOSE, __VA_ARGS__) +#define crypt_log(cd, ...) sym_crypt_logf(cd, CRYPT_LOG_NORMAL, __VA_ARGS__) #define crypt_log_full_errno(cd, e, lvl, ...) ({ \ int _e = ABS(e), _s = errno; \ errno = _e; \ - crypt_logf(cd, lvl, __VA_ARGS__); \ + sym_crypt_logf(cd, lvl, __VA_ARGS__); \ errno = _s; \ -_e; \ }) diff --git a/src/cryptsetup/cryptsetup-tokens/meson.build b/src/cryptsetup/cryptsetup-tokens/meson.build index 0fd6309201..772c29f50f 100644 --- a/src/cryptsetup/cryptsetup-tokens/meson.build +++ b/src/cryptsetup/cryptsetup-tokens/meson.build @@ -45,8 +45,8 @@ modules += [ ], 'sources' : cryptsetup_token_systemd_tpm2_sources, 'dependencies' : [ - libcryptsetup, - tpm2, + libcryptsetup_cflags, + tpm2_cflags, ], }, template + { @@ -57,7 +57,7 @@ modules += [ ], 'sources' : cryptsetup_token_systemd_fido2_sources, 'dependencies' : [ - libcryptsetup, + libcryptsetup_cflags, libfido2_cflags, ], }, @@ -69,7 +69,7 @@ modules += [ ], 'sources' : cryptsetup_token_systemd_pkcs11_sources, 'dependencies' : [ - libcryptsetup, + libcryptsetup_cflags, libp11kit_cflags, ], }, diff --git a/src/shared/cryptsetup-util.c b/src/shared/cryptsetup-util.c index 7aa3d5d9c5..a51783cb29 100644 --- a/src/shared/cryptsetup-util.c +++ b/src/shared/cryptsetup-util.c @@ -45,6 +45,7 @@ DLSYM_PROTOTYPE(crypt_keyslot_destroy) = NULL; DLSYM_PROTOTYPE(crypt_keyslot_max) = NULL; DLSYM_PROTOTYPE(crypt_keyslot_status) = NULL; DLSYM_PROTOTYPE(crypt_load) = NULL; +DLSYM_PROTOTYPE(crypt_logf) = NULL; DLSYM_PROTOTYPE(crypt_metadata_locking) = NULL; DLSYM_PROTOTYPE(crypt_persistent_flags_get) = NULL; DLSYM_PROTOTYPE(crypt_persistent_flags_set) = NULL; @@ -315,6 +316,7 @@ int dlopen_cryptsetup(int log_level) { DLSYM_ARG(crypt_keyslot_max), DLSYM_ARG(crypt_keyslot_status), DLSYM_ARG(crypt_load), + DLSYM_ARG(crypt_logf), DLSYM_ARG(crypt_metadata_locking), DLSYM_ARG(crypt_persistent_flags_get), DLSYM_ARG(crypt_persistent_flags_set), diff --git a/src/shared/cryptsetup-util.h b/src/shared/cryptsetup-util.h index 5c83aad8ee..23d52d111a 100644 --- a/src/shared/cryptsetup-util.h +++ b/src/shared/cryptsetup-util.h @@ -46,6 +46,7 @@ extern DLSYM_PROTOTYPE(crypt_keyslot_destroy); extern DLSYM_PROTOTYPE(crypt_keyslot_max); extern DLSYM_PROTOTYPE(crypt_keyslot_status); extern DLSYM_PROTOTYPE(crypt_load); +extern DLSYM_PROTOTYPE(crypt_logf); extern DLSYM_PROTOTYPE(crypt_metadata_locking); extern DLSYM_PROTOTYPE(crypt_persistent_flags_get); extern DLSYM_PROTOTYPE(crypt_persistent_flags_set);