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

systemd / systemd / 29461261567

15 Jul 2026 04:59PM UTC coverage: 72.983% (+0.05%) from 72.936%
29461261567

push

github

yuwata
tpm2-util: keep the measurement log's torn-write marker intact

The userspace measurement log carries a sticky-bit marker while a writer
is between updating a measurement register and appending the matching
record, so that a writer dying in between leaves the log detectably
incomplete.

However, the next successful writer used to clear the marker again after
appending its own record, erasing the evidence that an earlier writer
had died and the log is still missing a record. Keep the marker set in
that case instead; the new record is appended and synced regardless. The
marker likewise stays set if the measurement itself fails, so that any
non-clean completion remains flagged: a spurious flag on a failed but
harmless measurement is preferable to erasing evidence of a real gap,
and PCR replay stays authoritative either way.

Finally, warn when systemd-pcrlock loads a marked log, so the resulting
PCR validation failures come with a hint at their cause.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>

11 of 12 new or added lines in 2 files covered. (91.67%)

2475 existing lines in 54 files now uncovered.

346100 of 474222 relevant lines covered (72.98%)

1321758.71 hits per line

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

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

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

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

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

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

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

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

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

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

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

157
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(passphrase_type, PassphraseType);
×
158

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

165
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(token_type, TokenType);
46✔
166

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

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

181
        assert(option);
165✔
182

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

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

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

195
        } else if ((val = startswith(option, "size="))) {
164✔
196

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

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

208
                arg_key_size /= 8;
×
209

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

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

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

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

226
        } else if ((val = startswith(option, "key-slot=")) ||
164✔
227
                   (val = startswith(option, "keyslot="))) {
162✔
228

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

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

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

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

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

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

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

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

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

263
                arg_keyfile_erase = r;
2✔
264

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

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

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

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

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

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

289
        } else if ((val = startswith(option, "tries="))) {
143✔
290

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

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

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

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

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

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

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

368
        } else if ((val = startswith(option, "offset="))) {
135✔
369

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

374
        } else if ((val = startswith(option, "skip="))) {
135✔
375

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

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

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

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

393
                        arg_pkcs11_uri_auto = false;
×
394
                }
395

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

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

406
                        arg_fido2_device_auto = false;
×
407
                }
408

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

479
                        arg_tpm2_device_auto = false;
×
480
                }
481

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

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

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

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

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

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

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

506
                arg_tpm2_pin = r;
×
507

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

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

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

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

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

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

535
                arg_tpm2_measure_pcr = pcr;
×
536

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

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

542
                r = DLOPEN_LIBCRYPTO(LOG_ERR, recommended);
×
543
                if (r < 0)
×
544
                        return r;
545

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

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

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

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

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

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

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

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

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

589
                arg_try_empty_password = r;
1✔
590

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

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

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

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

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

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

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

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

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

637
                sep += 2;
×
638

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

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

650
                        sep = c + 1;
×
651
                }
652

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

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

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

668
        return 0;
669
}
670

671
static int parse_crypt_config(const char *options) {
81✔
672
        assert(options);
81✔
673

674
        for (;;) {
411✔
675
                _cleanup_free_ char *word = NULL;
165✔
676
                int r;
246✔
677

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

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

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

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

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

708
        return 0;
709
}
710

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

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

721
        assert(path);
14✔
722

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

726
        if (!S_ISBLK(st.st_mode))
14✔
727
                return NULL;
728

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

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

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

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

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

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

756
        return NULL;
757
}
758

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

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

767
        assert(label);
14✔
768

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

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

777
        for (;;) {
×
778
                struct libmnt_fs *fs;
14✔
779

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

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

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

797
        assert(src);
14✔
798
        assert(vol);
14✔
799

800
        description = disk_description(src);
14✔
801
        mount_point = disk_mount_point(vol);
14✔
802

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

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

818
        return name_buffer;
×
819
}
820

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

826
        assert(cd);
15✔
827

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

994
        strv_uniq(passwords);
×
995

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

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

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

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

1012
        *ret = TAKE_PTR(passwords);
×
1013

1014
        return 0;
×
1015
}
1016

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

1023
        int r;
×
1024

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

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

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

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

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

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

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

1064
        _cleanup_free_ char *prefix = NULL;
×
1065

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

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

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

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

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

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

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

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

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

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

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

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

1141
        r = tpm2_nvpcr_extend_bytes(
×
1142
                        c,
1143
                        /* session= */ NULL,
1144
                        arg_tpm2_measure_keyslot_nvpcr,
1145
                        &IOVEC_MAKE_STRING(s),
×
1146
                        /* secret= */ NULL,
1147
                        /* sync_secondary_anchor= */ false,
1148
                        TPM2_EVENT_KEYSLOT,
1149
                        s);
1150
        if (r < 0)
×
1151
                return log_error_errno(r, "Could not extend NvPCR: %m");
×
1152

1153
        log_struct(LOG_INFO,
×
1154
                   "MESSAGE_ID=" SD_MESSAGE_TPM_NVPCR_EXTEND_STR,
1155
                   LOG_MESSAGE("Successfully extended NvPCR index '%s' with '%s'.", arg_tpm2_measure_keyslot_nvpcr, s),
1156
                   "MEASURING=%s", s,
1157
                   "NVPCR=%s", arg_tpm2_measure_keyslot_nvpcr);
1158

1159
        return 0;
1160
#else
1161
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support disabled, not measuring keyslot.");
1162
#endif
1163
}
1164

UNCOV
1165
static int log_external_activation(int r, const char *volume) {
×
UNCOV
1166
        assert(volume);
×
1167

UNCOV
1168
        log_notice_errno(r, "Volume '%s' has been activated externally while we have been trying to activate it.", volume);
×
UNCOV
1169
        return 0;
×
1170
}
1171

1172
static int measured_crypt_activate_by_volume_key(
4✔
1173
                struct crypt_device *cd,
1174
                const char *name,
1175
                const char *mechanism,
1176
                int keyslot,
1177
                const void *volume_key,
1178
                size_t volume_key_size,
1179
                uint32_t flags) {
1180

1181
        int r;
4✔
1182

1183
        assert(cd);
4✔
1184
        assert(name);
4✔
1185

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

1188
        /* First, check if volume key digest matches the expectation. */
1189
        if (arg_fixate_volume_key) {
4✔
1190
                 _cleanup_free_ char *key_id = NULL;
4✔
1191

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

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

1207
        r = sym_crypt_activate_by_volume_key(cd, name, volume_key, volume_key_size, flags);
2✔
1208
        if (r == -EEXIST) /* volume is already active */
2✔
UNCOV
1209
                return log_external_activation(r, name);
×
1210
        if (r < 0)
2✔
1211
                return r;
1212

1213
        if (arg_tpm2_measure_pcr == UINT_MAX) {
2✔
1214
                log_debug("Not measuring volume key, deactivated.");
2✔
1215
                return 0;
1216
        }
1217

UNCOV
1218
        if (volume_key_size > 0)
×
UNCOV
1219
                (void) measure_volume_key(cd, name, volume_key, volume_key_size); /* OK if fails */
×
1220
        else
UNCOV
1221
                log_debug("Not measuring volume key, none specified.");
×
1222

1223
        (void) measure_keyslot(cd, name, mechanism, keyslot); /* ditto */
×
1224
        return r;
×
1225
}
1226

1227
static int measured_crypt_activate_by_passphrase(
33✔
1228
                struct crypt_device *cd,
1229
                const char *name,
1230
                const char *mechanism,
1231
                int keyslot,
1232
                const char *passphrase,
1233
                size_t passphrase_size,
1234
                uint32_t flags) {
1235

1236
        _cleanup_(erase_and_freep) void *vk = NULL;
33✔
1237
        size_t vks;
33✔
1238
        int r;
33✔
1239

1240
        assert(cd);
33✔
1241

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

1247
        if (arg_tpm2_measure_pcr == UINT_MAX && !arg_fixate_volume_key)
33✔
1248
                goto shortcut;
29✔
1249

1250
        r = sym_crypt_get_volume_key_size(cd);
4✔
1251
        if (r < 0)
4✔
1252
                return r;
1253
        if (r == 0) {
4✔
UNCOV
1254
                log_debug("Not measuring volume key, none defined.");
×
UNCOV
1255
                goto shortcut;
×
1256
        }
1257

1258
        vk = malloc(vks = r);
4✔
1259
        if (!vk)
4✔
1260
                return -ENOMEM;
1261

1262
        keyslot = sym_crypt_volume_key_get(cd, keyslot, vk, &vks, passphrase, passphrase_size);
4✔
1263
        if (keyslot < 0)
4✔
1264
                return keyslot;
1265

1266
        return measured_crypt_activate_by_volume_key(cd, name, mechanism, keyslot, vk, vks, flags);
4✔
1267

1268
shortcut:
29✔
1269
        keyslot = sym_crypt_activate_by_passphrase(cd, name, keyslot, passphrase, passphrase_size, flags);
29✔
1270
        if (keyslot == -EEXIST) /* volume is already active */
29✔
UNCOV
1271
                return log_external_activation(keyslot, name);
×
1272
        if (keyslot < 0)
29✔
1273
                return keyslot;
1274

1275
        (void) measure_keyslot(cd, name, mechanism, keyslot);
25✔
1276
        return keyslot;
1277
}
1278

UNCOV
1279
static int attach_tcrypt(
×
1280
                struct crypt_device *cd,
1281
                const char *name,
1282
                TokenType token_type,
1283
                const char *key_file,
1284
                const struct iovec *key_data,
1285
                char **passwords,
1286
                uint32_t flags) {
1287

UNCOV
1288
        int r = 0;
×
UNCOV
1289
        _cleanup_(erase_and_freep) char *passphrase = NULL;
×
UNCOV
1290
        struct crypt_params_tcrypt params = {
×
1291
                .flags = CRYPT_TCRYPT_LEGACY_MODES,
1292
                .keyfiles = (const char **)arg_tcrypt_keyfiles,
1293
                .keyfiles_count = strv_length(arg_tcrypt_keyfiles)
×
1294
        };
1295

UNCOV
1296
        assert(cd);
×
UNCOV
1297
        assert(name);
×
1298
        assert(key_file || key_data || !strv_isempty(passwords));
×
1299

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

1305
        if (arg_tcrypt_hidden)
×
UNCOV
1306
                params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
×
1307

UNCOV
1308
        if (arg_tcrypt_system)
×
UNCOV
1309
                params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
×
1310

1311
        if (arg_tcrypt_veracrypt)
×
UNCOV
1312
                params.flags |= CRYPT_TCRYPT_VERA_MODES;
×
1313

1314
        if (arg_tcrypt_veracrypt && arg_tcrypt_veracrypt_pim != 0)
×
UNCOV
1315
                params.veracrypt_pim = arg_tcrypt_veracrypt_pim;
×
1316

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

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

1350
                        return r;
1351
                }
1352

1353
                return log_error_errno(r, "Failed to load tcrypt superblock on device %s: %m", sym_crypt_get_device_name(cd));
×
1354
        }
1355

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

1367
        return 0;
1368
}
1369

1370
static char *make_bindname(const char *volume, TokenType token_type) {
45✔
1371
        const char *token_type_name = token_type_to_string(token_type), *suffix;
45✔
1372
        char *bindname;
45✔
1373
        int r;
45✔
1374

1375
        switch (token_type) {
45✔
1376

1377
        case TOKEN_FIDO2:
1378
                suffix = "-salt";
1379
                break;
1380

1381
        default:
1382
                suffix = NULL;
45✔
1383
        }
1384

1385
        r = asprintf(&bindname,
45✔
1386
                     "@%" PRIx64"/cryptsetup%s%s%s/%s",
1387
                     random_u64(),
1388
                     token_type_name ? "-" : "",
1389
                     strempty(token_type_name),
1390
                     strempty(suffix),
1391
                     volume);
1392
        if (r < 0)
45✔
1393
                return NULL;
45✔
1394

1395
        return bindname;
45✔
1396
}
1397

UNCOV
1398
static int make_security_device_monitor(
×
1399
                sd_event **ret_event,
1400
                sd_device_monitor **ret_monitor) {
UNCOV
1401
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
UNCOV
1402
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1403
        int r;
×
1404

UNCOV
1405
        assert(ret_event);
×
1406
        assert(ret_monitor);
×
1407

1408
        /* Waits for a device with "security-device" tag to show up in udev */
UNCOV
1409
        log_debug("Creating device monitor for tag 'security-device' with timeout %s",
×
1410
                  FORMAT_TIMESPAN(arg_token_timeout_usec, 1*USEC_PER_SEC));
1411

UNCOV
1412
        r = sd_event_default(&event);
×
UNCOV
1413
        if (r < 0)
×
1414
                return log_error_errno(r, "Failed to allocate event loop: %m");
×
1415

UNCOV
1416
        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
×
1417
        if (r < 0)
×
1418
                return log_error_errno(r, "Failed to install timeout event source: %m");
×
1419

UNCOV
1420
        r = sd_device_monitor_new(&monitor);
×
1421
        if (r < 0)
×
1422
                return log_error_errno(r, "Failed to allocate device monitor: %m");
×
1423

UNCOV
1424
        (void) sd_device_monitor_set_description(monitor, "security-device");
×
1425

1426
        r = sd_device_monitor_filter_add_match_tag(monitor, "security-device");
×
1427
        if (r < 0)
×
UNCOV
1428
                return log_error_errno(r, "Failed to configure device monitor: %m");
×
1429

UNCOV
1430
        r = sd_device_monitor_attach_event(monitor, event);
×
1431
        if (r < 0)
×
1432
                return log_error_errno(r, "Failed to attach device monitor: %m");
×
1433

UNCOV
1434
        r = sd_device_monitor_start(monitor, NULL, NULL);
×
1435
        if (r < 0)
×
1436
                return log_error_errno(r, "Failed to start device monitor: %m");
×
1437

UNCOV
1438
        *ret_event = TAKE_PTR(event);
×
1439
        *ret_monitor = TAKE_PTR(monitor);
×
1440
        return 0;
×
1441
}
1442

1443
static int run_security_device_monitor(
×
1444
                sd_event *event,
1445
                sd_device_monitor *monitor) {
UNCOV
1446
        bool processed = false;
×
UNCOV
1447
        int r;
×
1448

UNCOV
1449
        assert(event);
×
UNCOV
1450
        assert(monitor);
×
1451

1452
        /* Runs the event loop for the device monitor until either something happens, or the timeout is
1453
         * hit. */
1454

1455
        for (;;) {
×
UNCOV
1456
                int x;
×
1457

UNCOV
1458
                r = sd_event_get_exit_code(event, &x);
×
UNCOV
1459
                if (r < 0) {
×
1460
                        if (r != -ENODATA)
×
1461
                                return log_error_errno(r, "Failed to query exit code from event loop: %m");
×
1462

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

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

1477
                processed = true;
×
1478
        }
1479
}
1480

1481
static bool use_token_plugins(void) {
67✔
1482

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

1495
        /* Disable tokens if we're in FIDO2 mode with manual parameters. */
1496
        if (arg_fido2_cid)
67✔
1497
                return false;
1498

1499
#if HAVE_LIBCRYPTSETUP_PLUGINS
1500
        int r;
67✔
1501

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

1509
        return sym_crypt_token_external_path();
63✔
1510
#else
1511
        return false;
1512
#endif
1513
}
1514

1515
#if HAVE_LIBCRYPTSETUP_PLUGINS
1516
static int acquire_pins_from_env_variable(char ***ret_pins) {
24✔
1517
        _cleanup_(erase_and_freep) char *envpin = NULL;
24✔
1518
        _cleanup_strv_free_erase_ char **pins = NULL;
24✔
1519
        int r;
24✔
1520

1521
        assert(ret_pins);
24✔
1522

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

1532
        *ret_pins = TAKE_PTR(pins);
24✔
1533

1534
        return 0;
24✔
1535
}
1536
#endif
1537

1538
static int crypt_activate_by_token_pin_ask_password(
62✔
1539
                struct crypt_device *cd,
1540
                const char *name,
1541
                const char *type,
1542
                usec_t until,
1543
                void *userdata,
1544
                uint32_t activation_flags,
1545
                const char *message,
1546
                const char *keyring,
1547
                const char *credential) {
1548

1549
#if HAVE_LIBCRYPTSETUP_PLUGINS
1550
        AskPasswordFlags flags = arg_ask_password_flags;
62✔
1551
        _cleanup_strv_free_erase_ char **pins = NULL;
62✔
1552
        int r;
62✔
1553

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

1562
        r = acquire_pins_from_env_variable(&pins);
24✔
1563
        if (r < 0)
24✔
1564
                return r;
1565

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

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

UNCOV
1579
        for (;;) {
×
UNCOV
1580
                pins = strv_free_erase(pins);
×
1581

UNCOV
1582
                AskPasswordRequest req = {
×
1583
                        .tty_fd = -EBADF,
1584
                        .message = message,
1585
                        .icon = "drive-harddisk",
1586
                        .keyring = keyring,
1587
                        .credential = credential,
1588
                        .until = until,
1589
                        .hup_fd = -EBADF,
1590
                };
1591

UNCOV
1592
                r = ask_password_auto(&req, flags, &pins);
×
UNCOV
1593
                if (r < 0)
×
UNCOV
1594
                        return r;
×
1595

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

1606
                flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
×
1607
        }
1608
        return r;
1609
#else
1610
        return -EOPNOTSUPP;
1611
#endif
1612
}
1613

UNCOV
1614
static int attach_luks2_by_fido2_via_plugin(
×
1615
                struct crypt_device *cd,
1616
                const char *name,
1617
                usec_t until,
1618
                void *userdata,
1619
                uint32_t activation_flags) {
1620

UNCOV
1621
        return crypt_activate_by_token_pin_ask_password(
×
1622
                        cd,
1623
                        name,
1624
                        "systemd-fido2",
1625
                        until,
1626
                        userdata,
1627
                        activation_flags,
1628
                        "Please enter security token PIN:",
1629
                        "fido2-pin",
1630
                        "cryptsetup.fido2-pin");
1631
}
1632

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

UNCOV
1642
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
UNCOV
1643
        _cleanup_(erase_and_freep) void *decrypted_key = NULL;
×
UNCOV
1644
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
UNCOV
1645
        size_t decrypted_key_size;
×
UNCOV
1646
        _cleanup_free_ char *friendly = NULL;
×
1647
        int keyslot = arg_key_slot, r;
×
1648
        bool use_libcryptsetup_plugin = use_token_plugins();
×
1649

1650
        assert(cd);
×
1651
        assert(name);
×
1652
        assert(arg_fido2_device || arg_fido2_device_auto);
×
1653

UNCOV
1654
        if (arg_fido2_cid && !key_file && !iovec_is_set(key_data))
×
1655
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1656
                                        "FIDO2 mode with manual parameters selected, but no keyfile specified, refusing.");
1657

UNCOV
1658
        friendly = friendly_disk_name(sym_crypt_get_device_name(cd), name);
×
1659
        if (!friendly)
×
1660
                return log_oom();
×
1661

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

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

UNCOV
1700
                if (r != -EAGAIN) /* EAGAIN means: token not found */
×
1701
                        return r;
1702

UNCOV
1703
                if (!monitor) {
×
1704
                        /* We didn't find the token. In this case, watch for it via udev. Let's
1705
                         * create an event loop and monitor first. */
1706

UNCOV
1707
                        assert(!event);
×
1708

UNCOV
1709
                        r = make_security_device_monitor(&event, &monitor);
×
UNCOV
1710
                        if (r < 0)
×
1711
                                return r;
1712

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

1715
                        /* Let's immediately rescan in case the token appeared in the time we needed
1716
                         * to create and configure the monitor */
UNCOV
1717
                        continue;
×
1718
                }
1719

UNCOV
1720
                r = run_security_device_monitor(event, monitor);
×
UNCOV
1721
                if (r < 0)
×
1722
                        return r;
1723

UNCOV
1724
                log_debug("Got one or more potentially relevant udev events, rescanning FIDO2...");
×
1725
        }
1726

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

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

1742
                base64_encoded_size = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
×
1743
                if (base64_encoded_size < 0)
×
UNCOV
1744
                        return log_oom();
×
1745

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

1762
        return 0;
1763
}
1764

1765
static int attach_luks2_by_pkcs11_via_plugin(
1✔
1766
                struct crypt_device *cd,
1767
                const char *name,
1768
                const char *friendly_name,
1769
                usec_t until,
1770
                const char *askpw_credential,
1771
                uint32_t flags) {
1772

1773
#if HAVE_LIBCRYPTSETUP_PLUGINS
1774
        int r;
1✔
1775

1776
        if (!streq_ptr(sym_crypt_get_type(cd), CRYPT_LUKS2))
1✔
UNCOV
1777
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Automatic PKCS#11 metadata requires LUKS2 device.");
×
1778

1779
        systemd_pkcs11_plugin_params params = {
1✔
1780
                .friendly_name = friendly_name,
1781
                .until = until,
1782
                .askpw_credential = askpw_credential,
1783
                .askpw_flags = arg_ask_password_flags,
1784
        };
1785

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

1792
        return r;
1793
#else
1794
        return -EOPNOTSUPP;
1795
#endif
1796
}
1797

1798
static int attach_luks_or_plain_or_bitlk_by_pkcs11(
1✔
1799
                struct crypt_device *cd,
1800
                const char *name,
1801
                const char *key_file,
1802
                const struct iovec *key_data,
1803
                usec_t until,
1804
                uint32_t flags,
1805
                bool pass_volume_key) {
1806

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

1819
        assert(cd);
1✔
1820
        assert(name);
1✔
1821
        assert(arg_pkcs11_uri || arg_pkcs11_uri_auto);
1✔
1822

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

1832
                        uri = discovered_uri;
×
UNCOV
1833
                        discovered_key_data = IOVEC_MAKE(discovered_key, discovered_key_size);
×
1834
                        key_data = &discovered_key_data;
×
1835
                }
1836
        } else {
1837
                uri = arg_pkcs11_uri;
×
1838

1839
                if (!key_file && !iovec_is_set(key_data))
×
UNCOV
1840
                        return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "PKCS#11 mode selected but no key file specified, refusing.");
×
1841
        }
1842

1843
        friendly = friendly_disk_name(sym_crypt_get_device_name(cd), name);
1✔
1844
        if (!friendly)
1✔
1845
                return log_oom();
×
1846

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

1871
                if (r != -EAGAIN) /* EAGAIN means: token not found */
1✔
1872
                        return r;
1873

UNCOV
1874
                if (!monitor) {
×
1875
                        /* We didn't find the token. In this case, watch for it via udev. Let's
1876
                         * create an event loop and monitor first. */
1877

UNCOV
1878
                        assert(!event);
×
1879

UNCOV
1880
                        r = make_security_device_monitor(&event, &monitor);
×
UNCOV
1881
                        if (r < 0)
×
1882
                                return r;
1883

UNCOV
1884
                        log_notice("Security token%s%s not present for unlocking volume %s, please plug it in.",
×
1885
                                   uri ? " " : "", strempty(uri), friendly);
1886

1887
                        /* Let's immediately rescan in case the token appeared in the time we needed
1888
                         * to create and configure the monitor */
1889
                        continue;
×
1890
                }
1891

UNCOV
1892
                r = run_security_device_monitor(event, monitor);
×
UNCOV
1893
                if (r < 0)
×
1894
                        return r;
1895

UNCOV
1896
                log_debug("Got one or more potentially relevant udev events, rescanning PKCS#11...");
×
1897
        }
1898
        assert(decrypted_key);
×
1899

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

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

UNCOV
1921
                base64_encoded_size = base64mem(decrypted_key, decrypted_key_size, &base64_encoded);
×
UNCOV
1922
                if (base64_encoded_size < 0)
×
UNCOV
1923
                        return log_oom();
×
1924

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

1941
        return 0;
1942
}
1943

1944
static int make_tpm2_device_monitor(
×
1945
                sd_event **ret_event,
1946
                sd_device_monitor **ret_monitor) {
1947

UNCOV
1948
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1949
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
UNCOV
1950
        int r;
×
1951

UNCOV
1952
        assert(ret_event);
×
1953
        assert(ret_monitor);
×
1954

1955
        r = sd_event_default(&event);
×
UNCOV
1956
        if (r < 0)
×
1957
                return log_error_errno(r, "Failed to allocate event loop: %m");
×
1958

UNCOV
1959
        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
×
1960
        if (r < 0)
×
1961
                return log_error_errno(r, "Failed to install timeout event source: %m");
×
1962

UNCOV
1963
        r = sd_device_monitor_new(&monitor);
×
1964
        if (r < 0)
×
1965
                return log_error_errno(r, "Failed to allocate device monitor: %m");
×
1966

UNCOV
1967
        (void) sd_device_monitor_set_description(monitor, "tpmrm");
×
1968

1969
        r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, "tpmrm", NULL);
×
1970
        if (r < 0)
×
UNCOV
1971
                return log_error_errno(r, "Failed to configure device monitor: %m");
×
1972

UNCOV
1973
        r = sd_device_monitor_attach_event(monitor, event);
×
1974
        if (r < 0)
×
1975
                return log_error_errno(r, "Failed to attach device monitor: %m");
×
1976

UNCOV
1977
        r = sd_device_monitor_start(monitor, NULL, NULL);
×
1978
        if (r < 0)
×
1979
                return log_error_errno(r, "Failed to start device monitor: %m");
×
1980

UNCOV
1981
        *ret_event = TAKE_PTR(event);
×
1982
        *ret_monitor = TAKE_PTR(monitor);
×
1983
        return 0;
×
1984
}
1985

1986
static int attach_luks2_by_tpm2_via_plugin(
11✔
1987
                struct crypt_device *cd,
1988
                const char *name,
1989
                usec_t until,
1990
                uint32_t flags) {
1991

1992
#if HAVE_LIBCRYPTSETUP_PLUGINS
1993
        systemd_tpm2_plugin_params params = {
11✔
1994
                .search_pcr_mask = arg_tpm2_pcr_mask,
1995
                .device = arg_tpm2_device,
1996
                .signature_path = arg_tpm2_signature,
1997
                .pcrlock_path = arg_tpm2_pcrlock,
1998
        };
1999

2000
        if (!use_token_plugins())
11✔
2001
                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
2✔
2002
                                       "libcryptsetup has external plugins support disabled.");
2003

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

2019
static int attach_luks_or_plain_or_bitlk_by_tpm2(
13✔
2020
                struct crypt_device *cd,
2021
                const char *name,
2022
                const char *key_file,
2023
                const struct iovec *key_data,
2024
                usec_t until,
2025
                uint32_t flags,
2026
                bool pass_volume_key) {
2027

2028
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
13✔
UNCOV
2029
        _cleanup_(iovec_done_erase) struct iovec decrypted_key = {};
×
2030
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
13✔
2031
        _cleanup_free_ char *friendly = NULL;
13✔
2032
        int keyslot = arg_key_slot, r;
13✔
2033

2034
        assert(cd);
13✔
2035
        assert(name);
13✔
2036
        assert(arg_tpm2_device || arg_tpm2_device_auto);
13✔
2037

2038
        friendly = friendly_disk_name(sym_crypt_get_device_name(cd), name);
13✔
2039
        if (!friendly)
13✔
UNCOV
2040
                return log_oom();
×
2041

2042
        for (;;) {
13✔
2043
                if (key_file || iovec_is_set(key_data)) {
13✔
2044
                        /* If key data is specified, use that */
2045

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

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

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

2107
                        for (;;) {
6✔
2108
                                _cleanup_(iovec_done) struct iovec pubkey = {}, salt = {}, srk = {}, pcrlock_nv = {};
2✔
2109
                                _cleanup_free_ char *pubkey_policy_ref = NULL;
4✔
2110
                                struct iovec *blobs = NULL, *policy_hash = NULL;
4✔
2111
                                uint32_t hash_pcr_mask, pubkey_pcr_mask;
4✔
2112
                                size_t n_blobs = 0, n_policy_hash = 0;
4✔
2113
                                uint16_t pcr_bank, primary_alg;
4✔
2114
                                Argon2IdParameters argon2id_params = {};
4✔
2115
                                TPM2Flags tpm2_flags;
4✔
2116

2117
                                CLEANUP_ARRAY(blobs, n_blobs, iovec_array_free);
4✔
UNCOV
2118
                                CLEANUP_ARRAY(policy_hash, n_policy_hash, iovec_array_free);
×
2119

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

2155
                                found_some = true;
4✔
2156

2157
                                r = acquire_tpm2_key(
4✔
2158
                                                name,
2159
                                                arg_tpm2_device,
2160
                                                hash_pcr_mask,
2161
                                                pcr_bank,
2162
                                                &pubkey,
2163
                                                pubkey_policy_ref,
2164
                                                pubkey_pcr_mask,
2165
                                                arg_tpm2_signature,
2166
                                                arg_tpm2_pcrlock,
2167
                                                primary_alg,
2168
                                                /* key_file= */ NULL, /* key_file_size= */ 0, /* key_file_offset= */ 0, /* no key file */
2169
                                                blobs,
2170
                                                n_blobs,
2171
                                                policy_hash,
2172
                                                n_policy_hash,
2173
                                                &salt,
2174
                                                &srk,
2175
                                                &pcrlock_nv,
2176
                                                tpm2_flags,
2177
                                                until,
2178
                                                "cryptsetup.tpm2-pin",
2179
                                                arg_ask_password_flags,
2180
                                                &argon2id_params,
2181
                                                &decrypted_key);
2182
                                if (IN_SET(r, -EACCES, -ENOLCK))
4✔
UNCOV
2183
                                        return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN), "TPM2 PIN unlock failed, falling back to traditional unlocking.");
×
2184
                                /* Stop unless we should keep iterating to next token because the tried one
2185
                                 * does not match boot state. For now without -EUCLEAN because currently the
2186
                                 * only error it reports won't be solved by moving to another token. */
2187
                                if (!ERRNO_IS_NEG_TPM2_TOKEN_MISMATCH(r))
4✔
2188
                                        break;
2189

2190
                                token++; /* try a different token next time */
2✔
2191
                        }
2192

2193
                        if (r >= 0)
2✔
2194
                                break;
2195
                        /* EAGAIN means: no tpm2 chip found */
UNCOV
2196
                        if (r != -EAGAIN) {
×
UNCOV
2197
                                log_notice_errno(r, "TPM2 operation failed, falling back to traditional unlocking: %m");
×
2198
                                return -EAGAIN; /* Mangle error code: let's make any form of TPM2 failure non-fatal. */
2199
                        }
2200
                }
2201

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

UNCOV
2206
                        assert(!event);
×
2207

UNCOV
2208
                        if (is_efi_boot() && !efi_has_tpm2())
×
UNCOV
2209
                                return log_notice_errno(SYNTHETIC_ERRNO(EAGAIN),
×
2210
                                                        "No TPM2 hardware discovered and EFI firmware does not see it either, falling back to traditional unlocking.");
2211

UNCOV
2212
                        r = make_tpm2_device_monitor(&event, &monitor);
×
2213
                        if (r < 0)
×
2214
                                return r;
2215

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

2218
                        /* Let's immediately rescan in case the device appeared in the time we needed
2219
                         * to create and configure the monitor */
UNCOV
2220
                        continue;
×
2221
                }
2222

UNCOV
2223
                r = run_security_device_monitor(event, monitor);
×
UNCOV
2224
                if (r < 0)
×
2225
                        return r;
2226

UNCOV
2227
                log_debug("Got one or more potentially relevant udev events, rescanning for TPM2...");
×
2228
        }
2229

2230
        if (pass_volume_key)
2✔
UNCOV
2231
                r = measured_crypt_activate_by_volume_key(
×
2232
                                cd,
2233
                                name,
2234
                                "tpm2",
2235
                                /* keyslot= */ -1,
2236
                                decrypted_key.iov_base,
×
2237
                                decrypted_key.iov_len,
2238
                                flags);
2239
        else {
2240
                _cleanup_(erase_and_freep) char *base64_encoded = NULL;
2✔
2241
                ssize_t base64_encoded_size;
2✔
2242

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

2245
                base64_encoded_size = base64mem(decrypted_key.iov_base, decrypted_key.iov_len, &base64_encoded);
2✔
2246
                if (base64_encoded_size < 0)
2✔
UNCOV
2247
                        return log_oom();
×
2248

2249
                r = measured_crypt_activate_by_passphrase(
2✔
2250
                                cd,
2251
                                name,
2252
                                "tpm2",
2253
                                keyslot,
2254
                                base64_encoded,
2255
                                base64_encoded_size,
2256
                                flags);
2257
        }
2258
        if (r == -EPERM) {
2✔
2259
                log_error_errno(r, "Failed to activate with TPM2 decrypted key. (Key incorrect?)");
13✔
2260
                return -EAGAIN; /* log actual error, but return EAGAIN */
2261
        }
2262
        if (r < 0)
2✔
UNCOV
2263
                return log_error_errno(r, "Failed to activate with TPM2 acquired key: %m");
×
2264

2265
        return 0;
2266
}
2267

2268
static int attach_luks_or_plain_or_bitlk_by_key_data(
3✔
2269
                struct crypt_device *cd,
2270
                const char *name,
2271
                const struct iovec *key_data,
2272
                uint32_t flags,
2273
                bool pass_volume_key) {
2274

2275
        int r;
3✔
2276

2277
        assert(cd);
3✔
2278
        assert(name);
3✔
2279
        assert(key_data);
3✔
2280

2281
        if (pass_volume_key)
3✔
UNCOV
2282
                r = measured_crypt_activate_by_volume_key(cd, name, /* mechanism= */ NULL, /* keyslot= */ -1, key_data->iov_base, key_data->iov_len, flags);
×
2283
        else
2284
                r = measured_crypt_activate_by_passphrase(cd, name, /* mechanism= */ NULL, arg_key_slot, key_data->iov_base, key_data->iov_len, flags);
3✔
2285
        if (r == -EPERM) {
3✔
UNCOV
2286
                log_error_errno(r, "Failed to activate. (Key incorrect?)");
×
2287
                return -EAGAIN; /* Log actual error, but return EAGAIN */
2288
        }
2289
        if (r < 0)
3✔
UNCOV
2290
                return log_error_errno(r, "Failed to activate: %m");
×
2291

2292
        return 0;
2293
}
2294

2295
static int attach_luks_or_plain_or_bitlk_by_key_file(
28✔
2296
                struct crypt_device *cd,
2297
                const char *name,
2298
                const char *key_file,
2299
                uint32_t flags,
2300
                bool pass_volume_key) {
2301

2302
        _cleanup_(erase_and_freep) char *kfdata = NULL;
28✔
2303
        _cleanup_free_ char *bindname = NULL;
28✔
2304
        size_t kfsize;
28✔
2305
        int r;
28✔
2306

2307
        assert(cd);
28✔
2308
        assert(name);
28✔
2309
        assert(key_file);
28✔
2310

2311
        /* If we read the key via AF_UNIX, make this client recognizable */
2312
        bindname = make_bindname(name, /* token_type= */ _TOKEN_TYPE_INVALID);
28✔
2313
        if (!bindname)
28✔
UNCOV
2314
                return log_oom();
×
2315

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

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

2345
        return 0;
2346
}
2347

UNCOV
2348
static int attach_luks_or_plain_or_bitlk_by_passphrase(
×
2349
                struct crypt_device *cd,
2350
                const char *name,
2351
                char **passwords,
2352
                uint32_t flags,
2353
                bool pass_volume_key) {
2354

UNCOV
2355
        int r;
×
2356

UNCOV
2357
        assert(cd);
×
UNCOV
2358
        assert(name);
×
2359

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

2376
        return 0;
2377
}
2378

2379
static int attach_luks_or_plain_or_bitlk(
45✔
2380
                struct crypt_device *cd,
2381
                const char *name,
2382
                TokenType token_type,
2383
                const char *key_file,
2384
                const struct iovec *key_data,
2385
                char **passwords,
2386
                uint32_t flags,
2387
                usec_t until) {
2388

2389
        bool pass_volume_key = false;
45✔
2390
        int r;
45✔
2391

2392
        assert(cd);
45✔
2393
        assert(name);
45✔
2394

2395
        if ((!arg_type && !sym_crypt_get_type(cd)) || streq_ptr(arg_type, CRYPT_PLAIN)) {
45✔
UNCOV
2396
                struct crypt_params_plain params = {
×
2397
                        .offset = arg_offset,
2398
                        .skip = arg_skip,
2399
                        .sector_size = arg_sector_size,
2400
                };
2401
                const char *cipher, *cipher_mode;
×
UNCOV
2402
                _cleanup_free_ char *truncated_cipher = NULL;
×
2403

UNCOV
2404
                if (streq_ptr(arg_hash, "plain"))
×
2405
                        /* plain isn't a real hash type. it just means "use no hash" */
2406
                        params.hash = NULL;
2407
                else if (arg_hash)
×
UNCOV
2408
                        params.hash = arg_hash;
×
2409
                else if (!key_file)
×
2410
                        /* for CRYPT_PLAIN, the behaviour of cryptsetup package is to not hash when a key
2411
                         * file is provided */
2412
                        params.hash = "ripemd160";
×
2413

2414
                if (arg_cipher) {
×
UNCOV
2415
                        size_t l;
×
2416

2417
                        l = strcspn(arg_cipher, "-");
×
UNCOV
2418
                        truncated_cipher = strndup(arg_cipher, l);
×
2419
                        if (!truncated_cipher)
×
2420
                                return log_oom();
×
2421

2422
                        cipher = truncated_cipher;
×
2423
                        cipher_mode = arg_cipher[l] ? arg_cipher+l+1 : "plain";
×
2424
                } else {
2425
                        cipher = "aes";
2426
                        cipher_mode = "cbc-essiv:sha256";
2427
                }
2428

2429
                /* for CRYPT_PLAIN limit reads from keyfile to key length, and ignore keyfile-size */
UNCOV
2430
                arg_keyfile_size = arg_key_size;
×
2431

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

2438
                /* hash == NULL implies the user passed "plain" */
2439
                pass_volume_key = !params.hash;
×
2440
        }
2441

2442
        log_info("Set cipher %s, mode %s, key size %i bits for device %s.",
45✔
2443
                 sym_crypt_get_cipher(cd),
2444
                 sym_crypt_get_cipher_mode(cd),
2445
                 sym_crypt_get_volume_key_size(cd)*8,
2446
                 sym_crypt_get_device_name(cd));
2447

2448
        if (token_type == TOKEN_TPM2)
45✔
2449
                return attach_luks_or_plain_or_bitlk_by_tpm2(cd, name, key_file, key_data, until, flags, pass_volume_key);
13✔
2450
        if (token_type == TOKEN_FIDO2)
32✔
UNCOV
2451
                return attach_luks_or_plain_or_bitlk_by_fido2(cd, name, key_file, key_data, until, flags, pass_volume_key);
×
2452
        if (token_type == TOKEN_PKCS11)
32✔
2453
                return attach_luks_or_plain_or_bitlk_by_pkcs11(cd, name, key_file, key_data, until, flags, pass_volume_key);
1✔
2454
        if (key_data)
31✔
2455
                return attach_luks_or_plain_or_bitlk_by_key_data(cd, name, key_data, flags, pass_volume_key);
3✔
2456
        if (key_file)
28✔
2457
                return attach_luks_or_plain_or_bitlk_by_key_file(cd, name, key_file, flags, pass_volume_key);
28✔
2458

UNCOV
2459
        return attach_luks_or_plain_or_bitlk_by_passphrase(cd, name, passwords, flags, pass_volume_key);
×
2460
}
2461

UNCOV
2462
static int help(void) {
×
UNCOV
2463
        _cleanup_free_ char *link = NULL;
×
2464
        _cleanup_(table_unrefp) Table *options = NULL, *verbs = NULL;
×
UNCOV
2465
        int r;
×
2466

2467
        r = terminal_urlify_man("systemd-cryptsetup", "8", &link);
×
2468
        if (r < 0)
×
2469
                return log_oom();
×
2470

UNCOV
2471
        r = verbs_get_help_table(&verbs);
×
2472
        if (r < 0)
×
2473
                return r;
2474

UNCOV
2475
        r = option_parser_get_help_table(&options);
×
2476
        if (r < 0)
×
2477
                return r;
2478

UNCOV
2479
        (void) table_sync_column_widths(0, verbs, options);
×
2480

2481
        printf("%s [OPTIONS...] {COMMAND} ...\n\n"
×
2482
               "%sAttach or detach an encrypted block device.%s\n"
2483
               "\n%sCommands:%s\n",
2484
               program_invocation_short_name,
2485
               ansi_highlight(),
2486
               ansi_normal(),
2487
               ansi_underline(),
2488
               ansi_normal());
2489

UNCOV
2490
        r = table_print_or_warn(verbs);
×
UNCOV
2491
        if (r < 0)
×
2492
                return r;
2493

UNCOV
2494
        printf("\n%sOptions:%s\n",
×
2495
               ansi_underline(),
2496
               ansi_normal());
2497

UNCOV
2498
        r = table_print_or_warn(options);
×
2499
        if (r < 0)
×
2500
                return r;
2501

UNCOV
2502
        printf("\nSee the %s for details.\n", link);
×
2503
        return 0;
2504
}
2505

UNCOV
2506
VERB_COMMON_HELP_HIDDEN(help);
×
2507

2508
static int parse_argv(int argc, char *argv[], char ***ret_args) {
151✔
2509
        assert(argc >= 0);
151✔
2510
        assert(argv);
151✔
2511
        assert(ret_args);
151✔
2512

2513
        OptionParser opts = { argc, argv };
151✔
2514

2515
        FOREACH_OPTION_OR_RETURN(c, &opts)
151✔
UNCOV
2516
                switch (c) {
×
2517

UNCOV
2518
                OPTION_COMMON_HELP:
×
UNCOV
2519
                        return help();
×
2520

2521
                OPTION_COMMON_VERSION:
×
UNCOV
2522
                        return version();
×
2523
                }
2524

2525
        *ret_args = option_parser_get_args(&opts);
151✔
2526
        return 1;
151✔
2527
}
2528

2529
static uint32_t determine_flags(void) {
83✔
2530
        uint32_t flags = 0;
83✔
2531

2532
        if (arg_readonly)
83✔
UNCOV
2533
                flags |= CRYPT_ACTIVATE_READONLY;
×
2534

2535
        if (arg_discards)
83✔
UNCOV
2536
                flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
×
2537

2538
        if (arg_same_cpu_crypt)
83✔
UNCOV
2539
                flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
×
2540

2541
        if (arg_submit_from_crypt_cpus)
83✔
UNCOV
2542
                flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
×
2543

2544
        if (arg_no_read_workqueue)
83✔
UNCOV
2545
                flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
×
2546

2547
        if (arg_no_write_workqueue)
83✔
UNCOV
2548
                flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
×
2549

2550
        /* Try to decrease the risk of OOM event if memory hard key derivation function is in use */
2551
        /* https://gitlab.com/cryptsetup/cryptsetup/issues/446/ */
2552
        flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF;
83✔
2553

2554
        return flags;
83✔
2555
}
2556

2557
static void remove_and_erasep(const char **p) {
83✔
2558
        int r;
83✔
2559

2560
        assert(p);
83✔
2561

2562
        if (!*p)
83✔
2563
                return;
2564

2565
        r = unlinkat_deallocate(AT_FDCWD, *p, UNLINK_ERASE);
2✔
2566
        if (r < 0 && r != -ENOENT)
2✔
UNCOV
2567
                log_warning_errno(r, "Unable to erase key file '%s', ignoring: %m", *p);
×
2568
}
2569

2570
static TokenType determine_token_type(void) {
60✔
2571
        if (arg_tpm2_device || arg_tpm2_device_auto)
60✔
2572
                return TOKEN_TPM2;
2573
        if (arg_fido2_device || arg_fido2_device_auto)
47✔
2574
                return TOKEN_FIDO2;
2575
        if (arg_pkcs11_uri || arg_pkcs11_uri_auto)
47✔
2576
                return TOKEN_PKCS11;
1✔
2577

2578
        return _TOKEN_TYPE_INVALID;
2579
}
2580

2581
static int discover_key(const char *key_file, const char *volume, TokenType token_type, struct iovec *ret_key_data) {
17✔
2582
        _cleanup_free_ char *bindname = NULL;
17✔
2583
        const char *token_type_name;
17✔
2584
        int r;
17✔
2585

2586
        assert(key_file);
17✔
2587
        assert(volume);
17✔
2588
        assert(ret_key_data);
17✔
2589

2590
        bindname = make_bindname(volume, token_type);
17✔
2591
        if (!bindname)
17✔
UNCOV
2592
                return log_oom();
×
2593

2594
        /* If a key file is not explicitly specified, search for a key in a well defined search path, and load it. */
2595
        r = find_key_file(key_file, STRV_MAKE("/etc/cryptsetup-keys.d", "/run/cryptsetup-keys.d"), bindname, ret_key_data);
17✔
2596
        if (r <= 0)
17✔
2597
                return r;
2598

2599
        token_type_name = token_type_to_string(token_type);
1✔
2600
        if (token_type_name)
1✔
UNCOV
2601
                log_debug("Automatically discovered encrypted key for volume '%s' (token type: %s).", volume, token_type_name);
×
2602
        else
2603
                log_debug("Automatically discovered key for volume '%s'.", volume);
1✔
2604

2605
        return r;
2606
}
2607

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

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

2622
        assert(argc >= 3 && argc <= 5);
83✔
2623

2624
        const char *volume = ASSERT_PTR(argv[1]),
83✔
2625
                *source = ASSERT_PTR(argv[2]),
83✔
2626
                *key_file = argc >= 4 ? mangle_none(argv[3]) : NULL,
83✔
2627
                *config = argc >= 5 ? mangle_none(argv[4]) : NULL;
83✔
2628

2629
        if (!filename_is_valid(volume))
83✔
UNCOV
2630
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
×
2631

2632
        if (key_file && !path_is_absolute(key_file)) {
83✔
UNCOV
2633
                log_warning("Password file path '%s' is not absolute. Ignoring.", key_file);
×
2634
                key_file = NULL;
2635
        }
2636

2637
        if (config) {
83✔
2638
                r = parse_crypt_config(config);
81✔
2639
                if (r < 0)
81✔
2640
                        return r;
2641
        }
2642

2643
        log_debug("%s %s ← %s type=%s cipher=%s", __func__,
232✔
2644
                  volume, source, strempty(arg_type), strempty(arg_cipher));
2645

2646
        /* A delicious drop of snake oil */
2647
        (void) safe_mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT);
83✔
2648

2649
        /* Only erase key files explicitly configured on the command line, never the ones we
2650
         * auto-discover in /etc/cryptsetup-keys.d/ and /run/cryptsetup-keys.d/: those are shared
2651
         * resources not owned by an individual volume. (key_file is NULL when auto-discovery is used.) */
2652
        if (key_file && arg_keyfile_erase)
83✔
2653
                destroy_key_file = key_file; /* let's get this baby erased when we leave */
2✔
2654

2655
        if (arg_header) {
83✔
2656
                if (streq_ptr(arg_type, CRYPT_TCRYPT)){
9✔
UNCOV
2657
                        log_debug("tcrypt header: %s", arg_header);
×
UNCOV
2658
                        r = sym_crypt_init_data_device(&cd, arg_header, source);
×
2659
                } else {
2660
                        log_debug("LUKS header: %s", arg_header);
9✔
2661
                        r = sym_crypt_init(&cd, arg_header);
9✔
2662
                }
2663
        } else
2664
                r = sym_crypt_init(&cd, source);
74✔
2665
        if (r < 0)
83✔
UNCOV
2666
                return log_error_errno(r, "crypt_init() failed: %m");
×
2667

2668
        cryptsetup_enable_logging(cd);
83✔
2669

2670
        status = sym_crypt_status(cd, volume);
83✔
2671
        if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
83✔
UNCOV
2672
                log_info("Volume %s already active.", volume);
×
2673
                return 0;
2674
        }
2675

2676
        flags = determine_flags();
83✔
2677

2678
        until = usec_add(now(CLOCK_MONOTONIC), arg_timeout);
83✔
UNCOV
2679
        if (until == USEC_INFINITY)
×
2680
                until = 0;
83✔
2681

2682
        if (arg_key_size == 0)
83✔
2683
                arg_key_size = 256U / 8U;
83✔
2684

2685
        if (key_file) {
83✔
2686
                struct stat st;
28✔
2687

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

2694
        if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2)) {
83✔
2695
                r = sym_crypt_load(cd, !arg_type || streq(arg_type, ANY_LUKS) ? CRYPT_LUKS : arg_type, NULL);
83✔
2696
                if (r < 0)
83✔
2697
                        return log_error_errno(r, "Failed to load LUKS superblock on device %s: %m", sym_crypt_get_device_name(cd));
38✔
2698

2699
                /* since cryptsetup 2.7.0 (Jan 2024) */
2700
                if (arg_link_key_description) {
83✔
UNCOV
2701
                        r = sym_crypt_set_keyring_to_link(cd, arg_link_key_description, NULL, arg_link_key_type, arg_link_keyring);
×
UNCOV
2702
                        if (r == -ENOSYS)
×
UNCOV
2703
                                log_warning("Loaded libcryptsetup does not support linking volume keys in user specified kernel keyrings upon device activation, ignoring.");
×
UNCOV
2704
                        else if (r < 0)
×
UNCOV
2705
                                log_warning_errno(r, "Failed to set keyring or key description to link volume key in, ignoring: %m");
×
2706
                }
2707

2708
                if (arg_header) {
83✔
2709
                        r = sym_crypt_set_data_device(cd, source);
9✔
2710
                        if (r < 0)
9✔
UNCOV
2711
                                return log_error_errno(r, "Failed to set LUKS data device %s: %m", source);
×
2712
                }
2713

2714
                /* Tokens are available in LUKS2 only, but it is ok to call (and fail) with LUKS1. */
2715
                if (!key_file && use_token_plugins()) {
83✔
2716
                        r = crypt_activate_by_token_pin_ask_password(
53✔
2717
                                        cd,
2718
                                        volume,
2719
                                        /* type= */ NULL,
2720
                                        until,
2721
                                        /* userdata= */ NULL,
2722
                                        flags,
2723
                                        "Please enter LUKS2 token PIN:",
2724
                                        "luks2-pin",
2725
                                        "cryptsetup.luks2-pin");
2726
                        if (r >= 0) {
53✔
2727
                                log_debug("Volume %s activated with a LUKS token.", volume);
38✔
2728
                                return 0;
2729
                        }
2730

2731
                        log_debug_errno(r, "Token activation unsuccessful for device %s: %m", sym_crypt_get_device_name(cd));
15✔
2732
                }
2733
        }
2734

2735
        if (streq_ptr(arg_type, CRYPT_BITLK)) {
45✔
UNCOV
2736
                r = sym_crypt_load(cd, CRYPT_BITLK, NULL);
×
UNCOV
2737
                if (r < 0)
×
UNCOV
2738
                        return log_error_errno(r, "Failed to load Bitlocker superblock on device %s: %m", sym_crypt_get_device_name(cd));
×
2739
        }
2740

2741
        bool use_cached_passphrase = true, try_discover_key = !key_file;
45✔
2742
        const char *discovered_key_fn = strjoina(volume, ".key");
225✔
2743
        _cleanup_strv_free_erase_ char **passwords = NULL;
45✔
2744
        for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) {
60✔
2745
                _cleanup_(iovec_done_erase) struct iovec discovered_key_data = {};
60✔
2746
                const struct iovec *key_data = NULL;
60✔
2747
                TokenType token_type = determine_token_type();
60✔
2748

2749
                log_debug("Beginning attempt %u to unlock.", tries);
60✔
2750

2751
                /* When we were able to acquire multiple keys, let's always process them in this order:
2752
                 *
2753
                 *    1. A key acquired via PKCS#11 or FIDO2 token, or TPM2 chip
2754
                 *    2. The configured or discovered key, of which both are exclusive and optional
2755
                 *    3. The empty password, in case arg_try_empty_password is set
2756
                 *    4. We enquire the user for a password
2757
                 */
2758

2759
                if (try_discover_key) {
60✔
2760
                        r = discover_key(discovered_key_fn, volume, token_type, &discovered_key_data);
17✔
2761
                        if (r < 0)
17✔
2762
                                return r;
2763
                        if (r > 0)
17✔
2764
                                key_data = &discovered_key_data;
2765
                        else
2766
                                try_discover_key = false;
16✔
2767
                }
2768

2769
                if (token_type < 0 && !key_file && !key_data && !passwords) {
60✔
2770

2771
                        /* If we have nothing to try anymore, then acquire a new password */
2772

2773
                        if (arg_try_empty_password) {
17✔
2774
                                /* Hmm, let's try an empty password now, but only once */
2775
                                arg_try_empty_password = false;
2✔
2776
                                key_data = &iovec_empty;
2✔
2777
                        } else {
2778
                                /* Ask the user for a passphrase or recovery key only as last resort, if we
2779
                                 * have nothing else to check for */
2780
                                if (passphrase_type == PASSPHRASE_NONE) {
15✔
2781
                                        passphrase_type = check_registered_passwords(cd);
15✔
2782
                                        if (passphrase_type == PASSPHRASE_NONE)
15✔
UNCOV
2783
                                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "No passphrase or recovery key registered.");
×
2784
                                }
2785

2786
                                r = get_password(
15✔
2787
                                                volume,
2788
                                                source,
2789
                                                until,
2790
                                                /* ignore_cached= */ !use_cached_passphrase || arg_verify,
15✔
2791
                                                passphrase_type,
2792
                                                &passwords);
2793
                                use_cached_passphrase = false;
15✔
2794
                                if (r == -EAGAIN)
15✔
UNCOV
2795
                                        continue;
×
2796
                                if (r < 0)
15✔
2797
                                        return r;
2798
                        }
2799
                }
2800

2801
                if (streq_ptr(arg_type, CRYPT_TCRYPT))
45✔
UNCOV
2802
                        r = attach_tcrypt(cd, volume, token_type, key_file, key_data, passwords, flags);
×
2803
                else
2804
                        r = attach_luks_or_plain_or_bitlk(cd, volume, token_type, key_file, key_data, passwords, flags, until);
45✔
2805
                if (r >= 0)
45✔
2806
                        break;
2807
                if (r != -EAGAIN)
18✔
2808
                        return r;
2809

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

2813
                if (token_type == TOKEN_TPM2) {
15✔
2814
                        arg_tpm2_device = mfree(arg_tpm2_device);
11✔
2815
                        arg_tpm2_device_auto = false;
11✔
2816
                        continue;
11✔
2817
                }
2818

2819
                if (token_type == TOKEN_FIDO2) {
4✔
UNCOV
2820
                        arg_fido2_device = mfree(arg_fido2_device);
×
UNCOV
2821
                        arg_fido2_device_auto = false;
×
UNCOV
2822
                        continue;
×
2823
                }
2824

2825
                if (token_type == TOKEN_PKCS11) {
4✔
2826
                        arg_pkcs11_uri = mfree(arg_pkcs11_uri);
×
2827
                        arg_pkcs11_uri_auto = false;
×
UNCOV
2828
                        continue;
×
2829
                }
2830

2831
                if (try_discover_key) {
4✔
2832
                        try_discover_key = false;
×
2833
                        continue;
×
2834
                }
2835

2836
                if (key_file) {
4✔
2837
                        key_file = NULL;
4✔
2838
                        continue;
4✔
2839
                }
2840

UNCOV
2841
                if (passwords) {
×
UNCOV
2842
                        passwords = strv_free_erase(passwords);
×
UNCOV
2843
                        continue;
×
2844
                }
2845

2846
                log_debug("Prepared for next attempt to unlock.");
×
2847
        }
2848

2849
        if (arg_tries != 0 && tries >= arg_tries)
27✔
UNCOV
2850
                return log_error_errno(SYNTHETIC_ERRNO(EPERM), "Too many attempts to activate; giving up.");
×
2851

2852
        return 0;
2853
}
2854

2855
VERB(verb_detach, "detach", "VOLUME", 2, 2, 0,
2856
     "Detach an encrypted block device");
2857
static int verb_detach(int argc, char *argv[], uintptr_t _data, void *userdata) {
68✔
2858
        _cleanup_(crypt_freep) struct crypt_device *cd = NULL;
68✔
2859
        const char *volume = ASSERT_PTR(argv[1]);
68✔
2860
        int r;
68✔
2861

2862
        assert(argc == 2);
68✔
2863

2864
        if (!filename_is_valid(volume))
68✔
UNCOV
2865
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Volume name '%s' is not valid.", volume);
×
2866

2867
        r = sym_crypt_init_by_name(&cd, volume);
68✔
2868
        if (r == -ENODEV) {
68✔
2869
                log_info("Volume %s already inactive.", volume);
3✔
2870
                return 0;
2871
        }
2872
        if (r < 0)
65✔
UNCOV
2873
                return log_error_errno(r, "crypt_init_by_name() for volume '%s' failed: %m", volume);
×
2874

2875
        cryptsetup_enable_logging(cd);
65✔
2876

2877
        r = sym_crypt_deactivate(cd, volume);
65✔
2878
        if (r < 0)
65✔
UNCOV
2879
                return log_error_errno(r, "Failed to deactivate '%s': %m", volume);
×
2880

2881
        return 0;
2882
}
2883

2884
static int run(int argc, char *argv[]) {
151✔
2885
        int r;
151✔
2886

2887
        LIBBLKID_NOTE(recommended);
151✔
2888
        LIBFIDO2_NOTE(suggested);
151✔
2889
        LIBMOUNT_NOTE(recommended);
151✔
2890
        LIBP11KIT_NOTE(suggested);
151✔
2891
        TPM2_NOTE(suggested);
151✔
2892

2893
        log_setup();
151✔
2894

2895
        umask(0022);
151✔
2896

2897
        char **args = NULL;
151✔
2898
        r = parse_argv(argc, argv, &args);
151✔
2899
        if (r <= 0)
151✔
2900
                return r;
151✔
2901

2902
        r = DLOPEN_CRYPTSETUP(LOG_ERR, required);
151✔
2903
        if (r < 0)
151✔
2904
                return r;
2905

2906
        return dispatch_verb(args, NULL);
151✔
2907
}
2908

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

© 2026 Coveralls, Inc