1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include "alloc-util.h"
5 #include "cryptsetup-util.h"
6 #include "dlfcn-util.h"
8 #include "parse-util.h"
10 static void *cryptsetup_dl
= NULL
;
12 int (*sym_crypt_activate_by_passphrase
)(struct crypt_device
*cd
, const char *name
, int keyslot
, const char *passphrase
, size_t passphrase_size
, uint32_t flags
);
13 #if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
14 int (*sym_crypt_activate_by_signed_key
)(struct crypt_device
*cd
, const char *name
, const char *volume_key
, size_t volume_key_size
, const char *signature
, size_t signature_size
, uint32_t flags
);
16 int (*sym_crypt_activate_by_volume_key
)(struct crypt_device
*cd
, const char *name
, const char *volume_key
, size_t volume_key_size
, uint32_t flags
);
17 int (*sym_crypt_deactivate_by_name
)(struct crypt_device
*cd
, const char *name
, uint32_t flags
);
18 int (*sym_crypt_format
)(struct crypt_device
*cd
, const char *type
, const char *cipher
, const char *cipher_mode
, const char *uuid
, const char *volume_key
, size_t volume_key_size
, void *params
);
19 void (*sym_crypt_free
)(struct crypt_device
*cd
);
20 const char *(*sym_crypt_get_dir
)(void);
21 int (*sym_crypt_get_verity_info
)(struct crypt_device
*cd
, struct crypt_params_verity
*vp
);
22 int (*sym_crypt_init
)(struct crypt_device
**cd
, const char *device
);
23 int (*sym_crypt_init_by_name
)(struct crypt_device
**cd
, const char *name
);
24 int (*sym_crypt_keyslot_add_by_volume_key
)(struct crypt_device
*cd
, int keyslot
, const char *volume_key
, size_t volume_key_size
, const char *passphrase
, size_t passphrase_size
);
25 int (*sym_crypt_load
)(struct crypt_device
*cd
, const char *requested_type
, void *params
);
26 int (*sym_crypt_resize
)(struct crypt_device
*cd
, const char *name
, uint64_t new_size
);
27 int (*sym_crypt_set_data_device
)(struct crypt_device
*cd
, const char *device
);
28 void (*sym_crypt_set_debug_level
)(int level
);
29 void (*sym_crypt_set_log_callback
)(struct crypt_device
*cd
, void (*log
)(int level
, const char *msg
, void *usrptr
), void *usrptr
);
30 int (*sym_crypt_set_pbkdf_type
)(struct crypt_device
*cd
, const struct crypt_pbkdf_type
*pbkdf
) = NULL
;
31 int (*sym_crypt_token_json_get
)(struct crypt_device
*cd
, int token
, const char **json
) = NULL
;
32 int (*sym_crypt_token_json_set
)(struct crypt_device
*cd
, int token
, const char *json
) = NULL
;
33 int (*sym_crypt_volume_key_get
)(struct crypt_device
*cd
, int keyslot
, char *volume_key
, size_t *volume_key_size
, const char *passphrase
, size_t passphrase_size
);
34 #if HAVE_CRYPT_TOKEN_MAX
35 int (*sym_crypt_token_max
)(const char *type
);
38 int dlopen_cryptsetup(void) {
39 _cleanup_(dlclosep
) void *dl
= NULL
;
43 return 0; /* Already loaded */
45 dl
= dlopen("libcryptsetup.so.12", RTLD_LAZY
);
47 return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP
),
48 "libcryptsetup support is not installed: %s", dlerror());
50 r
= dlsym_many_and_warn(
53 DLSYM_ARG(crypt_activate_by_passphrase
),
54 #if HAVE_CRYPT_ACTIVATE_BY_SIGNED_KEY
55 DLSYM_ARG(crypt_activate_by_signed_key
),
57 DLSYM_ARG(crypt_activate_by_volume_key
),
58 DLSYM_ARG(crypt_deactivate_by_name
),
59 DLSYM_ARG(crypt_format
),
60 DLSYM_ARG(crypt_free
),
61 DLSYM_ARG(crypt_get_dir
),
62 DLSYM_ARG(crypt_get_verity_info
),
63 DLSYM_ARG(crypt_init
),
64 DLSYM_ARG(crypt_init_by_name
),
65 DLSYM_ARG(crypt_keyslot_add_by_volume_key
),
66 DLSYM_ARG(crypt_load
),
67 DLSYM_ARG(crypt_resize
),
68 DLSYM_ARG(crypt_set_data_device
),
69 DLSYM_ARG(crypt_set_debug_level
),
70 DLSYM_ARG(crypt_set_log_callback
),
71 DLSYM_ARG(crypt_set_pbkdf_type
),
72 DLSYM_ARG(crypt_token_json_get
),
73 DLSYM_ARG(crypt_token_json_set
),
74 DLSYM_ARG(crypt_volume_key_get
),
75 #if HAVE_CRYPT_TOKEN_MAX
76 DLSYM_ARG(crypt_token_max
),
82 /* Note that we never release the reference here, because there's no real reason to, after all this
83 * was traditionally a regular shared library dependency which lives forever too. */
84 cryptsetup_dl
= TAKE_PTR(dl
);
88 static void cryptsetup_log_glue(int level
, const char *msg
, void *usrptr
) {
91 case CRYPT_LOG_NORMAL
:
97 case CRYPT_LOG_VERBOSE
:
100 case CRYPT_LOG_DEBUG
:
104 log_error("Unknown libcryptsetup log level: %d", level
);
108 log_full(level
, "%s", msg
);
111 void cryptsetup_enable_logging(struct crypt_device
*cd
) {
115 if (dlopen_cryptsetup() < 0) /* If this fails, let's gracefully ignore the issue, this is just debug
116 * logging after all, and if this failed we already generated a debug
117 * log message that should help to track things down. */
120 sym_crypt_set_log_callback(cd
, cryptsetup_log_glue
, NULL
);
121 sym_crypt_set_debug_level(DEBUG_LOGGING
? CRYPT_DEBUG_ALL
: CRYPT_DEBUG_NONE
);
124 int cryptsetup_set_minimal_pbkdf(struct crypt_device
*cd
) {
126 /* With CRYPT_PBKDF_NO_BENCHMARK flag set .time_ms member is ignored
127 * while .iterations must be set at least to recommended minimum value. */
129 static const struct crypt_pbkdf_type minimal_pbkdf
= {
131 .type
= CRYPT_KDF_PBKDF2
,
132 .iterations
= 1000, /* recommended minimum count for pbkdf2
133 * according to NIST SP 800-132, ch. 5.2 */
134 .flags
= CRYPT_PBKDF_NO_BENCHMARK
139 /* Sets a minimal PKBDF in case we already have a high entropy key. */
141 r
= dlopen_cryptsetup();
145 r
= sym_crypt_set_pbkdf_type(cd
, &minimal_pbkdf
);
152 int cryptsetup_get_token_as_json(
153 struct crypt_device
*cd
,
155 const char *verify_type
,
158 _cleanup_(json_variant_unrefp
) JsonVariant
*v
= NULL
;
164 /* Extracts and parses the LUKS2 JSON token data from a LUKS2 device. Optionally verifies the type of
165 * the token. Returns:
167 * -EINVAL → token index out of range or "type" field missing
168 * -ENOENT → token doesn't exist
169 * -EMEDIUMTYPE → "verify_type" specified and doesn't match token's type
172 r
= dlopen_cryptsetup();
176 r
= sym_crypt_token_json_get(cd
, idx
, &text
);
180 r
= json_parse(text
, 0, &v
, NULL
, NULL
);
187 w
= json_variant_by_key(v
, "type");
191 if (!streq_ptr(json_variant_string(w
), verify_type
))
201 int cryptsetup_get_keyslot_from_token(JsonVariant
*v
) {
205 /* Parses the "keyslots" field of a LUKS2 token object. The field can be an array, but here we assume
206 * that it contains a single element only, since that's the only way we ever generate it
209 w
= json_variant_by_key(v
, "keyslots");
212 if (!json_variant_is_array(w
) || json_variant_elements(w
) != 1)
215 w
= json_variant_by_index(w
, 0);
218 if (!json_variant_is_string(w
))
221 r
= safe_atoi(json_variant_string(w
), &keyslot
);
230 int cryptsetup_add_token_json(struct crypt_device
*cd
, JsonVariant
*v
) {
231 _cleanup_free_
char *text
= NULL
;
234 r
= dlopen_cryptsetup();
238 r
= json_variant_format(v
, 0, &text
);
240 return log_debug_errno(r
, "Failed to format token data for LUKS: %m");
242 log_debug("Adding token text <%s>", text
);
244 r
= sym_crypt_token_json_set(cd
, CRYPT_ANY_TOKEN
, text
);
246 return log_debug_errno(r
, "Failed to write token data to LUKS: %m");