• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 26856653518

02 Jun 2026 04:05PM UTC coverage: 72.884% (-0.1%) from 72.979%
26856653518

push

github

web-flow
Add DLOPEN macros that stamp the caller's ELF and use it to ensure executables list their dlopen dependencies (#42398)

Currently almost all the dlopens happen in libbasic or libshared code,
so the ELF dlopen notes all end up in libsystemd-shared. Many
distributions split this library and various binaries in separate
packages, and the library ends up with soft-dependencies, even though
many binaries are either completely useless or do not work at all with
the dlopen dependency. This also makes it impossible to know which
executable uses which dlopen dependency without inspecting the source
code.

If someone only wants to add the soft dependencies from libshared they
can just avoid parsing the executable binaries. By design the code in
libbasic/libshared still does the stamping too, at lower priorities, so
that libsystemd-shared will always list all the optional dependencies,
and if one wants to build a minimal system by default, they can just
parse libsystemd-shared dlopen notes, and ignore the individual
executables. But for many distribution the current setup is insufficient
and requires adding a ton of manual library dependencies, as many
executables become effectively broken or useless without the dlopen
dependencies installed (eg: resolved fails to start without libssl,
repart can do basically nothing without blkid, etc).

Add a new set of DLOPEN_<LIB> macros that wrap the dlopen_lib and also
pull in the ELF note voodoo, so that the callers get their ELF binaries
stamped too. Convert a bunch of callers to use the macro, and use
`required` dependencies for the callers that do not work without the
dlopen library being available.

The one caveat is that, in order to avoid duplicating the exact same
note in a binary due to multiple call sites, some `asm` voodoo is done
instead of the previous bare-C section-creating macro. The drawback of
this approach is that if `--gc-sections` is used to link the binary (as
we do), then binutils >= 2.36 is required... (continued)

112 of 145 new or added lines in 78 files covered. (77.24%)

1126 existing lines in 53 files now uncovered.

336961 of 462328 relevant lines covered (72.88%)

1288046.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

45.41
/src/cryptsetup/cryptsetup.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <sys/mman.h>
4
#include <sys/stat.h>
5
#include <unistd.h>
6

7
#include "sd-device.h"
8
#include "sd-event.h"
9
#include "sd-json.h"
10
#include "sd-messages.h"
11

12
#include "alloc-util.h"
13
#include "ask-password-api.h"
14
#include "build.h"
15
#include "crypto-util.h"
16
#include "cryptsetup-fido2.h"
17
#include "cryptsetup-keyfile.h"
18
#include "cryptsetup-pkcs11.h"
19
#include "cryptsetup-tpm2.h"
20
#include "cryptsetup-util.h"
21
#include "efi-api.h"
22
#include "efi-loader.h"
23
#include "efivars.h"
24
#include "env-util.h"
25
#include "errno-util.h"
26
#include "escape.h"
27
#include "extract-word.h"
28
#include "fileio.h"
29
#include "format-table.h"
30
#include "fs-util.h"
31
#include "hexdecoct.h"
32
#include "json-util.h"
33
#include "libfido2-util.h"
34
#include "libmount-util.h"
35
#include "log.h"
36
#include "main-func.h"
37
#include "memory-util.h"
38
#include "nulstr-util.h"
39
#include "options.h"
40
#include "parse-util.h"
41
#include "path-util.h"
42
#include "pkcs11-util.h"
43
#include "pretty-print.h"
44
#include "process-util.h"
45
#include "random-util.h"
46
#include "string-table.h"
47
#include "string-util.h"
48
#include "strv.h"
49
#include "time-util.h"
50
#include "tpm2-pcr.h"
51
#include "tpm2-util.h"
52
#include "verbs.h"
53

54
/* internal helper */
55
#define ANY_LUKS "LUKS"
56
/* as in src/cryptsetup.h */
57
#define CRYPT_SECTOR_SIZE 512U
58
#define CRYPT_MAX_SECTOR_SIZE 4096U
59

60
typedef enum PassphraseType {
61
        PASSPHRASE_NONE,
62
        PASSPHRASE_REGULAR = 1 << 0,
63
        PASSPHRASE_RECOVERY_KEY = 1 << 1,
64
        PASSPHRASE_BOTH = PASSPHRASE_REGULAR|PASSPHRASE_RECOVERY_KEY,
65
        _PASSPHRASE_TYPE_MAX,
66
        _PASSPHRASE_TYPE_INVALID = -1,
67
} PassphraseType;
68

69
typedef enum TokenType {
70
        TOKEN_TPM2,
71
        TOKEN_FIDO2,
72
        TOKEN_PKCS11,
73
        _TOKEN_TYPE_MAX,
74
        _TOKEN_TYPE_INVALID = -EINVAL,
75
} TokenType;
76

77
static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT, CRYPT_BITLK or CRYPT_PLAIN */
78
static char *arg_cipher = NULL;
79
static unsigned arg_key_size = 0;
80
static unsigned arg_sector_size = CRYPT_SECTOR_SIZE;
81
static int arg_key_slot = CRYPT_ANY_SLOT;
82
static unsigned arg_keyfile_size = 0;
83
static uint64_t arg_keyfile_offset = 0;
84
static bool arg_keyfile_erase = false;
85
static bool arg_try_empty_password = false;
86
static char *arg_hash = NULL;
87
static char *arg_header = NULL;
88
static unsigned arg_tries = 3;
89
static bool arg_readonly = false;
90
static bool arg_verify = false;
91
static bool arg_password_cache_set = false; /* Not the actual argument value, just an indicator that some value is set */
92
static AskPasswordFlags arg_ask_password_flags = ASK_PASSWORD_ACCEPT_CACHED | ASK_PASSWORD_PUSH_CACHE;
93
static bool arg_discards = false;
94
static bool arg_same_cpu_crypt = false;
95
static bool arg_submit_from_crypt_cpus = false;
96
static bool arg_no_read_workqueue = false;
97
static bool arg_no_write_workqueue = false;
98
static bool arg_tcrypt_hidden = false;
99
static bool arg_tcrypt_system = false;
100
static bool arg_tcrypt_veracrypt = false;
101
static uint32_t arg_tcrypt_veracrypt_pim = 0;
102
static char **arg_tcrypt_keyfiles = NULL;
103
static uint64_t arg_offset = 0;
104
static uint64_t arg_skip = 0;
105
static usec_t arg_timeout = USEC_INFINITY;
106
static char *arg_pkcs11_uri = NULL;
107
static bool arg_pkcs11_uri_auto = false;
108
static char *arg_fido2_device = NULL;
109
static bool arg_fido2_device_auto = false;
110
static void *arg_fido2_cid = NULL;
111
static size_t arg_fido2_cid_size = 0;
112
static char *arg_fido2_rp_id = NULL;
113
/* For now and for compatibility, if the user explicitly configured FIDO2 support and we do
114
 * not read FIDO2 metadata off the LUKS2 header, default to the systemd 248 logic, where we
115
 * use PIN + UP when needed, and do not configure UV at all. */
116
static Fido2EnrollFlags arg_fido2_manual_flags = FIDO2ENROLL_PIN_IF_NEEDED | FIDO2ENROLL_UP_IF_NEEDED | FIDO2ENROLL_UV_OMIT;
117
static char *arg_tpm2_device = NULL; /* These and the following fields are about locking an encrypted volume to the local TPM */
118
static bool arg_tpm2_device_auto = false;
119
static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
120
static char *arg_tpm2_signature = NULL;
121
static bool arg_tpm2_pin = false;
122
static char *arg_tpm2_pcrlock = NULL;
123
static usec_t arg_token_timeout_usec = 30*USEC_PER_SEC;
124
static unsigned arg_tpm2_measure_pcr = UINT_MAX; /* This and the following field is about measuring the unlocked volume key to the local TPM */
125
static char **arg_tpm2_measure_banks = NULL;
126
static char *arg_tpm2_measure_keyslot_nvpcr = NULL;
127
static char *arg_link_keyring = NULL;
128
static char *arg_link_key_type = NULL;
129
static char *arg_link_key_description = NULL;
130
static char *arg_fixate_volume_key = NULL;
131

132
STATIC_DESTRUCTOR_REGISTER(arg_cipher, freep);
147✔
133
STATIC_DESTRUCTOR_REGISTER(arg_hash, freep);
147✔
134
STATIC_DESTRUCTOR_REGISTER(arg_header, freep);
147✔
135
STATIC_DESTRUCTOR_REGISTER(arg_tcrypt_keyfiles, strv_freep);
147✔
136
STATIC_DESTRUCTOR_REGISTER(arg_pkcs11_uri, freep);
147✔
137
STATIC_DESTRUCTOR_REGISTER(arg_fido2_device, freep);
147✔
138
STATIC_DESTRUCTOR_REGISTER(arg_fido2_cid, freep);
147✔
139
STATIC_DESTRUCTOR_REGISTER(arg_fido2_rp_id, freep);
147✔
140
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
147✔
141
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_signature, freep);
147✔
142
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_measure_banks, strv_freep);
147✔
143
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_measure_keyslot_nvpcr, freep);
147✔
144
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_pcrlock, freep);
147✔
145
STATIC_DESTRUCTOR_REGISTER(arg_link_keyring, freep);
147✔
146
STATIC_DESTRUCTOR_REGISTER(arg_link_key_type, freep);
147✔
147
STATIC_DESTRUCTOR_REGISTER(arg_link_key_description, freep);
147✔
148
STATIC_DESTRUCTOR_REGISTER(arg_fixate_volume_key, freep);
147✔
149

150
static const char* const passphrase_type_table[_PASSPHRASE_TYPE_MAX] = {
151
        [PASSPHRASE_REGULAR]      = "passphrase",
152
        [PASSPHRASE_RECOVERY_KEY] = "recovery key",
153
        [PASSPHRASE_BOTH]         = "passphrase or recovery key",
154
};
155

156
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(passphrase_type, PassphraseType);
×
157

158
static const char* const token_type_table[_TOKEN_TYPE_MAX] = {
159
        [TOKEN_TPM2]   = "tpm2",
160
        [TOKEN_FIDO2]  = "fido2",
161
        [TOKEN_PKCS11] = "pkcs11",
162
};
163

164
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(token_type, TokenType);
54✔
165

166
/* Options Debian's crypttab knows we don't:
167
    check=
168
    checkargs=
169
    noearly
170
    loud
171
    quiet
172
    keyscript=
173
    initramfs
174
*/
175

176
static int parse_one_option(const char *option) {
159✔
177
        const char *val;
159✔
178
        int r;
159✔
179

180
        assert(option);
159✔
181

182
        /* Handled outside of this tool */
183
        if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail", "_netdev", "keyfile-timeout"))
159✔
184
                return 0;
1✔
185

186
        if (startswith(option, "keyfile-timeout="))
158✔
187
                return 0;
188

189
        if ((val = startswith(option, "cipher="))) {
158✔
190
                r = free_and_strdup(&arg_cipher, val);
×
191
                if (r < 0)
×
192
                        return log_oom();
×
193

194
        } else if ((val = startswith(option, "size="))) {
158✔
195

196
                r = safe_atou(val, &arg_key_size);
×
197
                if (r < 0) {
×
198
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
199
                        return 0;
200
                }
201

202
                if (arg_key_size % 8) {
×
203
                        log_warning("size= not a multiple of 8, ignoring.");
×
204
                        return 0;
205
                }
206

207
                arg_key_size /= 8;
×
208

209
        } else if ((val = startswith(option, "sector-size="))) {
158✔
210

211
                r = safe_atou(val, &arg_sector_size);
×
212
                if (r < 0) {
×
213
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
214
                        return 0;
215
                }
216

217
                if (arg_sector_size % 2) {
×
218
                        log_warning("sector-size= not a multiple of 2, ignoring.");
×
219
                        return 0;
220
                }
221

222
                if (arg_sector_size < CRYPT_SECTOR_SIZE || arg_sector_size > CRYPT_MAX_SECTOR_SIZE)
×
223
                        log_warning("sector-size= is outside of %u and %u, ignoring.", CRYPT_SECTOR_SIZE, CRYPT_MAX_SECTOR_SIZE);
×
224

225
        } else if ((val = startswith(option, "key-slot=")) ||
158✔
226
                   (val = startswith(option, "keyslot="))) {
156✔
227

228
                arg_type = ANY_LUKS;
2✔
229
                r = safe_atoi(val, &arg_key_slot);
2✔
230
                if (r < 0)
2✔
231
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
232

233
        } else if ((val = startswith(option, "tcrypt-keyfile="))) {
156✔
234

235
                arg_type = CRYPT_TCRYPT;
×
236
                if (path_is_absolute(val)) {
×
237
                        if (strv_extend(&arg_tcrypt_keyfiles, val) < 0)
×
238
                                return log_oom();
×
239
                } else
240
                        log_warning("Key file path \"%s\" is not absolute, ignoring.", val);
×
241

242
        } else if ((val = startswith(option, "keyfile-size="))) {
156✔
243

244
                r = safe_atou(val, &arg_keyfile_size);
3✔
245
                if (r < 0)
3✔
246
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
247

248
        } else if ((val = startswith(option, "keyfile-offset="))) {
153✔
249

250
                r = safe_atou64(val, &arg_keyfile_offset);
5✔
251
                if (r < 0)
5✔
252
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
253

254
        } else if ((val = startswith(option, "keyfile-erase="))) {
148✔
255

256
                r = parse_boolean(val);
2✔
257
                if (r < 0) {
2✔
258
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
259
                        return 0;
260
                }
261

262
                arg_keyfile_erase = r;
2✔
263

264
        } else if (streq(option, "keyfile-erase"))
146✔
265
                arg_keyfile_erase = true;
×
266

267
        else if ((val = startswith(option, "hash="))) {
146✔
268
                r = free_and_strdup(&arg_hash, val);
×
269
                if (r < 0)
×
270
                        return log_oom();
×
271

272
        } else if ((val = startswith(option, "header="))) {
146✔
273
                if (!arg_type || !STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT))
9✔
274
                        arg_type = ANY_LUKS;
7✔
275

276
                if (!path_is_absolute(val))
9✔
277
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
278
                                               "Header path \"%s\" is not absolute, refusing.", val);
279

280
                if (arg_header)
9✔
281
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
282
                                               "Duplicate header= option, refusing.");
283

284
                arg_header = strdup(val);
9✔
285
                if (!arg_header)
9✔
286
                        return log_oom();
×
287

288
        } else if ((val = startswith(option, "tries="))) {
137✔
289

290
                r = safe_atou(val, &arg_tries);
×
291
                if (r < 0)
×
292
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
159✔
293

294
        } else if (STR_IN_SET(option, "readonly", "read-only"))
137✔
295
                arg_readonly = true;
×
296
        else if (streq(option, "verify"))
137✔
297
                arg_verify = true;
×
298
        else if ((val = startswith(option, "password-echo="))) {
137✔
299
                if (streq(val, "masked"))
×
300
                        arg_ask_password_flags &= ~(ASK_PASSWORD_ECHO|ASK_PASSWORD_SILENT);
×
301
                else {
302
                        r = parse_boolean(val);
×
303
                        if (r < 0) {
×
304
                                log_warning_errno(r, "Invalid password-echo= option \"%s\", ignoring.", val);
×
305
                                return 0;
×
306
                        }
307

308
                        SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_ECHO, r);
×
309
                        SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_SILENT, !r);
×
310
                }
311
        } else if ((val = startswith(option, "password-cache="))) {
137✔
312
                arg_password_cache_set = true;
×
313

314
                if (streq(val, "read-only")) {
×
315
                        arg_ask_password_flags |= ASK_PASSWORD_ACCEPT_CACHED;
×
316
                        arg_ask_password_flags &= ~ASK_PASSWORD_PUSH_CACHE;
×
317
                } else {
318
                        r = parse_boolean(val);
×
319
                        if (r < 0) {
×
320
                                log_warning_errno(r, "Invalid password-cache= option \"%s\", ignoring.", val);
×
321
                                return 0;
322
                        }
323

324
                        SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_ACCEPT_CACHED|ASK_PASSWORD_PUSH_CACHE, r);
×
325
                }
326
        } else if (STR_IN_SET(option, "allow-discards", "discard"))
137✔
327
                arg_discards = true;
×
328
        else if (streq(option, "same-cpu-crypt"))
137✔
329
                arg_same_cpu_crypt = true;
×
330
        else if (streq(option, "submit-from-crypt-cpus"))
137✔
331
                arg_submit_from_crypt_cpus = true;
×
332
        else if (streq(option, "no-read-workqueue"))
137✔
333
                arg_no_read_workqueue = true;
×
334
        else if (streq(option, "no-write-workqueue"))
137✔
335
                arg_no_write_workqueue = true;
×
336
        else if (streq(option, "luks"))
137✔
337
                arg_type = ANY_LUKS;
8✔
338
        else if (streq(option, "bitlk"))
129✔
339
                arg_type = CRYPT_BITLK;
×
340
        else if (streq(option, "tcrypt"))
129✔
341
                arg_type = CRYPT_TCRYPT;
×
342
        else if (STR_IN_SET(option, "tcrypt-hidden", "tcrypthidden")) {
129✔
343
                arg_type = CRYPT_TCRYPT;
×
344
                arg_tcrypt_hidden = true;
×
345
        } else if (streq(option, "tcrypt-system")) {
129✔
346
                arg_type = CRYPT_TCRYPT;
×
347
                arg_tcrypt_system = true;
×
348
        } else if (STR_IN_SET(option, "tcrypt-veracrypt", "veracrypt")) {
129✔
349
                arg_type = CRYPT_TCRYPT;
×
350
                arg_tcrypt_veracrypt = true;
×
351
        } else if ((val = startswith(option, "veracrypt-pim="))) {
129✔
352

353
                r = safe_atou32(val, &arg_tcrypt_veracrypt_pim);
×
354
                if (r < 0) {
×
355
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
356
                        return 0;
×
357
                }
358
        } else if (STR_IN_SET(option, "plain", "swap", "tmp") ||
258✔
359
                   startswith(option, "tmp="))
129✔
360
                arg_type = CRYPT_PLAIN;
×
361
        else if ((val = startswith(option, "timeout="))) {
129✔
362

363
                r = parse_sec_fix_0(val, &arg_timeout);
×
364
                if (r < 0)
×
365
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
366

367
        } else if ((val = startswith(option, "offset="))) {
129✔
368

369
                r = safe_atou64(val, &arg_offset);
×
370
                if (r < 0)
×
371
                        return log_error_errno(r, "Failed to parse %s: %m", option);
×
372

373
        } else if ((val = startswith(option, "skip="))) {
129✔
374

375
                r = safe_atou64(val, &arg_skip);
×
376
                if (r < 0)
×
377
                        return log_error_errno(r, "Failed to parse %s: %m", option);
×
378

379
        } else if ((val = startswith(option, "pkcs11-uri="))) {
129✔
380

381
                if (streq(val, "auto")) {
9✔
382
                        arg_pkcs11_uri = mfree(arg_pkcs11_uri);
9✔
383
                        arg_pkcs11_uri_auto = true;
9✔
384
                } else {
385
                        if (!pkcs11_uri_valid(val))
×
386
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "pkcs11-uri= parameter expects a PKCS#11 URI, refusing.");
×
387

388
                        r = free_and_strdup(&arg_pkcs11_uri, val);
×
389
                        if (r < 0)
×
390
                                return log_oom();
×
391

392
                        arg_pkcs11_uri_auto = false;
×
393
                }
394

395
        } else if ((val = startswith(option, "fido2-device="))) {
120✔
396

397
                if (streq(val, "auto")) {
×
398
                        arg_fido2_device = mfree(arg_fido2_device);
×
399
                        arg_fido2_device_auto = true;
×
400
                } else {
401
                        r = free_and_strdup(&arg_fido2_device, val);
×
402
                        if (r < 0)
×
403
                                return log_oom();
×
404

405
                        arg_fido2_device_auto = false;
×
406
                }
407

408
        } else if ((val = startswith(option, "fido2-cid="))) {
120✔
409

410
                if (streq(val, "auto"))
×
411
                        arg_fido2_cid = mfree(arg_fido2_cid);
×
412
                else {
413
                        _cleanup_free_ void *cid = NULL;
×
414
                        size_t cid_size;
×
415

416
                        r = unbase64mem(val, &cid, &cid_size);
×
417
                        if (r < 0)
×
418
                                return log_error_errno(r, "Failed to decode FIDO2 CID data: %m");
×
419

420
                        free(arg_fido2_cid);
×
421
                        arg_fido2_cid = TAKE_PTR(cid);
×
422
                        arg_fido2_cid_size = cid_size;
×
423
                }
424

425
                /* Turn on FIDO2 as side-effect, if not turned on yet. */
426
                if (!arg_fido2_device && !arg_fido2_device_auto)
×
427
                        arg_fido2_device_auto = true;
×
428

429
        } else if ((val = startswith(option, "fido2-rp="))) {
120✔
430

431
                r = free_and_strdup(&arg_fido2_rp_id, val);
×
432
                if (r < 0)
×
433
                        return log_oom();
×
434

435
        } else if ((val = startswith(option, "fido2-pin="))) {
120✔
436

437
                r = parse_boolean(val);
×
438
                if (r < 0) {
×
439
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
440
                        return 0;
441
                }
442

443
                arg_fido2_manual_flags &= ~FIDO2ENROLL_PIN_IF_NEEDED;
×
444
                SET_FLAG(arg_fido2_manual_flags, FIDO2ENROLL_PIN, r);
×
445

446
        } else if ((val = startswith(option, "fido2-up="))) {
120✔
447

448
                r = parse_boolean(val);
×
449
                if (r < 0) {
×
450
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
451
                        return 0;
452
                }
453

454
                arg_fido2_manual_flags &= ~FIDO2ENROLL_UP_IF_NEEDED;
×
455
                SET_FLAG(arg_fido2_manual_flags, FIDO2ENROLL_UP, r);
×
456

457
        } else if ((val = startswith(option, "fido2-uv="))) {
120✔
458

459
                r = parse_boolean(val);
×
460
                if (r < 0) {
×
461
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
462
                        return 0;
463
                }
464

465
                arg_fido2_manual_flags &= ~FIDO2ENROLL_UV_OMIT;
×
466
                SET_FLAG(arg_fido2_manual_flags, FIDO2ENROLL_UV, r);
×
467

468
        } else if ((val = startswith(option, "tpm2-device="))) {
120✔
469

470
                if (streq(val, "auto")) {
41✔
471
                        arg_tpm2_device = mfree(arg_tpm2_device);
41✔
472
                        arg_tpm2_device_auto = true;
41✔
473
                } else {
474
                        r = free_and_strdup(&arg_tpm2_device, val);
×
475
                        if (r < 0)
×
476
                                return log_oom();
×
477

478
                        arg_tpm2_device_auto = false;
×
479
                }
480

481
        } else if ((val = startswith(option, "tpm2-pcrs="))) {
79✔
482

483
                r = tpm2_parse_pcr_argument_to_mask(val, &arg_tpm2_pcr_mask);
×
484
                if (r < 0)
×
485
                        return r;
486

487
        } else if ((val = startswith(option, "tpm2-signature="))) {
79✔
488

489
                if (!path_is_absolute(val))
1✔
490
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
491
                                               "TPM2 signature path \"%s\" is not absolute, refusing.", val);
492

493
                r = free_and_strdup(&arg_tpm2_signature, val);
1✔
494
                if (r < 0)
1✔
495
                        return log_oom();
×
496

497
        } else if ((val = startswith(option, "tpm2-pin="))) {
78✔
498

499
                r = parse_boolean(val);
×
500
                if (r < 0) {
×
501
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
502
                        return 0;
503
                }
504

505
                arg_tpm2_pin = r;
×
506

507
        } else if ((val = startswith(option, "tpm2-pcrlock="))) {
78✔
508

509
                if (!path_is_absolute(val))
5✔
510
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
511
                                               "TPM2 pcrlock policy path \"%s\" is not absolute, refusing.", val);
512

513
                r = free_and_strdup(&arg_tpm2_pcrlock, val);
5✔
514
                if (r < 0)
5✔
515
                        return log_oom();
×
516

517
        } else if ((val = startswith(option, "tpm2-measure-pcr="))) {
73✔
518
                unsigned pcr;
×
519

520
                r = safe_atou(val, &pcr);
×
521
                if (r < 0) {
×
522
                        r = parse_boolean(val);
×
523
                        if (r < 0) {
×
524
                                log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
525
                                return 0;
×
526
                        }
527

528
                        pcr = r ? TPM2_PCR_SYSTEM_IDENTITY : UINT_MAX;
×
529
                } else if (!TPM2_PCR_INDEX_VALID(pcr)) {
×
530
                        log_warning("Selected TPM index for measurement %u outside of allowed range 0…%u, ignoring.", pcr, TPM2_PCRS_MAX-1);
×
531
                        return 0;
532
                }
533

534
                arg_tpm2_measure_pcr = pcr;
×
535

536
        } else if ((val = startswith(option, "tpm2-measure-bank="))) {
73✔
537

538
#if HAVE_OPENSSL
539
                _cleanup_strv_free_ char **l = NULL;
×
540

NEW
541
                r = DLOPEN_LIBCRYPTO(LOG_ERR, SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED);
×
542
                if (r < 0)
×
543
                        return r;
544

545
                l = strv_split(val, ":");
×
546
                if (!l)
×
547
                        return log_oom();
×
548

549
                STRV_FOREACH(i, l) {
×
550
                        const EVP_MD *implementation;
×
551

552
                        implementation = sym_EVP_get_digestbyname(*i);
×
553
                        if (!implementation)
×
554
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", val);
×
555

556
                        if (strv_extend(&arg_tpm2_measure_banks, sym_EVP_MD_get0_name(implementation)) < 0)
×
557
                                return log_oom();
×
558
                }
559
#else
560
                log_error("Build lacks OpenSSL support, cannot measure to PCR banks, ignoring: %s", option);
561
#endif
562

563
        } else if ((val = startswith(option, "tpm2-measure-keyslot-nvpcr="))) {
73✔
564

565
                r = isempty(val) ? false : parse_boolean(val);
×
566
                if (r == 0) {
×
567
                        arg_tpm2_measure_keyslot_nvpcr = mfree(arg_tpm2_measure_keyslot_nvpcr);
×
568
                        return 0;
×
569
                }
570
                if (r > 0)
×
571
                        val = "cryptsetup";
572
                else if (!tpm2_nvpcr_name_is_valid(val)) {
×
573
                        log_warning("Invalid NvPCR name, ignoring: %s", option);
×
574
                        return 0;
575
                }
576

577
                if (free_and_strdup(&arg_tpm2_measure_keyslot_nvpcr, val) < 0)
×
578
                        return log_oom();
×
579

580
        } else if ((val = startswith(option, "try-empty-password="))) {
73✔
581

582
                r = parse_boolean(val);
1✔
583
                if (r < 0) {
1✔
584
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
585
                        return 0;
586
                }
587

588
                arg_try_empty_password = r;
1✔
589

590
        } else if (streq(option, "try-empty-password"))
72✔
591
                arg_try_empty_password = true;
1✔
592
        else if ((val = startswith(option, "headless="))) {
71✔
593

594
                r = parse_boolean(val);
60✔
595
                if (r < 0) {
60✔
596
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
597
                        return 0;
598
                }
599

600
                SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_HEADLESS, r);
60✔
601
        } else if (streq(option, "headless"))
11✔
602
                arg_ask_password_flags |= ASK_PASSWORD_HEADLESS;
7✔
603

604
        else if ((val = startswith(option, "token-timeout="))) {
4✔
605

606
                r = parse_sec_fix_0(val, &arg_token_timeout_usec);
×
607
                if (r < 0)
×
608
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
129✔
609

610
        } else if ((val = startswith(option, "link-volume-key="))) {
4✔
611
                _cleanup_free_ char *keyring = NULL, *key_type = NULL, *key_description = NULL;
×
612
                const char *sep;
×
613

614
                /* Stick with cryptsetup --link-vk-to-keyring format
615
                 * <keyring_description>::%<key_type>:<key_description>,
616
                 * where %<key_type> is optional and defaults to 'user'.
617
                 */
618
                sep = strstr(val, "::");
×
619
                if (!sep)
×
620
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse link-volume-key= option value: %s", val);
×
621

622
                /* cryptsetup (cli) supports <keyring_description> passed in various formats:
623
                 * - well-known keyrings prefixed with '@' (@u user, @s session, etc)
624
                 * - text descriptions prefixed with "%:" or "%keyring:".
625
                 * - text description with no prefix.
626
                 * - numeric keyring id (ignored in current patch set). */
627
                keyring = strndup(val, sep - val);
×
628
                if (!keyring)
×
629
                        return log_oom();
×
630

631
                /* add type prefix if missing (crypt_set_keyring_to_link() expects it) */
632
                if (!IN_SET(*keyring, '@', '%'))
×
633
                        if (!strprepend(&keyring, "%:"))
×
634
                                return log_oom();
×
635

636
                sep += 2;
×
637

638
                /* %<key_type> is optional (and defaults to 'user') */
639
                if (*sep == '%') {
×
640
                        /* must be separated by colon */
641
                        const char *c = strchr(sep, ':');
×
642
                        if (!c)
×
643
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse link-volume-key= option value: %s", val);
×
644

645
                        key_type = strndup(sep + 1, c - sep - 1);
×
646
                        if (!key_type)
×
647
                                return log_oom();
×
648

649
                        sep = c + 1;
×
650
                }
651

652
                key_description = strdup(sep);
×
653
                if (!key_description)
×
654
                        return log_oom();
×
655

656
                free_and_replace(arg_link_keyring, keyring);
×
657
                free_and_replace(arg_link_key_type, key_type);
×
658
                free_and_replace(arg_link_key_description, key_description);
×
659
        } else if ((val = startswith(option, "fixate-volume-key="))) {
4✔
660
                r = free_and_strdup(&arg_fixate_volume_key, val);
4✔
661
                if (r < 0)
4✔
662
                        return log_oom();
×
663

664
        } else if (!streq(option, "x-initrd.attach"))
×
665
                log_warning("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
×
666

667
        return 0;
668
}
669

670
static int parse_crypt_config(const char *options) {
79✔
671
        assert(options);
79✔
672

673
        for (;;) {
397✔
674
                _cleanup_free_ char *word = NULL;
159✔
675
                int r;
238✔
676

677
                r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
238✔
678
                if (r < 0)
238✔
679
                        return log_error_errno(r, "Failed to parse options: %m");
×
680
                if (r == 0)
238✔
681
                        break;
682

683
                r = parse_one_option(word);
159✔
684
                if (r < 0)
159✔
685
                        return r;
686
        }
687

688
        /* sanity-check options */
689
        if (arg_type && !streq(arg_type, CRYPT_PLAIN)) {
79✔
690
                if (arg_offset != 0)
17✔
691
                      log_warning("offset= ignored with type %s", arg_type);
×
692
                if (arg_skip != 0)
17✔
693
                      log_warning("skip= ignored with type %s", arg_type);
×
694
        }
695

696
        if (arg_pkcs11_uri || arg_pkcs11_uri_auto) {
79✔
697
                /* If password-cache was not configured explicitly, default to no cache for PKCS#11 */
698
                if (!arg_password_cache_set)
9✔
699
                        arg_ask_password_flags &= ~(ASK_PASSWORD_ACCEPT_CACHED|ASK_PASSWORD_PUSH_CACHE);
9✔
700

701
                /* This prevents future backward-compatibility issues if we decide to allow caching for PKCS#11 */
702
                if (FLAGS_SET(arg_ask_password_flags, ASK_PASSWORD_ACCEPT_CACHED))
9✔
703
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
704
                                               "Password cache is not supported for PKCS#11 security tokens.");
705
        }
706

707
        return 0;
708
}
709

710
static char* disk_description(const char *path) {
13✔
711
        static const char name_fields[] =
13✔
712
                "DM_NAME\0"
713
                "ID_MODEL_FROM_DATABASE\0"
714
                "ID_MODEL\0";
715

716
        _cleanup_(sd_device_unrefp) sd_device *device = NULL;
13✔
717
        const char *name;
13✔
718
        struct stat st;
13✔
719

720
        assert(path);
13✔
721

722
        if (stat(path, &st) < 0)
13✔
723
                return NULL;
724

725
        if (!S_ISBLK(st.st_mode))
13✔
726
                return NULL;
727

728
        if (sd_device_new_from_stat_rdev(&device, &st) < 0)
×
729
                return NULL;
730

731
        if (sd_device_get_property_value(device, "ID_PART_ENTRY_NAME", &name) >= 0) {
×
732
                _cleanup_free_ char *unescaped = NULL;
×
733
                ssize_t l;
×
734

735
                /* ID_PART_ENTRY_NAME uses \x style escaping, using libblkid's blkid_encode_string(). Let's
736
                 * reverse this here to make the string more human friendly in case people embed spaces or
737
                 * other weird stuff. */
738

739
                l = cunescape(name, UNESCAPE_RELAX, &unescaped);
×
740
                if (l < 0) {
×
741
                        log_debug_errno(l, "Failed to unescape ID_PART_ENTRY_NAME, skipping device: %m");
×
742
                        return NULL;
743
                }
744

745
                if (!isempty(unescaped) && !string_has_cc(unescaped, NULL))
×
746
                        return TAKE_PTR(unescaped);
×
747
        }
748

749
        /* These need no unescaping. */
750
        NULSTR_FOREACH(i, name_fields)
×
751
                if (sd_device_get_property_value(device, i, &name) >= 0 &&
×
752
                    !isempty(name))
×
753
                        return strdup(name);
×
754

755
        return NULL;
756
}
757

758
static char* disk_mount_point(const char *label) {
13✔
759
        _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
13✔
760
        _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
×
761
        _cleanup_free_ char *device = NULL;
13✔
762
        int r;
13✔
763

764
        /* Yeah, we don't support native systemd unit files here for now */
765

766
        assert(label);
13✔
767

768
        device = strjoin("/dev/mapper/", label);
13✔
769
        if (!device)
13✔
770
                return NULL;
771

772
        r = libmount_parse_fstab(&table, &iter);
13✔
773
        if (r < 0)
13✔
774
                return NULL;
775

776
        for (;;) {
×
777
                struct libmnt_fs *fs;
13✔
778

779
                r = sym_mnt_table_next_fs(table, iter, &fs);
13✔
780
                if (r != 0)
13✔
781
                        return NULL;
13✔
782

783
                if (path_equal(sym_mnt_fs_get_source(fs), device)) {
×
784
                        const char *target = sym_mnt_fs_get_target(fs);
×
785
                        if (target)
×
786
                                return strdup(target);
×
787
                }
788
        }
789
}
790

791
static char *friendly_disk_name(const char *src, const char *vol) {
13✔
792
        _cleanup_free_ char *description = NULL, *mount_point = NULL;
13✔
793
        char *name_buffer = NULL;
13✔
794
        int r;
13✔
795

796
        assert(src);
13✔
797
        assert(vol);
13✔
798

799
        description = disk_description(src);
13✔
800
        mount_point = disk_mount_point(vol);
13✔
801

802
        /* If the description string is simply the volume name, then let's not show this twice */
803
        if (description && streq(vol, description))
13✔
804
                description = mfree(description);
×
805

806
        if (mount_point && description)
13✔
807
                r = asprintf(&name_buffer, "%s (%s) on %s", description, vol, mount_point);
×
808
        else if (mount_point)
×
809
                r = asprintf(&name_buffer, "%s on %s", vol, mount_point);
×
810
        else if (description)
13✔
811
                r = asprintf(&name_buffer, "%s (%s)", description, vol);
×
812
        else
813
                return strdup(vol);
13✔
814
        if (r < 0)
×
815
                return NULL;
816

817
        return name_buffer;
×
818
}
819

820
static PassphraseType check_registered_passwords(struct crypt_device *cd) {
15✔
821
        _cleanup_free_ bool *slots = NULL;
15✔
822
        int slot_max;
15✔
823
        PassphraseType passphrase_type = PASSPHRASE_NONE;
15✔
824

825
        assert(cd);
15✔
826

827
        if (!streq_ptr(sym_crypt_get_type(cd), CRYPT_LUKS2)) {
15✔
828
                log_debug("%s: not a LUKS2 device, only passphrases are supported", sym_crypt_get_device_name(cd));
×
829
                return PASSPHRASE_REGULAR;
830
        }
831

832
        /* Search all used slots */
833
        assert_se((slot_max = sym_crypt_keyslot_max(CRYPT_LUKS2)) > 0);
15✔
834
        slots = new(bool, slot_max);
15✔
835
        if (!slots)
15✔
836
                return log_oom();
×
837

838
        for (int slot = 0; slot < slot_max; slot++)
495✔
839
                slots[slot] = IN_SET(sym_crypt_keyslot_status(cd, slot), CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST);
480✔
840

841
        /* Iterate all LUKS2 tokens and keep track of all their slots */
842
        for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
495✔
843
                _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
480✔
844
                const char *type;
480✔
845
                sd_json_variant *w, *z;
480✔
846
                int tk;
480✔
847

848
                tk = cryptsetup_get_token_as_json(cd, token, NULL, &v);
480✔
849
                if (IN_SET(tk, -ENOENT, -EINVAL))
480✔
850
                        continue;
470✔
851
                if (tk < 0) {
10✔
852
                        log_warning_errno(tk, "Failed to read JSON token data, ignoring: %m");
×
853
                        continue;
×
854
                }
855

856
                w = sd_json_variant_by_key(v, "type");
10✔
857
                if (!w || !sd_json_variant_is_string(w)) {
10✔
858
                        log_warning("Token JSON data lacks type field, ignoring.");
×
859
                        continue;
×
860
                }
861

862
                type = sd_json_variant_string(w);
10✔
863
                if (STR_IN_SET(type, "systemd-recovery", "systemd-pkcs11", "systemd-fido2", "systemd-tpm2")) {
10✔
864

865
                        /* At least exists one recovery key */
866
                        if (streq(type, "systemd-recovery"))
10✔
867
                                passphrase_type |= PASSPHRASE_RECOVERY_KEY;
×
868

869
                        w = sd_json_variant_by_key(v, "keyslots");
10✔
870
                        if (!w || !sd_json_variant_is_array(w)) {
10✔
871
                                log_warning("Token JSON data lacks keyslots field, ignoring.");
×
872
                                continue;
×
873
                        }
874

875
                        JSON_VARIANT_ARRAY_FOREACH(z, w) {
20✔
876
                                unsigned u;
10✔
877
                                int at;
10✔
878

879
                                if (!sd_json_variant_is_string(z)) {
10✔
880
                                        log_warning("Token JSON data's keyslot field is not an array of strings, ignoring.");
×
881
                                        continue;
×
882
                                }
883

884
                                at = safe_atou(sd_json_variant_string(z), &u);
10✔
885
                                if (at < 0) {
10✔
886
                                        log_warning_errno(at, "Token JSON data's keyslot field is not an integer formatted as string, ignoring.");
×
887
                                        continue;
×
888
                                }
889

890
                                if (u >= (unsigned) slot_max) {
10✔
891
                                        log_warning_errno(at, "Token JSON data's keyslot field exceeds the maximum value allowed, ignoring.");
×
892
                                        continue;
×
893
                                }
894

895
                                slots[u] = false;
10✔
896
                        }
897
                }
898
        }
899

900
        /* Check if any of the slots is not referenced by systemd tokens */
901
        for (int slot = 0; slot < slot_max; slot++)
15✔
902
                if (slots[slot]) {
15✔
903
                        passphrase_type |= PASSPHRASE_REGULAR;
15✔
904
                        break;
15✔
905
                }
906

907
        /* All the slots are referenced by systemd tokens, so if a recovery key is not enrolled,
908
         * we will not be able to enter a passphrase. */
909
        return passphrase_type;
910
}
911

912
static int get_password(
15✔
913
                const char *vol,
914
                const char *src,
915
                usec_t until,
916
                bool ignore_cached,
917
                PassphraseType passphrase_type,
918
                char ***ret) {
919

920
        _cleanup_free_ char *friendly = NULL, *text = NULL, *disk_path = NULL, *id = NULL;
15✔
921
        _cleanup_strv_free_erase_ char **passwords = NULL;
×
922
        AskPasswordFlags flags = arg_ask_password_flags;
15✔
923
        int r;
15✔
924

925
        assert(vol);
15✔
926
        assert(src);
15✔
927
        assert(ret);
15✔
928

929
        if (FLAGS_SET(arg_ask_password_flags, ASK_PASSWORD_HEADLESS))
15✔
930
                return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Password querying disabled via 'headless' option.");
15✔
931

932
        friendly = friendly_disk_name(src, vol);
×
933
        if (!friendly)
×
934
                return log_oom();
×
935

936
        if (asprintf(&text, "Please enter %s for disk %s:", passphrase_type_to_string(passphrase_type), friendly) < 0)
×
937
                return log_oom();
×
938

939
        disk_path = cescape(src);
×
940
        if (!disk_path)
×
941
                return log_oom();
×
942

943
        id = strjoin("cryptsetup:", disk_path);
×
944
        if (!id)
×
945
                return log_oom();
×
946

947
        AskPasswordRequest req = {
×
948
                .tty_fd = -EBADF,
949
                .message = text,
950
                .icon = "drive-harddisk",
951
                .id = id,
952
                .keyring = "cryptsetup",
953
                .credential = "cryptsetup.passphrase",
954
                .until = until,
955
                .hup_fd = -EBADF,
956
        };
957

958
        if (ignore_cached)
×
959
                flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
×
960

961
        r = ask_password_auto(&req, flags, &passwords);
×
962
        if (r < 0)
×
963
                return log_error_errno(r, "Failed to query password: %m");
×
964

965
        if (arg_verify) {
×
966
                _cleanup_strv_free_erase_ char **passwords2 = NULL;
×
967

968
                assert(strv_length(passwords) == 1);
×
969

970
                text = mfree(text);
×
971
                if (asprintf(&text, "Please enter %s for disk %s (verification):", passphrase_type_to_string(passphrase_type), friendly) < 0)
×
972
                        return log_oom();
×
973

974
                free(id);
×
975
                id = strjoin("cryptsetup-verification:", disk_path);
×
976
                if (!id)
×
977
                        return log_oom();
×
978

979
                req.message = text;
×
980
                req.id = id;
×
981

982
                r = ask_password_auto(&req, flags, &passwords2);
×
983
                if (r < 0)
×
984
                        return log_error_errno(r, "Failed to query verification password: %m");
×
985

986
                assert(strv_length(passwords2) == 1);
×
987

988
                if (!streq(passwords[0], passwords2[0]))
×
989
                        return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN),
×
990
                                                 "Passwords did not match, retrying.");
991
        }
992

993
        strv_uniq(passwords);
×
994

995
        STRV_FOREACH(p, passwords) {
×
996
                char *c;
×
997

998
                if (strlen(*p)+1 >= arg_key_size)
×
999
                        continue;
×
1000

1001
                /* Pad password if necessary */
1002
                c = new(char, arg_key_size);
×
1003
                if (!c)
×
1004
                        return log_oom();
15✔
1005

1006
                strncpy(c, *p, arg_key_size);
×
1007
                erase_and_free(*p);
×
1008
                *p = TAKE_PTR(c);
×
1009
        }
1010

1011
        *ret = TAKE_PTR(passwords);
×
1012

1013
        return 0;
×
1014
}
1015

1016
static int measure_volume_key(
×
1017
                struct crypt_device *cd,
1018
                const char *name,
1019
                const void *volume_key,
1020
                size_t volume_key_size) {
1021

1022
        int r;
×
1023

1024
        assert(cd);
×
1025
        assert(name);
×
1026
        assert(volume_key);
×
1027
        assert(volume_key_size > 0);
×
1028

1029
        if (arg_tpm2_measure_pcr == UINT_MAX) {
×
1030
                log_debug("Not measuring volume key, deactivated.");
×
1031
                return 0;
×
1032
        }
1033

1034
        r = efi_measured_os(LOG_WARNING);
×
1035
        if (r < 0)
×
1036
                return r;
1037
        if (r == 0) {
×
1038
                log_debug("OS measurements not explicitly requested and kernel stub did not measure kernel image into the expected PCR, skipping userspace volume key measurement, too.");
×
1039
                return 0;
1040
        }
1041

1042
#if HAVE_TPM2
1043
        _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
×
1044
        r = tpm2_context_new_or_warn(arg_tpm2_device, &c);
×
1045
        if (r < 0)
×
1046
                return r;
1047

1048
        _cleanup_strv_free_ char **l = NULL;
×
1049
        if (strv_isempty(arg_tpm2_measure_banks)) {
×
1050
                r = tpm2_get_good_pcr_banks_strv(c, UINT32_C(1) << arg_tpm2_measure_pcr, &l);
×
1051
                if (r < 0)
×
1052
                        return log_error_errno(r, "Could not verify pcr banks: %m");
×
1053
        }
1054

1055
        _cleanup_free_ char *joined = strv_join(l ?: arg_tpm2_measure_banks, ", ");
×
1056
        if (!joined)
×
1057
                return log_oom();
×
1058

1059
        /* Note: we don't directly measure the volume key, it might be a security problem to send an
1060
         * unprotected direct hash of the secret volume key over the wire to the TPM. Hence let's instead
1061
         * send a HMAC signature instead. */
1062

1063
        _cleanup_free_ char *prefix = NULL;
×
1064

1065
        /* Note: what is extended to the SHA256 bank here must match the expected hash of 'fixate-volume-key='
1066
         * calculated by cryptsetup_get_volume_key_id(). */
1067
        r = cryptsetup_get_volume_key_prefix(cd, name, &prefix);
×
1068
        if (r)
×
1069
                return log_error_errno(r, "Could not verify pcr banks: %m");
×
1070

1071
        r = tpm2_pcr_extend_bytes(
×
1072
                        c,
1073
                        /* banks= */ l ?: arg_tpm2_measure_banks,
×
1074
                        /* pcr_index = */ arg_tpm2_measure_pcr,
1075
                        /* data = */ &IOVEC_MAKE_STRING(prefix),
×
1076
                        /* secret = */ &IOVEC_MAKE(volume_key, volume_key_size),
×
1077
                        /* event_type = */ TPM2_EVENT_VOLUME_KEY,
1078
                        /* description = */ prefix);
1079
        if (r < 0)
×
1080
                return log_error_errno(r, "Could not extend PCR: %m");
×
1081

1082
        log_struct(LOG_INFO,
×
1083
                   LOG_MESSAGE_ID(SD_MESSAGE_TPM_PCR_EXTEND_STR),
1084
                   LOG_MESSAGE("Successfully extended PCR index %u with '%s' and volume key (banks %s).", arg_tpm2_measure_pcr, prefix, joined),
1085
                   LOG_ITEM("MEASURING=%s", prefix),
1086
                   LOG_ITEM("PCR=%u", arg_tpm2_measure_pcr),
1087
                   LOG_ITEM("BANKS=%s", joined));
1088

1089
        return 0;
1090
#else
1091
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support disabled, not measuring volume key.");
1092
#endif
1093
}
1094

1095
static int measure_keyslot(
24✔
1096
                struct crypt_device *cd,
1097
                const char *name,
1098
                const char *mechanism,
1099
                int keyslot) {
1100

1101
#if HAVE_TPM2
1102
        int r;
24✔
1103
#endif
1104
        assert(cd);
24✔
1105
        assert(name);
24✔
1106

1107
        if (!arg_tpm2_measure_keyslot_nvpcr) {
24✔
1108
                log_debug("Not measuring unlock keyslot, deactivated.");
24✔
1109
                return 0;
24✔
1110
        }
1111

1112
#if HAVE_TPM2
1113
        r = efi_measured_os(LOG_WARNING);
×
1114
        if (r < 0)
×
1115
                return r;
1116
        if (r == 0) {
×
1117
                log_debug("OS measurements not explicitly requested and kernel stub did not measure kernel image into the expected PCR, skipping userspace key slot measurement, too.");
×
1118
                return 0;
1119
        }
1120

1121
        _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
×
1122
        r = tpm2_context_new_or_warn(arg_tpm2_device, &c);
×
1123
        if (r < 0)
×
1124
                return r;
1125

1126
        _cleanup_free_ char *escaped = NULL;
×
1127
        escaped = xescape(name, ":"); /* avoid ambiguity around ":" once we join things below */
×
1128
        if (!escaped)
×
1129
                return log_oom();
×
1130

1131
        _cleanup_free_ char *k = NULL;
×
1132
        if (keyslot >= 0 && asprintf(&k, "%i", keyslot) < 0)
×
1133
                return log_oom();
×
1134

1135
        _cleanup_free_ char *s = NULL;
×
1136
        s = strjoin("cryptsetup-keyslot:", escaped, ":", strempty(sym_crypt_get_uuid(cd)), ":", strempty(mechanism), ":", strempty(k));
×
1137
        if (!s)
×
1138
                return log_oom();
×
1139

1140
        r = tpm2_nvpcr_extend_bytes(c, /* session= */ NULL, arg_tpm2_measure_keyslot_nvpcr, &IOVEC_MAKE_STRING(s), /* secret= */ NULL, TPM2_EVENT_KEYSLOT, s);
×
1141
        if (r == -ENETDOWN) {
×
1142
                /* NvPCR is not initialized yet. Do so now. */
1143
                _cleanup_(iovec_done_erase) struct iovec anchor_secret = {};
×
1144
                r = tpm2_nvpcr_acquire_anchor_secret(&anchor_secret, /* sync_secondary= */ false);
×
1145
                if (r < 0)
×
1146
                        return r;
1147

1148
                r = tpm2_nvpcr_initialize(c, /* session= */ NULL, arg_tpm2_measure_keyslot_nvpcr, &anchor_secret);
×
1149
                if (r < 0)
×
1150
                        return log_error_errno(r, "Failed to extend NvPCR index '%s' with anchor secret: %m", name);
×
1151

1152
                r = tpm2_nvpcr_extend_bytes(c, /* session= */ NULL, arg_tpm2_measure_keyslot_nvpcr, &IOVEC_MAKE_STRING(s), /* secret= */ NULL, TPM2_EVENT_KEYSLOT, s);
×
1153
        }
1154
        if (r < 0)
×
1155
                return log_error_errno(r, "Could not extend NvPCR: %m");
×
1156

1157
        log_struct(LOG_INFO,
×
1158
                   "MESSAGE_ID=" SD_MESSAGE_TPM_NVPCR_EXTEND_STR,
1159
                   LOG_MESSAGE("Successfully extended NvPCR index '%s' with '%s'.", arg_tpm2_measure_keyslot_nvpcr, s),
1160
                   "MEASURING=%s", s,
1161
                   "NVPCR=%s", arg_tpm2_measure_keyslot_nvpcr);
1162

1163
        return 0;
1164
#else
1165
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support disabled, not measuring keyslot.");
1166
#endif
1167
}
1168

1169
static int log_external_activation(int r, const char *volume) {
×
1170
        assert(volume);
×
1171

1172
        log_notice_errno(r, "Volume '%s' has been activated externally while we have been trying to activate it.", volume);
×
1173
        return 0;
×
1174
}
1175

1176
static int measured_crypt_activate_by_volume_key(
4✔
1177
                struct crypt_device *cd,
1178
                const char *name,
1179
                const char *mechanism,
1180
                int keyslot,
1181
                const void *volume_key,
1182
                size_t volume_key_size,
1183
                uint32_t flags) {
1184

1185
        int r;
4✔
1186

1187
        assert(cd);
4✔
1188
        assert(name);
4✔
1189

1190
        /* A wrapper around crypt_activate_by_volume_key() which also measures to a PCR if that's requested. */
1191

1192
        /* First, check if volume key digest matches the expectation. */
1193
        if (arg_fixate_volume_key) {
4✔
1194
                 _cleanup_free_ char *key_id = NULL;
4✔
1195

1196
                 r = cryptsetup_get_volume_key_id(
4✔
1197
                                 cd,
1198
                                 /* volume_name= */ name,
1199
                                 /* volume_key= */ volume_key,
1200
                                 /* volume_key_size= */ volume_key_size,
1201
                                 /* ret= */ &key_id);
1202
                 if (r < 0)
4✔
1203
                         return log_error_errno(r, "Failed to get volume key id.");
×
1204

1205
                 if (!streq(arg_fixate_volume_key, key_id))
4✔
1206
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
2✔
1207
                                                "Volume key id: '%s' does not match the expectation: '%s'.",
1208
                                                key_id, arg_fixate_volume_key);
1209
        }
1210

1211
        r = sym_crypt_activate_by_volume_key(cd, name, volume_key, volume_key_size, flags);
2✔
1212
        if (r == -EEXIST) /* volume is already active */
2✔
1213
                return log_external_activation(r, name);
×
1214
        if (r < 0)
2✔
1215
                return r;
1216

1217
        if (arg_tpm2_measure_pcr == UINT_MAX) {
2✔
1218
                log_debug("Not measuring volume key, deactivated.");
2✔
1219
                return 0;
1220
        }
1221

1222
        if (volume_key_size > 0)
×
1223
                (void) measure_volume_key(cd, name, volume_key, volume_key_size); /* OK if fails */
×
1224
        else
1225
                log_debug("Not measuring volume key, none specified.");
×
1226

1227
        (void) measure_keyslot(cd, name, mechanism, keyslot); /* ditto */
×
1228
        return r;
×
1229
}
1230

1231
static int measured_crypt_activate_by_passphrase(
32✔
1232
                struct crypt_device *cd,
1233
                const char *name,
1234
                const char *mechanism,
1235
                int keyslot,
1236
                const char *passphrase,
1237
                size_t passphrase_size,
1238
                uint32_t flags) {
1239

1240
        _cleanup_(erase_and_freep) void *vk = NULL;
32✔
1241
        size_t vks;
32✔
1242
        int r;
32✔
1243

1244
        assert(cd);
32✔
1245

1246
        /* A wrapper around crypt_activate_by_passphrase() which also measures to a PCR if that's
1247
         * requested. Note that we may need the volume key for the measurement and/or for the comparison, and
1248
         * crypt_activate_by_passphrase() doesn't give us access to this. Hence, we operate indirectly, and
1249
         * retrieve the volume key first, and then activate through that. */
1250

1251
        if (arg_tpm2_measure_pcr == UINT_MAX && !arg_fixate_volume_key)
32✔
1252
                goto shortcut;
28✔
1253

1254
        r = sym_crypt_get_volume_key_size(cd);
4✔
1255
        if (r < 0)
4✔
1256
                return r;
1257
        if (r == 0) {
4✔
1258
                log_debug("Not measuring volume key, none defined.");
×
1259
                goto shortcut;
×
1260
        }
1261

1262
        vk = malloc(vks = r);
4✔
1263
        if (!vk)
4✔
1264
                return -ENOMEM;
1265

1266
        keyslot = sym_crypt_volume_key_get(cd, keyslot, vk, &vks, passphrase, passphrase_size);
4✔
1267
        if (keyslot < 0)
4✔
1268
                return keyslot;
1269

1270
        return measured_crypt_activate_by_volume_key(cd, name, mechanism, keyslot, vk, vks, flags);
4✔
1271

1272
shortcut:
28✔
1273
        keyslot = sym_crypt_activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags);
28✔
1274
        if (keyslot == -EEXIST) /* volume is already active */
28✔
1275
                return log_external_activation(keyslot, name);
×
1276
        if (keyslot < 0)
28✔
1277
                return keyslot;
1278

1279
        (void) measure_keyslot(cd, name, mechanism, keyslot);
24✔
1280
        return keyslot;
1281
}
1282

1283
static int attach_tcrypt(
×
1284
                struct crypt_device *cd,
1285
                const char *name,
1286
                TokenType token_type,
1287
                const char *key_file,
1288
                const struct iovec *key_data,
1289
                char **passwords,
1290
                uint32_t flags) {
1291

1292
        int r = 0;
×
1293
        _cleanup_(erase_and_freep) char *passphrase = NULL;
×
1294
        struct crypt_params_tcrypt params = {
×
1295
                .flags = CRYPT_TCRYPT_LEGACY_MODES,
1296
                .keyfiles = (const char **)arg_tcrypt_keyfiles,
1297
                .keyfiles_count = strv_length(arg_tcrypt_keyfiles)
×
1298
        };
1299

1300
        assert(cd);
×
1301
        assert(name);
×
1302
        assert(key_file || key_data || !strv_isempty(passwords));
×
1303

1304
        if (token_type >= 0)
×
1305
                /* Ask for a regular password */
1306
                return log_error_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1307
                                       "Sorry, but tcrypt devices are currently not supported in conjunction with pkcs11/fido2/tpm2 support.");
1308

1309
        if (arg_tcrypt_hidden)
×
1310
                params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
×
1311

1312
        if (arg_tcrypt_system)
×
1313
                params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
×
1314

1315
        if (arg_tcrypt_veracrypt)
×
1316
                params.flags |= CRYPT_TCRYPT_VERA_MODES;
×
1317

1318
        if (arg_tcrypt_veracrypt && arg_tcrypt_veracrypt_pim != 0)
×
1319
                params.veracrypt_pim = arg_tcrypt_veracrypt_pim;
×
1320

1321
        if (key_data) {
×
1322
                params.passphrase = key_data->iov_base;
×
1323
                params.passphrase_size = key_data->iov_len;
×
1324
                r = sym_crypt_load(cd, CRYPT_TCRYPT, &params);
×
1325
        } else if (key_file) {
×
1326
                r = read_one_line_file(key_file, &passphrase);
×
1327
                if (r < 0) {
×
1328
                        log_error_errno(r, "Failed to read password file '%s': %m", key_file);
×
1329
                        return -EAGAIN; /* log with the actual error, but return EAGAIN */
1330
                }
1331
                params.passphrase = passphrase;
×
1332
                params.passphrase_size = strlen(passphrase);
×
1333
                r = sym_crypt_load(cd, CRYPT_TCRYPT, &params);
×
1334
        } else {
1335
                r = -EINVAL;
1336
                STRV_FOREACH(p, passwords){
×
1337
                        params.passphrase = *p;
×
1338
                        params.passphrase_size = strlen(*p);
×
1339
                        r = sym_crypt_load(cd, CRYPT_TCRYPT, &params);
×
1340
                        if (r >= 0)
×
1341
                                break;
1342
                }
1343
        }
1344

1345
        if (r < 0) {
×
1346
                if (r == -EPERM) {
×
1347
                        if (key_data)
×
1348
                                log_error_errno(r, "Failed to activate using discovered key. (Key not correct?)");
×
1349
                        else if (key_file)
×
1350
                                log_error_errno(r, "Failed to activate using password file '%s'. (Key data not correct?)", key_file);
×
1351
                        else
1352
                                log_error_errno(r, "Failed to activate using supplied passwords.");
×
1353

1354
                        return r;
1355
                }
1356

1357
                return log_error_errno(r, "Failed to load tcrypt superblock on device %s: %m", sym_crypt_get_device_name(cd));
×
1358
        }
1359

1360
        r = measured_crypt_activate_by_volume_key(
×
1361
                        cd,
1362
                        name,
1363
                        /* mechanism= */ NULL,
1364
                        /* keyslot= */ -1,
1365
                        /* volume_key= */ NULL,
1366
                        /* volume_key_size= */ 0,
1367
                        flags);
1368
        if (r < 0)
×
1369
                return log_error_errno(r, "Failed to activate tcrypt device %s: %m", sym_crypt_get_device_name(cd));
×
1370

1371
        return 0;
1372
}
1373

1374
static char *make_bindname(const char *volume, TokenType token_type) {
53✔
1375
        const char *token_type_name = token_type_to_string(token_type), *suffix;
53✔
1376
        char *bindname;
53✔
1377
        int r;
53✔
1378

1379
        switch (token_type) {
53✔
1380

1381
        case TOKEN_FIDO2:
1382
                suffix = "-salt";
1383
                break;
1384

1385
        default:
1386
                suffix = NULL;
53✔
1387
        }
1388

1389
        r = asprintf(&bindname,
53✔
1390
                     "@%" PRIx64"/cryptsetup%s%s%s/%s",
1391
                     random_u64(),
1392
                     token_type_name ? "-" : "",
1393
                     strempty(token_type_name),
1394
                     strempty(suffix),
1395
                     volume);
1396
        if (r < 0)
53✔
1397
                return NULL;
53✔
1398

1399
        return bindname;
53✔
1400
}
1401

1402
static int make_security_device_monitor(
×
1403
                sd_event **ret_event,
1404
                sd_device_monitor **ret_monitor) {
1405
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1406
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1407
        int r;
×
1408

1409
        assert(ret_event);
×
1410
        assert(ret_monitor);
×
1411

1412
        /* Waits for a device with "security-device" tag to show up in udev */
1413
        log_debug("Creating device monitor for tag 'security-device' with timeout %s",
×
1414
                  FORMAT_TIMESPAN(arg_token_timeout_usec, 1*USEC_PER_SEC));
1415

1416
        r = sd_event_default(&event);
×
1417
        if (r < 0)
×
1418
                return log_error_errno(r, "Failed to allocate event loop: %m");
×
1419

1420
        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
×
1421
        if (r < 0)
×
1422
                return log_error_errno(r, "Failed to install timeout event source: %m");
×
1423

1424
        r = sd_device_monitor_new(&monitor);
×
1425
        if (r < 0)
×
1426
                return log_error_errno(r, "Failed to allocate device monitor: %m");
×
1427

1428
        (void) sd_device_monitor_set_description(monitor, "security-device");
×
1429

1430
        r = sd_device_monitor_filter_add_match_tag(monitor, "security-device");
×
1431
        if (r < 0)
×
1432
                return log_error_errno(r, "Failed to configure device monitor: %m");
×
1433

1434
        r = sd_device_monitor_attach_event(monitor, event);
×
1435
        if (r < 0)
×
1436
                return log_error_errno(r, "Failed to attach device monitor: %m");
×
1437

1438
        r = sd_device_monitor_start(monitor, NULL, NULL);
×
1439
        if (r < 0)
×
1440
                return log_error_errno(r, "Failed to start device monitor: %m");
×
1441

1442
        *ret_event = TAKE_PTR(event);
×
1443
        *ret_monitor = TAKE_PTR(monitor);
×
1444
        return 0;
×
1445
}
1446

1447
static int run_security_device_monitor(
×
1448
                sd_event *event,
1449
                sd_device_monitor *monitor) {
1450
        bool processed = false;
×
1451
        int r;
×
1452

1453
        assert(event);
×
1454
        assert(monitor);
×
1455

1456
        /* Runs the event loop for the device monitor until either something happens, or the timeout is
1457
         * hit. */
1458

1459
        for (;;) {
×
1460
                int x;
×
1461

1462
                r = sd_event_get_exit_code(event, &x);
×
1463
                if (r < 0) {
×
1464
                        if (r != -ENODATA)
×
1465
                                return log_error_errno(r, "Failed to query exit code from event loop: %m");
×
1466

1467
                        /* On ENODATA we aren't told to exit yet. */
1468
                } else {
1469
                        assert(x == -ETIMEDOUT);
×
1470
                        return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1471
                                                "Timed out waiting for security device, aborting security device based authentication attempt.");
1472
                }
1473

1474
                /* Wait for one event, and then eat all subsequent events until there are no further ones */
1475
                r = sd_event_run(event, processed ? 0 : UINT64_MAX);
×
1476
                if (r < 0)
×
1477
                        return log_error_errno(r, "Failed to run event loop: %m");
×
1478
                if (r == 0) /* no events queued anymore */
×
1479
                        return 0;
1480

1481
                processed = true;
×
1482
        }
1483
}
1484

1485
static bool use_token_plugins(void) {
64✔
1486

1487
#if HAVE_TPM2
1488
        /* Currently, there's no way for us to query the volume key when plugins are used. Hence don't use
1489
         * plugins, if measurement has been requested. */
1490
        if (arg_tpm2_measure_pcr != UINT_MAX)
64✔
1491
                return false;
1492
        if (arg_tpm2_measure_keyslot_nvpcr)
64✔
1493
                return false;
1494
        /* Volume key is also needed if the expected key id is set */
1495
        if (arg_fixate_volume_key)
64✔
1496
                return false;
1497
#endif
1498

1499
        /* Disable tokens if we're in FIDO2 mode with manual parameters. */
1500
        if (arg_fido2_cid)
64✔
1501
                return false;
1502

1503
#if HAVE_LIBCRYPTSETUP_PLUGINS
1504
        int r;
64✔
1505

1506
        /* Permit a way to disable libcryptsetup token module support, for debugging purposes. */
1507
        r = getenv_bool("SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE");
64✔
1508
        if (r < 0 && r != -ENXIO)
64✔
1509
                log_debug_errno(r, "Failed to parse $SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE env var: %m");
×
1510
        if (r == 0)
64✔
1511
                return false;
1512

1513
        return sym_crypt_token_external_path();
62✔
1514
#else
1515
        return false;
1516
#endif
1517
}
1518

1519
#if HAVE_LIBCRYPTSETUP_PLUGINS
1520
static int acquire_pins_from_env_variable(char ***ret_pins) {
24✔
1521
        _cleanup_(erase_and_freep) char *envpin = NULL;
24✔
1522
        _cleanup_strv_free_erase_ char **pins = NULL;
24✔
1523
        int r;
24✔
1524

1525
        assert(ret_pins);
24✔
1526

1527
        r = getenv_steal_erase("PIN", &envpin);
24✔
1528
        if (r < 0)
24✔
1529
                return log_error_errno(r, "Failed to acquire PIN from environment: %m");
×
1530
        if (r > 0) {
24✔
1531
                pins = strv_new(envpin);
19✔
1532
                if (!pins)
19✔
1533
                        return log_oom();
×
1534
        }
1535

1536
        *ret_pins = TAKE_PTR(pins);
24✔
1537

1538
        return 0;
24✔
1539
}
1540
#endif
1541

1542
static int crypt_activate_by_token_pin_ask_password(
61✔
1543
                struct crypt_device *cd,
1544
                const char *name,
1545
                const char *type,
1546
                usec_t until,
1547
                void *userdata,
1548
                uint32_t activation_flags,
1549
                const char *message,
1550
                const char *keyring,
1551
                const char *credential) {
1552

1553
#if HAVE_LIBCRYPTSETUP_PLUGINS
1554
        AskPasswordFlags flags = arg_ask_password_flags;
61✔
1555
        _cleanup_strv_free_erase_ char **pins = NULL;
61✔
1556
        int r;
61✔
1557

1558
        r = sym_crypt_activate_by_token_pin(cd, name, type, CRYPT_ANY_TOKEN, /* pin= */ NULL, /* pin_size= */ 0, userdata, activation_flags);
61✔
1559
        if (r > 0) /* returns unlocked keyslot id on success */
61✔
1560
                return 0;
1561
        if (r == -EEXIST) /* volume is already active */
38✔
1562
                return log_external_activation(r, name);
×
1563
        if (r != -ENOANO) /* needs pin or pin is wrong */
38✔
1564
                return r;
1565

1566
        r = acquire_pins_from_env_variable(&pins);
24✔
1567
        if (r < 0)
24✔
1568
                return r;
1569

1570
        STRV_FOREACH(p, pins) {
28✔
1571
                r = sym_crypt_activate_by_token_pin(cd, name, type, CRYPT_ANY_TOKEN, *p, strlen(*p), userdata, activation_flags);
19✔
1572
                if (r > 0) /* returns unlocked keyslot id on success */
19✔
1573
                        return 0;
1574
                if (r == -EEXIST) /* volume is already active */
6✔
1575
                        return log_external_activation(r, name);
×
1576
                if (r != -ENOANO) /* needs pin or pin is wrong */
6✔
1577
                        return r;
1578
        }
1579

1580
        if (FLAGS_SET(arg_ask_password_flags, ASK_PASSWORD_HEADLESS))
9✔
1581
                return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
9✔
1582

1583
        for (;;) {
×
1584
                pins = strv_free_erase(pins);
×
1585

1586
                AskPasswordRequest req = {
×
1587
                        .tty_fd = -EBADF,
1588
                        .message = message,
1589
                        .icon = "drive-harddisk",
1590
                        .keyring = keyring,
1591
                        .credential = credential,
1592
                        .until = until,
1593
                        .hup_fd = -EBADF,
1594
                };
1595

1596
                r = ask_password_auto(&req, flags, &pins);
×
1597
                if (r < 0)
×
1598
                        return r;
×
1599

1600
                STRV_FOREACH(p, pins) {
×
1601
                        r = sym_crypt_activate_by_token_pin(cd, name, type, CRYPT_ANY_TOKEN, *p, strlen(*p), userdata, activation_flags);
×
1602
                        if (r > 0) /* returns unlocked keyslot id on success */
×
1603
                                return 0;
1604
                        if (r == -EEXIST) /* volume is already active */
×
1605
                                return log_external_activation(r, name);
×
1606
                        if (r != -ENOANO) /* needs pin or pin is wrong */
×
1607
                                return r;
1608
                }
1609

1610
                flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
×
1611
        }
1612
        return r;
1613
#else
1614
        return -EOPNOTSUPP;
1615
#endif
1616
}
1617

1618
static int attach_luks2_by_fido2_via_plugin(
×
1619
                struct crypt_device *cd,
1620
                const char *name,
1621
                usec_t until,
1622
                void *userdata,
1623
                uint32_t activation_flags) {
1624

1625
        return crypt_activate_by_token_pin_ask_password(
×
1626
                        cd,
1627
                        name,
1628
                        "systemd-fido2",
1629
                        until,
1630
                        userdata,
1631
                        activation_flags,
1632
                        "Please enter security token PIN:",
1633
                        "fido2-pin",
1634
                        "cryptsetup.fido2-pin");
1635
}
1636

1637
static int attach_luks_or_plain_or_bitlk_by_fido2(
×
1638
                struct crypt_device *cd,
1639
                const char *name,
1640
                const char *key_file,
1641
                const struct iovec *key_data,
1642
                usec_t until,
1643
                uint32_t flags,
1644
                bool pass_volume_key) {
1645

1646
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1647
        _cleanup_(erase_and_freep) void *decrypted_key = NULL;
×
1648
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1649
        size_t decrypted_key_size;
×
1650
        _cleanup_free_ char *friendly = NULL;
×
1651
        int keyslot = arg_key_slot, r;
×
1652
        bool use_libcryptsetup_plugin = use_token_plugins();
×
1653

1654
        assert(cd);
×
1655
        assert(name);
×
1656
        assert(arg_fido2_device || arg_fido2_device_auto);
×
1657

1658
        if (arg_fido2_cid && !key_file && !iovec_is_set(key_data))
×
1659
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1660
                                        "FIDO2 mode with manual parameters selected, but no keyfile specified, refusing.");
1661

1662
        friendly = friendly_disk_name(sym_crypt_get_device_name(cd), name);
×
1663
        if (!friendly)
×
1664
                return log_oom();
×
1665

1666
        for (;;) {
×
1667
                if (use_libcryptsetup_plugin && !arg_fido2_cid) {
×
1668
                        r = attach_luks2_by_fido2_via_plugin(cd, name, until, arg_fido2_device, flags);
×
1669
                        if (IN_SET(r, -ENOTUNIQ, -ENXIO, -ENOENT))
×
1670
                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1671
                                                       "Automatic FIDO2 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
1672

1673
                } else {
1674
                        if (arg_fido2_cid)
×
1675
                                r = acquire_fido2_key(
×
1676
                                                name,
1677
                                                friendly,
1678
                                                arg_fido2_device,
1679
                                                arg_fido2_rp_id,
1680
                                                arg_fido2_cid, arg_fido2_cid_size,
1681
                                                key_file, arg_keyfile_size, arg_keyfile_offset,
1682
                                                key_data,
1683
                                                until,
1684
                                                arg_fido2_manual_flags,
1685
                                                "cryptsetup.fido2-pin",
1686
                                                arg_ask_password_flags,
1687
                                                &decrypted_key,
1688
                                                &decrypted_key_size);
1689
                        else
1690
                                r = acquire_fido2_key_auto(
×
1691
                                                cd,
1692
                                                name,
1693
                                                friendly,
1694
                                                arg_fido2_device,
1695
                                                until,
1696
                                                "cryptsetup.fido2-pin",
1697
                                                arg_ask_password_flags,
1698
                                                &decrypted_key,
1699
                                                &decrypted_key_size);
1700
                        if (r >= 0)
×
1701
                                break;
1702
                }
1703

1704
                if (r != -EAGAIN) /* EAGAIN means: token not found */
×
1705
                        return r;
1706

1707
                if (!monitor) {
×
1708
                        /* We didn't find the token. In this case, watch for it via udev. Let's
1709
                         * create an event loop and monitor first. */
1710

1711
                        assert(!event);
×
1712

1713
                        r = make_security_device_monitor(&event, &monitor);
×
1714
                        if (r < 0)
×
1715
                                return r;
1716

1717
                        log_notice("Security token not present for unlocking volume %s, please plug it in.", friendly);
×
1718

1719
                        /* Let's immediately rescan in case the token appeared in the time we needed
1720
                         * to create and configure the monitor */
1721
                        continue;
×
1722
                }
1723

1724
                r = run_security_device_monitor(event, monitor);
×
1725
                if (r < 0)
×
1726
                        return r;
1727

1728
                log_debug("Got one or more potentially relevant udev events, rescanning FIDO2...");
×
1729
        }
1730

1731
        if (pass_volume_key)
×
1732
                r = measured_crypt_activate_by_volume_key(
×
1733
                                cd,
1734
                                name,
1735
                                "fido2",
1736
                                /* keyslot= */ -1,
1737
                                decrypted_key,
1738
                                decrypted_key_size,
1739
                                flags);
1740
        else {
1741
                _cleanup_(erase_and_freep) char *base64_encoded = NULL;
×
1742
                ssize_t base64_encoded_size;
×
1743

1744
                /* Before using this key as passphrase we base64 encode it, for compat with homed */
1745

1746
                base64_encoded_size = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
×
1747
                if (base64_encoded_size < 0)
×
1748
                        return log_oom();
×
1749

1750
                r = measured_crypt_activate_by_passphrase(
×
1751
                                cd,
1752
                                name,
1753
                                "fido2",
1754
                                keyslot,
1755
                                base64_encoded,
1756
                                base64_encoded_size,
1757
                                flags);
1758
        }
1759
        if (r == -EPERM) {
×
1760
                log_error_errno(r, "Failed to activate with FIDO2 decrypted key. (Key incorrect?)");
×
1761
                return -EAGAIN; /* log actual error, but return EAGAIN */
1762
        }
1763
        if (r < 0)
×
1764
                return log_error_errno(r, "Failed to activate with FIDO2 acquired key: %m");
×
1765

1766
        return 0;
1767
}
1768

1769
static int attach_luks2_by_pkcs11_via_plugin(
1✔
1770
                struct crypt_device *cd,
1771
                const char *name,
1772
                const char *friendly_name,
1773
                usec_t until,
1774
                const char *askpw_credential,
1775
                uint32_t flags) {
1776

1777
#if HAVE_LIBCRYPTSETUP_PLUGINS
1778
        int r;
1✔
1779

1780
        if (!streq_ptr(sym_crypt_get_type(cd), CRYPT_LUKS2))
1✔
1781
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Automatic PKCS#11 metadata requires LUKS2 device.");
×
1782

1783
        systemd_pkcs11_plugin_params params = {
1✔
1784
                .friendly_name = friendly_name,
1785
                .until = until,
1786
                .askpw_credential = askpw_credential,
1787
                .askpw_flags = arg_ask_password_flags,
1788
        };
1789

1790
        r = sym_crypt_activate_by_token_pin(cd, name, "systemd-pkcs11", CRYPT_ANY_TOKEN, NULL, 0, &params, flags);
1✔
1791
        if (r > 0) /* returns unlocked keyslot id on success */
1✔
1792
                r = 0;
1793
        if (r == -EEXIST) /* volume is already active */
1✔
1794
                r = log_external_activation(r, name);
×
1795

1796
        return r;
1797
#else
1798
        return -EOPNOTSUPP;
1799
#endif
1800
}
1801

1802
static int attach_luks_or_plain_or_bitlk_by_pkcs11(
1✔
1803
                struct crypt_device *cd,
1804
                const char *name,
1805
                const char *key_file,
1806
                const struct iovec *key_data,
1807
                usec_t until,
1808
                uint32_t flags,
1809
                bool pass_volume_key) {
1810

1811
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
1✔
1812
        _cleanup_free_ char *friendly = NULL, *discovered_uri = NULL;
1✔
1813
        size_t decrypted_key_size = 0, discovered_key_size = 0;
1✔
1814
        _cleanup_(erase_and_freep) void *decrypted_key = NULL;
1✔
1815
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
1✔
1816
        _cleanup_free_ void *discovered_key = NULL;
1✔
1817
        struct iovec discovered_key_data = {};
1✔
1818
        Pkcs11RsaPadding rsa_padding = PKCS11_RSA_PADDING_PKCS1V15;
1✔
1819
        int keyslot = arg_key_slot, r;
1✔
1820
        const char *uri = NULL;
1✔
1821
        bool use_libcryptsetup_plugin = use_token_plugins();
1✔
1822

1823
        assert(cd);
1✔
1824
        assert(name);
1✔
1825
        assert(arg_pkcs11_uri || arg_pkcs11_uri_auto);
1✔
1826

1827
        if (arg_pkcs11_uri_auto) {
1✔
1828
                if (!use_libcryptsetup_plugin) {
1✔
1829
                        r = find_pkcs11_auto_data(cd, &discovered_uri, &discovered_key, &discovered_key_size, &rsa_padding, &keyslot);
×
1830
                        if (IN_SET(r, -ENOTUNIQ, -ENXIO))
×
1831
                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1832
                                                       "Automatic PKCS#11 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
1833
                        if (r < 0)
×
1834
                                return r;
1835

1836
                        uri = discovered_uri;
×
1837
                        discovered_key_data = IOVEC_MAKE(discovered_key, discovered_key_size);
×
1838
                        key_data = &discovered_key_data;
×
1839
                }
1840
        } else {
1841
                uri = arg_pkcs11_uri;
×
1842

1843
                if (!key_file && !iovec_is_set(key_data))
×
1844
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "PKCS#11 mode selected but no key file specified, refusing.");
×
1845
        }
1846

1847
        friendly = friendly_disk_name(sym_crypt_get_device_name(cd), name);
1✔
1848
        if (!friendly)
1✔
1849
                return log_oom();
×
1850

1851
        for (;;) {
1✔
1852
                if (use_libcryptsetup_plugin && arg_pkcs11_uri_auto)
1✔
1853
                        r = attach_luks2_by_pkcs11_via_plugin(
1✔
1854
                                        cd,
1855
                                        name,
1856
                                        friendly,
1857
                                        until,
1858
                                        "cryptsetup.pkcs11-pin",
1859
                                        flags);
1860
                else {
1861
                        r = decrypt_pkcs11_key(
×
1862
                                        name,
1863
                                        friendly,
1864
                                        uri,
1865
                                        rsa_padding,
1866
                                        key_file, arg_keyfile_size, arg_keyfile_offset,
1867
                                        key_data,
1868
                                        until,
1869
                                        arg_ask_password_flags,
1870
                                        &decrypted_key, &decrypted_key_size);
1871
                        if (r >= 0)
×
1872
                                break;
1873
                }
1874

1875
                if (r != -EAGAIN) /* EAGAIN means: token not found */
1✔
1876
                        return r;
1877

1878
                if (!monitor) {
×
1879
                        /* We didn't find the token. In this case, watch for it via udev. Let's
1880
                         * create an event loop and monitor first. */
1881

1882
                        assert(!event);
×
1883

1884
                        r = make_security_device_monitor(&event, &monitor);
×
1885
                        if (r < 0)
×
1886
                                return r;
1887

1888
                        log_notice("Security token%s%s not present for unlocking volume %s, please plug it in.",
×
1889
                                   uri ? " " : "", strempty(uri), friendly);
1890

1891
                        /* Let's immediately rescan in case the token appeared in the time we needed
1892
                         * to create and configure the monitor */
1893
                        continue;
×
1894
                }
1895

1896
                r = run_security_device_monitor(event, monitor);
×
1897
                if (r < 0)
×
1898
                        return r;
1899

1900
                log_debug("Got one or more potentially relevant udev events, rescanning PKCS#11...");
×
1901
        }
1902
        assert(decrypted_key);
×
1903

1904
        if (pass_volume_key)
×
1905
                r = measured_crypt_activate_by_volume_key(
×
1906
                                cd,
1907
                                name,
1908
                                "pkcs11",
1909
                                /* keyslot= */ -1,
1910
                                decrypted_key,
1911
                                decrypted_key_size,
1912
                                flags);
1913
        else {
1914
                _cleanup_(erase_and_freep) char *base64_encoded = NULL;
×
1915
                ssize_t base64_encoded_size;
×
1916

1917
                /* Before using this key as passphrase we base64 encode it. Why? For compatibility
1918
                 * with homed's PKCS#11 hookup: there we want to use the key we acquired through
1919
                 * PKCS#11 for other authentication/decryption mechanisms too, and some of them do
1920
                 * not take arbitrary binary blobs, but require NUL-terminated strings — most
1921
                 * importantly UNIX password hashes. Hence, for compatibility we want to use a string
1922
                 * without embedded NUL here too, and that's easiest to generate from a binary blob
1923
                 * via base64 encoding. */
1924

1925
                base64_encoded_size = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
×
1926
                if (base64_encoded_size < 0)
×
1927
                        return log_oom();
×
1928

1929
                r = measured_crypt_activate_by_passphrase(
×
1930
                                cd,
1931
                                name,
1932
                                "pkcs11",
1933
                                keyslot,
1934
                                base64_encoded,
1935
                                base64_encoded_size,
1936
                                flags);
1937
        }
1938
        if (r == -EPERM) {
×
1939
                log_error_errno(r, "Failed to activate with PKCS#11 decrypted key. (Key incorrect?)");
1✔
1940
                return -EAGAIN; /* log actual error, but return EAGAIN */
1941
        }
1942
        if (r < 0)
×
1943
                return log_error_errno(r, "Failed to activate with PKCS#11 acquired key: %m");
×
1944

1945
        return 0;
1946
}
1947

1948
static int make_tpm2_device_monitor(
×
1949
                sd_event **ret_event,
1950
                sd_device_monitor **ret_monitor) {
1951

1952
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1953
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1954
        int r;
×
1955

1956
        assert(ret_event);
×
1957
        assert(ret_monitor);
×
1958

1959
        r = sd_event_default(&event);
×
1960
        if (r < 0)
×
1961
                return log_error_errno(r, "Failed to allocate event loop: %m");
×
1962

1963
        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
×
1964
        if (r < 0)
×
1965
                return log_error_errno(r, "Failed to install timeout event source: %m");
×
1966

1967
        r = sd_device_monitor_new(&monitor);
×
1968
        if (r < 0)
×
1969
                return log_error_errno(r, "Failed to allocate device monitor: %m");
×
1970

1971
        (void) sd_device_monitor_set_description(monitor, "tpmrm");
×
1972

1973
        r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, "tpmrm", NULL);
×
1974
        if (r < 0)
×
1975
                return log_error_errno(r, "Failed to configure device monitor: %m");
×
1976

1977
        r = sd_device_monitor_attach_event(monitor, event);
×
1978
        if (r < 0)
×
1979
                return log_error_errno(r, "Failed to attach device monitor: %m");
×
1980

1981
        r = sd_device_monitor_start(monitor, NULL, NULL);
×
1982
        if (r < 0)
×
1983
                return log_error_errno(r, "Failed to start device monitor: %m");
×
1984

1985
        *ret_event = TAKE_PTR(event);
×
1986
        *ret_monitor = TAKE_PTR(monitor);
×
1987
        return 0;
×
1988
}
1989

1990
static int attach_luks2_by_tpm2_via_plugin(
10✔
1991
                struct crypt_device *cd,
1992
                const char *name,
1993
                usec_t until,
1994
                uint32_t flags) {
1995

1996
#if HAVE_LIBCRYPTSETUP_PLUGINS
1997
        systemd_tpm2_plugin_params params = {
10✔
1998
                .search_pcr_mask = arg_tpm2_pcr_mask,
1999
                .device = arg_tpm2_device,
2000
                .signature_path = arg_tpm2_signature,
2001
                .pcrlock_path = arg_tpm2_pcrlock,
2002
        };
2003

2004
        if (!use_token_plugins())
10✔
2005
                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1✔
2006
                                       "libcryptsetup has external plugins support disabled.");
2007

2008
        return crypt_activate_by_token_pin_ask_password(
9✔
2009
                        cd,
2010
                        name,
2011
                        "systemd-tpm2",
2012
                        until,
2013
                        &params,
2014
                        flags,
2015
                        "Please enter TPM2 PIN:",
2016
                        "tpm2-pin",
2017
                        "cryptsetup.tpm2-pin");
2018
#else
2019
        return -EOPNOTSUPP;
2020
#endif
2021
}
2022

2023
static int attach_luks_or_plain_or_bitlk_by_tpm2(
12✔
2024
                struct crypt_device *cd,
2025
                const char *name,
2026
                const char *key_file,
2027
                const struct iovec *key_data,
2028
                usec_t until,
2029
                uint32_t flags,
2030
                bool pass_volume_key) {
2031

2032
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
12✔
2033
        _cleanup_(iovec_done_erase) struct iovec decrypted_key = {};
×
2034
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
12✔
2035
        _cleanup_free_ char *friendly = NULL;
12✔
2036
        int keyslot = arg_key_slot, r;
12✔
2037

2038
        assert(cd);
12✔
2039
        assert(name);
12✔
2040
        assert(arg_tpm2_device || arg_tpm2_device_auto);
12✔
2041

2042
        friendly = friendly_disk_name(sym_crypt_get_device_name(cd), name);
12✔
2043
        if (!friendly)
12✔
2044
                return log_oom();
×
2045

2046
        for (;;) {
12✔
2047
                if (key_file || iovec_is_set(key_data)) {
12✔
2048
                        /* If key data is specified, use that */
2049

2050
                        r = acquire_tpm2_key(
4✔
2051
                                        name,
2052
                                        arg_tpm2_device,
2053
                                        arg_tpm2_pcr_mask == UINT32_MAX ? TPM2_PCR_MASK_DEFAULT_LEGACY : arg_tpm2_pcr_mask,
2✔
2054
                                        UINT16_MAX,
2055
                                        /* pubkey= */ NULL,
2056
                                        /* pubkey_pcr_mask= */ 0,
2057
                                        /* signature_path= */ NULL,
2058
                                        /* pcrlock_path= */ NULL,
2059
                                        /* primary_alg= */ 0,
2060
                                        key_file, arg_keyfile_size, arg_keyfile_offset,
2061
                                        key_data, /* n_blobs= */ iovec_is_set(key_data) ? 1 : 0,
2✔
2062
                                        /* policy_hash= */ NULL, /* we don't know the policy hash */
2063
                                        /* n_policy_hash= */ 0,
2064
                                        /* salt= */ NULL,
2065
                                        /* srk= */ NULL,
2066
                                        /* pcrlock_nv= */ NULL,
2067
                                        arg_tpm2_pin ? TPM2_FLAGS_USE_PIN : 0,
2068
                                        until,
2069
                                        "cryptsetup.tpm2-pin",
2070
                                        arg_ask_password_flags,
2071
                                        &decrypted_key);
2072
                        if (r >= 0)
2✔
2073
                                break;
2074
                        if (IN_SET(r, -EACCES, -ENOLCK))
2✔
2075
                                return log_error_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 PIN unlock failed, falling back to traditional unlocking.");
×
2076
                        if (ERRNO_IS_NOT_SUPPORTED(r)) /* TPM2 support not compiled in? */
2✔
2077
                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 support not available, falling back to traditional unlocking.");
×
2078
                        /* EAGAIN means: no tpm2 chip found */
2079
                        if (r != -EAGAIN) {
2✔
2080
                                log_notice_errno(r, "TPM2 operation failed, falling back to traditional unlocking: %m");
2✔
2081
                                return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
2082
                        }
2083
                } else {
2084
                        r = attach_luks2_by_tpm2_via_plugin(cd, name, until, flags);
10✔
2085
                        if (r >= 0)
10✔
2086
                                return 0;
2087
                        /* EAGAIN     means: no tpm2 chip found
2088
                         * EOPNOTSUPP means: no libcryptsetup plugins support */
2089
                        if (r == -ENXIO)
10✔
2090
                                return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
×
2091
                                                        "No TPM2 metadata matching the current system state found in LUKS2 header, falling back to traditional unlocking.");
2092
                        if (r == -ENOENT)
10✔
2093
                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
3✔
2094
                                                       "No TPM2 metadata enrolled in LUKS2 header or TPM2 support not available, falling back to traditional unlocking.");
2095
                        if (!IN_SET(r, -EOPNOTSUPP, -EAGAIN)) {
7✔
2096
                                log_notice_errno(r, "TPM2 operation failed, falling back to traditional unlocking: %m");
6✔
2097
                                return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
2098
                        }
2099
                }
2100

2101
                if (r == -EOPNOTSUPP) { /* Plugin not available, let's process TPM2 stuff right here instead */
1✔
2102
                        bool found_some = false;
1✔
2103
                        int token = 0; /* first token to look at */
1✔
2104

2105
                        /* If no key data is specified, look for it in the header. In order to support
2106
                         * software upgrades we'll iterate through all suitable tokens, maybe one of them
2107
                         * works. */
2108

2109
                        for (;;) {
1✔
2110
                                _cleanup_(iovec_done) struct iovec pubkey = {}, salt = {}, srk = {}, pcrlock_nv = {};
×
2111
                                struct iovec *blobs = NULL, *policy_hash = NULL;
1✔
2112
                                uint32_t hash_pcr_mask, pubkey_pcr_mask;
1✔
2113
                                size_t n_blobs = 0, n_policy_hash = 0;
1✔
2114
                                uint16_t pcr_bank, primary_alg;
1✔
2115
                                TPM2Flags tpm2_flags;
1✔
2116

2117
                                CLEANUP_ARRAY(blobs, n_blobs, iovec_array_free);
1✔
2118
                                CLEANUP_ARRAY(policy_hash, n_policy_hash, iovec_array_free);
1✔
2119

2120
                                r = find_tpm2_auto_data(
1✔
2121
                                                cd,
2122
                                                arg_tpm2_pcr_mask, /* if != UINT32_MAX we'll only look for tokens with this PCR mask */
2123
                                                token, /* search for the token with this index, or any later index than this */
2124
                                                &hash_pcr_mask,
2125
                                                &pcr_bank,
2126
                                                &pubkey,
2127
                                                &pubkey_pcr_mask,
2128
                                                &primary_alg,
2129
                                                &blobs,
2130
                                                &n_blobs,
2131
                                                &policy_hash,
2132
                                                &n_policy_hash,
2133
                                                &salt,
2134
                                                &srk,
2135
                                                &pcrlock_nv,
2136
                                                &tpm2_flags,
2137
                                                &keyslot,
2138
                                                &token);
2139
                                if (r == -ENXIO)
1✔
2140
                                        /* No further TPM2 tokens found in the LUKS2 header. */
2141
                                        return log_full_errno(found_some ? LOG_NOTICE : LOG_DEBUG,
×
2142
                                                              SYNTHETIC_ERRNO(EAGAIN),
2143
                                                              found_some
2144
                                                              ? "No TPM2 metadata matching the current system state found in LUKS2 header, falling back to traditional unlocking."
2145
                                                              : "No TPM2 metadata enrolled in LUKS2 header, falling back to traditional unlocking.");
2146
                                if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
1✔
2147
                                        /* TPM2 support not compiled in? */
2148
                                        return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
×
2149
                                                               "TPM2 support not available, falling back to traditional unlocking.");
2150
                                if (r < 0)
1✔
2151
                                        return r;
2152

2153
                                found_some = true;
1✔
2154

2155
                                r = acquire_tpm2_key(
1✔
2156
                                                name,
2157
                                                arg_tpm2_device,
2158
                                                hash_pcr_mask,
2159
                                                pcr_bank,
2160
                                                &pubkey,
2161
                                                pubkey_pcr_mask,
2162
                                                arg_tpm2_signature,
2163
                                                arg_tpm2_pcrlock,
2164
                                                primary_alg,
2165
                                                /* key_file= */ NULL, /* key_file_size= */ 0, /* key_file_offset= */ 0, /* no key file */
2166
                                                blobs,
2167
                                                n_blobs,
2168
                                                policy_hash,
2169
                                                n_policy_hash,
2170
                                                &salt,
2171
                                                &srk,
2172
                                                &pcrlock_nv,
2173
                                                tpm2_flags,
2174
                                                until,
2175
                                                "cryptsetup.tpm2-pin",
2176
                                                arg_ask_password_flags,
2177
                                                &decrypted_key);
2178
                                if (IN_SET(r, -EACCES, -ENOLCK))
1✔
2179
                                        return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 PIN unlock failed, falling back to traditional unlocking.");
×
2180
                                if (r != -EPERM)
1✔
2181
                                        break;
2182

2183
                                token++; /* try a different token next time */
×
2184
                        }
2185

2186
                        if (r >= 0)
1✔
2187
                                break;
2188
                        /* EAGAIN means: no tpm2 chip found */
2189
                        if (r != -EAGAIN) {
×
2190
                                log_notice_errno(r, "TPM2 operation failed, falling back to traditional unlocking: %m");
×
2191
                                return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
2192
                        }
2193
                }
2194

2195
                if (!monitor) {
×
2196
                        /* We didn't find the TPM2 device. In this case, watch for it via udev. Let's create
2197
                         * an event loop and monitor first. */
2198

2199
                        assert(!event);
×
2200

2201
                        if (is_efi_boot() && !efi_has_tpm2())
×
2202
                                return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
×
2203
                                                        "No TPM2 hardware discovered and EFI firmware does not see it either, falling back to traditional unlocking.");
2204

2205
                        r = make_tpm2_device_monitor(&event, &monitor);
×
2206
                        if (r < 0)
×
2207
                                return r;
2208

2209
                        log_info("TPM2 device not present for unlocking %s, waiting for it to become available.", friendly);
×
2210

2211
                        /* Let's immediately rescan in case the device appeared in the time we needed
2212
                         * to create and configure the monitor */
2213
                        continue;
×
2214
                }
2215

2216
                r = run_security_device_monitor(event, monitor);
×
2217
                if (r < 0)
×
2218
                        return r;
2219

2220
                log_debug("Got one or more potentially relevant udev events, rescanning for TPM2...");
×
2221
        }
2222

2223
        if (pass_volume_key)
1✔
2224
                r = measured_crypt_activate_by_volume_key(
×
2225
                                cd,
2226
                                name,
2227
                                "tpm2",
2228
                                /* keyslot= */ -1,
2229
                                decrypted_key.iov_base,
×
2230
                                decrypted_key.iov_len,
2231
                                flags);
2232
        else {
2233
                _cleanup_(erase_and_freep) char *base64_encoded = NULL;
1✔
2234
                ssize_t base64_encoded_size;
1✔
2235

2236
                /* Before using this key as passphrase we base64 encode it, for compat with homed */
2237

2238
                base64_encoded_size = base64mem(decrypted_key.iov_base, decrypted_key.iov_len, &base64_encoded);
1✔
2239
                if (base64_encoded_size < 0)
1✔
2240
                        return log_oom();
×
2241

2242
                r = measured_crypt_activate_by_passphrase(
1✔
2243
                                cd,
2244
                                name,
2245
                                "tpm2",
2246
                                keyslot,
2247
                                base64_encoded,
2248
                                base64_encoded_size,
2249
                                flags);
2250
        }
2251
        if (r == -EPERM) {
1✔
2252
                log_error_errno(r, "Failed to activate with TPM2 decrypted key. (Key incorrect?)");
12✔
2253
                return -EAGAIN; /* log actual error, but return EAGAIN */
2254
        }
2255
        if (r < 0)
1✔
2256
                return log_error_errno(r, "Failed to activate with TPM2 acquired key: %m");
×
2257

2258
        return 0;
2259
}
2260

2261
static int attach_luks_or_plain_or_bitlk_by_key_data(
3✔
2262
                struct crypt_device *cd,
2263
                const char *name,
2264
                const struct iovec *key_data,
2265
                uint32_t flags,
2266
                bool pass_volume_key) {
2267

2268
        int r;
3✔
2269

2270
        assert(cd);
3✔
2271
        assert(name);
3✔
2272
        assert(key_data);
3✔
2273

2274
        if (pass_volume_key)
3✔
2275
                r = measured_crypt_activate_by_volume_key(cd, name, /* mechanism= */ NULL, /* keyslot= */ -1, key_data->iov_base, key_data->iov_len, flags);
×
2276
        else
2277
                r = measured_crypt_activate_by_passphrase(cd, name, /* mechanism= */ NULL, arg_key_slot, key_data->iov_base, key_data->iov_len, flags);
3✔
2278
        if (r == -EPERM) {
3✔
2279
                log_error_errno(r, "Failed to activate. (Key incorrect?)");
×
2280
                return -EAGAIN; /* Log actual error, but return EAGAIN */
2281
        }
2282
        if (r < 0)
3✔
2283
                return log_error_errno(r, "Failed to activate: %m");
×
2284

2285
        return 0;
2286
}
2287

2288
static int attach_luks_or_plain_or_bitlk_by_key_file(
28✔
2289
                struct crypt_device *cd,
2290
                const char *name,
2291
                const char *key_file,
2292
                uint32_t flags,
2293
                bool pass_volume_key) {
2294

2295
        _cleanup_(erase_and_freep) char *kfdata = NULL;
28✔
2296
        _cleanup_free_ char *bindname = NULL;
28✔
2297
        size_t kfsize;
28✔
2298
        int r;
28✔
2299

2300
        assert(cd);
28✔
2301
        assert(name);
28✔
2302
        assert(key_file);
28✔
2303

2304
        /* If we read the key via AF_UNIX, make this client recognizable */
2305
        bindname = make_bindname(name, /* token_type= */ _TOKEN_TYPE_INVALID);
28✔
2306
        if (!bindname)
28✔
2307
                return log_oom();
×
2308

2309
        r = read_full_file_full(
31✔
2310
                        AT_FDCWD, key_file,
2311
                        arg_keyfile_offset == 0 ? UINT64_MAX : arg_keyfile_offset,
28✔
2312
                        arg_keyfile_size == 0 ? SIZE_MAX : arg_keyfile_size,
28✔
2313
                        READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
2314
                        bindname,
2315
                        &kfdata, &kfsize);
2316
        if (r == -E2BIG) {
28✔
2317
                log_error_errno(r, "Failed to activate, key file '%s' too large.", key_file);
×
2318
                return -EAGAIN;
2319
        }
2320
        if (r == -ENOENT) {
28✔
2321
                log_error_errno(r, "Failed to activate, key file '%s' missing.", key_file);
×
2322
                return -EAGAIN; /* Log actual error, but return EAGAIN */
2323
        }
2324
        if (r < 0)
28✔
2325
                return log_error_errno(r, "Failed to read key file '%s': %m", key_file);
×
2326

2327
        if (pass_volume_key)
28✔
2328
                r = measured_crypt_activate_by_volume_key(cd, name, /* mechanism= */ NULL, /* keyslot= */ -1, kfdata, kfsize, flags);
×
2329
        else
2330
                r = measured_crypt_activate_by_passphrase(cd, name, /* mechanism= */ NULL, arg_key_slot, kfdata, kfsize, flags);
28✔
2331
        if (r == -EPERM) {
28✔
2332
                log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file);
28✔
2333
                return -EAGAIN; /* Log actual error, but return EAGAIN */
2334
        }
2335
        if (r < 0)
24✔
2336
                return log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
2✔
2337

2338
        return 0;
2339
}
2340

2341
static int attach_luks_or_plain_or_bitlk_by_passphrase(
×
2342
                struct crypt_device *cd,
2343
                const char *name,
2344
                char **passwords,
2345
                uint32_t flags,
2346
                bool pass_volume_key) {
2347

2348
        int r;
×
2349

2350
        assert(cd);
×
2351
        assert(name);
×
2352

2353
        r = -EINVAL;
2354
        STRV_FOREACH(p, passwords) {
×
2355
                if (pass_volume_key)
×
2356
                        r = measured_crypt_activate_by_volume_key(cd, name, /* mechanism= */ NULL, /* keyslot= */ -1, *p, arg_key_size, flags);
×
2357
                else
2358
                        r = measured_crypt_activate_by_passphrase(cd, name, /* mechanism= */ NULL, arg_key_slot, *p, strlen(*p), flags);
×
2359
                if (r >= 0)
×
2360
                        break;
2361
        }
2362
        if (r == -EPERM) {
×
2363
                log_error_errno(r, "Failed to activate with specified passphrase. (Passphrase incorrect?)");
×
2364
                return -EAGAIN; /* log actual error, but return EAGAIN */
2365
        }
2366
        if (r < 0)
×
2367
                return log_error_errno(r, "Failed to activate with specified passphrase: %m");
×
2368

2369
        return 0;
2370
}
2371

2372
static int attach_luks_or_plain_or_bitlk(
44✔
2373
                struct crypt_device *cd,
2374
                const char *name,
2375
                TokenType token_type,
2376
                const char *key_file,
2377
                const struct iovec *key_data,
2378
                char **passwords,
2379
                uint32_t flags,
2380
                usec_t until) {
2381

2382
        bool pass_volume_key = false;
44✔
2383
        int r;
44✔
2384

2385
        assert(cd);
44✔
2386
        assert(name);
44✔
2387

2388
        if ((!arg_type && !sym_crypt_get_type(cd)) || streq_ptr(arg_type, CRYPT_PLAIN)) {
44✔
2389
                struct crypt_params_plain params = {
×
2390
                        .offset = arg_offset,
2391
                        .skip = arg_skip,
2392
                        .sector_size = arg_sector_size,
2393
                };
2394
                const char *cipher, *cipher_mode;
×
2395
                _cleanup_free_ char *truncated_cipher = NULL;
×
2396

2397
                if (streq_ptr(arg_hash, "plain"))
×
2398
                        /* plain isn't a real hash type. it just means "use no hash" */
2399
                        params.hash = NULL;
2400
                else if (arg_hash)
×
2401
                        params.hash = arg_hash;
×
2402
                else if (!key_file)
×
2403
                        /* for CRYPT_PLAIN, the behaviour of cryptsetup package is to not hash when a key
2404
                         * file is provided */
2405
                        params.hash = "ripemd160";
×
2406

2407
                if (arg_cipher) {
×
2408
                        size_t l;
×
2409

2410
                        l = strcspn(arg_cipher, "-");
×
2411
                        truncated_cipher = strndup(arg_cipher, l);
×
2412
                        if (!truncated_cipher)
×
2413
                                return log_oom();
×
2414

2415
                        cipher = truncated_cipher;
×
2416
                        cipher_mode = arg_cipher[l] ? arg_cipher+l+1 : "plain";
×
2417
                } else {
2418
                        cipher = "aes";
2419
                        cipher_mode = "cbc-essiv:sha256";
2420
                }
2421

2422
                /* for CRYPT_PLAIN limit reads from keyfile to key length, and ignore keyfile-size */
2423
                arg_keyfile_size = arg_key_size;
×
2424

2425
                /* In contrast to what the name crypt_format() might suggest this doesn't actually format
2426
                 * anything, it just configures encryption parameters when used for plain mode. */
2427
                r = sym_crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, arg_keyfile_size, &params);
×
2428
                if (r < 0)
×
2429
                        return log_error_errno(r, "Loading of cryptographic parameters failed: %m");
×
2430

2431
                /* hash == NULL implies the user passed "plain" */
2432
                pass_volume_key = !params.hash;
×
2433
        }
2434

2435
        log_info("Set cipher %s, mode %s, key size %i bits for device %s.",
44✔
2436
                 sym_crypt_get_cipher(cd),
2437
                 sym_crypt_get_cipher_mode(cd),
2438
                 sym_crypt_get_volume_key_size(cd)*8,
2439
                 sym_crypt_get_device_name(cd));
2440

2441
        if (token_type == TOKEN_TPM2)
44✔
2442
                return attach_luks_or_plain_or_bitlk_by_tpm2(cd, name, key_file, key_data, until, flags, pass_volume_key);
12✔
2443
        if (token_type == TOKEN_FIDO2)
32✔
2444
                return attach_luks_or_plain_or_bitlk_by_fido2(cd, name, key_file, key_data, until, flags, pass_volume_key);
×
2445
        if (token_type == TOKEN_PKCS11)
32✔
2446
                return attach_luks_or_plain_or_bitlk_by_pkcs11(cd, name, key_file, key_data, until, flags, pass_volume_key);
1✔
2447
        if (key_data)
31✔
2448
                return attach_luks_or_plain_or_bitlk_by_key_data(cd, name, key_data, flags, pass_volume_key);
3✔
2449
        if (key_file)
28✔
2450
                return attach_luks_or_plain_or_bitlk_by_key_file(cd, name, key_file, flags, pass_volume_key);
28✔
2451

2452
        return attach_luks_or_plain_or_bitlk_by_passphrase(cd, name, passwords, flags, pass_volume_key);
×
2453
}
2454

2455
static int help(void) {
×
2456
        _cleanup_free_ char *link = NULL;
×
2457
        _cleanup_(table_unrefp) Table *options = NULL, *verbs = NULL;
×
2458
        int r;
×
2459

2460
        r = terminal_urlify_man("systemd-cryptsetup", "8", &link);
×
2461
        if (r < 0)
×
2462
                return log_oom();
×
2463

2464
        r = verbs_get_help_table(&verbs);
×
2465
        if (r < 0)
×
2466
                return r;
2467

2468
        r = option_parser_get_help_table(&options);
×
2469
        if (r < 0)
×
2470
                return r;
2471

2472
        (void) table_sync_column_widths(0, verbs, options);
×
2473

2474
        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
×
2475
               "%sAttach or detach an encrypted block device.%s\n"
2476
               "\n%sCommands:%s\n",
2477
               program_invocation_short_name,
2478
               ansi_highlight(),
2479
               ansi_normal(),
2480
               ansi_underline(),
2481
               ansi_normal());
2482

2483
        r = table_print_or_warn(verbs);
×
2484
        if (r < 0)
×
2485
                return r;
2486

2487
        printf("\n%sOptions:%s\n",
×
2488
               ansi_underline(),
2489
               ansi_normal());
2490

2491
        r = table_print_or_warn(options);
×
2492
        if (r < 0)
×
2493
                return r;
2494

2495
        printf("\nSee the %s for details.\n", link);
×
2496
        return 0;
2497
}
2498

2499
VERB_COMMON_HELP_HIDDEN(help);
×
2500

2501
static int parse_argv(int argc, char *argv[], char ***ret_args) {
147✔
2502
        assert(argc >= 0);
147✔
2503
        assert(argv);
147✔
2504
        assert(ret_args);
147✔
2505

2506
        OptionParser opts = { argc, argv };
147✔
2507

2508
        FOREACH_OPTION_OR_RETURN(c, &opts)
147✔
2509
                switch (c) {
×
2510

2511
                OPTION_COMMON_HELP:
×
2512
                        return help();
×
2513

2514
                OPTION_COMMON_VERSION:
×
2515
                        return version();
×
2516
                }
2517

2518
        *ret_args = option_parser_get_args(&opts);
147✔
2519
        return 1;
147✔
2520
}
2521

2522
static uint32_t determine_flags(void) {
81✔
2523
        uint32_t flags = 0;
81✔
2524

2525
        if (arg_readonly)
81✔
2526
                flags |= CRYPT_ACTIVATE_READONLY;
×
2527

2528
        if (arg_discards)
81✔
2529
                flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
×
2530

2531
        if (arg_same_cpu_crypt)
81✔
2532
                flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
×
2533

2534
        if (arg_submit_from_crypt_cpus)
81✔
2535
                flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
×
2536

2537
        if (arg_no_read_workqueue)
81✔
2538
                flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
×
2539

2540
        if (arg_no_write_workqueue)
81✔
2541
                flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
×
2542

2543
        /* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
2544
        /* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */
2545
        flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF;
81✔
2546

2547
        return flags;
81✔
2548
}
2549

2550
static void remove_and_erasep(const char **p) {
81✔
2551
        int r;
81✔
2552

2553
        assert(p);
81✔
2554

2555
        if (!*p)
81✔
2556
                return;
2557

2558
        r = unlinkat_deallocate(AT_FDCWD, *p, UNLINK_ERASE);
2✔
2559
        if (r < 0 && r != -ENOENT)
2✔
2560
                log_warning_errno(r, "Unable to erase key file '%s', ignoring: %m", *p);
×
2561
}
2562

2563
static TokenType determine_token_type(void) {
59✔
2564
        if (arg_tpm2_device || arg_tpm2_device_auto)
59✔
2565
                return TOKEN_TPM2;
2566
        if (arg_fido2_device || arg_fido2_device_auto)
47✔
2567
                return TOKEN_FIDO2;
2568
        if (arg_pkcs11_uri || arg_pkcs11_uri_auto)
47✔
2569
                return TOKEN_PKCS11;
1✔
2570

2571
        return _TOKEN_TYPE_INVALID;
2572
}
2573

2574
static int discover_key(const char *key_file, const char *volume, TokenType token_type, struct iovec *ret_key_data) {
25✔
2575
        _cleanup_free_ char *bindname = NULL;
25✔
2576
        const char *token_type_name;
25✔
2577
        int r;
25✔
2578

2579
        assert(key_file);
25✔
2580
        assert(volume);
25✔
2581
        assert(ret_key_data);
25✔
2582

2583
        bindname = make_bindname(volume, token_type);
25✔
2584
        if (!bindname)
25✔
2585
                return log_oom();
×
2586

2587
        /* If a key file is not explicitly specified, search for a key in a well defined search path, and load it. */
2588
        r = find_key_file(key_file, STRV_MAKE("/etc/cryptsetup-keys.d", "/run/cryptsetup-keys.d"), bindname, ret_key_data);
25✔
2589
        if (r <= 0)
25✔
2590
                return r;
2591

2592
        token_type_name = token_type_to_string(token_type);
1✔
2593
        if (token_type_name)
1✔
2594
                log_debug("Automatically discovered encrypted key for volume '%s' (token type: %s).", volume, token_type_name);
×
2595
        else
2596
                log_debug("Automatically discovered key for volume '%s'.", volume);
1✔
2597

2598
        return r;
2599
}
2600

2601
VERB(verb_attach, "attach", "VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG]", 3, 5, 0,
2602
     "Attach an encrypted block device");
2603
static int verb_attach(int argc, char *argv[], uintptr_t _data, void *userdata) {
81✔
2604
        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
81✔
2605
        _unused_ _cleanup_(remove_and_erasep) const char *destroy_key_file = NULL;
81✔
2606
        crypt_status_info status;
81✔
2607
        uint32_t flags = 0;
81✔
2608
        unsigned tries;
81✔
2609
        usec_t until;
81✔
2610
        PassphraseType passphrase_type = PASSPHRASE_NONE;
81✔
2611
        int r;
81✔
2612

2613
        /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG] */
2614

2615
        assert(argc >= 3 && argc <= 5);
81✔
2616

2617
        const char *volume = ASSERT_PTR(argv[1]),
81✔
2618
                *source = ASSERT_PTR(argv[2]),
81✔
2619
                *key_file = argc >= 4 ? mangle_none(argv[3]) : NULL,
81✔
2620
                *config = argc >= 5 ? mangle_none(argv[4]) : NULL;
81✔
2621

2622
        if (!filename_is_valid(volume))
81✔
2623
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
×
2624

2625
        if (key_file && !path_is_absolute(key_file)) {
81✔
2626
                log_warning("Password file path '%s' is not absolute. Ignoring.", key_file);
×
2627
                key_file = NULL;
2628
        }
2629

2630
        if (config) {
81✔
2631
                r = parse_crypt_config(config);
79✔
2632
                if (r < 0)
79✔
2633
                        return r;
2634
        }
2635

2636
        log_debug("%s %s ← %s type=%s cipher=%s", __func__,
226✔
2637
                  volume, source, strempty(arg_type), strempty(arg_cipher));
2638

2639
        /* A delicious drop of snake oil */
2640
        (void) safe_mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT);
81✔
2641

2642
        if (key_file && arg_keyfile_erase)
81✔
2643
                destroy_key_file = key_file; /* let's get this baby erased when we leave */
2✔
2644

2645
        if (arg_header) {
81✔
2646
                if (streq_ptr(arg_type, CRYPT_TCRYPT)){
9✔
2647
                        log_debug("tcrypt header: %s", arg_header);
×
2648
                        r = sym_crypt_init_data_device(&cd, arg_header, source);
×
2649
                } else {
2650
                        log_debug("LUKS header: %s", arg_header);
9✔
2651
                        r = sym_crypt_init(&cd, arg_header);
9✔
2652
                }
2653
        } else
2654
                r = sym_crypt_init(&cd, source);
72✔
2655
        if (r < 0)
81✔
2656
                return log_error_errno(r, "crypt_init() failed: %m");
×
2657

2658
        cryptsetup_enable_logging(cd);
81✔
2659

2660
        status = sym_crypt_status(cd, volume);
81✔
2661
        if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
81✔
2662
                log_info("Volume %s already active.", volume);
×
2663
                return 0;
2664
        }
2665

2666
        flags = determine_flags();
81✔
2667

2668
        until = usec_add(now(CLOCK_MONOTONIC), arg_timeout);
81✔
2669
        if (until == USEC_INFINITY)
×
2670
                until = 0;
81✔
2671

2672
        if (arg_key_size == 0)
81✔
2673
                arg_key_size = 256U / 8U;
81✔
2674

2675
        if (key_file) {
81✔
2676
                struct stat st;
28✔
2677

2678
                /* Ideally we'd do this on the open fd, but since this is just a warning it's OK to do this
2679
                 * in two steps. */
2680
                if (stat(key_file, &st) >= 0 && S_ISREG(st.st_mode) && (st.st_mode & 0005))
28✔
2681
                        log_warning("Key file %s is world-readable. This is not a good idea!", key_file);
6✔
2682
        }
2683

2684
        if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2)) {
81✔
2685
                r = sym_crypt_load(cd, !arg_type || streq(arg_type, ANY_LUKS) ? CRYPT_LUKS : arg_type, NULL);
81✔
2686
                if (r < 0)
81✔
2687
                        return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", sym_crypt_get_device_name(cd));
37✔
2688

2689
                /* since cryptsetup 2.7.0 (Jan 2024) */
2690
                if (arg_link_key_description) {
81✔
2691
                        r = sym_crypt_set_keyring_to_link(cd, arg_link_key_description, NULL, arg_link_key_type, arg_link_keyring);
×
2692
                        if (r == -ENOSYS)
×
2693
                                log_warning("Loaded libcryptsetup does not support linking volume keys in user specified kernel keyrings upon device activation, ignoring.");
×
2694
                        else if (r < 0)
×
2695
                                log_warning_errno(r, "Failed to set keyring or key description to link volume key in, ignoring: %m");
×
2696
                }
2697

2698
                if (arg_header) {
81✔
2699
                        r = sym_crypt_set_data_device(cd, source);
9✔
2700
                        if (r < 0)
9✔
2701
                                return log_error_errno(r, "Failed to set LUKS data device %s: %m", source);
×
2702
                }
2703

2704
                /* Tokens are available in LUKS2 only, but it is ok to call (and fail) with LUKS1. */
2705
                if (!key_file && use_token_plugins()) {
81✔
2706
                        r = crypt_activate_by_token_pin_ask_password(
52✔
2707
                                        cd,
2708
                                        volume,
2709
                                        /* type= */ NULL,
2710
                                        until,
2711
                                        /* userdata= */ NULL,
2712
                                        flags,
2713
                                        "Please enter LUKS2 token PIN:",
2714
                                        "luks2-pin",
2715
                                        "cryptsetup.luks2-pin");
2716
                        if (r >= 0) {
52✔
2717
                                log_debug("Volume %s activated with a LUKS token.", volume);
37✔
2718
                                return 0;
2719
                        }
2720

2721
                        log_debug_errno(r, "Token activation unsuccessful for device %s: %m", sym_crypt_get_device_name(cd));
15✔
2722
                }
2723
        }
2724

2725
        if (streq_ptr(arg_type, CRYPT_BITLK)) {
44✔
2726
                r = sym_crypt_load(cd, CRYPT_BITLK, NULL);
×
2727
                if (r < 0)
×
2728
                        return log_error_errno(r, "Failed to load Bitlocker superblock on device %s: %m", sym_crypt_get_device_name(cd));
×
2729
        }
2730

2731
        bool use_cached_passphrase = true, try_discover_key = !key_file;
44✔
2732
        const char *discovered_key_fn = strjoina(volume, ".key");
220✔
2733
        _cleanup_strv_free_erase_ char **passwords = NULL;
44✔
2734
        for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) {
59✔
2735
                _cleanup_(iovec_done_erase) struct iovec discovered_key_data = {};
59✔
2736
                const struct iovec *key_data = NULL;
59✔
2737
                TokenType token_type = determine_token_type();
59✔
2738

2739
                log_debug("Beginning attempt %u to unlock.", tries);
59✔
2740

2741
                /* When we were able to acquire multiple keys, let's always process them in this order:
2742
                 *
2743
                 *    1. A key acquired via PKCS#11 or FIDO2 token, or TPM2 chip
2744
                 *    2. The configured or discovered key, of which both are exclusive and optional
2745
                 *    3. The empty password, in case arg_try_empty_password is set
2746
                 *    4. We enquire the user for a password
2747
                 */
2748

2749
                if (try_discover_key) {
59✔
2750
                        r = discover_key(discovered_key_fn, volume, token_type, &discovered_key_data);
25✔
2751
                        if (r < 0)
25✔
2752
                                return r;
2753
                        if (r > 0)
25✔
2754
                                key_data = &discovered_key_data;
1✔
2755
                }
2756

2757
                if (token_type < 0 && !key_file && !key_data && !passwords) {
59✔
2758

2759
                        /* If we have nothing to try anymore, then acquire a new password */
2760

2761
                        if (arg_try_empty_password) {
17✔
2762
                                /* Hmm, let's try an empty password now, but only once */
2763
                                arg_try_empty_password = false;
2✔
2764
                                key_data = &iovec_empty;
2✔
2765
                        } else {
2766
                                /* Ask the user for a passphrase or recovery key only as last resort, if we
2767
                                 * have nothing else to check for */
2768
                                if (passphrase_type == PASSPHRASE_NONE) {
15✔
2769
                                        passphrase_type = check_registered_passwords(cd);
15✔
2770
                                        if (passphrase_type == PASSPHRASE_NONE)
15✔
2771
                                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No passphrase or recovery key registered.");
×
2772
                                }
2773

2774
                                r = get_password(
15✔
2775
                                                volume,
2776
                                                source,
2777
                                                until,
2778
                                                /* ignore_cached= */ !use_cached_passphrase || arg_verify,
15✔
2779
                                                passphrase_type,
2780
                                                &passwords);
2781
                                use_cached_passphrase = false;
15✔
2782
                                if (r == -EAGAIN)
15✔
2783
                                        continue;
×
2784
                                if (r < 0)
15✔
2785
                                        return r;
2786
                        }
2787
                }
2788

2789
                if (streq_ptr(arg_type, CRYPT_TCRYPT))
44✔
2790
                        r = attach_tcrypt(cd, volume, token_type, key_file, key_data, passwords, flags);
×
2791
                else
2792
                        r = attach_luks_or_plain_or_bitlk(cd, volume, token_type, key_file, key_data, passwords, flags, until);
44✔
2793
                if (r >= 0)
44✔
2794
                        break;
2795
                if (r != -EAGAIN)
18✔
2796
                        return r;
2797

2798
                /* Key not correct? Let's try again, but let's invalidate one of the passed fields, so that
2799
                 * we fall back to the next best thing. */
2800

2801
                if (token_type == TOKEN_TPM2) {
15✔
2802
                        arg_tpm2_device = mfree(arg_tpm2_device);
11✔
2803
                        arg_tpm2_device_auto = false;
11✔
2804
                        continue;
11✔
2805
                }
2806

2807
                if (token_type == TOKEN_FIDO2) {
4✔
2808
                        arg_fido2_device = mfree(arg_fido2_device);
×
2809
                        arg_fido2_device_auto = false;
×
2810
                        continue;
×
2811
                }
2812

2813
                if (token_type == TOKEN_PKCS11) {
4✔
2814
                        arg_pkcs11_uri = mfree(arg_pkcs11_uri);
×
2815
                        arg_pkcs11_uri_auto = false;
×
2816
                        continue;
×
2817
                }
2818

2819
                if (try_discover_key) {
4✔
2820
                        try_discover_key = false;
×
2821
                        continue;
×
2822
                }
2823

2824
                if (key_file) {
4✔
2825
                        key_file = NULL;
4✔
2826
                        continue;
4✔
2827
                }
2828

2829
                if (passwords) {
×
2830
                        passwords = strv_free_erase(passwords);
×
2831
                        continue;
×
2832
                }
2833

2834
                log_debug("Prepared for next attempt to unlock.");
×
2835
        }
2836

2837
        if (arg_tries != 0 && tries >= arg_tries)
26✔
2838
                return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Too many attempts to activate; giving up.");
×
2839

2840
        return 0;
2841
}
2842

2843
VERB(verb_detach, "detach", "VOLUME", 2, 2, 0,
2844
     "Detach an encrypted block device");
2845
static int verb_detach(int argc, char *argv[], uintptr_t _data, void *userdata) {
66✔
2846
        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
66✔
2847
        const char *volume = ASSERT_PTR(argv[1]);
66✔
2848
        int r;
66✔
2849

2850
        assert(argc == 2);
66✔
2851

2852
        if (!filename_is_valid(volume))
66✔
2853
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
×
2854

2855
        r = sym_crypt_init_by_name(&cd, volume);
66✔
2856
        if (r == -ENODEV) {
66✔
2857
                log_info("Volume %s already inactive.", volume);
3✔
2858
                return 0;
2859
        }
2860
        if (r < 0)
63✔
2861
                return log_error_errno(r, "crypt_init_by_name() for volume '%s' failed: %m", volume);
×
2862

2863
        cryptsetup_enable_logging(cd);
63✔
2864

2865
        r = sym_crypt_deactivate(cd, volume);
63✔
2866
        if (r < 0)
63✔
2867
                return log_error_errno(r, "Failed to deactivate '%s': %m", volume);
×
2868

2869
        return 0;
2870
}
2871

2872
static int run(int argc, char *argv[]) {
147✔
2873
        int r;
147✔
2874

2875
        log_setup();
147✔
2876

2877
        umask(0022);
147✔
2878

2879
        char **args = NULL;
147✔
2880
        r = parse_argv(argc, argv, &args);
147✔
2881
        if (r <= 0)
147✔
2882
                return r;
147✔
2883

2884
        r = DLOPEN_CRYPTSETUP(LOG_ERR, SD_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED);
147✔
2885
        if (r < 0)
147✔
2886
                return r;
2887

2888
        return dispatch_verb(args, NULL);
147✔
2889
}
2890

2891
DEFINE_MAIN_FUNCTION(run);
147✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc