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.
This commit is contained in:
Daan De Meyer
2026-05-18 21:17:38 +00:00
parent 7d822ca8af
commit 94d745c42c
9 changed files with 54 additions and 14 deletions
@@ -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
@@ -9,6 +9,7 @@ Packages=
btrfs-progs
coreutils
kmod
libcryptsetup12
policycoreutils
tpm2.0-tools
@@ -2,6 +2,7 @@
#include <libcryptsetup.h>
#include <string.h>
#include <syslog.h>
#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.");
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <libcryptsetup.h>
#include <syslog.h>
#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.");
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <libcryptsetup.h>
#include <syslog.h>
#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");
@@ -2,22 +2,21 @@
#pragma once
#include <libcryptsetup.h>
#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; \
})
+4 -4
View File
@@ -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,
],
},
+2
View File
@@ -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),
+1
View File
@@ -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);