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

systemd / systemd / 25615496818

09 May 2026 05:08PM UTC coverage: 72.511% (-0.1%) from 72.64%
25615496818

push

github

bluca
hwdb/keyboard: fix KP_Enter on Clevo PA70ES

The ITE keyboard controller firmware (version 0xAB83) is shared
between the Clevo PA70ES and the X+ piccolo series.

The piccolo's hwdb rule matches by input device ID
(evdev:input:b0011v0001p0001eAB83*) and remaps scan code 0x9c
(KP_Enter) to Enter, since the piccolo has no numpad and its
main Enter key sends the wrong scan code.

The Clevo PA70ES has a real numpad. The piccolo rule matches it
because both laptops use the same ITE controller firmware, which
breaks KP_Enter on the PA70ES.

Add a DMI-specific override that restores KEY_KPENTER for 0x9c
on the PA70ES.

The piccolo rule should ideally be narrowed to use DMI matching
instead of input device ID to avoid catching other laptops with
the same ITE controller firmware.

326196 of 449859 relevant lines covered (72.51%)

1210161.93 hits per line

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

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

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

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

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

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

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

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

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

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

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

156
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(passphrase_type, PassphraseType);
×
157

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

164
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(token_type, TokenType);
53✔
165

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

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

180
        assert(option);
153✔
181

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

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

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

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

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

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

207
                arg_key_size /= 8;
×
208

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

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

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

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

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

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

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

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

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

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

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

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

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

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

262
                arg_keyfile_erase = r;
2✔
263

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

392
                        arg_pkcs11_uri_auto = false;
×
393
                }
394

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

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

405
                        arg_fido2_device_auto = false;
×
406
                }
407

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

478
                        arg_tpm2_device_auto = false;
×
479
                }
480

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

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

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

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

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

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

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

505
                arg_tpm2_pin = r;
×
506

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

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

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

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

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

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

534
                arg_tpm2_measure_pcr = pcr;
×
535

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

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

541
                r = dlopen_libcrypto(LOG_ERR);
×
542
                if (r < 0)
×
543
                        return r;
544

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

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

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

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

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

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

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

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

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

588
                arg_try_empty_password = r;
1✔
589

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

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

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

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

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

610
        } else if ((val = startswith(option, "link-volume-key="))) {
4✔
611
#if HAVE_CRYPT_SET_KEYRING_TO_LINK
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
661
                log_error("Build lacks libcryptsetup support for linking volume keys in user specified kernel keyrings upon device activation, ignoring: %s", option);
662
#endif
663
        } else if ((val = startswith(option, "fixate-volume-key="))) {
4✔
664
                r = free_and_strdup(&arg_fixate_volume_key, val);
4✔
665
                if (r < 0)
4✔
666
                        return log_oom();
×
667

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

671
        return 0;
672
}
673

674
static int parse_crypt_config(const char *options) {
76✔
675
        assert(options);
76✔
676

677
        for (;;) {
382✔
678
                _cleanup_free_ char *word = NULL;
153✔
679
                int r;
229✔
680

681
                r = extract_first_word(&options, &word, ",", EXTRACT_DONT_COALESCE_SEPARATORS | EXTRACT_UNESCAPE_SEPARATORS);
229✔
682
                if (r < 0)
229✔
683
                        return log_error_errno(r, "Failed to parse options: %m");
×
684
                if (r == 0)
229✔
685
                        break;
686

687
                r = parse_one_option(word);
153✔
688
                if (r < 0)
153✔
689
                        return r;
690
        }
691

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

700
        if (arg_pkcs11_uri || arg_pkcs11_uri_auto) {
76✔
701
                /* If password-cache was not configured explicitly, default to no cache for PKCS#11 */
702
                if (!arg_password_cache_set)
6✔
703
                        arg_ask_password_flags &= ~(ASK_PASSWORD_ACCEPT_CACHED|ASK_PASSWORD_PUSH_CACHE);
6✔
704

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

711
        return 0;
712
}
713

714
static char* disk_description(const char *path) {
12✔
715
        static const char name_fields[] =
12✔
716
                "DM_NAME\0"
717
                "ID_MODEL_FROM_DATABASE\0"
718
                "ID_MODEL\0";
719

720
        _cleanup_(sd_device_unrefp) sd_device *device = NULL;
12✔
721
        const char *name;
12✔
722
        struct stat st;
12✔
723

724
        assert(path);
12✔
725

726
        if (stat(path, &st) < 0)
12✔
727
                return NULL;
728

729
        if (!S_ISBLK(st.st_mode))
12✔
730
                return NULL;
731

732
        if (sd_device_new_from_stat_rdev(&device, &st) < 0)
×
733
                return NULL;
734

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

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

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

749
                if (!isempty(unescaped) && !string_has_cc(unescaped, NULL))
×
750
                        return TAKE_PTR(unescaped);
×
751
        }
752

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

759
        return NULL;
760
}
761

762
static char* disk_mount_point(const char *label) {
12✔
763
        _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
12✔
764
        _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
×
765
        _cleanup_free_ char *device = NULL;
12✔
766
        int r;
12✔
767

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

770
        assert(label);
12✔
771

772
        device = strjoin("/dev/mapper/", label);
12✔
773
        if (!device)
12✔
774
                return NULL;
775

776
        r = libmount_parse_fstab(&table, &iter);
12✔
777
        if (r < 0)
12✔
778
                return NULL;
779

780
        for (;;) {
×
781
                struct libmnt_fs *fs;
12✔
782

783
                r = sym_mnt_table_next_fs(table, iter, &fs);
12✔
784
                if (r != 0)
12✔
785
                        return NULL;
12✔
786

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

795
static char *friendly_disk_name(const char *src, const char *vol) {
12✔
796
        _cleanup_free_ char *description = NULL, *mount_point = NULL;
12✔
797
        char *name_buffer = NULL;
12✔
798
        int r;
12✔
799

800
        assert(src);
12✔
801
        assert(vol);
12✔
802

803
        description = disk_description(src);
12✔
804
        mount_point = disk_mount_point(vol);
12✔
805

806
        /* If the description string is simply the volume name, then let's not show this twice */
807
        if (description && streq(vol, description))
12✔
808
                description = mfree(description);
×
809

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

821
        return name_buffer;
×
822
}
823

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

829
        assert(cd);
15✔
830

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

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

842
        for (int slot = 0; slot < slot_max; slot++)
495✔
843
                slots[slot] = IN_SET(sym_crypt_keyslot_status(cd, slot), CRYPT_SLOT_ACTIVE, CRYPT_SLOT_ACTIVE_LAST);
480✔
844

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

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

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

866
                type = sd_json_variant_string(w);
10✔
867
                if (STR_IN_SET(type, "systemd-recovery", "systemd-pkcs11", "systemd-fido2", "systemd-tpm2")) {
10✔
868

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

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

879
                        JSON_VARIANT_ARRAY_FOREACH(z, w) {
20✔
880
                                unsigned u;
10✔
881
                                int at;
10✔
882

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

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

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

899
                                slots[u] = false;
10✔
900
                        }
901
                }
902
        }
903

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

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

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

924
        _cleanup_free_ char *friendly = NULL, *text = NULL, *disk_path = NULL, *id = NULL;
15✔
925
        _cleanup_strv_free_erase_ char **passwords = NULL;
×
926
        AskPasswordFlags flags = arg_ask_password_flags;
15✔
927
        int r;
15✔
928

929
        assert(vol);
15✔
930
        assert(src);
15✔
931
        assert(ret);
15✔
932

933
        if (FLAGS_SET(arg_ask_password_flags, ASK_PASSWORD_HEADLESS))
15✔
934
                return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Password querying disabled via 'headless' option.");
15✔
935

936
        friendly = friendly_disk_name(src, vol);
×
937
        if (!friendly)
×
938
                return log_oom();
×
939

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

943
        disk_path = cescape(src);
×
944
        if (!disk_path)
×
945
                return log_oom();
×
946

947
        id = strjoin("cryptsetup:", disk_path);
×
948
        if (!id)
×
949
                return log_oom();
×
950

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

962
        if (ignore_cached)
×
963
                flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
×
964

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

969
        if (arg_verify) {
×
970
                _cleanup_strv_free_erase_ char **passwords2 = NULL;
×
971

972
                assert(strv_length(passwords) == 1);
×
973

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

978
                free(id);
×
979
                id = strjoin("cryptsetup-verification:", disk_path);
×
980
                if (!id)
×
981
                        return log_oom();
×
982

983
                req.message = text;
×
984
                req.id = id;
×
985

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

990
                assert(strv_length(passwords2) == 1);
×
991

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

997
        strv_uniq(passwords);
×
998

999
        STRV_FOREACH(p, passwords) {
×
1000
                char *c;
×
1001

1002
                if (strlen(*p)+1 >= arg_key_size)
×
1003
                        continue;
×
1004

1005
                /* Pad password if necessary */
1006
                c = new(char, arg_key_size);
×
1007
                if (!c)
×
1008
                        return log_oom();
15✔
1009

1010
                strncpy(c, *p, arg_key_size);
×
1011
                erase_and_free(*p);
×
1012
                *p = TAKE_PTR(c);
×
1013
        }
1014

1015
        *ret = TAKE_PTR(passwords);
×
1016

1017
        return 0;
×
1018
}
1019

1020
static int measure_volume_key(
×
1021
                struct crypt_device *cd,
1022
                const char *name,
1023
                const void *volume_key,
1024
                size_t volume_key_size) {
1025

1026
        int r;
×
1027

1028
        assert(cd);
×
1029
        assert(name);
×
1030
        assert(volume_key);
×
1031
        assert(volume_key_size > 0);
×
1032

1033
        if (arg_tpm2_measure_pcr == UINT_MAX) {
×
1034
                log_debug("Not measuring volume key, deactivated.");
×
1035
                return 0;
×
1036
        }
1037

1038
        r = efi_measured_os(LOG_WARNING);
×
1039
        if (r < 0)
×
1040
                return r;
1041
        if (r == 0) {
×
1042
                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.");
×
1043
                return 0;
1044
        }
1045

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

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

1059
        _cleanup_free_ char *joined = strv_join(l ?: arg_tpm2_measure_banks, ", ");
×
1060
        if (!joined)
×
1061
                return log_oom();
×
1062

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

1067
        _cleanup_free_ char *prefix = NULL;
×
1068

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

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

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

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

1099
static int measure_keyslot(
24✔
1100
                struct crypt_device *cd,
1101
                const char *name,
1102
                const char *mechanism,
1103
                int keyslot) {
1104

1105
#if HAVE_TPM2
1106
        int r;
24✔
1107
#endif
1108
        assert(cd);
24✔
1109
        assert(name);
24✔
1110

1111
        if (!arg_tpm2_measure_keyslot_nvpcr) {
24✔
1112
                log_debug("Not measuring unlock keyslot, deactivated.");
24✔
1113
                return 0;
24✔
1114
        }
1115

1116
#if HAVE_TPM2
1117
        r = efi_measured_os(LOG_WARNING);
×
1118
        if (r < 0)
×
1119
                return r;
1120
        if (r == 0) {
×
1121
                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.");
×
1122
                return 0;
1123
        }
1124

1125
        _cleanup_(tpm2_context_unrefp) Tpm2Context *c = NULL;
×
1126
        r = tpm2_context_new_or_warn(arg_tpm2_device, &c);
×
1127
        if (r < 0)
×
1128
                return r;
1129

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

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

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

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

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

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

1161
        log_struct(LOG_INFO,
×
1162
                   "MESSAGE_ID=" SD_MESSAGE_TPM_NVPCR_EXTEND_STR,
1163
                   LOG_MESSAGE("Successfully extended NvPCR index '%s' with '%s'.", arg_tpm2_measure_keyslot_nvpcr, s),
1164
                   "MEASURING=%s", s,
1165
                   "NVPCR=%s", arg_tpm2_measure_keyslot_nvpcr);
1166

1167
        return 0;
1168
#else
1169
        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "TPM2 support disabled, not measuring keyslot.");
1170
#endif
1171
}
1172

1173
static int log_external_activation(int r, const char *volume) {
×
1174
        assert(volume);
×
1175

1176
        log_notice_errno(r, "Volume '%s' has been activated externally while we have been trying to activate it.", volume);
×
1177
        return 0;
×
1178
}
1179

1180
static int measured_crypt_activate_by_volume_key(
4✔
1181
                struct crypt_device *cd,
1182
                const char *name,
1183
                const char *mechanism,
1184
                int keyslot,
1185
                const void *volume_key,
1186
                size_t volume_key_size,
1187
                uint32_t flags) {
1188

1189
        int r;
4✔
1190

1191
        assert(cd);
4✔
1192
        assert(name);
4✔
1193

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

1196
        /* First, check if volume key digest matches the expectation. */
1197
        if (arg_fixate_volume_key) {
4✔
1198
                 _cleanup_free_ char *key_id = NULL;
4✔
1199

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

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

1215
        r = sym_crypt_activate_by_volume_key(cd, name, volume_key, volume_key_size, flags);
2✔
1216
        if (r == -EEXIST) /* volume is already active */
2✔
1217
                return log_external_activation(r, name);
×
1218
        if (r < 0)
2✔
1219
                return r;
1220

1221
        if (arg_tpm2_measure_pcr == UINT_MAX) {
2✔
1222
                log_debug("Not measuring volume key, deactivated.");
2✔
1223
                return 0;
1224
        }
1225

1226
        if (volume_key_size > 0)
×
1227
                (void) measure_volume_key(cd, name, volume_key, volume_key_size); /* OK if fails */
×
1228
        else
1229
                log_debug("Not measuring volume key, none specified.");
×
1230

1231
        (void) measure_keyslot(cd, name, mechanism, keyslot); /* ditto */
×
1232
        return r;
×
1233
}
1234

1235
static int measured_crypt_activate_by_passphrase(
32✔
1236
                struct crypt_device *cd,
1237
                const char *name,
1238
                const char *mechanism,
1239
                int keyslot,
1240
                const char *passphrase,
1241
                size_t passphrase_size,
1242
                uint32_t flags) {
1243

1244
        _cleanup_(erase_and_freep) void *vk = NULL;
32✔
1245
        size_t vks;
32✔
1246
        int r;
32✔
1247

1248
        assert(cd);
32✔
1249

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

1255
        if (arg_tpm2_measure_pcr == UINT_MAX && !arg_fixate_volume_key)
32✔
1256
                goto shortcut;
28✔
1257

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

1266
        vk = malloc(vks = r);
4✔
1267
        if (!vk)
4✔
1268
                return -ENOMEM;
1269

1270
        keyslot = sym_crypt_volume_key_get(cd, keyslot, vk, &vks, passphrase, passphrase_size);
4✔
1271
        if (keyslot < 0)
4✔
1272
                return keyslot;
1273

1274
        return measured_crypt_activate_by_volume_key(cd, name, mechanism, keyslot, vk, vks, flags);
4✔
1275

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

1283
        (void) measure_keyslot(cd, name, mechanism, keyslot);
24✔
1284
        return keyslot;
1285
}
1286

1287
static int attach_tcrypt(
×
1288
                struct crypt_device *cd,
1289
                const char *name,
1290
                TokenType token_type,
1291
                const char *key_file,
1292
                const struct iovec *key_data,
1293
                char **passwords,
1294
                uint32_t flags) {
1295

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

1304
        assert(cd);
×
1305
        assert(name);
×
1306
        assert(key_file || key_data || !strv_isempty(passwords));
×
1307

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

1313
        if (arg_tcrypt_hidden)
×
1314
                params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
×
1315

1316
        if (arg_tcrypt_system)
×
1317
                params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
×
1318

1319
        if (arg_tcrypt_veracrypt)
×
1320
                params.flags |= CRYPT_TCRYPT_VERA_MODES;
×
1321

1322
        if (arg_tcrypt_veracrypt && arg_tcrypt_veracrypt_pim != 0)
×
1323
                params.veracrypt_pim = arg_tcrypt_veracrypt_pim;
×
1324

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

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

1358
                        return r;
1359
                }
1360

1361
                return log_error_errno(r, "Failed to load tcrypt superblock on device %s: %m", sym_crypt_get_device_name(cd));
×
1362
        }
1363

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

1375
        return 0;
1376
}
1377

1378
static char *make_bindname(const char *volume, TokenType token_type) {
52✔
1379
        const char *token_type_name = token_type_to_string(token_type), *suffix;
52✔
1380
        char *bindname;
52✔
1381
        int r;
52✔
1382

1383
        switch (token_type) {
52✔
1384

1385
        case TOKEN_FIDO2:
1386
                suffix = "-salt";
1387
                break;
1388

1389
        default:
1390
                suffix = NULL;
52✔
1391
        }
1392

1393
        r = asprintf(&bindname,
52✔
1394
                     "@%" PRIx64"/cryptsetup%s%s%s/%s",
1395
                     random_u64(),
1396
                     token_type_name ? "-" : "",
1397
                     strempty(token_type_name),
1398
                     strempty(suffix),
1399
                     volume);
1400
        if (r < 0)
52✔
1401
                return NULL;
52✔
1402

1403
        return bindname;
52✔
1404
}
1405

1406
static int make_security_device_monitor(
×
1407
                sd_event **ret_event,
1408
                sd_device_monitor **ret_monitor) {
1409
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1410
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1411
        int r;
×
1412

1413
        assert(ret_event);
×
1414
        assert(ret_monitor);
×
1415

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

1420
        r = sd_event_default(&event);
×
1421
        if (r < 0)
×
1422
                return log_error_errno(r, "Failed to allocate event loop: %m");
×
1423

1424
        r = sd_event_add_time_relative(event, NULL, CLOCK_MONOTONIC, arg_token_timeout_usec, USEC_PER_SEC, NULL, INT_TO_PTR(-ETIMEDOUT));
×
1425
        if (r < 0)
×
1426
                return log_error_errno(r, "Failed to install timeout event source: %m");
×
1427

1428
        r = sd_device_monitor_new(&monitor);
×
1429
        if (r < 0)
×
1430
                return log_error_errno(r, "Failed to allocate device monitor: %m");
×
1431

1432
        (void) sd_device_monitor_set_description(monitor, "security-device");
×
1433

1434
        r = sd_device_monitor_filter_add_match_tag(monitor, "security-device");
×
1435
        if (r < 0)
×
1436
                return log_error_errno(r, "Failed to configure device monitor: %m");
×
1437

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

1442
        r = sd_device_monitor_start(monitor, NULL, NULL);
×
1443
        if (r < 0)
×
1444
                return log_error_errno(r, "Failed to start device monitor: %m");
×
1445

1446
        *ret_event = TAKE_PTR(event);
×
1447
        *ret_monitor = TAKE_PTR(monitor);
×
1448
        return 0;
×
1449
}
1450

1451
static int run_security_device_monitor(
×
1452
                sd_event *event,
1453
                sd_device_monitor *monitor) {
1454
        bool processed = false;
×
1455
        int r;
×
1456

1457
        assert(event);
×
1458
        assert(monitor);
×
1459

1460
        /* Runs the event loop for the device monitor until either something happens, or the timeout is
1461
         * hit. */
1462

1463
        for (;;) {
×
1464
                int x;
×
1465

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

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

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

1485
                processed = true;
×
1486
        }
1487
}
1488

1489
static bool use_token_plugins(void) {
60✔
1490

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

1503
        /* Disable tokens if we're in FIDO2 mode with manual parameters. */
1504
        if (arg_fido2_cid)
60✔
1505
                return false;
1506

1507
#if HAVE_LIBCRYPTSETUP_PLUGINS
1508
        int r;
60✔
1509

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

1517
        return sym_crypt_token_external_path();
58✔
1518
#else
1519
        return false;
1520
#endif
1521
}
1522

1523
#if HAVE_LIBCRYPTSETUP_PLUGINS
1524
static int acquire_pins_from_env_variable(char ***ret_pins) {
21✔
1525
        _cleanup_(erase_and_freep) char *envpin = NULL;
21✔
1526
        _cleanup_strv_free_erase_ char **pins = NULL;
21✔
1527
        int r;
21✔
1528

1529
        assert(ret_pins);
21✔
1530

1531
        r = getenv_steal_erase("PIN", &envpin);
21✔
1532
        if (r < 0)
21✔
1533
                return log_error_errno(r, "Failed to acquire PIN from environment: %m");
×
1534
        if (r > 0) {
21✔
1535
                pins = strv_new(envpin);
16✔
1536
                if (!pins)
16✔
1537
                        return log_oom();
×
1538
        }
1539

1540
        *ret_pins = TAKE_PTR(pins);
21✔
1541

1542
        return 0;
21✔
1543
}
1544
#endif
1545

1546
static int crypt_activate_by_token_pin_ask_password(
58✔
1547
                struct crypt_device *cd,
1548
                const char *name,
1549
                const char *type,
1550
                usec_t until,
1551
                void *userdata,
1552
                uint32_t activation_flags,
1553
                const char *message,
1554
                const char *keyring,
1555
                const char *credential) {
1556

1557
#if HAVE_LIBCRYPTSETUP_PLUGINS
1558
        AskPasswordFlags flags = arg_ask_password_flags;
58✔
1559
        _cleanup_strv_free_erase_ char **pins = NULL;
58✔
1560
        int r;
58✔
1561

1562
        r = sym_crypt_activate_by_token_pin(cd, name, type, CRYPT_ANY_TOKEN, /* pin= */ NULL, /* pin_size= */ 0, userdata, activation_flags);
58✔
1563
        if (r > 0) /* returns unlocked keyslot id on success */
58✔
1564
                return 0;
1565
        if (r == -EEXIST) /* volume is already active */
35✔
1566
                return log_external_activation(r, name);
×
1567
        if (r != -ENOANO) /* needs pin or pin is wrong */
35✔
1568
                return r;
1569

1570
        r = acquire_pins_from_env_variable(&pins);
21✔
1571
        if (r < 0)
21✔
1572
                return r;
1573

1574
        STRV_FOREACH(p, pins) {
25✔
1575
                r = sym_crypt_activate_by_token_pin(cd, name, type, CRYPT_ANY_TOKEN, *p, strlen(*p), userdata, activation_flags);
16✔
1576
                if (r > 0) /* returns unlocked keyslot id on success */
16✔
1577
                        return 0;
1578
                if (r == -EEXIST) /* volume is already active */
5✔
1579
                        return log_external_activation(r, name);
×
1580
                if (r != -ENOANO) /* needs pin or pin is wrong */
5✔
1581
                        return r;
1582
        }
1583

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

1587
        for (;;) {
×
1588
                pins = strv_free_erase(pins);
×
1589

1590
                AskPasswordRequest req = {
×
1591
                        .tty_fd = -EBADF,
1592
                        .message = message,
1593
                        .icon = "drive-harddisk",
1594
                        .keyring = keyring,
1595
                        .credential = credential,
1596
                        .until = until,
1597
                        .hup_fd = -EBADF,
1598
                };
1599

1600
                r = ask_password_auto(&req, flags, &pins);
×
1601
                if (r < 0)
×
1602
                        return r;
×
1603

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

1614
                flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
×
1615
        }
1616
        return r;
1617
#else
1618
        return -EOPNOTSUPP;
1619
#endif
1620
}
1621

1622
static int attach_luks2_by_fido2_via_plugin(
×
1623
                struct crypt_device *cd,
1624
                const char *name,
1625
                usec_t until,
1626
                void *userdata,
1627
                uint32_t activation_flags) {
1628

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

1641
static int attach_luks_or_plain_or_bitlk_by_fido2(
×
1642
                struct crypt_device *cd,
1643
                const char *name,
1644
                const char *key_file,
1645
                const struct iovec *key_data,
1646
                usec_t until,
1647
                uint32_t flags,
1648
                bool pass_volume_key) {
1649

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

1658
        assert(cd);
×
1659
        assert(name);
×
1660
        assert(arg_fido2_device || arg_fido2_device_auto);
×
1661

1662
        if (arg_fido2_cid && !key_file && !iovec_is_set(key_data))
×
1663
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
×
1664
                                        "FIDO2 mode with manual parameters selected, but no keyfile specified, refusing.");
1665

1666
        friendly = friendly_disk_name(sym_crypt_get_device_name(cd), name);
×
1667
        if (!friendly)
×
1668
                return log_oom();
×
1669

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

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

1708
                if (r != -EAGAIN) /* EAGAIN means: token not found */
×
1709
                        return r;
1710

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

1715
                        assert(!event);
×
1716

1717
                        r = make_security_device_monitor(&event, &monitor);
×
1718
                        if (r < 0)
×
1719
                                return r;
1720

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

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

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

1732
                log_debug("Got one or more potentially relevant udev events, rescanning FIDO2...");
×
1733
        }
1734

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

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

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

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

1770
        return 0;
1771
}
1772

1773
static int attach_luks2_by_pkcs11_via_plugin(
×
1774
                struct crypt_device *cd,
1775
                const char *name,
1776
                const char *friendly_name,
1777
                usec_t until,
1778
                const char *askpw_credential,
1779
                uint32_t flags) {
1780

1781
#if HAVE_LIBCRYPTSETUP_PLUGINS
1782
        int r;
×
1783

1784
        if (!streq_ptr(sym_crypt_get_type(cd), CRYPT_LUKS2))
×
1785
                return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Automatic PKCS#11 metadata requires LUKS2 device.");
×
1786

1787
        systemd_pkcs11_plugin_params params = {
×
1788
                .friendly_name = friendly_name,
1789
                .until = until,
1790
                .askpw_credential = askpw_credential,
1791
                .askpw_flags = arg_ask_password_flags,
1792
        };
1793

1794
        r = sym_crypt_activate_by_token_pin(cd, name, "systemd-pkcs11", CRYPT_ANY_TOKEN, NULL, 0, &params, flags);
×
1795
        if (r > 0) /* returns unlocked keyslot id on success */
×
1796
                r = 0;
1797
        if (r == -EEXIST) /* volume is already active */
×
1798
                r = log_external_activation(r, name);
×
1799

1800
        return r;
1801
#else
1802
        return -EOPNOTSUPP;
1803
#endif
1804
}
1805

1806
static int attach_luks_or_plain_or_bitlk_by_pkcs11(
×
1807
                struct crypt_device *cd,
1808
                const char *name,
1809
                const char *key_file,
1810
                const struct iovec *key_data,
1811
                usec_t until,
1812
                uint32_t flags,
1813
                bool pass_volume_key) {
1814

1815
        _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
×
1816
        _cleanup_free_ char *friendly = NULL, *discovered_uri = NULL;
×
1817
        size_t decrypted_key_size = 0, discovered_key_size = 0;
×
1818
        _cleanup_(erase_and_freep) void *decrypted_key = NULL;
×
1819
        _cleanup_(sd_event_unrefp) sd_event *event = NULL;
×
1820
        _cleanup_free_ void *discovered_key = NULL;
×
1821
        struct iovec discovered_key_data = {};
×
1822
        int keyslot = arg_key_slot, r;
×
1823
        const char *uri = NULL;
×
1824
        bool use_libcryptsetup_plugin = use_token_plugins();
×
1825

1826
        assert(cd);
×
1827
        assert(name);
×
1828
        assert(arg_pkcs11_uri || arg_pkcs11_uri_auto);
×
1829

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

1839
                        uri = discovered_uri;
×
1840
                        discovered_key_data = IOVEC_MAKE(discovered_key, discovered_key_size);
×
1841
                        key_data = &discovered_key_data;
×
1842
                }
1843
        } else {
1844
                uri = arg_pkcs11_uri;
×
1845

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

1850
        friendly = friendly_disk_name(sym_crypt_get_device_name(cd), name);
×
1851
        if (!friendly)
×
1852
                return log_oom();
×
1853

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

1877
                if (r != -EAGAIN) /* EAGAIN means: token not found */
×
1878
                        return r;
1879

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

1884
                        assert(!event);
×
1885

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

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

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

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

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

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

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

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

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

1947
        return 0;
1948
}
1949

1950
static int make_tpm2_device_monitor(
×
1951
                sd_event **ret_event,
1952
                sd_device_monitor **ret_monitor) {
1953

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

1958
        assert(ret_event);
×
1959
        assert(ret_monitor);
×
1960

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

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

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

1973
        (void) sd_device_monitor_set_description(monitor, "tpmrm");
×
1974

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

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

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

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

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

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

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

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

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

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

2040
        assert(cd);
12✔
2041
        assert(name);
12✔
2042
        assert(arg_tpm2_device || arg_tpm2_device_auto);
12✔
2043

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

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

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

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

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

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

2119
                                CLEANUP_ARRAY(blobs, n_blobs, iovec_array_free);
1✔
2120
                                CLEANUP_ARRAY(policy_hash, n_policy_hash, iovec_array_free);
1✔
2121

2122
                                r = find_tpm2_auto_data(
1✔
2123
                                                cd,
2124
                                                arg_tpm2_pcr_mask, /* if != UINT32_MAX we'll only look for tokens with this PCR mask */
2125
                                                token, /* search for the token with this index, or any later index than this */
2126
                                                &hash_pcr_mask,
2127
                                                &pcr_bank,
2128
                                                &pubkey,
2129
                                                &pubkey_pcr_mask,
2130
                                                &primary_alg,
2131
                                                &blobs,
2132
                                                &n_blobs,
2133
                                                &policy_hash,
2134
                                                &n_policy_hash,
2135
                                                &salt,
2136
                                                &srk,
2137
                                                &pcrlock_nv,
2138
                                                &tpm2_flags,
2139
                                                &keyslot,
2140
                                                &token);
2141
                                if (r == -ENXIO)
1✔
2142
                                        /* No further TPM2 tokens found in the LUKS2 header. */
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))
1✔
2149
                                        /* TPM2 support not compiled in? */
2150
                                        return log_debug_errno(SYNTHETIC_ERRNO(EAGAIN),
×
2151
                                                               "TPM2 support not available, falling back to traditional unlocking.");
2152
                                if (r < 0)
1✔
2153
                                        return r;
2154

2155
                                found_some = true;
1✔
2156

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

2185
                                token++; /* try a different token next time */
×
2186
                        }
2187

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

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

2201
                        assert(!event);
×
2202

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

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

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

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

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

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

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

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

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

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

2260
        return 0;
2261
}
2262

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

2270
        int r;
3✔
2271

2272
        assert(cd);
3✔
2273
        assert(name);
3✔
2274
        assert(key_data);
3✔
2275

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

2287
        return 0;
2288
}
2289

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

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

2302
        assert(cd);
28✔
2303
        assert(name);
28✔
2304
        assert(key_file);
28✔
2305

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

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

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

2340
        return 0;
2341
}
2342

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

2350
        int r;
×
2351

2352
        assert(cd);
×
2353
        assert(name);
×
2354

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

2371
        return 0;
2372
}
2373

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

2384
        bool pass_volume_key = false;
43✔
2385
        int r;
43✔
2386

2387
        assert(cd);
43✔
2388
        assert(name);
43✔
2389

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

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

2409
                if (arg_cipher) {
×
2410
                        size_t l;
×
2411

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

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

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

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

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

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

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

2454
        return attach_luks_or_plain_or_bitlk_by_passphrase(cd, name, passwords, flags, pass_volume_key);
×
2455
}
2456

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

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

2466
        r = verbs_get_help_table(&verbs);
×
2467
        if (r < 0)
×
2468
                return r;
2469

2470
        r = option_parser_get_help_table(&options);
×
2471
        if (r < 0)
×
2472
                return r;
2473

2474
        (void) table_sync_column_widths(0, verbs, options);
×
2475

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

2485
        r = table_print_or_warn(verbs);
×
2486
        if (r < 0)
×
2487
                return r;
2488

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

2493
        r = table_print_or_warn(options);
×
2494
        if (r < 0)
×
2495
                return r;
2496

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

2501
VERB_COMMON_HELP_HIDDEN(help);
×
2502

2503
static int parse_argv(int argc, char *argv[], char ***ret_args) {
142✔
2504
        assert(argc >= 0);
142✔
2505
        assert(argv);
142✔
2506
        assert(ret_args);
142✔
2507

2508
        OptionParser opts = { argc, argv };
142✔
2509

2510
        FOREACH_OPTION_OR_RETURN(c, &opts)
142✔
2511
                switch (c) {
×
2512

2513
                OPTION_COMMON_HELP:
×
2514
                        return help();
×
2515

2516
                OPTION_COMMON_VERSION:
×
2517
                        return version();
×
2518
                }
2519

2520
        *ret_args = option_parser_get_args(&opts);
142✔
2521
        return 1;
142✔
2522
}
2523

2524
static uint32_t determine_flags(void) {
78✔
2525
        uint32_t flags = 0;
78✔
2526

2527
        if (arg_readonly)
78✔
2528
                flags |= CRYPT_ACTIVATE_READONLY;
×
2529

2530
        if (arg_discards)
78✔
2531
                flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
×
2532

2533
        if (arg_same_cpu_crypt)
78✔
2534
                flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
×
2535

2536
        if (arg_submit_from_crypt_cpus)
78✔
2537
                flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
×
2538

2539
        if (arg_no_read_workqueue)
78✔
2540
                flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
×
2541

2542
        if (arg_no_write_workqueue)
78✔
2543
                flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
×
2544

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

2549
        return flags;
78✔
2550
}
2551

2552
static void remove_and_erasep(const char **p) {
78✔
2553
        int r;
78✔
2554

2555
        assert(p);
78✔
2556

2557
        if (!*p)
78✔
2558
                return;
2559

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

2565
static TokenType determine_token_type(void) {
58✔
2566
        if (arg_tpm2_device || arg_tpm2_device_auto)
58✔
2567
                return TOKEN_TPM2;
2568
        if (arg_fido2_device || arg_fido2_device_auto)
46✔
2569
                return TOKEN_FIDO2;
2570
        if (arg_pkcs11_uri || arg_pkcs11_uri_auto)
46✔
2571
                return TOKEN_PKCS11;
×
2572

2573
        return _TOKEN_TYPE_INVALID;
2574
}
2575

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

2581
        assert(key_file);
24✔
2582
        assert(volume);
24✔
2583
        assert(ret_key_data);
24✔
2584

2585
        bindname = make_bindname(volume, token_type);
24✔
2586
        if (!bindname)
24✔
2587
                return log_oom();
×
2588

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

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

2600
        return r;
2601
}
2602

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

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

2617
        assert(argc >= 3 && argc <= 5);
78✔
2618

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

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

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

2632
        if (config) {
78✔
2633
                r = parse_crypt_config(config);
76✔
2634
                if (r < 0)
76✔
2635
                        return r;
2636
        }
2637

2638
        log_debug("%s %s ← %s type=%s cipher=%s", __func__,
217✔
2639
                  volume, source, strempty(arg_type), strempty(arg_cipher));
2640

2641
        /* A delicious drop of snake oil */
2642
        (void) safe_mlockall(MCL_CURRENT|MCL_FUTURE|MCL_ONFAULT);
78✔
2643

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

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

2660
        cryptsetup_enable_logging(cd);
78✔
2661

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

2668
        flags = determine_flags();
78✔
2669

2670
        until = usec_add(now(CLOCK_MONOTONIC), arg_timeout);
78✔
2671
        if (until == USEC_INFINITY)
×
2672
                until = 0;
78✔
2673

2674
        if (arg_key_size == 0)
78✔
2675
                arg_key_size = 256U / 8U;
78✔
2676

2677
        if (key_file) {
78✔
2678
                struct stat st;
28✔
2679

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

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

2691
/* since cryptsetup 2.7.0 (Jan 2024) */
2692
#if HAVE_CRYPT_SET_KEYRING_TO_LINK
2693
                if (arg_link_key_description) {
78✔
2694
                        r = sym_crypt_set_keyring_to_link(cd, arg_link_key_description, NULL, arg_link_key_type, arg_link_keyring);
×
2695
                        if (r < 0)
×
2696
                                log_warning_errno(r, "Failed to set keyring or key description to link volume key in, ignoring: %m");
×
2697
                }
2698
#endif
2699

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

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

2723
                        log_debug_errno(r, "Token activation unsuccessful for device %s: %m", sym_crypt_get_device_name(cd));
14✔
2724
                }
2725
        }
2726

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

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

2741
                log_debug("Beginning attempt %u to unlock.", tries);
58✔
2742

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

2751
                if (try_discover_key) {
58✔
2752
                        r = discover_key(discovered_key_fn, volume, token_type, &discovered_key_data);
24✔
2753
                        if (r < 0)
24✔
2754
                                return r;
2755
                        if (r > 0)
24✔
2756
                                key_data = &discovered_key_data;
1✔
2757
                }
2758

2759
                if (token_type < 0 && !key_file && !key_data && !passwords) {
58✔
2760

2761
                        /* If we have nothing to try anymore, then acquire a new password */
2762

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

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

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

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

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

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

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

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

2826
                if (key_file) {
4✔
2827
                        key_file = NULL;
4✔
2828
                        continue;
4✔
2829
                }
2830

2831
                if (passwords) {
×
2832
                        passwords = strv_free_erase(passwords);
×
2833
                        continue;
×
2834
                }
2835

2836
                log_debug("Prepared for next attempt to unlock.");
×
2837
        }
2838

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

2842
        return 0;
2843
}
2844

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

2852
        assert(argc == 2);
64✔
2853

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

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

2865
        cryptsetup_enable_logging(cd);
61✔
2866

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

2871
        return 0;
2872
}
2873

2874
static int run(int argc, char *argv[]) {
142✔
2875
        int r;
142✔
2876

2877
        log_setup();
142✔
2878

2879
        umask(0022);
142✔
2880

2881
        char **args = NULL;
142✔
2882
        r = parse_argv(argc, argv, &args);
142✔
2883
        if (r <= 0)
142✔
2884
                return r;
142✔
2885

2886
        r = dlopen_cryptsetup(LOG_ERR);
142✔
2887
        if (r < 0)
142✔
2888
                return r;
2889

2890
        return dispatch_verb_with_args(args, NULL);
142✔
2891
}
2892

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

© 2026 Coveralls, Inc