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

systemd / systemd / 16791678039

06 Aug 2025 11:10PM UTC coverage: 72.181% (-0.04%) from 72.223%
16791678039

push

github

yuwata
logging: Improve logging messages related to NFTSet.

The 'NFTSet' directive in various units adds and removes entries in nftables
sets, it does not add or remove entire sets. The logging messages should
indicate that an entry was added or removed, not that a set was added or
removed.

2 of 6 new or added lines in 3 files covered. (33.33%)

496 existing lines in 52 files now uncovered.

302228 of 418708 relevant lines covered (72.18%)

647735.83 hits per line

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

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

3
#include <getopt.h>
4
#include <mntent.h>
5
#include <sys/mman.h>
6
#include <sys/stat.h>
7
#include <unistd.h>
8

9
#include "sd-device.h"
10
#include "sd-event.h"
11
#include "sd-json.h"
12
#include "sd-messages.h"
13

14
#include "alloc-util.h"
15
#include "argv-util.h"
16
#include "ask-password-api.h"
17
#include "build.h"
18
#include "cryptsetup-fido2.h"
19
#include "cryptsetup-keyfile.h"
20
#include "cryptsetup-pkcs11.h"
21
#include "cryptsetup-tpm2.h"
22
#include "cryptsetup-util.h"
23
#include "efi-api.h"
24
#include "efi-loader.h"
25
#include "efivars.h"
26
#include "env-util.h"
27
#include "errno-util.h"
28
#include "escape.h"
29
#include "extract-word.h"
30
#include "fileio.h"
31
#include "fs-util.h"
32
#include "fstab-util.h"
33
#include "hexdecoct.h"
34
#include "json-util.h"
35
#include "libfido2-util.h"
36
#include "log.h"
37
#include "main-func.h"
38
#include "memory-util.h"
39
#include "mount-util.h"
40
#include "nulstr-util.h"
41
#include "parse-util.h"
42
#include "path-util.h"
43
#include "pkcs11-util.h"
44
#include "pretty-print.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_link_keyring = NULL;
127
static char *arg_link_key_type = NULL;
128
static char *arg_link_key_description = NULL;
129

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

146
static const char* const passphrase_type_table[_PASSPHRASE_TYPE_MAX] = {
147
        [PASSPHRASE_REGULAR]      = "passphrase",
148
        [PASSPHRASE_RECOVERY_KEY] = "recovery key",
149
        [PASSPHRASE_BOTH]         = "passphrase or recovery key",
150
};
151

152
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(passphrase_type, PassphraseType);
×
153

154
static const char* const token_type_table[_TOKEN_TYPE_MAX] = {
155
        [TOKEN_TPM2]   = "tpm2",
156
        [TOKEN_FIDO2]  = "fido2",
157
        [TOKEN_PKCS11] = "pkcs11",
158
};
159

160
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(token_type, TokenType);
45✔
161

162
/* Options Debian's crypttab knows we don't:
163
    check=
164
    checkargs=
165
    noearly
166
    loud
167
    quiet
168
    keyscript=
169
    initramfs
170
*/
171

172
static int parse_one_option(const char *option) {
145✔
173
        const char *val;
145✔
174
        int r;
145✔
175

176
        assert(option);
145✔
177

178
        /* Handled outside of this tool */
179
        if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail", "_netdev", "keyfile-timeout"))
145✔
180
                return 0;
1✔
181

182
        if (startswith(option, "keyfile-timeout="))
144✔
183
                return 0;
184

185
        if ((val = startswith(option, "cipher="))) {
144✔
186
                r = free_and_strdup(&arg_cipher, val);
×
187
                if (r < 0)
×
188
                        return log_oom();
×
189

190
        } else if ((val = startswith(option, "size="))) {
144✔
191

192
                r = safe_atou(val, &arg_key_size);
×
193
                if (r < 0) {
×
194
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
195
                        return 0;
×
196
                }
197

198
                if (arg_key_size % 8) {
×
199
                        log_warning("size= not a multiple of 8, ignoring.");
×
200
                        return 0;
×
201
                }
202

203
                arg_key_size /= 8;
×
204

205
        } else if ((val = startswith(option, "sector-size="))) {
144✔
206

207
                r = safe_atou(val, &arg_sector_size);
×
208
                if (r < 0) {
×
209
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
210
                        return 0;
×
211
                }
212

213
                if (arg_sector_size % 2) {
×
214
                        log_warning("sector-size= not a multiple of 2, ignoring.");
×
215
                        return 0;
×
216
                }
217

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

221
        } else if ((val = startswith(option, "key-slot=")) ||
144✔
222
                   (val = startswith(option, "keyslot="))) {
142✔
223

224
                arg_type = ANY_LUKS;
2✔
225
                r = safe_atoi(val, &arg_key_slot);
2✔
226
                if (r < 0)
2✔
227
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
228

229
        } else if ((val = startswith(option, "tcrypt-keyfile="))) {
142✔
230

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

238
        } else if ((val = startswith(option, "keyfile-size="))) {
142✔
239

240
                r = safe_atou(val, &arg_keyfile_size);
3✔
241
                if (r < 0)
3✔
242
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
243

244
        } else if ((val = startswith(option, "keyfile-offset="))) {
139✔
245

246
                r = safe_atou64(val, &arg_keyfile_offset);
5✔
247
                if (r < 0)
5✔
248
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
249

250
        } else if ((val = startswith(option, "keyfile-erase="))) {
134✔
251

252
                r = parse_boolean(val);
2✔
253
                if (r < 0) {
2✔
254
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
255
                        return 0;
×
256
                }
257

258
                arg_keyfile_erase = r;
2✔
259

260
        } else if (streq(option, "keyfile-erase"))
132✔
261
                arg_keyfile_erase = true;
×
262

263
        else if ((val = startswith(option, "hash="))) {
132✔
264
                r = free_and_strdup(&arg_hash, val);
×
265
                if (r < 0)
×
266
                        return log_oom();
×
267

268
        } else if ((val = startswith(option, "header="))) {
132✔
269
                if (!arg_type || !STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT))
9✔
270
                        arg_type = ANY_LUKS;
7✔
271

272
                if (!path_is_absolute(val))
9✔
273
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
274
                                               "Header path \"%s\" is not absolute, refusing.", val);
275

276
                if (arg_header)
9✔
277
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
278
                                               "Duplicate header= option, refusing.");
279

280
                arg_header = strdup(val);
9✔
281
                if (!arg_header)
9✔
282
                        return log_oom();
×
283

284
        } else if ((val = startswith(option, "tries="))) {
123✔
285

286
                r = safe_atou(val, &arg_tries);
×
287
                if (r < 0)
×
288
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
145✔
289

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

304
                        SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_ECHO, r);
×
305
                        SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_SILENT, !r);
×
306
                }
307
        } else if ((val = startswith(option, "password-cache="))) {
123✔
308
                arg_password_cache_set = true;
×
309

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

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

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

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

366
        } else if ((val = startswith(option, "offset="))) {
115✔
367

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

372
        } else if ((val = startswith(option, "skip="))) {
115✔
373

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

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

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

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

391
                        arg_pkcs11_uri_auto = false;
×
392
                }
393

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

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

404
                        arg_fido2_device_auto = false;
×
405
                }
406

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

477
                        arg_tpm2_device_auto = false;
×
478
                }
479

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

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

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

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

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

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

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

504
                arg_tpm2_pin = r;
×
505

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

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

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

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

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

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

533
                arg_tpm2_measure_pcr = pcr;
×
534

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

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

540
                l = strv_split(optarg, ":");
×
541
                if (!l)
×
542
                        return log_oom();
×
543

544
                STRV_FOREACH(i, l) {
×
545
                        const EVP_MD *implementation;
×
546

547
                        implementation = EVP_get_digestbyname(*i);
×
548
                        if (!implementation)
×
549
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Unknown bank '%s', refusing.", val);
×
550

551
                        if (strv_extend(&arg_tpm2_measure_banks, EVP_MD_name(implementation)) < 0)
×
552
                                return log_oom();
×
553
                }
554
#else
555
                log_error("Build lacks OpenSSL support, cannot measure to PCR banks, ignoring: %s", option);
556
#endif
557

558
        } else if ((val = startswith(option, "try-empty-password="))) {
64✔
559

560
                r = parse_boolean(val);
1✔
561
                if (r < 0) {
1✔
562
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
563
                        return 0;
×
564
                }
565

566
                arg_try_empty_password = r;
1✔
567

568
        } else if (streq(option, "try-empty-password"))
63✔
569
                arg_try_empty_password = true;
1✔
570
        else if ((val = startswith(option, "headless="))) {
62✔
571

572
                r = parse_boolean(val);
55✔
573
                if (r < 0) {
55✔
574
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
×
575
                        return 0;
×
576
                }
577

578
                SET_FLAG(arg_ask_password_flags, ASK_PASSWORD_HEADLESS, r);
55✔
579
        } else if (streq(option, "headless"))
7✔
580
                arg_ask_password_flags |= ASK_PASSWORD_HEADLESS;
7✔
581

UNCOV
582
        else if ((val = startswith(option, "token-timeout="))) {
×
583

584
                r = parse_sec_fix_0(val, &arg_token_timeout_usec);
×
585
                if (r < 0)
×
586
                        log_warning_errno(r, "Failed to parse %s, ignoring: %m", option);
115✔
587

UNCOV
588
        } else if ((val = startswith(option, "link-volume-key="))) {
×
589
#ifdef HAVE_CRYPT_SET_KEYRING_TO_LINK
590
                _cleanup_free_ char *keyring = NULL, *key_type = NULL, *key_description = NULL;
×
591
                const char *sep;
×
592

593
                /* Stick with cryptsetup --link-vk-to-keyring format
594
                 * <keyring_description>::%<key_type>:<key_description>,
595
                 * where %<key_type> is optional and defaults to 'user'.
596
                 */
597
                sep = strstr(val, "::");
×
598
                if (!sep)
×
599
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse link-volume-key= option value: %s", val);
×
600

601
                /* cryptsetup (cli) supports <keyring_description> passed in various formats:
602
                 * - well-known keyrings prefixed with '@' (@u user, @s session, etc)
603
                 * - text descriptions prefixed with "%:" or "%keyring:".
604
                 * - text description with no prefix.
605
                 * - numeric keyring id (ignored in current patch set). */
606
                keyring = strndup(val, sep - val);
×
607
                if (!keyring)
×
608
                        return log_oom();
×
609

610
                /* add type prefix if missing (crypt_set_keyring_to_link() expects it) */
611
                if (!IN_SET(*keyring, '@', '%'))
×
612
                        if (!strprepend(&keyring, "%:"))
×
613
                                return log_oom();
×
614

615
                sep += 2;
×
616

617
                /* %<key_type> is optional (and defaults to 'user') */
618
                if (*sep == '%') {
×
619
                        /* must be separated by colon */
620
                        const char *c = strchr(sep, ':');
×
621
                        if (!c)
×
622
                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Failed to parse link-volume-key= option value: %s", val);
×
623

624
                        key_type = strndup(sep + 1, c - sep - 1);
×
625
                        if (!key_type)
×
626
                                return log_oom();
×
627

628
                        sep = c + 1;
×
629
                }
630

631
                key_description = strdup(sep);
×
632
                if (!key_description)
×
633
                        return log_oom();
×
634

635
                free_and_replace(arg_link_keyring, keyring);
×
636
                free_and_replace(arg_link_key_type, key_type);
×
637
                free_and_replace(arg_link_key_description, key_description);
×
638
#else
639
                log_error("Build lacks libcryptsetup support for linking volume keys in user specified kernel keyrings upon device activation, ignoring: %s", option);
640
#endif
UNCOV
641
        } else if (!streq(option, "x-initrd.attach"))
×
642
                log_warning("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
×
643

644
        return 0;
645
}
646

647
static int parse_crypt_config(const char *options) {
70✔
648
        assert(options);
70✔
649

650
        for (;;) {
360✔
651
                _cleanup_free_ char *word = NULL;
145✔
652
                int r;
215✔
653

654
                r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
215✔
655
                if (r < 0)
215✔
656
                        return log_error_errno(r, "Failed to parse options: %m");
×
657
                if (r == 0)
215✔
658
                        break;
659

660
                r = parse_one_option(word);
145✔
661
                if (r < 0)
145✔
662
                        return r;
663
        }
664

665
        /* sanity-check options */
666
        if (arg_type && !streq(arg_type, CRYPT_PLAIN)) {
70✔
667
                if (arg_offset != 0)
17✔
668
                      log_warning("offset= ignored with type %s", arg_type);
×
669
                if (arg_skip != 0)
17✔
670
                      log_warning("skip= ignored with type %s", arg_type);
×
671
        }
672

673
        if (arg_pkcs11_uri || arg_pkcs11_uri_auto) {
70✔
674
                /* If password-cache was not configured explicitly, default to no cache for PKCS#11 */
675
                if (!arg_password_cache_set)
6✔
676
                        arg_ask_password_flags &= ~(ASK_PASSWORD_ACCEPT_CACHED|ASK_PASSWORD_PUSH_CACHE);
6✔
677

678
                /* This prevents future backward-compatibility issues if we decide to allow caching for PKCS#11 */
679
                if (FLAGS_SET(arg_ask_password_flags, ASK_PASSWORD_ACCEPT_CACHED))
6✔
680
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
681
                                               "Password cache is not supported for PKCS#11 security tokens.");
682
        }
683

684
        return 0;
685
}
686

687
static char* disk_description(const char *path) {
10✔
688
        static const char name_fields[] =
10✔
689
                "DM_NAME\0"
690
                "ID_MODEL_FROM_DATABASE\0"
691
                "ID_MODEL\0";
692

693
        _cleanup_(sd_device_unrefp) sd_device *device = NULL;
10✔
694
        const char *name;
10✔
695
        struct stat st;
10✔
696

697
        assert(path);
10✔
698

699
        if (stat(path, &st) < 0)
10✔
700
                return NULL;
701

702
        if (!S_ISBLK(st.st_mode))
10✔
703
                return NULL;
704

705
        if (sd_device_new_from_stat_rdev(&device, &st) < 0)
×
706
                return NULL;
707

708
        if (sd_device_get_property_value(device, "ID_PART_ENTRY_NAME", &name) >= 0) {
×
709
                _cleanup_free_ char *unescaped = NULL;
×
710
                ssize_t l;
×
711

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

716
                l = cunescape(name, UNESCAPE_RELAX, &unescaped);
×
717
                if (l < 0) {
×
718
                        log_debug_errno(l, "Failed to unescape ID_PART_ENTRY_NAME, skipping device: %m");
×
719
                        return NULL;
×
720
                }
721

722
                if (!isempty(unescaped) && !string_has_cc(unescaped, NULL))
×
723
                        return TAKE_PTR(unescaped);
×
724
        }
725

726
        /* These need no unescaping. */
727
        NULSTR_FOREACH(i, name_fields)
×
728
                if (sd_device_get_property_value(device, i, &name) >= 0 &&
×
729
                    !isempty(name))
×
730
                        return strdup(name);
×
731

732
        return NULL;
733
}
734

735
static char *disk_mount_point(const char *label) {
10✔
736
        _cleanup_free_ char *device = NULL;
10✔
737
        _cleanup_endmntent_ FILE *f = NULL;
10✔
738
        struct mntent *m;
10✔
739

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

742
        device = strjoin("/dev/mapper/", label);
10✔
743
        if (!device)
10✔
744
                return NULL;
745

746
        f = setmntent(fstab_path(), "re");
10✔
747
        if (!f)
10✔
748
                return NULL;
749

750
        while ((m = getmntent(f)))
10✔
751
                if (path_equal(m->mnt_fsname, device))
×
752
                        return strdup(m->mnt_dir);
×
753

754
        return NULL;
755
}
756

757
static char *friendly_disk_name(const char *src, const char *vol) {
10✔
758
        _cleanup_free_ char *description = NULL, *mount_point = NULL;
10✔
759
        char *name_buffer = NULL;
10✔
760
        int r;
10✔
761

762
        assert(src);
10✔
763
        assert(vol);
10✔
764

765
        description = disk_description(src);
10✔
766
        mount_point = disk_mount_point(vol);
10✔
767

768
        /* If the description string is simply the volume name, then let's not show this twice */
769
        if (description && streq(vol, description))
10✔
770
                description = mfree(description);
×
771

772
        if (mount_point && description)
10✔
773
                r = asprintf(&name_buffer, "%s (%s) on %s", description, vol, mount_point);
×
774
        else if (mount_point)
×
775
                r = asprintf(&name_buffer, "%s on %s", vol, mount_point);
×
776
        else if (description)
10✔
777
                r = asprintf(&name_buffer, "%s (%s)", description, vol);
×
778
        else
779
                return strdup(vol);
10✔
780
        if (r < 0)
×
781
                return NULL;
782

783
        return name_buffer;
×
784
}
785

786
static PassphraseType check_registered_passwords(struct crypt_device *cd) {
14✔
787
        _cleanup_free_ bool *slots = NULL;
14✔
788
        int slot_max;
14✔
789
        PassphraseType passphrase_type = PASSPHRASE_NONE;
14✔
790

791
        assert(cd);
14✔
792

793
        if (!streq_ptr(crypt_get_type(cd), CRYPT_LUKS2)) {
14✔
794
                log_debug("%s: not a LUKS2 device, only passphrases are supported", crypt_get_device_name(cd));
×
795
                return PASSPHRASE_REGULAR;
×
796
        }
797

798
        /* Search all used slots */
799
        assert_se((slot_max = crypt_keyslot_max(CRYPT_LUKS2)) > 0);
14✔
800
        slots = new(bool, slot_max);
14✔
801
        if (!slots)
14✔
802
                return log_oom();
×
803

804
        for (int slot = 0; slot < slot_max; slot++)
462✔
805
                slots[slot] = IN_SET(crypt_keyslot_status(cd, slot), CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST);
448✔
806

807
        /* Iterate all LUKS2 tokens and keep track of all their slots */
808
        for (int token = 0; token < sym_crypt_token_max(CRYPT_LUKS2); token++) {
462✔
809
                _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
448✔
810
                const char *type;
448✔
811
                sd_json_variant *w, *z;
448✔
812
                int tk;
448✔
813

814
                tk = cryptsetup_get_token_as_json(cd, token, NULL, &v);
448✔
815
                if (IN_SET(tk, -ENOENT, -EINVAL))
448✔
816
                        continue;
439✔
817
                if (tk < 0) {
9✔
818
                        log_warning_errno(tk, "Failed to read JSON token data, ignoring: %m");
×
819
                        continue;
×
820
                }
821

822
                w = sd_json_variant_by_key(v, "type");
9✔
823
                if (!w || !sd_json_variant_is_string(w)) {
9✔
824
                        log_warning("Token JSON data lacks type field, ignoring.");
×
825
                        continue;
×
826
                }
827

828
                type = sd_json_variant_string(w);
9✔
829
                if (STR_IN_SET(type, "systemd-recovery", "systemd-pkcs11", "systemd-fido2", "systemd-tpm2")) {
9✔
830

831
                        /* At least exists one recovery key */
832
                        if (streq(type, "systemd-recovery"))
9✔
833
                                passphrase_type |= PASSPHRASE_RECOVERY_KEY;
×
834

835
                        w = sd_json_variant_by_key(v, "keyslots");
9✔
836
                        if (!w || !sd_json_variant_is_array(w)) {
9✔
837
                                log_warning("Token JSON data lacks keyslots field, ignoring.");
×
838
                                continue;
×
839
                        }
840

841
                        JSON_VARIANT_ARRAY_FOREACH(z, w) {
18✔
842
                                unsigned u;
9✔
843
                                int at;
9✔
844

845
                                if (!sd_json_variant_is_string(z)) {
9✔
846
                                        log_warning("Token JSON data's keyslot field is not an array of strings, ignoring.");
×
847
                                        continue;
×
848
                                }
849

850
                                at = safe_atou(sd_json_variant_string(z), &u);
9✔
851
                                if (at < 0) {
9✔
852
                                        log_warning_errno(at, "Token JSON data's keyslot field is not an integer formatted as string, ignoring.");
×
853
                                        continue;
×
854
                                }
855

856
                                if (u >= (unsigned) slot_max) {
9✔
857
                                        log_warning_errno(at, "Token JSON data's keyslot field exceeds the maximum value allowed, ignoring.");
×
858
                                        continue;
×
859
                                }
860

861
                                slots[u] = false;
9✔
862
                        }
863
                }
864
        }
865

866
        /* Check if any of the slots is not referenced by systemd tokens */
867
        for (int slot = 0; slot < slot_max; slot++)
14✔
868
                if (slots[slot]) {
14✔
869
                        passphrase_type |= PASSPHRASE_REGULAR;
14✔
870
                        break;
14✔
871
                }
872

873
        /* All the slots are referenced by systemd tokens, so if a recovery key is not enrolled,
874
         * we will not be able to enter a passphrase. */
875
        return passphrase_type;
876
}
877

878
static int get_password(
14✔
879
                const char *vol,
880
                const char *src,
881
                usec_t until,
882
                bool ignore_cached,
883
                PassphraseType passphrase_type,
884
                char ***ret) {
885

886
        _cleanup_free_ char *friendly = NULL, *text = NULL, *disk_path = NULL, *id = NULL;
14✔
887
        _cleanup_strv_free_erase_ char **passwords = NULL;
×
888
        AskPasswordFlags flags = arg_ask_password_flags;
14✔
889
        int r;
14✔
890

891
        assert(vol);
14✔
892
        assert(src);
14✔
893
        assert(ret);
14✔
894

895
        if (FLAGS_SET(arg_ask_password_flags, ASK_PASSWORD_HEADLESS))
14✔
896
                return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Password querying disabled via 'headless' option.");
14✔
897

898
        friendly = friendly_disk_name(src, vol);
×
899
        if (!friendly)
×
900
                return log_oom();
×
901

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

905
        disk_path = cescape(src);
×
906
        if (!disk_path)
×
907
                return log_oom();
×
908

909
        id = strjoin("cryptsetup:", disk_path);
×
910
        if (!id)
×
911
                return log_oom();
×
912

913
        AskPasswordRequest req = {
×
914
                .tty_fd = -EBADF,
915
                .message = text,
916
                .icon = "drive-harddisk",
917
                .id = id,
918
                .keyring = "cryptsetup",
919
                .credential = "cryptsetup.passphrase",
920
                .until = until,
921
                .hup_fd = -EBADF,
922
        };
923

924
        if (ignore_cached)
×
925
                flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
×
926

927
        r = ask_password_auto(&req, flags, &passwords);
×
928
        if (r < 0)
×
929
                return log_error_errno(r, "Failed to query password: %m");
×
930

931
        if (arg_verify) {
×
932
                _cleanup_strv_free_erase_ char **passwords2 = NULL;
×
933

934
                assert(strv_length(passwords) == 1);
×
935

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

940
                free(id);
×
941
                id = strjoin("cryptsetup-verification:", disk_path);
×
942
                if (!id)
×
943
                        return log_oom();
×
944

945
                req.message = text;
×
946
                req.id = id;
×
947

948
                r = ask_password_auto(&req, flags, &passwords2);
×
949
                if (r < 0)
×
950
                        return log_error_errno(r, "Failed to query verification password: %m");
×
951

952
                assert(strv_length(passwords2) == 1);
×
953

954
                if (!streq(passwords[0], passwords2[0]))
×
955
                        return log_warning_errno(SYNTHETIC_ERRNO(EAGAIN),
×
956
                                                 "Passwords did not match, retrying.");
957
        }
958

959
        strv_uniq(passwords);
×
960

961
        STRV_FOREACH(p, passwords) {
×
962
                char *c;
×
963

964
                if (strlen(*p)+1 >= arg_key_size)
×
965
                        continue;
×
966

967
                /* Pad password if necessary */
968
                c = new(char, arg_key_size);
×
969
                if (!c)
×
970
                        return log_oom();
14✔
971

972
                strncpy(c, *p, arg_key_size);
×
973
                erase_and_free(*p);
×
974
                *p = TAKE_PTR(c);
×
975
        }
976

977
        *ret = TAKE_PTR(passwords);
×
978

979
        return 0;
×
980
}
981

982
static int measure_volume_key(
×
983
                struct crypt_device *cd,
984
                const char *name,
985
                const void *volume_key,
986
                size_t volume_key_size) {
987

988
        int r;
×
989

990
        assert(cd);
×
991
        assert(name);
×
992
        assert(volume_key);
×
993
        assert(volume_key_size > 0);
×
994

995
        if (arg_tpm2_measure_pcr == UINT_MAX) {
×
996
                log_debug("Not measuring volume key, deactivated.");
×
997
                return 0;
×
998
        }
999

1000
        r = efi_measured_uki(LOG_WARNING);
×
1001
        if (r < 0)
×
1002
                return r;
1003
        if (r == 0) {
×
1004
                log_debug("Kernel stub did not measure kernel image into the expected PCR, skipping userspace measurement, too.");
×
1005
                return 0;
×
1006
        }
1007

1008
#if HAVE_TPM2
1009
        _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
×
1010
        r = tpm2_context_new_or_warn(arg_tpm2_device, &c);
×
1011
        if (r < 0)
×
1012
                return r;
1013

1014
        _cleanup_strv_free_ char **l = NULL;
×
1015
        if (strv_isempty(arg_tpm2_measure_banks)) {
×
1016
                r = tpm2_get_good_pcr_banks_strv(c, UINT32_C(1) << arg_tpm2_measure_pcr, &l);
×
1017
                if (r < 0)
×
1018
                        return log_error_errno(r, "Could not verify pcr banks: %m");
×
1019
        }
1020

1021
        _cleanup_free_ char *joined = strv_join(l ?: arg_tpm2_measure_banks, ", ");
×
1022
        if (!joined)
×
1023
                return log_oom();
×
1024

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

1029
        _cleanup_free_ char *escaped = NULL;
×
1030
        escaped = xescape(name, ":"); /* avoid ambiguity around ":" once we join things below */
×
1031
        if (!escaped)
×
1032
                return log_oom();
×
1033

1034
        _cleanup_free_ char *s = NULL;
×
1035
        s = strjoin("cryptsetup:", escaped, ":", strempty(crypt_get_uuid(cd)));
×
1036
        if (!s)
×
1037
                return log_oom();
×
1038

1039
        r = tpm2_extend_bytes(c, l ?: arg_tpm2_measure_banks, arg_tpm2_measure_pcr, s, SIZE_MAX, volume_key, volume_key_size, TPM2_EVENT_VOLUME_KEY, s);
×
1040
        if (r < 0)
×
1041
                return log_error_errno(r, "Could not extend PCR: %m");
×
1042

1043
        log_struct(LOG_INFO,
×
1044
                   LOG_MESSAGE_ID(SD_MESSAGE_TPM_PCR_EXTEND_STR),
1045
                   LOG_MESSAGE("Successfully extended PCR index %u with '%s' and volume key (banks %s).", arg_tpm2_measure_pcr, s, joined),
1046
                   LOG_ITEM("MEASURING=%s", s),
1047
                   LOG_ITEM("PCR=%u", arg_tpm2_measure_pcr),
1048
                   LOG_ITEM("BANKS=%s", joined));
1049

1050
        return 0;
1051
#else
1052
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support disabled, not measuring.");
1053
#endif
1054
}
1055

1056
static int log_external_activation(int r, const char *volume) {
×
1057
        assert(volume);
×
1058

1059
        log_notice_errno(r, "Volume '%s' has been activated externally while we have been trying to activate it.", volume);
×
1060
        return 0;
×
1061
}
1062

1063
static int measured_crypt_activate_by_volume_key(
×
1064
                struct crypt_device *cd,
1065
                const char *name,
1066
                const void *volume_key,
1067
                size_t volume_key_size,
1068
                uint32_t flags) {
1069

1070
        int r;
×
1071

1072
        assert(cd);
×
1073
        assert(name);
×
1074

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

1077
        r = crypt_activate_by_volume_key(cd, name, volume_key, volume_key_size, flags);
×
1078
        if (r == -EEXIST) /* volume is already active */
×
1079
                return log_external_activation(r, name);
×
1080
        if (r < 0)
×
1081
                return r;
1082

1083
        if (volume_key_size == 0) {
×
1084
                log_debug("Not measuring volume key, none specified.");
×
1085
                return r;
×
1086
        }
1087

1088
        (void) measure_volume_key(cd, name, volume_key, volume_key_size); /* OK if fails */
×
1089
        return r;
×
1090
}
1091

1092
static int measured_crypt_activate_by_passphrase(
24✔
1093
                struct crypt_device *cd,
1094
                const char *name,
1095
                int keyslot,
1096
                const char *passphrase,
1097
                size_t passphrase_size,
1098
                uint32_t flags) {
1099

1100
        _cleanup_(erase_and_freep) void *vk = NULL;
24✔
1101
        size_t vks;
24✔
1102
        int r;
24✔
1103

1104
        assert(cd);
24✔
1105

1106
        /* A wrapper around crypt_activate_by_passphrase() which also measures to a PCR if that's
1107
         * requested. Note that we need the volume key for the measurement, and
1108
         * crypt_activate_by_passphrase() doesn't give us access to this. Hence, we operate indirectly, and
1109
         * retrieve the volume key first, and then activate through that. */
1110

1111
        if (arg_tpm2_measure_pcr == UINT_MAX) {
24✔
1112
                log_debug("Not measuring volume key, deactivated.");
24✔
1113
                goto shortcut;
24✔
1114
        }
1115

1116
        r = crypt_get_volume_key_size(cd);
×
1117
        if (r < 0)
×
1118
                return r;
1119
        if (r == 0) {
×
1120
                log_debug("Not measuring volume key, none defined.");
×
1121
                goto shortcut;
×
1122
        }
1123

1124
        vk = malloc(vks = r);
×
1125
        if (!vk)
×
1126
                return -ENOMEM;
1127

1128
        r = crypt_volume_key_get(cd, keyslot, vk, &vks, passphrase, passphrase_size);
×
1129
        if (r < 0)
×
1130
                return r;
1131

1132
        return measured_crypt_activate_by_volume_key(cd, name, vk, vks, flags);
×
1133

1134
shortcut:
24✔
1135
        r = crypt_activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags);
24✔
1136
        if (r == -EEXIST) /* volume is already active */
24✔
1137
                return log_external_activation(r, name);
×
1138
        return r;
1139
}
1140

1141
static int attach_tcrypt(
×
1142
                struct crypt_device *cd,
1143
                const char *name,
1144
                TokenType token_type,
1145
                const char *key_file,
1146
                const struct iovec *key_data,
1147
                char **passwords,
1148
                uint32_t flags) {
1149

1150
        int r = 0;
×
1151
        _cleanup_(erase_and_freep) char *passphrase = NULL;
×
1152
        struct crypt_params_tcrypt params = {
×
1153
                .flags = CRYPT_TCRYPT_LEGACY_MODES,
1154
                .keyfiles = (const char **)arg_tcrypt_keyfiles,
1155
                .keyfiles_count = strv_length(arg_tcrypt_keyfiles)
×
1156
        };
1157

1158
        assert(cd);
×
1159
        assert(name);
×
1160
        assert(key_file || key_data || !strv_isempty(passwords));
×
1161

1162
        if (token_type >= 0)
×
1163
                /* Ask for a regular password */
1164
                return log_error_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1165
                                       "Sorry, but tcrypt devices are currently not supported in conjunction with pkcs11/fido2/tpm2 support.");
1166

1167
        if (arg_tcrypt_hidden)
×
1168
                params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
×
1169

1170
        if (arg_tcrypt_system)
×
1171
                params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
×
1172

1173
        if (arg_tcrypt_veracrypt)
×
1174
                params.flags |= CRYPT_TCRYPT_VERA_MODES;
×
1175

1176
        if (arg_tcrypt_veracrypt && arg_tcrypt_veracrypt_pim != 0)
×
1177
                params.veracrypt_pim = arg_tcrypt_veracrypt_pim;
×
1178

1179
        if (key_data) {
×
1180
                params.passphrase = key_data->iov_base;
×
1181
                params.passphrase_size = key_data->iov_len;
×
1182
                r = crypt_load(cd, CRYPT_TCRYPT, &params);
×
1183
        } else if (key_file) {
×
1184
                r = read_one_line_file(key_file, &passphrase);
×
1185
                if (r < 0) {
×
1186
                        log_error_errno(r, "Failed to read password file '%s': %m", key_file);
×
1187
                        return -EAGAIN; /* log with the actual error, but return EAGAIN */
×
1188
                }
1189
                params.passphrase = passphrase;
×
1190
                params.passphrase_size = strlen(passphrase);
×
1191
                r = crypt_load(cd, CRYPT_TCRYPT, &params);
×
1192
        } else {
1193
                r = -EINVAL;
1194
                STRV_FOREACH(p, passwords){
×
1195
                        params.passphrase = *p;
×
1196
                        params.passphrase_size = strlen(*p);
×
1197
                        r = crypt_load(cd, CRYPT_TCRYPT, &params);
×
1198
                        if (r >= 0)
×
1199
                                break;
1200
                }
1201
        }
1202

1203
        if (r < 0) {
×
1204
                if (r == -EPERM) {
×
1205
                        if (key_data)
×
1206
                                log_error_errno(r, "Failed to activate using discovered key. (Key not correct?)");
×
1207
                        else if (key_file)
×
1208
                                log_error_errno(r, "Failed to activate using password file '%s'. (Key data not correct?)", key_file);
×
1209
                        else
1210
                                log_error_errno(r, "Failed to activate using supplied passwords.");
×
1211

1212
                        return r;
×
1213
                }
1214

1215
                return log_error_errno(r, "Failed to load tcrypt superblock on device %s: %m", crypt_get_device_name(cd));
×
1216
        }
1217

1218
        r = measured_crypt_activate_by_volume_key(cd, name, NULL, 0, flags);
×
1219
        if (r < 0)
×
1220
                return log_error_errno(r, "Failed to activate tcrypt device %s: %m", crypt_get_device_name(cd));
×
1221

1222
        return 0;
1223
}
1224

1225
static char *make_bindname(const char *volume, TokenType token_type) {
44✔
1226
        const char *token_type_name = token_type_to_string(token_type), *suffix;
44✔
1227
        char *bindname;
44✔
1228
        int r;
44✔
1229

1230
        switch (token_type) {
44✔
1231

1232
        case TOKEN_FIDO2:
1233
                suffix = "-salt";
1234
                break;
1235

1236
        default:
1237
                suffix = NULL;
44✔
1238
        }
1239

1240
        r = asprintf(&bindname,
44✔
1241
                     "@%" PRIx64"/cryptsetup%s%s%s/%s",
1242
                     random_u64(),
1243
                     token_type_name ? "-" : "",
1244
                     strempty(token_type_name),
1245
                     strempty(suffix),
1246
                     volume);
1247
        if (r < 0)
44✔
1248
                return NULL;
44✔
1249

1250
        return bindname;
44✔
1251
}
1252

1253
static int make_security_device_monitor(
×
1254
                sd_event **ret_event,
1255
                sd_device_monitor **ret_monitor) {
1256
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1257
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1258
        int r;
×
1259

1260
        assert(ret_event);
×
1261
        assert(ret_monitor);
×
1262

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

1267
        r = sd_event_default(&event);
×
1268
        if (r < 0)
×
1269
                return log_error_errno(r, "Failed to allocate event loop: %m");
×
1270

1271
        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
×
1272
        if (r < 0)
×
1273
                return log_error_errno(r, "Failed to install timeout event source: %m");
×
1274

1275
        r = sd_device_monitor_new(&monitor);
×
1276
        if (r < 0)
×
1277
                return log_error_errno(r, "Failed to allocate device monitor: %m");
×
1278

1279
        (void) sd_device_monitor_set_description(monitor, "security-device");
×
1280

1281
        r = sd_device_monitor_filter_add_match_tag(monitor, "security-device");
×
1282
        if (r < 0)
×
1283
                return log_error_errno(r, "Failed to configure device monitor: %m");
×
1284

1285
        r = sd_device_monitor_attach_event(monitor, event);
×
1286
        if (r < 0)
×
1287
                return log_error_errno(r, "Failed to attach device monitor: %m");
×
1288

1289
        r = sd_device_monitor_start(monitor, NULL, NULL);
×
1290
        if (r < 0)
×
1291
                return log_error_errno(r, "Failed to start device monitor: %m");
×
1292

1293
        *ret_event = TAKE_PTR(event);
×
1294
        *ret_monitor = TAKE_PTR(monitor);
×
1295
        return 0;
×
1296
}
1297

1298
static int run_security_device_monitor(
×
1299
                sd_event *event,
1300
                sd_device_monitor *monitor) {
1301
        bool processed = false;
×
1302
        int r;
×
1303

1304
        assert(event);
×
1305
        assert(monitor);
×
1306

1307
        /* Runs the event loop for the device monitor until either something happens, or the timeout is
1308
         * hit. */
1309

1310
        for (;;) {
×
1311
                int x;
×
1312

1313
                r = sd_event_get_exit_code(event, &x);
×
1314
                if (r < 0) {
×
1315
                        if (r != -ENODATA)
×
1316
                                return log_error_errno(r, "Failed to query exit code from event loop: %m");
×
1317

1318
                        /* On ENODATA we aren't told to exit yet. */
1319
                } else {
1320
                        assert(x == -ETIMEDOUT);
×
1321
                        return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1322
                                                "Timed out waiting for security device, aborting security device based authentication attempt.");
1323
                }
1324

1325
                /* Wait for one event, and then eat all subsequent events until there are no further ones */
1326
                r = sd_event_run(event, processed ? 0 : UINT64_MAX);
×
1327
                if (r < 0)
×
1328
                        return log_error_errno(r, "Failed to run event loop: %m");
×
1329
                if (r == 0) /* no events queued anymore */
×
1330
                        return 0;
1331

1332
                processed = true;
×
1333
        }
1334
}
1335

1336
static bool use_token_plugins(void) {
60✔
1337

1338
#if HAVE_TPM2
1339
        /* Currently, there's no way for us to query the volume key when plugins are used. Hence don't use
1340
         * plugins, if measurement has been requested. */
1341
        if (arg_tpm2_measure_pcr != UINT_MAX)
60✔
1342
                return false;
1343
#endif
1344

1345
        /* Disable tokens if we're in FIDO2 mode with manual parameters. */
1346
        if (arg_fido2_cid)
60✔
1347
                return false;
1348

1349
#if HAVE_LIBCRYPTSETUP_PLUGINS
1350
        int r;
60✔
1351

1352
        /* Permit a way to disable libcryptsetup token module support, for debugging purposes. */
1353
        r = getenv_bool("SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE");
60✔
1354
        if (r < 0 && r != -ENXIO)
60✔
1355
                log_debug_errno(r, "Failed to parse $SYSTEMD_CRYPTSETUP_USE_TOKEN_MODULE env var: %m");
×
1356
        if (r == 0)
60✔
1357
                return false;
1358

1359
        return crypt_token_external_path();
58✔
1360
#else
1361
        return false;
1362
#endif
1363
}
1364

1365
#if HAVE_LIBCRYPTSETUP_PLUGINS
1366
static int acquire_pins_from_env_variable(char ***ret_pins) {
21✔
1367
        _cleanup_(erase_and_freep) char *envpin = NULL;
21✔
1368
        _cleanup_strv_free_erase_ char **pins = NULL;
21✔
1369
        int r;
21✔
1370

1371
        assert(ret_pins);
21✔
1372

1373
        r = getenv_steal_erase("PIN", &envpin);
21✔
1374
        if (r < 0)
21✔
1375
                return log_error_errno(r, "Failed to acquire PIN from environment: %m");
×
1376
        if (r > 0) {
21✔
1377
                pins = strv_new(envpin);
16✔
1378
                if (!pins)
16✔
1379
                        return log_oom();
×
1380
        }
1381

1382
        *ret_pins = TAKE_PTR(pins);
21✔
1383

1384
        return 0;
21✔
1385
}
1386
#endif
1387

1388
static int crypt_activate_by_token_pin_ask_password(
58✔
1389
                struct crypt_device *cd,
1390
                const char *name,
1391
                const char *type,
1392
                usec_t until,
1393
                void *userdata,
1394
                uint32_t activation_flags,
1395
                const char *message,
1396
                const char *keyring,
1397
                const char *credential) {
1398

1399
#if HAVE_LIBCRYPTSETUP_PLUGINS
1400
        AskPasswordFlags flags = arg_ask_password_flags;
58✔
1401
        _cleanup_strv_free_erase_ char **pins = NULL;
58✔
1402
        int r;
58✔
1403

1404
        r = crypt_activate_by_token_pin(cd, name, type, CRYPT_ANY_TOKEN, /* pin=*/ NULL, /* pin_size= */ 0, userdata, activation_flags);
58✔
1405
        if (r > 0) /* returns unlocked keyslot id on success */
58✔
1406
                return 0;
1407
        if (r == -EEXIST) /* volume is already active */
35✔
1408
                return log_external_activation(r, name);
×
1409
        if (r != -ENOANO) /* needs pin or pin is wrong */
35✔
1410
                return r;
1411

1412
        r = acquire_pins_from_env_variable(&pins);
21✔
1413
        if (r < 0)
21✔
1414
                return r;
1415

1416
        STRV_FOREACH(p, pins) {
25✔
1417
                r = crypt_activate_by_token_pin(cd, name, type, CRYPT_ANY_TOKEN, *p, strlen(*p), userdata, activation_flags);
16✔
1418
                if (r > 0) /* returns unlocked keyslot id on success */
16✔
1419
                        return 0;
1420
                if (r == -EEXIST) /* volume is already active */
5✔
1421
                        return log_external_activation(r, name);
×
1422
                if (r != -ENOANO) /* needs pin or pin is wrong */
5✔
1423
                        return r;
1424
        }
1425

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

1429
        for (;;) {
×
1430
                pins = strv_free_erase(pins);
×
1431

1432
                AskPasswordRequest req = {
×
1433
                        .tty_fd = -EBADF,
1434
                        .message = message,
1435
                        .icon = "drive-harddisk",
1436
                        .keyring = keyring,
1437
                        .credential = credential,
1438
                        .until = until,
1439
                        .hup_fd = -EBADF,
1440
                };
1441

1442
                r = ask_password_auto(&req, flags, &pins);
×
1443
                if (r < 0)
×
1444
                        return r;
×
1445

1446
                STRV_FOREACH(p, pins) {
×
1447
                        r = crypt_activate_by_token_pin(cd, name, type, CRYPT_ANY_TOKEN, *p, strlen(*p), userdata, activation_flags);
×
1448
                        if (r > 0) /* returns unlocked keyslot id on success */
×
1449
                                return 0;
1450
                        if (r == -EEXIST) /* volume is already active */
×
1451
                                return log_external_activation(r, name);
×
1452
                        if (r != -ENOANO) /* needs pin or pin is wrong */
×
1453
                                return r;
1454
                }
1455

1456
                flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
×
1457
        }
1458
        return r;
1459
#else
1460
        return -EOPNOTSUPP;
1461
#endif
1462
}
1463

1464
static int attach_luks2_by_fido2_via_plugin(
×
1465
                struct crypt_device *cd,
1466
                const char *name,
1467
                usec_t until,
1468
                void *userdata,
1469
                uint32_t activation_flags) {
1470

1471
        return crypt_activate_by_token_pin_ask_password(
×
1472
                        cd,
1473
                        name,
1474
                        "systemd-fido2",
1475
                        until,
1476
                        userdata,
1477
                        activation_flags,
1478
                        "Please enter security token PIN:",
1479
                        "fido2-pin",
1480
                        "cryptsetup.fido2-pin");
1481
}
1482

1483
static int attach_luks_or_plain_or_bitlk_by_fido2(
×
1484
                struct crypt_device *cd,
1485
                const char *name,
1486
                const char *key_file,
1487
                const struct iovec *key_data,
1488
                usec_t until,
1489
                uint32_t flags,
1490
                bool pass_volume_key) {
1491

1492
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1493
        _cleanup_(erase_and_freep) void *decrypted_key = NULL;
×
1494
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1495
        size_t decrypted_key_size;
×
1496
        _cleanup_free_ char *friendly = NULL;
×
1497
        int keyslot = arg_key_slot, r;
×
1498
        bool use_libcryptsetup_plugin = use_token_plugins();
×
1499

1500
        assert(cd);
×
1501
        assert(name);
×
1502
        assert(arg_fido2_device || arg_fido2_device_auto);
×
1503

1504
        if (arg_fido2_cid && !key_file && !iovec_is_set(key_data))
×
1505
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1506
                                        "FIDO2 mode with manual parameters selected, but no keyfile specified, refusing.");
1507

1508
        friendly = friendly_disk_name(crypt_get_device_name(cd), name);
×
1509
        if (!friendly)
×
1510
                return log_oom();
×
1511

1512
        for (;;) {
×
1513
                if (use_libcryptsetup_plugin && !arg_fido2_cid) {
×
1514
                        r = attach_luks2_by_fido2_via_plugin(cd, name, until, arg_fido2_device, flags);
×
1515
                        if (IN_SET(r, -ENOTUNIQ, -ENXIO, -ENOENT))
×
1516
                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1517
                                                       "Automatic FIDO2 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
1518

1519
                } else {
1520
                        if (arg_fido2_cid)
×
1521
                                r = acquire_fido2_key(
×
1522
                                                name,
1523
                                                friendly,
1524
                                                arg_fido2_device,
1525
                                                arg_fido2_rp_id,
1526
                                                arg_fido2_cid, arg_fido2_cid_size,
1527
                                                key_file, arg_keyfile_size, arg_keyfile_offset,
1528
                                                key_data,
1529
                                                until,
1530
                                                arg_fido2_manual_flags,
1531
                                                "cryptsetup.fido2-pin",
1532
                                                arg_ask_password_flags,
1533
                                                &decrypted_key,
1534
                                                &decrypted_key_size);
1535
                        else
1536
                                r = acquire_fido2_key_auto(
×
1537
                                                cd,
1538
                                                name,
1539
                                                friendly,
1540
                                                arg_fido2_device,
1541
                                                until,
1542
                                                "cryptsetup.fido2-pin",
1543
                                                arg_ask_password_flags,
1544
                                                &decrypted_key,
1545
                                                &decrypted_key_size);
1546
                        if (r >= 0)
×
1547
                                break;
1548
                }
1549

1550
                if (r != -EAGAIN) /* EAGAIN means: token not found */
×
1551
                        return r;
1552

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

1557
                        assert(!event);
×
1558

1559
                        r = make_security_device_monitor(&event, &monitor);
×
1560
                        if (r < 0)
×
1561
                                return r;
1562

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

1565
                        /* Let's immediately rescan in case the token appeared in the time we needed
1566
                         * to create and configure the monitor */
1567
                        continue;
×
1568
                }
1569

1570
                r = run_security_device_monitor(event, monitor);
×
1571
                if (r < 0)
×
1572
                        return r;
1573

1574
                log_debug("Got one or more potentially relevant udev events, rescanning FIDO2...");
×
1575
        }
1576

1577
        if (pass_volume_key)
×
1578
                r = measured_crypt_activate_by_volume_key(cd, name, decrypted_key, decrypted_key_size, flags);
×
1579
        else {
1580
                _cleanup_(erase_and_freep) char *base64_encoded = NULL;
×
1581
                ssize_t base64_encoded_size;
×
1582

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

1585
                base64_encoded_size = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
×
1586
                if (base64_encoded_size < 0)
×
1587
                        return log_oom();
×
1588

1589
                r = measured_crypt_activate_by_passphrase(cd, name, keyslot, base64_encoded, base64_encoded_size, flags);
×
1590
        }
1591
        if (r == -EPERM) {
×
1592
                log_error_errno(r, "Failed to activate with FIDO2 decrypted key. (Key incorrect?)");
×
1593
                return -EAGAIN; /* log actual error, but return EAGAIN */
×
1594
        }
1595
        if (r < 0)
×
1596
                return log_error_errno(r, "Failed to activate with FIDO2 acquired key: %m");
×
1597

1598
        return 0;
1599
}
1600

1601
static int attach_luks2_by_pkcs11_via_plugin(
×
1602
                struct crypt_device *cd,
1603
                const char *name,
1604
                const char *friendly_name,
1605
                usec_t until,
1606
                const char *askpw_credential,
1607
                uint32_t flags) {
1608

1609
#if HAVE_LIBCRYPTSETUP_PLUGINS
1610
        int r;
×
1611

1612
        if (!streq_ptr(crypt_get_type(cd), CRYPT_LUKS2))
×
1613
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Automatic PKCS#11 metadata requires LUKS2 device.");
×
1614

1615
        systemd_pkcs11_plugin_params params = {
×
1616
                .friendly_name = friendly_name,
1617
                .until = until,
1618
                .askpw_credential = askpw_credential,
1619
                .askpw_flags = arg_ask_password_flags,
1620
        };
1621

1622
        r = crypt_activate_by_token_pin(cd, name, "systemd-pkcs11", CRYPT_ANY_TOKEN, NULL, 0, &params, flags);
×
1623
        if (r > 0) /* returns unlocked keyslot id on success */
×
1624
                r = 0;
1625
        if (r == -EEXIST) /* volume is already active */
×
1626
                r = log_external_activation(r, name);
×
1627

1628
        return r;
1629
#else
1630
        return -EOPNOTSUPP;
1631
#endif
1632
}
1633

1634
static int attach_luks_or_plain_or_bitlk_by_pkcs11(
×
1635
                struct crypt_device *cd,
1636
                const char *name,
1637
                const char *key_file,
1638
                const struct iovec *key_data,
1639
                usec_t until,
1640
                uint32_t flags,
1641
                bool pass_volume_key) {
1642

1643
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1644
        _cleanup_free_ char *friendly = NULL, *discovered_uri = NULL;
×
1645
        size_t decrypted_key_size = 0, discovered_key_size = 0;
×
1646
        _cleanup_(erase_and_freep) void *decrypted_key = NULL;
×
1647
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1648
        _cleanup_free_ void *discovered_key = NULL;
×
1649
        struct iovec discovered_key_data = {};
×
1650
        int keyslot = arg_key_slot, r;
×
1651
        const char *uri = NULL;
×
1652
        bool use_libcryptsetup_plugin = use_token_plugins();
×
1653

1654
        assert(cd);
×
1655
        assert(name);
×
1656
        assert(arg_pkcs11_uri || arg_pkcs11_uri_auto);
×
1657

1658
        if (arg_pkcs11_uri_auto) {
×
1659
                if (!use_libcryptsetup_plugin) {
×
1660
                        r = find_pkcs11_auto_data(cd, &discovered_uri, &discovered_key, &discovered_key_size, &keyslot);
×
1661
                        if (IN_SET(r, -ENOTUNIQ, -ENXIO))
×
1662
                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1663
                                                       "Automatic PKCS#11 metadata discovery was not possible because missing or not unique, falling back to traditional unlocking.");
1664
                        if (r < 0)
×
1665
                                return r;
1666

1667
                        uri = discovered_uri;
×
1668
                        discovered_key_data = IOVEC_MAKE(discovered_key, discovered_key_size);
×
1669
                        key_data = &discovered_key_data;
×
1670
                }
1671
        } else {
1672
                uri = arg_pkcs11_uri;
×
1673

1674
                if (!key_file && !iovec_is_set(key_data))
×
1675
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "PKCS#11 mode selected but no key file specified, refusing.");
×
1676
        }
1677

1678
        friendly = friendly_disk_name(crypt_get_device_name(cd), name);
×
1679
        if (!friendly)
×
1680
                return log_oom();
×
1681

1682
        for (;;) {
×
1683
                if (use_libcryptsetup_plugin && arg_pkcs11_uri_auto)
×
1684
                        r = attach_luks2_by_pkcs11_via_plugin(
×
1685
                                        cd,
1686
                                        name,
1687
                                        friendly,
1688
                                        until,
1689
                                        "cryptsetup.pkcs11-pin",
1690
                                        flags);
1691
                else {
1692
                        r = decrypt_pkcs11_key(
×
1693
                                        name,
1694
                                        friendly,
1695
                                        uri,
1696
                                        key_file, arg_keyfile_size, arg_keyfile_offset,
1697
                                        key_data,
1698
                                        until,
1699
                                        arg_ask_password_flags,
1700
                                        &decrypted_key, &decrypted_key_size);
1701
                        if (r >= 0)
×
1702
                                break;
1703
                }
1704

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

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

1712
                        assert(!event);
×
1713

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

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

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

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

1730
                log_debug("Got one or more potentially relevant udev events, rescanning PKCS#11...");
×
1731
        }
1732
        assert(decrypted_key);
×
1733

1734
        if (pass_volume_key)
×
1735
                r = measured_crypt_activate_by_volume_key(cd, name, decrypted_key, decrypted_key_size, flags);
×
1736
        else {
1737
                _cleanup_(erase_and_freep) char *base64_encoded = NULL;
×
1738
                ssize_t base64_encoded_size;
×
1739

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

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

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

1761
        return 0;
1762
}
1763

1764
static int make_tpm2_device_monitor(
×
1765
                sd_event **ret_event,
1766
                sd_device_monitor **ret_monitor) {
1767

1768
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1769
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1770
        int r;
×
1771

1772
        assert(ret_event);
×
1773
        assert(ret_monitor);
×
1774

1775
        r = sd_event_default(&event);
×
1776
        if (r < 0)
×
1777
                return log_error_errno(r, "Failed to allocate event loop: %m");
×
1778

1779
        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
×
1780
        if (r < 0)
×
1781
                return log_error_errno(r, "Failed to install timeout event source: %m");
×
1782

1783
        r = sd_device_monitor_new(&monitor);
×
1784
        if (r < 0)
×
1785
                return log_error_errno(r, "Failed to allocate device monitor: %m");
×
1786

1787
        (void) sd_device_monitor_set_description(monitor, "tpmrm");
×
1788

1789
        r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, "tpmrm", NULL);
×
1790
        if (r < 0)
×
1791
                return log_error_errno(r, "Failed to configure device monitor: %m");
×
1792

1793
        r = sd_device_monitor_attach_event(monitor, event);
×
1794
        if (r < 0)
×
1795
                return log_error_errno(r, "Failed to attach device monitor: %m");
×
1796

1797
        r = sd_device_monitor_start(monitor, NULL, NULL);
×
1798
        if (r < 0)
×
1799
                return log_error_errno(r, "Failed to start device monitor: %m");
×
1800

1801
        *ret_event = TAKE_PTR(event);
×
1802
        *ret_monitor = TAKE_PTR(monitor);
×
1803
        return 0;
×
1804
}
1805

1806
static int attach_luks2_by_tpm2_via_plugin(
10✔
1807
                struct crypt_device *cd,
1808
                const char *name,
1809
                usec_t until,
1810
                uint32_t flags) {
1811

1812
#if HAVE_LIBCRYPTSETUP_PLUGINS
1813
        systemd_tpm2_plugin_params params = {
10✔
1814
                .search_pcr_mask = arg_tpm2_pcr_mask,
1815
                .device = arg_tpm2_device,
1816
                .signature_path = arg_tpm2_signature,
1817
                .pcrlock_path = arg_tpm2_pcrlock,
1818
        };
1819

1820
        if (!use_token_plugins())
10✔
1821
                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
1✔
1822
                                       "libcryptsetup has external plugins support disabled.");
1823

1824
        return crypt_activate_by_token_pin_ask_password(
9✔
1825
                        cd,
1826
                        name,
1827
                        "systemd-tpm2",
1828
                        until,
1829
                        &params,
1830
                        flags,
1831
                        "Please enter TPM2 PIN:",
1832
                        "tpm2-pin",
1833
                        "cryptsetup.tpm2-pin");
1834
#else
1835
        return -EOPNOTSUPP;
1836
#endif
1837
}
1838

1839
static int attach_luks_or_plain_or_bitlk_by_tpm2(
10✔
1840
                struct crypt_device *cd,
1841
                const char *name,
1842
                const char *key_file,
1843
                const struct iovec *key_data,
1844
                usec_t until,
1845
                uint32_t flags,
1846
                bool pass_volume_key) {
1847

1848
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
10✔
1849
        _cleanup_(iovec_done_erase) struct iovec decrypted_key = {};
×
1850
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
10✔
1851
        _cleanup_free_ char *friendly = NULL;
10✔
1852
        int keyslot = arg_key_slot, r;
10✔
1853

1854
        assert(cd);
10✔
1855
        assert(name);
10✔
1856
        assert(arg_tpm2_device || arg_tpm2_device_auto);
10✔
1857

1858
        friendly = friendly_disk_name(crypt_get_device_name(cd), name);
10✔
1859
        if (!friendly)
10✔
1860
                return log_oom();
×
1861

1862
        for (;;) {
10✔
1863
                if (key_file || iovec_is_set(key_data)) {
10✔
1864
                        /* If key data is specified, use that */
1865

1866
                        r = acquire_tpm2_key(
×
1867
                                        name,
1868
                                        arg_tpm2_device,
1869
                                        arg_tpm2_pcr_mask == UINT32_MAX ? TPM2_PCR_MASK_DEFAULT_LEGACY : arg_tpm2_pcr_mask,
×
1870
                                        UINT16_MAX,
1871
                                        /* pubkey= */ NULL,
1872
                                        /* pubkey_pcr_mask= */ 0,
1873
                                        /* signature_path= */ NULL,
1874
                                        /* pcrlock_path= */ NULL,
1875
                                        /* primary_alg= */ 0,
1876
                                        key_file, arg_keyfile_size, arg_keyfile_offset,
1877
                                        key_data, /* n_blobs= */ 1,
1878
                                        /* policy_hash= */ NULL, /* we don't know the policy hash */
1879
                                        /* n_policy_hash= */ 0,
1880
                                        /* salt= */ NULL,
1881
                                        /* srk= */ NULL,
1882
                                        /* pcrlock_nv= */ NULL,
1883
                                        arg_tpm2_pin ? TPM2_FLAGS_USE_PIN : 0,
1884
                                        until,
1885
                                        "cryptsetup.tpm2-pin",
1886
                                        arg_ask_password_flags,
1887
                                        &decrypted_key);
1888
                        if (r >= 0)
×
1889
                                break;
1890
                        if (IN_SET(r, -EACCES, -ENOLCK))
×
1891
                                return log_error_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 PIN unlock failed, falling back to traditional unlocking.");
×
1892
                        if (ERRNO_IS_NOT_SUPPORTED(r)) /* TPM2 support not compiled in? */
×
1893
                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 support not available, falling back to traditional unlocking.");
×
1894
                        /* EAGAIN means: no tpm2 chip found */
1895
                        if (r != -EAGAIN) {
×
1896
                                log_notice_errno(r, "TPM2 operation failed, falling back to traditional unlocking: %m");
×
1897
                                return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
×
1898
                        }
1899
                } else {
1900
                        r = attach_luks2_by_tpm2_via_plugin(cd, name, until, flags);
10✔
1901
                        if (r >= 0)
10✔
1902
                                return 0;
1903
                        /* EAGAIN     means: no tpm2 chip found
1904
                         * EOPNOTSUPP means: no libcryptsetup plugins support */
1905
                        if (r == -ENXIO)
10✔
1906
                                return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1907
                                                        "No TPM2 metadata matching the current system state found in LUKS2 header, falling back to traditional unlocking.");
1908
                        if (r == -ENOENT)
10✔
1909
                                return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
3✔
1910
                                                       "No TPM2 metadata enrolled in LUKS2 header or TPM2 support not available, falling back to traditional unlocking.");
1911
                        if (!IN_SET(r, -EOPNOTSUPP, -EAGAIN)) {
7✔
1912
                                log_notice_errno(r, "TPM2 operation failed, falling back to traditional unlocking: %m");
6✔
1913
                                return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
6✔
1914
                        }
1915
                }
1916

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

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

1925
                        for (;;) {
1✔
1926
                                _cleanup_(iovec_done) struct iovec pubkey = {}, salt = {}, srk = {}, pcrlock_nv = {};
×
1927
                                struct iovec *blobs = NULL, *policy_hash = NULL;
1✔
1928
                                uint32_t hash_pcr_mask, pubkey_pcr_mask;
1✔
1929
                                size_t n_blobs = 0, n_policy_hash = 0;
1✔
1930
                                uint16_t pcr_bank, primary_alg;
1✔
1931
                                TPM2Flags tpm2_flags;
1✔
1932

1933
                                CLEANUP_ARRAY(blobs, n_blobs, iovec_array_free);
1✔
1934
                                CLEANUP_ARRAY(policy_hash, n_policy_hash, iovec_array_free);
1✔
1935

1936
                                r = find_tpm2_auto_data(
1✔
1937
                                                cd,
1938
                                                arg_tpm2_pcr_mask, /* if != UINT32_MAX we'll only look for tokens with this PCR mask */
1939
                                                token, /* search for the token with this index, or any later index than this */
1940
                                                &hash_pcr_mask,
1941
                                                &pcr_bank,
1942
                                                &pubkey,
1943
                                                &pubkey_pcr_mask,
1944
                                                &primary_alg,
1945
                                                &blobs,
1946
                                                &n_blobs,
1947
                                                &policy_hash,
1948
                                                &n_policy_hash,
1949
                                                &salt,
1950
                                                &srk,
1951
                                                &pcrlock_nv,
1952
                                                &tpm2_flags,
1953
                                                &keyslot,
1954
                                                &token);
1955
                                if (r == -ENXIO)
1✔
1956
                                        /* No further TPM2 tokens found in the LUKS2 header. */
1957
                                        return log_full_errno(found_some ? LOG_NOTICE : LOG_DEBUG,
×
1958
                                                              SYNTHETIC_ERRNO(EAGAIN),
1959
                                                              found_some
1960
                                                              ? "No TPM2 metadata matching the current system state found in LUKS2 header, falling back to traditional unlocking."
1961
                                                              : "No TPM2 metadata enrolled in LUKS2 header, falling back to traditional unlocking.");
1962
                                if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
1✔
1963
                                        /* TPM2 support not compiled in? */
1964
                                        return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
×
1965
                                                               "TPM2 support not available, falling back to traditional unlocking.");
1966
                                if (r < 0)
1✔
1967
                                        return r;
1968

1969
                                found_some = true;
1✔
1970

1971
                                r = acquire_tpm2_key(
1✔
1972
                                                name,
1973
                                                arg_tpm2_device,
1974
                                                hash_pcr_mask,
1975
                                                pcr_bank,
1976
                                                &pubkey,
1977
                                                pubkey_pcr_mask,
1978
                                                arg_tpm2_signature,
1979
                                                arg_tpm2_pcrlock,
1980
                                                primary_alg,
1981
                                                /* key_file= */ NULL, /* key_file_size= */ 0, /* key_file_offset= */ 0, /* no key file */
1982
                                                blobs,
1983
                                                n_blobs,
1984
                                                policy_hash,
1985
                                                n_policy_hash,
1986
                                                &salt,
1987
                                                &srk,
1988
                                                &pcrlock_nv,
1989
                                                tpm2_flags,
1990
                                                until,
1991
                                                "cryptsetup.tpm2-pin",
1992
                                                arg_ask_password_flags,
1993
                                                &decrypted_key);
1994
                                if (IN_SET(r, -EACCES, -ENOLCK))
1✔
1995
                                        return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 PIN unlock failed, falling back to traditional unlocking.");
×
1996
                                if (r != -EPERM)
1✔
1997
                                        break;
1998

1999
                                token++; /* try a different token next time */
×
2000
                        }
2001

2002
                        if (r >= 0)
1✔
2003
                                break;
2004
                        /* EAGAIN means: no tpm2 chip found */
2005
                        if (r != -EAGAIN) {
×
2006
                                log_notice_errno(r, "TPM2 operation failed, falling back to traditional unlocking: %m");
×
2007
                                return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
×
2008
                        }
2009
                }
2010

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

2015
                        assert(!event);
×
2016

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

2021
                        r = make_tpm2_device_monitor(&event, &monitor);
×
2022
                        if (r < 0)
×
2023
                                return r;
2024

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

2027
                        /* Let's immediately rescan in case the device appeared in the time we needed
2028
                         * to create and configure the monitor */
2029
                        continue;
×
2030
                }
2031

2032
                r = run_security_device_monitor(event, monitor);
×
2033
                if (r < 0)
×
2034
                        return r;
2035

2036
                log_debug("Got one or more potentially relevant udev events, rescanning for TPM2...");
×
2037
        }
2038

2039
        if (pass_volume_key)
1✔
2040
                r = measured_crypt_activate_by_volume_key(cd, name, decrypted_key.iov_base, decrypted_key.iov_len, flags);
×
2041
        else {
2042
                _cleanup_(erase_and_freep) char *base64_encoded = NULL;
1✔
2043
                ssize_t base64_encoded_size;
1✔
2044

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

2047
                base64_encoded_size = base64mem(decrypted_key.iov_base, decrypted_key.iov_len, &base64_encoded);
1✔
2048
                if (base64_encoded_size < 0)
1✔
2049
                        return log_oom();
×
2050

2051
                r = measured_crypt_activate_by_passphrase(cd, name, keyslot, base64_encoded, base64_encoded_size, flags);
1✔
2052
        }
2053
        if (r == -EPERM) {
1✔
2054
                log_error_errno(r, "Failed to activate with TPM2 decrypted key. (Key incorrect?)");
×
2055
                return -EAGAIN; /* log actual error, but return EAGAIN */
×
2056
        }
2057
        if (r < 0)
1✔
2058
                return log_error_errno(r, "Failed to activate with TPM2 acquired key: %m");
×
2059

2060
        return 0;
2061
}
2062

2063
static int attach_luks_or_plain_or_bitlk_by_key_data(
3✔
2064
                struct crypt_device *cd,
2065
                const char *name,
2066
                const struct iovec *key_data,
2067
                uint32_t flags,
2068
                bool pass_volume_key) {
2069

2070
        int r;
3✔
2071

2072
        assert(cd);
3✔
2073
        assert(name);
3✔
2074
        assert(key_data);
3✔
2075

2076
        if (pass_volume_key)
3✔
2077
                r = measured_crypt_activate_by_volume_key(cd, name, key_data->iov_base, key_data->iov_len, flags);
×
2078
        else
2079
                r = measured_crypt_activate_by_passphrase(cd, name, arg_key_slot, key_data->iov_base, key_data->iov_len, flags);
3✔
2080
        if (r == -EPERM) {
3✔
2081
                log_error_errno(r, "Failed to activate. (Key incorrect?)");
×
2082
                return -EAGAIN; /* Log actual error, but return EAGAIN */
×
2083
        }
2084
        if (r < 0)
3✔
2085
                return log_error_errno(r, "Failed to activate: %m");
×
2086

2087
        return 0;
2088
}
2089

2090
static int attach_luks_or_plain_or_bitlk_by_key_file(
20✔
2091
                struct crypt_device *cd,
2092
                const char *name,
2093
                const char *key_file,
2094
                uint32_t flags,
2095
                bool pass_volume_key) {
2096

2097
        _cleanup_(erase_and_freep) char *kfdata = NULL;
20✔
2098
        _cleanup_free_ char *bindname = NULL;
20✔
2099
        size_t kfsize;
20✔
2100
        int r;
20✔
2101

2102
        assert(cd);
20✔
2103
        assert(name);
20✔
2104
        assert(key_file);
20✔
2105

2106
        /* If we read the key via AF_UNIX, make this client recognizable */
2107
        bindname = make_bindname(name, /* token_type= */ _TOKEN_TYPE_INVALID);
20✔
2108
        if (!bindname)
20✔
2109
                return log_oom();
×
2110

2111
        r = read_full_file_full(
23✔
2112
                        AT_FDCWD, key_file,
2113
                        arg_keyfile_offset == 0 ? UINT64_MAX : arg_keyfile_offset,
20✔
2114
                        arg_keyfile_size == 0 ? SIZE_MAX : arg_keyfile_size,
20✔
2115
                        READ_FULL_FILE_SECURE|READ_FULL_FILE_WARN_WORLD_READABLE|READ_FULL_FILE_CONNECT_SOCKET,
2116
                        bindname,
2117
                        &kfdata, &kfsize);
2118
        if (r == -E2BIG) {
20✔
2119
                log_error_errno(r, "Failed to activate, key file '%s' too large.", key_file);
×
2120
                return -EAGAIN;
×
2121
        }
2122
        if (r == -ENOENT) {
20✔
2123
                log_error_errno(r, "Failed to activate, key file '%s' missing.", key_file);
×
2124
                return -EAGAIN; /* Log actual error, but return EAGAIN */
×
2125
        }
2126
        if (r < 0)
20✔
2127
                return log_error_errno(r, "Failed to read key file '%s': %m", key_file);
×
2128

2129
        if (pass_volume_key)
20✔
2130
                r = measured_crypt_activate_by_volume_key(cd, name, kfdata, kfsize, flags);
×
2131
        else
2132
                r = measured_crypt_activate_by_passphrase(cd, name, arg_key_slot, kfdata, kfsize, flags);
20✔
2133
        if (r == -EPERM) {
20✔
2134
                log_error_errno(r, "Failed to activate with key file '%s'. (Key data incorrect?)", key_file);
3✔
2135
                return -EAGAIN; /* Log actual error, but return EAGAIN */
3✔
2136
        }
2137
        if (r < 0)
17✔
2138
                return log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
×
2139

2140
        return 0;
2141
}
2142

2143
static int attach_luks_or_plain_or_bitlk_by_passphrase(
×
2144
                struct crypt_device *cd,
2145
                const char *name,
2146
                char **passwords,
2147
                uint32_t flags,
2148
                bool pass_volume_key) {
2149

2150
        int r;
×
2151

2152
        assert(cd);
×
2153
        assert(name);
×
2154

2155
        r = -EINVAL;
2156
        STRV_FOREACH(p, passwords) {
×
2157
                if (pass_volume_key)
×
2158
                        r = measured_crypt_activate_by_volume_key(cd, name, *p, arg_key_size, flags);
×
2159
                else
2160
                        r = measured_crypt_activate_by_passphrase(cd, name, arg_key_slot, *p, strlen(*p), flags);
×
2161
                if (r >= 0)
×
2162
                        break;
2163
        }
2164
        if (r == -EPERM) {
×
2165
                log_error_errno(r, "Failed to activate with specified passphrase. (Passphrase incorrect?)");
×
2166
                return -EAGAIN; /* log actual error, but return EAGAIN */
×
2167
        }
2168
        if (r < 0)
×
2169
                return log_error_errno(r, "Failed to activate with specified passphrase: %m");
×
2170

2171
        return 0;
2172
}
2173

2174
static int attach_luks_or_plain_or_bitlk(
33✔
2175
                struct crypt_device *cd,
2176
                const char *name,
2177
                TokenType token_type,
2178
                const char *key_file,
2179
                const struct iovec *key_data,
2180
                char **passwords,
2181
                uint32_t flags,
2182
                usec_t until) {
2183

2184
        bool pass_volume_key = false;
33✔
2185
        int r;
33✔
2186

2187
        assert(cd);
33✔
2188
        assert(name);
33✔
2189

2190
        if ((!arg_type && !crypt_get_type(cd)) || streq_ptr(arg_type, CRYPT_PLAIN)) {
33✔
2191
                struct crypt_params_plain params = {
×
2192
                        .offset = arg_offset,
2193
                        .skip = arg_skip,
2194
                        .sector_size = arg_sector_size,
2195
                };
2196
                const char *cipher, *cipher_mode;
×
2197
                _cleanup_free_ char *truncated_cipher = NULL;
×
2198

2199
                if (streq_ptr(arg_hash, "plain"))
×
2200
                        /* plain isn't a real hash type. it just means "use no hash" */
2201
                        params.hash = NULL;
2202
                else if (arg_hash)
×
2203
                        params.hash = arg_hash;
×
2204
                else if (!key_file)
×
2205
                        /* for CRYPT_PLAIN, the behaviour of cryptsetup package is to not hash when a key
2206
                         * file is provided */
2207
                        params.hash = "ripemd160";
×
2208

2209
                if (arg_cipher) {
×
2210
                        size_t l;
×
2211

2212
                        l = strcspn(arg_cipher, "-");
×
2213
                        truncated_cipher = strndup(arg_cipher, l);
×
2214
                        if (!truncated_cipher)
×
2215
                                return log_oom();
×
2216

2217
                        cipher = truncated_cipher;
×
2218
                        cipher_mode = arg_cipher[l] ? arg_cipher+l+1 : "plain";
×
2219
                } else {
2220
                        cipher = "aes";
2221
                        cipher_mode = "cbc-essiv:sha256";
2222
                }
2223

2224
                /* for CRYPT_PLAIN limit reads from keyfile to key length, and ignore keyfile-size */
2225
                arg_keyfile_size = arg_key_size;
×
2226

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

2233
                /* hash == NULL implies the user passed "plain" */
2234
                pass_volume_key = !params.hash;
×
2235
        }
2236

2237
        log_info("Set cipher %s, mode %s, key size %i bits for device %s.",
33✔
2238
                 crypt_get_cipher(cd),
2239
                 crypt_get_cipher_mode(cd),
2240
                 crypt_get_volume_key_size(cd)*8,
2241
                 crypt_get_device_name(cd));
2242

2243
        if (token_type == TOKEN_TPM2)
33✔
2244
                return attach_luks_or_plain_or_bitlk_by_tpm2(cd, name, key_file, key_data, until, flags, pass_volume_key);
10✔
2245
        if (token_type == TOKEN_FIDO2)
23✔
2246
                return attach_luks_or_plain_or_bitlk_by_fido2(cd, name, key_file, key_data, until, flags, pass_volume_key);
×
2247
        if (token_type == TOKEN_PKCS11)
23✔
2248
                return attach_luks_or_plain_or_bitlk_by_pkcs11(cd, name, key_file, key_data, until, flags, pass_volume_key);
×
2249
        if (key_data)
23✔
2250
                return attach_luks_or_plain_or_bitlk_by_key_data(cd, name, key_data, flags, pass_volume_key);
3✔
2251
        if (key_file)
20✔
2252
                return attach_luks_or_plain_or_bitlk_by_key_file(cd, name, key_file, flags, pass_volume_key);
20✔
2253

2254
        return attach_luks_or_plain_or_bitlk_by_passphrase(cd, name, passwords, flags, pass_volume_key);
×
2255
}
2256

2257
static int help(void) {
×
2258
        _cleanup_free_ char *link = NULL;
×
2259
        int r;
×
2260

2261
        r = terminal_urlify_man("systemd-cryptsetup", "8", &link);
×
2262
        if (r < 0)
×
2263
                return log_oom();
×
2264

2265
        printf("%1$s attach VOLUME SOURCE-DEVICE [KEY-FILE] [CONFIG]\n"
×
2266
               "%1$s detach VOLUME\n\n"
2267
               "%2$sAttach or detach an encrypted block device.%3$s\n\n"
2268
               "  -h --help            Show this help\n"
2269
               "     --version         Show package version\n"
2270
               "\nSee the %4$s for details.\n",
2271
               program_invocation_short_name,
2272
               ansi_highlight(),
2273
               ansi_normal(),
2274
               link);
2275

2276
        return 0;
2277
}
2278

2279
static int parse_argv(int argc, char *argv[]) {
125✔
2280
        enum {
125✔
2281
                ARG_VERSION = 0x100,
2282
        };
2283

2284
        static const struct option options[] = {
125✔
2285
                { "help",                         no_argument,       NULL, 'h'                       },
2286
                { "version",                      no_argument,       NULL, ARG_VERSION               },
2287
                {}
2288
        };
2289

2290
        int c;
125✔
2291

2292
        assert(argc >= 0);
125✔
2293
        assert(argv);
125✔
2294

2295
        if (argv_looks_like_help(argc, argv))
125✔
2296
                return help();
×
2297

2298
        while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
125✔
2299
                switch (c) {
×
2300

2301
                case 'h':
×
2302
                        return help();
×
2303

2304
                case ARG_VERSION:
×
2305
                        return version();
×
2306

2307
                case '?':
2308
                        return -EINVAL;
2309

2310
                default:
×
2311
                        assert_not_reached();
×
2312
                }
2313

2314
        return 1;
2315
}
2316

2317
static uint32_t determine_flags(void) {
70✔
2318
        uint32_t flags = 0;
70✔
2319

2320
        if (arg_readonly)
70✔
2321
                flags |= CRYPT_ACTIVATE_READONLY;
×
2322

2323
        if (arg_discards)
70✔
2324
                flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
×
2325

2326
        if (arg_same_cpu_crypt)
70✔
2327
                flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
×
2328

2329
        if (arg_submit_from_crypt_cpus)
70✔
2330
                flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
×
2331

2332
        if (arg_no_read_workqueue)
70✔
2333
                flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
×
2334

2335
        if (arg_no_write_workqueue)
70✔
2336
                flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
×
2337

2338
#ifdef CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF
2339
        /* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
2340
        /* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */
2341
        flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF;
70✔
2342
#endif
2343

2344
        return flags;
70✔
2345
}
2346

2347
static void remove_and_erasep(const char **p) {
70✔
2348
        int r;
70✔
2349

2350
        if (!*p)
70✔
2351
                return;
2352

2353
        r = unlinkat_deallocate(AT_FDCWD, *p, UNLINK_ERASE);
2✔
2354
        if (r < 0 && r != -ENOENT)
2✔
2355
                log_warning_errno(r, "Unable to erase key file '%s', ignoring: %m", *p);
×
2356
}
2357

2358
static TokenType determine_token_type(void) {
47✔
2359
        if (arg_tpm2_device || arg_tpm2_device_auto)
47✔
2360
                return TOKEN_TPM2;
2361
        if (arg_fido2_device || arg_fido2_device_auto)
37✔
2362
                return TOKEN_FIDO2;
2363
        if (arg_pkcs11_uri || arg_pkcs11_uri_auto)
37✔
2364
                return TOKEN_PKCS11;
×
2365

2366
        return _TOKEN_TYPE_INVALID;
2367
}
2368

2369
static int discover_key(const char *key_file, const char *volume, TokenType token_type, struct iovec *ret_key_data) {
24✔
2370
        _cleanup_free_ char *bindname = NULL;
24✔
2371
        const char *token_type_name;
24✔
2372
        int r;
24✔
2373

2374
        assert(key_file);
24✔
2375
        assert(volume);
24✔
2376
        assert(ret_key_data);
24✔
2377

2378
        bindname = make_bindname(volume, token_type);
24✔
2379
        if (!bindname)
24✔
2380
                return log_oom();
×
2381

2382
        /* If a key file is not explicitly specified, search for a key in a well defined search path, and load it. */
2383
        r = find_key_file(key_file, STRV_MAKE("/etc/cryptsetup-keys.d", "/run/cryptsetup-keys.d"), bindname, ret_key_data);
24✔
2384
        if (r <= 0)
24✔
2385
                return r;
2386

2387
        token_type_name = token_type_to_string(token_type);
1✔
2388
        if (token_type_name)
1✔
2389
                log_debug("Automatically discovered encrypted key for volume '%s' (token type: %s).", volume, token_type_name);
×
2390
        else
2391
                log_debug("Automatically discovered key for volume '%s'.", volume);
1✔
2392

2393
        return r;
2394
}
2395

2396
static int verb_attach(int argc, char *argv[], void *userdata) {
70✔
2397
        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
70✔
2398
        _unused_ _cleanup_(remove_and_erasep) const char *destroy_key_file = NULL;
70✔
2399
        crypt_status_info status;
70✔
2400
        uint32_t flags = 0;
70✔
2401
        unsigned tries;
70✔
2402
        usec_t until;
70✔
2403
        PassphraseType passphrase_type = PASSPHRASE_NONE;
70✔
2404
        int r;
70✔
2405

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

2408
        assert(argc >= 3 && argc <= 5);
70✔
2409

2410
        const char *volume = ASSERT_PTR(argv[1]),
70✔
2411
                *source = ASSERT_PTR(argv[2]),
70✔
2412
                *key_file = argc >= 4 ? mangle_none(argv[3]) : NULL,
70✔
2413
                *config = argc >= 5 ? mangle_none(argv[4]) : NULL;
70✔
2414

2415
        if (!filename_is_valid(volume))
70✔
2416
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
×
2417

2418
        if (key_file && !path_is_absolute(key_file)) {
70✔
2419
                log_warning("Password file path '%s' is not absolute. Ignoring.", key_file);
×
2420
                key_file = NULL;
2421
        }
2422

2423
        if (config) {
70✔
2424
                r = parse_crypt_config(config);
70✔
2425
                if (r < 0)
70✔
2426
                        return r;
2427
        }
2428

2429
        log_debug("%s %s ← %s type=%s cipher=%s", __func__,
193✔
2430
                  volume, source, strempty(arg_type), strempty(arg_cipher));
2431

2432
        /* A delicious drop of snake oil */
2433
        (void) mlockall(MCL_FUTURE);
70✔
2434

2435
        if (key_file && arg_keyfile_erase)
70✔
2436
                destroy_key_file = key_file; /* let's get this baby erased when we leave */
2✔
2437

2438
        if (arg_header) {
70✔
2439
                if (streq_ptr(arg_type, CRYPT_TCRYPT)){
9✔
2440
                        log_debug("tcrypt header: %s", arg_header);
×
2441
                        r = crypt_init_data_device(&cd, arg_header, source);
×
2442
                } else {
2443
                        log_debug("LUKS header: %s", arg_header);
9✔
2444
                        r = crypt_init(&cd, arg_header);
9✔
2445
                }
2446
        } else
2447
                r = crypt_init(&cd, source);
61✔
2448
        if (r < 0)
70✔
2449
                return log_error_errno(r, "crypt_init() failed: %m");
×
2450

2451
        cryptsetup_enable_logging(cd);
70✔
2452

2453
        status = crypt_status(cd, volume);
70✔
2454
        if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
70✔
2455
                log_info("Volume %s already active.", volume);
×
2456
                return 0;
×
2457
        }
2458

2459
        flags = determine_flags();
70✔
2460

2461
        until = usec_add(now(CLOCK_MONOTONIC), arg_timeout);
70✔
2462
        if (until == USEC_INFINITY)
×
2463
                until = 0;
70✔
2464

2465
        if (arg_key_size == 0)
70✔
2466
                arg_key_size = 256U / 8U;
70✔
2467

2468
        if (key_file) {
70✔
2469
                struct stat st;
20✔
2470

2471
                /* Ideally we'd do this on the open fd, but since this is just a warning it's OK to do this
2472
                 * in two steps. */
2473
                if (stat(key_file, &st) >= 0 && S_ISREG(st.st_mode) && (st.st_mode & 0005))
20✔
UNCOV
2474
                        log_warning("Key file %s is world-readable. This is not a good idea!", key_file);
×
2475
        }
2476

2477
        if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2)) {
70✔
2478
                r = crypt_load(cd, !arg_type || streq(arg_type, ANY_LUKS) ? CRYPT_LUKS : arg_type, NULL);
70✔
2479
                if (r < 0)
70✔
2480
                        return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", crypt_get_device_name(cd));
35✔
2481

2482
/* since cryptsetup 2.7.0 (Jan 2024) */
2483
#if HAVE_CRYPT_SET_KEYRING_TO_LINK
2484
                if (arg_link_key_description) {
70✔
2485
                        r = crypt_set_keyring_to_link(cd, arg_link_key_description, NULL, arg_link_key_type, arg_link_keyring);
×
2486
                        if (r < 0)
×
2487
                                log_warning_errno(r, "Failed to set keyring or key description to link volume key in, ignoring: %m");
×
2488
                }
2489
#endif
2490

2491
                if (arg_header) {
70✔
2492
                        r = crypt_set_data_device(cd, source);
9✔
2493
                        if (r < 0)
9✔
2494
                                return log_error_errno(r, "Failed to set LUKS data device %s: %m", source);
×
2495
                }
2496

2497
                /* Tokens are available in LUKS2 only, but it is ok to call (and fail) with LUKS1. */
2498
                if (!key_file && use_token_plugins()) {
70✔
2499
                        r = crypt_activate_by_token_pin_ask_password(
49✔
2500
                                        cd,
2501
                                        volume,
2502
                                        /* type= */ NULL,
2503
                                        until,
2504
                                        /* userdata= */ NULL,
2505
                                        flags,
2506
                                        "Please enter LUKS2 token PIN:",
2507
                                        "luks2-pin",
2508
                                        "cryptsetup.luks2-pin");
2509
                        if (r >= 0) {
49✔
2510
                                log_debug("Volume %s activated with a LUKS token.", volume);
35✔
2511
                                return 0;
35✔
2512
                        }
2513

2514
                        log_debug_errno(r, "Token activation unsuccessful for device %s: %m", crypt_get_device_name(cd));
14✔
2515
                }
2516
        }
2517

2518
/* since cryptsetup 2.3.0 (Feb 2020) */
2519
#ifdef CRYPT_BITLK
2520
        if (streq_ptr(arg_type, CRYPT_BITLK)) {
35✔
2521
                r = crypt_load(cd, CRYPT_BITLK, NULL);
×
2522
                if (r < 0)
×
2523
                        return log_error_errno(r, "Failed to load Bitlocker superblock on device %s: %m", crypt_get_device_name(cd));
×
2524
        }
2525
#endif
2526

2527
        bool use_cached_passphrase = true, try_discover_key = !key_file;
35✔
2528
        const char *discovered_key_fn = strjoina(volume, ".key");
175✔
2529
        _cleanup_strv_free_erase_ char **passwords = NULL;
35✔
2530
        for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) {
47✔
2531
                _cleanup_(iovec_done_erase) struct iovec discovered_key_data = {};
47✔
2532
                const struct iovec *key_data = NULL;
47✔
2533
                TokenType token_type = determine_token_type();
47✔
2534

2535
                log_debug("Beginning attempt %u to unlock.", tries);
47✔
2536

2537
                /* When we were able to acquire multiple keys, let's always process them in this order:
2538
                 *
2539
                 *    1. A key acquired via PKCS#11 or FIDO2 token, or TPM2 chip
2540
                 *    2. The configured or discovered key, of which both are exclusive and optional
2541
                 *    3. The empty password, in case arg_try_empty_password is set
2542
                 *    4. We enquire the user for a password
2543
                 */
2544

2545
                if (try_discover_key) {
47✔
2546
                        r = discover_key(discovered_key_fn, volume, token_type, &discovered_key_data);
24✔
2547
                        if (r < 0)
24✔
2548
                                return r;
2549
                        if (r > 0)
24✔
2550
                                key_data = &discovered_key_data;
1✔
2551
                }
2552

2553
                if (token_type < 0 && !key_file && !key_data && !passwords) {
47✔
2554

2555
                        /* If we have nothing to try anymore, then acquire a new password */
2556

2557
                        if (arg_try_empty_password) {
16✔
2558
                                /* Hmm, let's try an empty password now, but only once */
2559
                                arg_try_empty_password = false;
2✔
2560
                                key_data = &iovec_empty;
2✔
2561
                        } else {
2562
                                /* Ask the user for a passphrase or recovery key only as last resort, if we
2563
                                 * have nothing else to check for */
2564
                                if (passphrase_type == PASSPHRASE_NONE) {
14✔
2565
                                        passphrase_type = check_registered_passwords(cd);
14✔
2566
                                        if (passphrase_type == PASSPHRASE_NONE)
14✔
2567
                                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No passphrase or recovery key registered.");
×
2568
                                }
2569

2570
                                r = get_password(
14✔
2571
                                                volume,
2572
                                                source,
2573
                                                until,
2574
                                                /* ignore_cached= */ !use_cached_passphrase || arg_verify,
14✔
2575
                                                passphrase_type,
2576
                                                &passwords);
2577
                                use_cached_passphrase = false;
14✔
2578
                                if (r == -EAGAIN)
14✔
2579
                                        continue;
×
2580
                                if (r < 0)
14✔
2581
                                        return r;
2582
                        }
2583
                }
2584

2585
                if (streq_ptr(arg_type, CRYPT_TCRYPT))
33✔
2586
                        r = attach_tcrypt(cd, volume, token_type, key_file, key_data, passwords, flags);
×
2587
                else
2588
                        r = attach_luks_or_plain_or_bitlk(cd, volume, token_type, key_file, key_data, passwords, flags, until);
33✔
2589
                if (r >= 0)
33✔
2590
                        break;
2591
                if (r != -EAGAIN)
12✔
2592
                        return r;
2593

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

2597
                if (token_type == TOKEN_TPM2) {
12✔
2598
                        arg_tpm2_device = mfree(arg_tpm2_device);
9✔
2599
                        arg_tpm2_device_auto = false;
9✔
2600
                        continue;
9✔
2601
                }
2602

2603
                if (token_type == TOKEN_FIDO2) {
3✔
2604
                        arg_fido2_device = mfree(arg_fido2_device);
×
2605
                        arg_fido2_device_auto = false;
×
2606
                        continue;
×
2607
                }
2608

2609
                if (token_type == TOKEN_PKCS11) {
3✔
2610
                        arg_pkcs11_uri = mfree(arg_pkcs11_uri);
×
2611
                        arg_pkcs11_uri_auto = false;
×
2612
                        continue;
×
2613
                }
2614

2615
                if (try_discover_key) {
3✔
2616
                        try_discover_key = false;
×
2617
                        continue;
×
2618
                }
2619

2620
                if (key_file) {
3✔
2621
                        key_file = NULL;
3✔
2622
                        continue;
3✔
2623
                }
2624

2625
                if (passwords) {
×
2626
                        passwords = strv_free_erase(passwords);
×
2627
                        continue;
×
2628
                }
2629

2630
                log_debug("Prepared for next attempt to unlock.");
×
2631
        }
2632

2633
        if (arg_tries != 0 && tries >= arg_tries)
21✔
2634
                return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Too many attempts to activate; giving up.");
×
2635

2636
        return 0;
2637
}
2638

2639
static int verb_detach(int argc, char *argv[], void *userdata) {
55✔
2640
        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
55✔
2641
        const char *volume = ASSERT_PTR(argv[1]);
55✔
2642
        int r;
55✔
2643

2644
        assert(argc == 2);
55✔
2645

2646
        if (!filename_is_valid(volume))
55✔
2647
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
×
2648

2649
        r = crypt_init_by_name(&cd, volume);
55✔
2650
        if (r == -ENODEV) {
55✔
2651
                log_info("Volume %s already inactive.", volume);
×
2652
                return 0;
×
2653
        }
2654
        if (r < 0)
55✔
2655
                return log_error_errno(r, "crypt_init_by_name() for volume '%s' failed: %m", volume);
×
2656

2657
        cryptsetup_enable_logging(cd);
55✔
2658

2659
        r = crypt_deactivate(cd, volume);
55✔
2660
        if (r < 0)
55✔
2661
                return log_error_errno(r, "Failed to deactivate '%s': %m", volume);
×
2662

2663
        return 0;
2664
}
2665

2666
static int run(int argc, char *argv[]) {
125✔
2667
        int r;
125✔
2668

2669
        log_setup();
125✔
2670

2671
        umask(0022);
125✔
2672

2673
        r = parse_argv(argc, argv);
125✔
2674
        if (r <= 0)
125✔
2675
                return r;
2676

2677
        cryptsetup_enable_logging(NULL);
125✔
2678

2679
        static const Verb verbs[] = {
125✔
2680
                { "attach", 3, 5, 0, verb_attach },
2681
                { "detach", 2, 2, 0, verb_detach },
2682
                {}
2683
        };
2684

2685
        return dispatch_verb(argc, argv, verbs, NULL);
125✔
2686
}
2687

2688
DEFINE_MAIN_FUNCTION(run);
125✔
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