]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/cryptsetup/cryptsetup.c
Merge pull request #7089 from oniko/luks2-support
[thirdparty/systemd.git] / src / cryptsetup / cryptsetup.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <errno.h>
21 #include <libcryptsetup.h>
22 #include <mntent.h>
23 #include <string.h>
24 #include <sys/mman.h>
25
26 #include "sd-device.h"
27
28 #include "alloc-util.h"
29 #include "ask-password-api.h"
30 #include "device-util.h"
31 #include "escape.h"
32 #include "fileio.h"
33 #include "log.h"
34 #include "mount-util.h"
35 #include "parse-util.h"
36 #include "path-util.h"
37 #include "string-util.h"
38 #include "strv.h"
39 #include "util.h"
40
41 /* libcryptsetup define for any LUKS version, compatible with libcryptsetup 1.x */
42 #ifndef CRYPT_LUKS
43 #define CRYPT_LUKS NULL
44 #endif
45
46 /* internal helper */
47 #define ANY_LUKS "LUKS"
48
49 static const char *arg_type = NULL; /* ANY_LUKS, CRYPT_LUKS1, CRYPT_LUKS2, CRYPT_TCRYPT or CRYPT_PLAIN */
50 static char *arg_cipher = NULL;
51 static unsigned arg_key_size = 0;
52 static int arg_key_slot = CRYPT_ANY_SLOT;
53 static unsigned arg_keyfile_size = 0;
54 static unsigned arg_keyfile_offset = 0;
55 static char *arg_hash = NULL;
56 static char *arg_header = NULL;
57 static unsigned arg_tries = 3;
58 static bool arg_readonly = false;
59 static bool arg_verify = false;
60 static bool arg_discards = false;
61 static bool arg_tcrypt_hidden = false;
62 static bool arg_tcrypt_system = false;
63 #ifdef CRYPT_TCRYPT_VERA_MODES
64 static bool arg_tcrypt_veracrypt = false;
65 #endif
66 static char **arg_tcrypt_keyfiles = NULL;
67 static uint64_t arg_offset = 0;
68 static uint64_t arg_skip = 0;
69 static usec_t arg_timeout = USEC_INFINITY;
70
71 /* Options Debian's crypttab knows we don't:
72
73 precheck=
74 check=
75 checkargs=
76 noearly=
77 loud=
78 keyscript=
79 */
80
81 static int parse_one_option(const char *option) {
82 const char *val;
83 int r;
84
85 assert(option);
86
87 /* Handled outside of this tool */
88 if (STR_IN_SET(option, "noauto", "auto", "nofail", "fail", "_netdev"))
89 return 0;
90
91 if ((val = startswith(option, "cipher="))) {
92 r = free_and_strdup(&arg_cipher, val);
93 if (r < 0)
94 return log_oom();
95
96 } else if ((val = startswith(option, "size="))) {
97
98 r = safe_atou(val, &arg_key_size);
99 if (r < 0) {
100 log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
101 return 0;
102 }
103
104 if (arg_key_size % 8) {
105 log_error("size= not a multiple of 8, ignoring.");
106 return 0;
107 }
108
109 arg_key_size /= 8;
110
111 } else if ((val = startswith(option, "key-slot="))) {
112
113 arg_type = ANY_LUKS;
114 r = safe_atoi(val, &arg_key_slot);
115 if (r < 0) {
116 log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
117 return 0;
118 }
119
120 } else if ((val = startswith(option, "tcrypt-keyfile="))) {
121
122 arg_type = CRYPT_TCRYPT;
123 if (path_is_absolute(val)) {
124 if (strv_extend(&arg_tcrypt_keyfiles, val) < 0)
125 return log_oom();
126 } else
127 log_error("Key file path \"%s\" is not absolute. Ignoring.", val);
128
129 } else if ((val = startswith(option, "keyfile-size="))) {
130
131 r = safe_atou(val, &arg_keyfile_size);
132 if (r < 0) {
133 log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
134 return 0;
135 }
136
137 } else if ((val = startswith(option, "keyfile-offset="))) {
138
139 r = safe_atou(val, &arg_keyfile_offset);
140 if (r < 0) {
141 log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
142 return 0;
143 }
144
145 } else if ((val = startswith(option, "hash="))) {
146 r = free_and_strdup(&arg_hash, val);
147 if (r < 0)
148 return log_oom();
149
150 } else if ((val = startswith(option, "header="))) {
151 arg_type = ANY_LUKS;
152
153 if (!path_is_absolute(val)) {
154 log_error("Header path \"%s\" is not absolute, refusing.", val);
155 return -EINVAL;
156 }
157
158 if (arg_header) {
159 log_error("Duplicate header= option, refusing.");
160 return -EINVAL;
161 }
162
163 arg_header = strdup(val);
164 if (!arg_header)
165 return log_oom();
166
167 } else if ((val = startswith(option, "tries="))) {
168
169 r = safe_atou(val, &arg_tries);
170 if (r < 0) {
171 log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
172 return 0;
173 }
174
175 } else if (STR_IN_SET(option, "readonly", "read-only"))
176 arg_readonly = true;
177 else if (streq(option, "verify"))
178 arg_verify = true;
179 else if (STR_IN_SET(option, "allow-discards", "discard"))
180 arg_discards = true;
181 else if (streq(option, "luks"))
182 arg_type = ANY_LUKS;
183 else if (streq(option, "tcrypt"))
184 arg_type = CRYPT_TCRYPT;
185 else if (streq(option, "tcrypt-hidden")) {
186 arg_type = CRYPT_TCRYPT;
187 arg_tcrypt_hidden = true;
188 } else if (streq(option, "tcrypt-system")) {
189 arg_type = CRYPT_TCRYPT;
190 arg_tcrypt_system = true;
191 } else if (streq(option, "tcrypt-veracrypt")) {
192 #ifdef CRYPT_TCRYPT_VERA_MODES
193 arg_type = CRYPT_TCRYPT;
194 arg_tcrypt_veracrypt = true;
195 #else
196 log_error("This version of cryptsetup does not support tcrypt-veracrypt; refusing.");
197 return -EINVAL;
198 #endif
199 } else if (STR_IN_SET(option, "plain", "swap", "tmp"))
200 arg_type = CRYPT_PLAIN;
201 else if ((val = startswith(option, "timeout="))) {
202
203 r = parse_sec_fix_0(val, &arg_timeout);
204 if (r < 0) {
205 log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
206 return 0;
207 }
208
209 } else if ((val = startswith(option, "offset="))) {
210
211 r = safe_atou64(val, &arg_offset);
212 if (r < 0)
213 return log_error_errno(r, "Failed to parse %s: %m", option);
214
215 } else if ((val = startswith(option, "skip="))) {
216
217 r = safe_atou64(val, &arg_skip);
218 if (r < 0)
219 return log_error_errno(r, "Failed to parse %s: %m", option);
220
221 } else if (!streq(option, "none"))
222 log_warning("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
223
224 return 0;
225 }
226
227 static int parse_options(const char *options) {
228 const char *word, *state;
229 size_t l;
230 int r;
231
232 assert(options);
233
234 FOREACH_WORD_SEPARATOR(word, l, options, ",", state) {
235 _cleanup_free_ char *o;
236
237 o = strndup(word, l);
238 if (!o)
239 return -ENOMEM;
240 r = parse_one_option(o);
241 if (r < 0)
242 return r;
243 }
244
245 /* sanity-check options */
246 if (arg_type != NULL && !streq(arg_type, CRYPT_PLAIN)) {
247 if (arg_offset)
248 log_warning("offset= ignored with type %s", arg_type);
249 if (arg_skip)
250 log_warning("skip= ignored with type %s", arg_type);
251 }
252
253 return 0;
254 }
255
256 static void log_glue(int level, const char *msg, void *usrptr) {
257 log_debug("%s", msg);
258 }
259
260 static int disk_major_minor(const char *path, char **ret) {
261 struct stat st;
262
263 assert(path);
264
265 if (stat(path, &st) < 0)
266 return -errno;
267
268 if (!S_ISBLK(st.st_mode))
269 return -EINVAL;
270
271 if (asprintf(ret, "/dev/block/%d:%d", major(st.st_rdev), minor(st.st_rdev)) < 0)
272 return -errno;
273
274 return 0;
275 }
276
277 static char* disk_description(const char *path) {
278
279 static const char name_fields[] =
280 "ID_PART_ENTRY_NAME\0"
281 "DM_NAME\0"
282 "ID_MODEL_FROM_DATABASE\0"
283 "ID_MODEL\0";
284
285 _cleanup_(sd_device_unrefp) sd_device *device = NULL;
286 struct stat st;
287 const char *i;
288 int r;
289
290 assert(path);
291
292 if (stat(path, &st) < 0)
293 return NULL;
294
295 if (!S_ISBLK(st.st_mode))
296 return NULL;
297
298 r = sd_device_new_from_devnum(&device, 'b', st.st_rdev);
299 if (r < 0)
300 return NULL;
301
302 NULSTR_FOREACH(i, name_fields) {
303 const char *name;
304
305 r = sd_device_get_property_value(device, i, &name);
306 if (r >= 0 && !isempty(name))
307 return strdup(name);
308 }
309
310 return NULL;
311 }
312
313 static char *disk_mount_point(const char *label) {
314 _cleanup_free_ char *device = NULL;
315 _cleanup_endmntent_ FILE *f = NULL;
316 struct mntent *m;
317
318 /* Yeah, we don't support native systemd unit files here for now */
319
320 if (asprintf(&device, "/dev/mapper/%s", label) < 0)
321 return NULL;
322
323 f = setmntent("/etc/fstab", "re");
324 if (!f)
325 return NULL;
326
327 while ((m = getmntent(f)))
328 if (path_equal(m->mnt_fsname, device))
329 return strdup(m->mnt_dir);
330
331 return NULL;
332 }
333
334 static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***ret) {
335 _cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL, *maj_min = NULL, *text = NULL, *escaped_name = NULL;
336 _cleanup_strv_free_erase_ char **passwords = NULL;
337 const char *name = NULL;
338 char **p, *id;
339 int r = 0;
340
341 assert(vol);
342 assert(src);
343 assert(ret);
344
345 description = disk_description(src);
346 mount_point = disk_mount_point(vol);
347
348 if (description && streq(vol, description))
349 /* If the description string is simply the
350 * volume name, then let's not show this
351 * twice */
352 description = mfree(description);
353
354 if (mount_point && description)
355 r = asprintf(&name_buffer, "%s (%s) on %s", description, vol, mount_point);
356 else if (mount_point)
357 r = asprintf(&name_buffer, "%s on %s", vol, mount_point);
358 else if (description)
359 r = asprintf(&name_buffer, "%s (%s)", description, vol);
360
361 if (r < 0)
362 return log_oom();
363
364 name = name_buffer ? name_buffer : vol;
365
366 if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0)
367 return log_oom();
368
369 if (src)
370 (void) disk_major_minor(src, &maj_min);
371
372 if (maj_min) {
373 escaped_name = maj_min;
374 maj_min = NULL;
375 } else
376 escaped_name = cescape(name);
377
378 if (!escaped_name)
379 return log_oom();
380
381 id = strjoina("cryptsetup:", escaped_name);
382
383 r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until,
384 ASK_PASSWORD_PUSH_CACHE | (accept_cached*ASK_PASSWORD_ACCEPT_CACHED),
385 &passwords);
386 if (r < 0)
387 return log_error_errno(r, "Failed to query password: %m");
388
389 if (arg_verify) {
390 _cleanup_strv_free_erase_ char **passwords2 = NULL;
391
392 assert(strv_length(passwords) == 1);
393
394 if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0)
395 return log_oom();
396
397 id = strjoina("cryptsetup-verification:", escaped_name);
398
399 r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, ASK_PASSWORD_PUSH_CACHE, &passwords2);
400 if (r < 0)
401 return log_error_errno(r, "Failed to query verification password: %m");
402
403 assert(strv_length(passwords2) == 1);
404
405 if (!streq(passwords[0], passwords2[0])) {
406 log_warning("Passwords did not match, retrying.");
407 return -EAGAIN;
408 }
409 }
410
411 strv_uniq(passwords);
412
413 STRV_FOREACH(p, passwords) {
414 char *c;
415
416 if (strlen(*p)+1 >= arg_key_size)
417 continue;
418
419 /* Pad password if necessary */
420 c = new(char, arg_key_size);
421 if (!c)
422 return log_oom();
423
424 strncpy(c, *p, arg_key_size);
425 free(*p);
426 *p = c;
427 }
428
429 *ret = passwords;
430 passwords = NULL;
431
432 return 0;
433 }
434
435 static int attach_tcrypt(
436 struct crypt_device *cd,
437 const char *name,
438 const char *key_file,
439 char **passwords,
440 uint32_t flags) {
441
442 int r = 0;
443 _cleanup_free_ char *passphrase = NULL;
444 struct crypt_params_tcrypt params = {
445 .flags = CRYPT_TCRYPT_LEGACY_MODES,
446 .keyfiles = (const char **)arg_tcrypt_keyfiles,
447 .keyfiles_count = strv_length(arg_tcrypt_keyfiles)
448 };
449
450 assert(cd);
451 assert(name);
452 assert(key_file || (passwords && passwords[0]));
453
454 if (arg_tcrypt_hidden)
455 params.flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
456
457 if (arg_tcrypt_system)
458 params.flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
459
460 #ifdef CRYPT_TCRYPT_VERA_MODES
461 if (arg_tcrypt_veracrypt)
462 params.flags |= CRYPT_TCRYPT_VERA_MODES;
463 #endif
464
465 if (key_file) {
466 r = read_one_line_file(key_file, &passphrase);
467 if (r < 0) {
468 log_error_errno(r, "Failed to read password file '%s': %m", key_file);
469 return -EAGAIN;
470 }
471
472 params.passphrase = passphrase;
473 } else
474 params.passphrase = passwords[0];
475 params.passphrase_size = strlen(params.passphrase);
476
477 r = crypt_load(cd, CRYPT_TCRYPT, &params);
478 if (r < 0) {
479 if (key_file && r == -EPERM) {
480 log_error("Failed to activate using password file '%s'.", key_file);
481 return -EAGAIN;
482 }
483 return r;
484 }
485
486 return crypt_activate_by_volume_key(cd, name, NULL, 0, flags);
487 }
488
489 static int attach_luks_or_plain(struct crypt_device *cd,
490 const char *name,
491 const char *key_file,
492 const char *data_device,
493 char **passwords,
494 uint32_t flags) {
495 int r = 0;
496 bool pass_volume_key = false;
497
498 assert(cd);
499 assert(name);
500 assert(key_file || passwords);
501
502 if (!arg_type || STR_IN_SET(arg_type, ANY_LUKS, CRYPT_LUKS1)) {
503 r = crypt_load(cd, CRYPT_LUKS, NULL);
504 if (r < 0) {
505 log_error("crypt_load() failed on device %s.\n", crypt_get_device_name(cd));
506 return r;
507 }
508
509 if (data_device)
510 r = crypt_set_data_device(cd, data_device);
511 }
512
513 if ((!arg_type && r < 0) || streq_ptr(arg_type, CRYPT_PLAIN)) {
514 struct crypt_params_plain params = {
515 .offset = arg_offset,
516 .skip = arg_skip,
517 };
518 const char *cipher, *cipher_mode;
519 _cleanup_free_ char *truncated_cipher = NULL;
520
521 if (arg_hash) {
522 /* plain isn't a real hash type. it just means "use no hash" */
523 if (!streq(arg_hash, "plain"))
524 params.hash = arg_hash;
525 } else if (!key_file)
526 /* for CRYPT_PLAIN, the behaviour of cryptsetup
527 * package is to not hash when a key file is provided */
528 params.hash = "ripemd160";
529
530 if (arg_cipher) {
531 size_t l;
532
533 l = strcspn(arg_cipher, "-");
534 truncated_cipher = strndup(arg_cipher, l);
535 if (!truncated_cipher)
536 return log_oom();
537
538 cipher = truncated_cipher;
539 cipher_mode = arg_cipher[l] ? arg_cipher+l+1 : "plain";
540 } else {
541 cipher = "aes";
542 cipher_mode = "cbc-essiv:sha256";
543 }
544
545 /* for CRYPT_PLAIN limit reads
546 * from keyfile to key length, and
547 * ignore keyfile-size */
548 arg_keyfile_size = arg_key_size;
549
550 /* In contrast to what the name
551 * crypt_setup() might suggest this
552 * doesn't actually format anything,
553 * it just configures encryption
554 * parameters when used for plain
555 * mode. */
556 r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, arg_keyfile_size, &params);
557
558 /* hash == NULL implies the user passed "plain" */
559 pass_volume_key = (params.hash == NULL);
560 }
561
562 if (r < 0)
563 return log_error_errno(r, "Loading of cryptographic parameters failed: %m");
564
565 log_info("Set cipher %s, mode %s, key size %i bits for device %s.",
566 crypt_get_cipher(cd),
567 crypt_get_cipher_mode(cd),
568 crypt_get_volume_key_size(cd)*8,
569 crypt_get_device_name(cd));
570
571 if (key_file) {
572 r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags);
573 if (r < 0) {
574 log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
575 return -EAGAIN;
576 }
577 } else {
578 char **p;
579
580 STRV_FOREACH(p, passwords) {
581 if (pass_volume_key)
582 r = crypt_activate_by_volume_key(cd, name, *p, arg_key_size, flags);
583 else
584 r = crypt_activate_by_passphrase(cd, name, arg_key_slot, *p, strlen(*p), flags);
585
586 if (r >= 0)
587 break;
588 }
589 }
590
591 return r;
592 }
593
594 static int help(void) {
595
596 printf("%s attach VOLUME SOURCEDEVICE [PASSWORD] [OPTIONS]\n"
597 "%s detach VOLUME\n\n"
598 "Attaches or detaches an encrypted block device.\n",
599 program_invocation_short_name,
600 program_invocation_short_name);
601
602 return 0;
603 }
604
605 int main(int argc, char *argv[]) {
606 struct crypt_device *cd = NULL;
607 int r = -EINVAL;
608
609 if (argc <= 1) {
610 r = help();
611 goto finish;
612 }
613
614 if (argc < 3) {
615 log_error("This program requires at least two arguments.");
616 goto finish;
617 }
618
619 log_set_target(LOG_TARGET_AUTO);
620 log_parse_environment();
621 log_open();
622
623 umask(0022);
624
625 if (streq(argv[1], "attach")) {
626 uint32_t flags = 0;
627 unsigned tries;
628 usec_t until;
629 crypt_status_info status;
630 const char *key_file = NULL;
631
632 /* Arguments: systemd-cryptsetup attach VOLUME SOURCE-DEVICE [PASSWORD] [OPTIONS] */
633
634 if (argc < 4) {
635 log_error("attach requires at least two arguments.");
636 goto finish;
637 }
638
639 if (argc >= 5 &&
640 argv[4][0] &&
641 !streq(argv[4], "-") &&
642 !streq(argv[4], "none")) {
643
644 if (!path_is_absolute(argv[4]))
645 log_error("Password file path '%s' is not absolute. Ignoring.", argv[4]);
646 else
647 key_file = argv[4];
648 }
649
650 if (argc >= 6 && argv[5][0] && !streq(argv[5], "-")) {
651 if (parse_options(argv[5]) < 0)
652 goto finish;
653 }
654
655 /* A delicious drop of snake oil */
656 mlockall(MCL_FUTURE);
657
658 if (arg_header) {
659 log_debug("LUKS header: %s", arg_header);
660 r = crypt_init(&cd, arg_header);
661 } else
662 r = crypt_init(&cd, argv[3]);
663 if (r < 0) {
664 log_error_errno(r, "crypt_init() failed: %m");
665 goto finish;
666 }
667
668 crypt_set_log_callback(cd, log_glue, NULL);
669
670 status = crypt_status(cd, argv[2]);
671 if (IN_SET(status, CRYPT_ACTIVE, CRYPT_BUSY)) {
672 log_info("Volume %s already active.", argv[2]);
673 r = 0;
674 goto finish;
675 }
676
677 if (arg_readonly)
678 flags |= CRYPT_ACTIVATE_READONLY;
679
680 if (arg_discards)
681 flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
682
683 if (arg_timeout == USEC_INFINITY)
684 until = 0;
685 else
686 until = now(CLOCK_MONOTONIC) + arg_timeout;
687
688 arg_key_size = (arg_key_size > 0 ? arg_key_size : (256 / 8));
689
690 if (key_file) {
691 struct stat st;
692
693 /* Ideally we'd do this on the open fd, but since this is just a
694 * warning it's OK to do this in two steps. */
695 if (stat(key_file, &st) >= 0 && S_ISREG(st.st_mode) && (st.st_mode & 0005))
696 log_warning("Key file %s is world-readable. This is not a good idea!", key_file);
697 }
698
699 for (tries = 0; arg_tries == 0 || tries < arg_tries; tries++) {
700 _cleanup_strv_free_erase_ char **passwords = NULL;
701
702 if (!key_file) {
703 r = get_password(argv[2], argv[3], until, tries == 0 && !arg_verify, &passwords);
704 if (r == -EAGAIN)
705 continue;
706 if (r < 0)
707 goto finish;
708 }
709
710 if (streq_ptr(arg_type, CRYPT_TCRYPT))
711 r = attach_tcrypt(cd, argv[2], key_file, passwords, flags);
712 else
713 r = attach_luks_or_plain(cd,
714 argv[2],
715 key_file,
716 arg_header ? argv[3] : NULL,
717 passwords,
718 flags);
719 if (r >= 0)
720 break;
721 if (r == -EAGAIN) {
722 key_file = NULL;
723 continue;
724 }
725 if (r != -EPERM) {
726 log_error_errno(r, "Failed to activate: %m");
727 goto finish;
728 }
729
730 log_warning("Invalid passphrase.");
731 }
732
733 if (arg_tries != 0 && tries >= arg_tries) {
734 log_error("Too many attempts; giving up.");
735 r = -EPERM;
736 goto finish;
737 }
738
739 } else if (streq(argv[1], "detach")) {
740
741 r = crypt_init_by_name(&cd, argv[2]);
742 if (r == -ENODEV) {
743 log_info("Volume %s already inactive.", argv[2]);
744 r = 0;
745 goto finish;
746 }
747 if (r < 0) {
748 log_error_errno(r, "crypt_init_by_name() failed: %m");
749 goto finish;
750 }
751
752 crypt_set_log_callback(cd, log_glue, NULL);
753
754 r = crypt_deactivate(cd, argv[2]);
755 if (r < 0) {
756 log_error_errno(r, "Failed to deactivate: %m");
757 goto finish;
758 }
759
760 } else {
761 log_error("Unknown verb %s.", argv[1]);
762 goto finish;
763 }
764
765 r = 0;
766
767 finish:
768 if (cd)
769 crypt_free(cd);
770
771 free(arg_cipher);
772 free(arg_hash);
773 free(arg_header);
774 strv_free(arg_tcrypt_keyfiles);
775
776 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
777 }