cryptsetup.c 91.6 KB
Newer Older
1 2 3
/*
 * cryptsetup - setup cryptographic volumes for dm-crypt
 *
Milan Broz's avatar
Milan Broz committed
4 5 6 7
 * Copyright (C) 2004 Jana Saout <jana@saout.de>
 * Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
 * Copyright (C) 2009-2019 Red Hat, Inc. All rights reserved.
 * Copyright (C) 2009-2019 Milan Broz
8 9 10
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
11 12
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
13 14 15 16 17 18 19 20
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
21
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 23
 */

24
#include "cryptsetup.h"
Milan Broz's avatar
Milan Broz committed
25
#include <uuid/uuid.h>
26

27
static const char *opt_cipher = NULL;
28
static const char *opt_keyslot_cipher = NULL;
29
static const char *opt_hash = NULL;
30
static int opt_verify_passphrase = 0;
Milan Broz's avatar
Milan Broz committed
31

32
static const char *opt_json_file = NULL;
33
static const char *opt_key_file = NULL;
34
static const char *opt_keyfile_stdin = NULL;
Milan Broz's avatar
Milan Broz committed
35 36 37
static int opt_keyfiles_count = 0;
static const char *opt_keyfiles[MAX_KEYFILES];

38 39 40
static const char *opt_master_key_file = NULL;
static const char *opt_header_backup_file = NULL;
static const char *opt_uuid = NULL;
41
static const char *opt_header_device = NULL;
42
static const char *opt_type = "luks";
43
static int opt_key_size = 0;
44
static int opt_keyslot_key_size = 0;
45 46
static long opt_keyfile_size = 0;
static long opt_new_keyfile_size = 0;
47 48
static uint64_t opt_keyfile_offset = 0;
static uint64_t opt_new_keyfile_offset = 0;
49
static int opt_key_slot = CRYPT_ANY_SLOT;
Milan Broz's avatar
Milan Broz committed
50 51
static int opt_token = CRYPT_ANY_TOKEN;
static int opt_token_only = 0;
52 53 54
static uint64_t opt_size = 0;
static uint64_t opt_offset = 0;
static uint64_t opt_skip = 0;
55
static int opt_skip_valid = 0;
56 57 58 59 60
static int opt_readonly = 0;
static int opt_version_mode = 0;
static int opt_timeout = 0;
static int opt_tries = 3;
static int opt_align_payload = 0;
61 62
static int opt_random = 0;
static int opt_urandom = 0;
63
static int opt_dump_master_key = 0;
64
static int opt_shared = 0;
65
static int opt_allow_discards = 0;
66 67
static int opt_perf_same_cpu_crypt = 0;
static int opt_perf_submit_from_crypt_cpus = 0;
68
static int opt_test_passphrase = 0;
69 70
static int opt_tcrypt_hidden = 0;
static int opt_tcrypt_system = 0;
71
static int opt_tcrypt_backup = 0;
72
static int opt_veracrypt = 0;
73 74
static int opt_veracrypt_pim = -1;
static int opt_veracrypt_query_pim = 0;
75
static int opt_deferred_remove = 0;
76
static int opt_serialize_memory_hard_pbkdf = 0;
77
//FIXME: check uint32 overflow for long type
78
static const char *opt_pbkdf = NULL;
Milan Broz's avatar
Milan Broz committed
79 80
static long opt_pbkdf_memory = DEFAULT_LUKS2_MEMORY_KB;
static long opt_pbkdf_parallel = DEFAULT_LUKS2_PARALLEL_THREADS;
81 82
static long opt_pbkdf_iterations = 0;
static int opt_iteration_time = 0;
Milan Broz's avatar
Milan Broz committed
83 84 85 86 87 88 89
static int opt_disable_locks = 0;
static int opt_disable_keyring = 0;
static const char *opt_priority = NULL; /* normal */
static const char *opt_integrity = NULL; /* none */
static int opt_integrity_nojournal = 0;
static int opt_integrity_no_wipe = 0;
static const char *opt_key_description = NULL;
90
static int opt_sector_size = SECTOR_SIZE;
Milan Broz's avatar
Milan Broz committed
91 92 93
static int opt_persistent = 0;
static const char *opt_label = NULL;
static const char *opt_subsystem = NULL;
94
static int opt_unbound = 0;
95
static int opt_refresh = 0;
96

97 98 99 100 101
static const char *opt_luks2_metadata_size_str = NULL;
static uint64_t opt_luks2_metadata_size = 0;
static const char *opt_luks2_keyslots_size_str = NULL;
static uint64_t opt_luks2_keyslots_size = 0;

102 103
static const char **action_argv;
static int action_argc;
104
static const char *null_action_argv[] = {NULL, NULL};
105

106 107 108 109 110 111 112 113
static const char *uuid_or_device_header(const char **data_device)
{
	if (data_device)
		*data_device = opt_header_device ? action_argv[0] : NULL;

	return uuid_or_device(opt_header_device ?: action_argv[0]);
}

Milan Broz's avatar
Milan Broz committed
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
static const char *luksType(const char *type)
{
	if (type && !strcmp(type, "luks2"))
		return CRYPT_LUKS2;

	if (type && !strcmp(type, "luks1"))
		return CRYPT_LUKS1;

	if (type && !strcmp(type, "luks"))
		return CRYPT_LUKS; /* NULL */

	if (type && *type)
		return type;

	return CRYPT_LUKS; /* NULL */
}

131 132
static int _verify_passphrase(int def)
{
Andrea Gelmini's avatar
Andrea Gelmini committed
133
	/* Batch mode switch off verify - if not overridden by -y */
134 135 136 137 138 139 140 141
	if (opt_verify_passphrase)
		def = 1;
	else if (opt_batch_mode)
		def = 0;

	/* Non-tty input doesn't allow verify */
	if (def && !isatty(STDIN_FILENO)) {
		if (opt_verify_passphrase)
142
			log_err(_("Can't do passphrase verification on non-tty inputs."));
143 144 145 146 147 148
		def = 0;
	}

	return def;
}

149 150 151 152 153 154 155 156 157 158 159 160 161
static void _set_activation_flags(uint32_t *flags)
{
	if (opt_readonly)
		*flags |= CRYPT_ACTIVATE_READONLY;

	if (opt_allow_discards)
		*flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;

	if (opt_perf_same_cpu_crypt)
		*flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;

	if (opt_perf_submit_from_crypt_cpus)
		*flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
Milan Broz's avatar
Milan Broz committed
162 163 164 165 166 167 168

	if (opt_integrity_nojournal)
		*flags |= CRYPT_ACTIVATE_NO_JOURNAL;

	/* In persistent mode, we use what is set on command line */
	if (opt_persistent)
		*flags |= CRYPT_ACTIVATE_IGNORE_PERSISTENT;
169 170 171 172

	/* Only for LUKS2 but ignored elsewhere */
	if (opt_test_passphrase)
		*flags |= CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY;
173 174 175

	if (opt_serialize_memory_hard_pbkdf)
		*flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF;
176 177
}

178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
static int _set_keyslot_encryption_params(struct crypt_device *cd)
{
	const char *type = crypt_get_type(cd);

	if (!opt_keyslot_key_size && !opt_keyslot_cipher)
		return 0;

	if (!type || strcmp(type, CRYPT_LUKS2)) {
		log_err(_("Keyslot encryption parameters can be set only for LUKS2 device."));
		return -EINVAL;
	}

	return crypt_keyslot_set_encryption(cd, opt_keyslot_cipher, opt_keyslot_key_size / 8);
}

193
static int action_open_plain(void)
194
{
195 196
	struct crypt_device *cd = NULL, *cd1 = NULL;
	const char *pcipher, *pmode;
197
	char *msg, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
198
	struct crypt_active_device cad;
199
	struct crypt_params_plain params = {
200
		.hash = opt_hash ?: DEFAULT_PLAIN_HASH,
201
		.skip = opt_skip,
202
		.offset = opt_offset,
203
		.size = opt_size,
204
		.sector_size = opt_sector_size,
205
	};
206
	char *password = NULL;
207
	const char *activated_name = NULL;
Milan Broz's avatar
Milan Broz committed
208
	size_t passwordLen, key_size_max, signatures = 0,
209
	       key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
210
	uint32_t activate_flags = 0;
211
	int r;
212

213
	r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(PLAIN),
214
				      cipher, NULL, cipher_mode);
215
	if (r < 0) {
216
		log_err(_("No known cipher specification pattern detected."));
217 218 219
		goto out;
	}

220
	/* FIXME: temporary hack, no hashing for keyfiles in plain mode */
221
	if (opt_key_file && !tools_is_stdin(opt_key_file)) {
222 223 224 225 226 227 228 229 230
		params.hash = NULL;
		if (!opt_batch_mode && opt_hash)
			log_std(_("WARNING: The --hash parameter is being ignored "
				 "in plain mode with keyfile specified.\n"));
	}

	if (params.hash && !strcmp(params.hash, "plain"))
		params.hash = NULL;

231
	if (!opt_batch_mode && !params.hash && opt_key_file && !tools_is_stdin(opt_key_file) && opt_keyfile_size)
232 233 234
		log_std(_("WARNING: The --keyfile-size option is being ignored, "
			 "the read size is the same as the encryption key size.\n"));

235 236 237 238 239 240 241 242
	if (opt_refresh) {
		activated_name = action_argc > 1 ? action_argv[1] : action_argv[0];
		r = crypt_init_by_name_and_header(&cd1, activated_name, NULL);
		if (r)
			goto out;
		r = crypt_get_active_device(cd1, activated_name, &cad);
		if (r)
			goto out;
243

244 245 246 247 248 249 250 251
		/* copy known parameters from existing device */
		params.skip = crypt_get_iv_offset(cd1);
		params.offset = crypt_get_data_offset(cd1);
		params.size = cad.size;
		params.sector_size = crypt_get_sector_size(cd1);
		key_size = crypt_get_volume_key_size(cd1);

		if ((r = crypt_init(&cd, crypt_get_device_name(cd1))))
252 253
			goto out;

254 255 256 257 258 259 260
		activate_flags |= CRYPT_ACTIVATE_REFRESH;

		pcipher = crypt_get_cipher(cd1);
		pmode = crypt_get_cipher_mode(cd1);
	} else {
		activated_name = action_argv[1];
		if ((r = crypt_init(&cd, action_argv[0])))
261
			goto out;
262 263 264 265 266 267 268

		/* Skip blkid scan when activating plain device with offset */
		if (!opt_offset) {
			/* Print all present signatures in read-only mode */
			r = tools_detect_signatures(action_argv[0], 0, &signatures);
			if (r < 0)
				goto out;
269 270
		}

271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
		if (signatures) {
			r = asprintf(&msg, _("Detected device signature(s) on %s. Proceeding further may damage existing data."), action_argv[0]);
			if (r == -1) {
				r = -ENOMEM;
				goto out;
			}

			r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
			free(msg);
			if (r < 0)
				goto out;
		}

		pcipher = cipher;
		pmode = cipher_mode;
286 287
	}

288
	r = crypt_format(cd, CRYPT_PLAIN,
289
			 pcipher, pmode,
290
			 NULL, NULL,
291
			 key_size,
292
			 &params);
293
	check_signal(&r);
294 295 296
	if (r < 0)
		goto out;

297 298 299
	if (opt_shared)
		activate_flags |= CRYPT_ACTIVATE_SHARED;

300
	_set_activation_flags(&activate_flags);
301

302
	if (!tools_is_stdin(opt_key_file)) {
303 304 305 306 307
		/* If no hash, key is read directly, read size is always key_size
		 * (possible opt_keyfile_size is ignored.
		 * If hash is specified, opt_keyfile_size is applied.
		 * The opt_keyfile_offset is applied always.
		 */
308
		key_size_max = params.hash ? (size_t)opt_keyfile_size : key_size;
309
		r = crypt_activate_by_keyfile_device_offset(cd, action_argv[1],
310 311
			CRYPT_ANY_SLOT, opt_key_file, key_size_max,
			opt_keyfile_offset, activate_flags);
312
	} else {
313
		key_size_max = (opt_key_file && !params.hash) ? key_size : (size_t)opt_keyfile_size;
314
		r = tools_get_key(NULL, &password, &passwordLen,
315
				  opt_keyfile_offset, key_size_max,
316
				  opt_key_file, opt_timeout,
317
				  _verify_passphrase(0), 0, cd);
318 319 320
		if (r < 0)
			goto out;

321
		r = crypt_activate_by_passphrase(cd, activated_name,
322
			CRYPT_ANY_SLOT, password, passwordLen, activate_flags);
323
	}
324 325
out:
	crypt_free(cd);
326
	crypt_free(cd1);
327 328
	crypt_safe_free(password);

329
	return r;
330 331
}

332
static int action_open_loopaes(void)
333 334 335
{
	struct crypt_device *cd = NULL;
	struct crypt_params_loopaes params = {
336
		.hash = opt_hash ?: NULL,
337
		.offset = opt_offset,
338
		.skip = opt_skip_valid ? opt_skip : opt_offset,
339
	};
340
	unsigned int key_size = (opt_key_size ?: DEFAULT_LOOPAES_KEYBITS) / 8;
341
	uint32_t activate_flags = 0;
342
	const char *activated_name = NULL;
343 344 345
	int r;

	if (!opt_key_file) {
346
		log_err(_("Option --key-file is required."));
347 348 349
		return -EINVAL;
	}

350 351 352 353 354 355 356 357 358
	if (opt_refresh) {
		activated_name = action_argc > 1 ? action_argv[1] : action_argv[0];
		if ((r = crypt_init_by_name(&cd, activated_name)))
			goto out;
		activate_flags |= CRYPT_ACTIVATE_REFRESH;
	} else {
		activated_name = action_argv[1];
		if ((r = crypt_init(&cd, action_argv[0])))
			goto out;
359

360 361 362 363 364 365
		r = crypt_format(cd, CRYPT_LOOPAES, opt_cipher ?: DEFAULT_LOOPAES_CIPHER,
				 NULL, NULL, NULL, key_size, &params);
		check_signal(&r);
		if (r < 0)
			goto out;
	}
366

367
	_set_activation_flags(&activate_flags);
368

369
	r = crypt_activate_by_keyfile_device_offset(cd, activated_name, CRYPT_ANY_SLOT,
370 371
		tools_is_stdin(opt_key_file) ? "/dev/stdin" : opt_key_file, opt_keyfile_size,
		opt_keyfile_offset, activate_flags);
372 373 374 375 376 377
out:
	crypt_free(cd);

	return r;
}

378 379 380 381
static int tcrypt_load(struct crypt_device *cd, struct crypt_params_tcrypt *params)
{
	int r, tries = opt_tries, eperm = 0;

382 383 384
	if (opt_keyfile_stdin)
		tries = 1;

385 386
	do {
		/* TCRYPT header is encrypted, get passphrase now */
387
		r = tools_get_key(NULL, CONST_CAST(char**)&params->passphrase,
388
				  &params->passphrase_size, 0, 0, opt_keyfile_stdin, opt_timeout,
389 390 391 392
				 _verify_passphrase(0), 0, cd);
		if (r < 0)
			continue;

393 394
		if (opt_veracrypt_query_pim) {
			char *tmp_pim_nptr = NULL;
395
			char *tmp_pim_end = NULL;
396
			size_t tmp_pim_size = 0;
Milan Broz's avatar
Milan Broz committed
397
			unsigned long long tmp_pim_ull = 0;
398 399 400 401 402 403 404 405

			r = tools_get_key(_("Enter VeraCrypt PIM: "),
					CONST_CAST(char**)&tmp_pim_nptr,
					&tmp_pim_size, 0, 0, opt_keyfile_stdin, opt_timeout,
					_verify_passphrase(0), 0, cd);
			if (r < 0)
				continue;

Milan Broz's avatar
Milan Broz committed
406
			tmp_pim_ull = strtoull(tmp_pim_nptr, &tmp_pim_end, 10);
407
			if (*tmp_pim_nptr == '\0' || !tmp_pim_end || *tmp_pim_end != '\0') {
408
				log_err(_("Invalid PIM value: parse error."));
409
				r = -EINVAL;
Milan Broz's avatar
Milan Broz committed
410
			} else if (tmp_pim_ull == 0) {
411
				log_err(_("Invalid PIM value: 0."));
412
				r = -EINVAL;
Milan Broz's avatar
Milan Broz committed
413
			} else if (tmp_pim_ull > UINT32_MAX) {
414
				log_err(_("Invalid PIM value: outside of range."));
415 416 417 418 419 420
				r = -ERANGE;
			}
			crypt_safe_free(CONST_CAST(char*)tmp_pim_nptr);
			if (r < 0)
				continue;

Milan Broz's avatar
Milan Broz committed
421 422
			params->veracrypt_pim = (uint32_t)tmp_pim_ull;
			crypt_memzero(&tmp_pim_ull, sizeof(tmp_pim_ull));
423 424
		}

425 426 427 428 429 430 431 432 433 434 435 436
		if (opt_tcrypt_hidden)
			params->flags |= CRYPT_TCRYPT_HIDDEN_HEADER;

		if (opt_tcrypt_system)
			params->flags |= CRYPT_TCRYPT_SYSTEM_HEADER;

		if (opt_tcrypt_backup)
			params->flags |= CRYPT_TCRYPT_BACKUP_HEADER;

		r = crypt_load(cd, CRYPT_TCRYPT, params);

		if (r == -EPERM) {
437
			log_err(_("No device header detected with this passphrase."));
438 439 440 441 442 443 444 445 446
			eperm = 1;
		}

		if (r < 0) {
			crypt_safe_free(CONST_CAST(char*)params->passphrase);
			params->passphrase = NULL;
			params->passphrase_size = 0;
		}
		check_signal(&r);
447
	} while ((r == -EPERM || r == -ERANGE) && (--tries > 0));
448 449 450 451 452 453 454 455

	/* Report wrong passphrase if at least one try failed */
	if (eperm && r == -EPIPE)
		r = -EPERM;

	return r;
}

456
static int action_open_tcrypt(void)
Milan Broz's avatar
Milan Broz committed
457 458
{
	struct crypt_device *cd = NULL;
Milan Broz's avatar
Milan Broz committed
459 460 461
	struct crypt_params_tcrypt params = {
		.keyfiles = opt_keyfiles,
		.keyfiles_count = opt_keyfiles_count,
462 463
		.flags = CRYPT_TCRYPT_LEGACY_MODES |
			 (opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0),
464
		.veracrypt_pim = (opt_veracrypt_pim > 0) ? opt_veracrypt_pim : 0,
Milan Broz's avatar
Milan Broz committed
465
	};
Milan Broz's avatar
Milan Broz committed
466
	const char *activated_name;
467
	uint32_t activate_flags = 0;
Milan Broz's avatar
Milan Broz committed
468 469 470 471 472 473 474
	int r;

	activated_name = opt_test_passphrase ? NULL : action_argv[1];

	if ((r = crypt_init(&cd, action_argv[0])))
		goto out;

475
	r = tcrypt_load(cd, &params);
Milan Broz's avatar
Milan Broz committed
476 477 478
	if (r < 0)
		goto out;

479
	_set_activation_flags(&activate_flags);
480

481
	if (activated_name)
482
		r = crypt_activate_by_volume_key(cd, activated_name, NULL, 0, activate_flags);
Milan Broz's avatar
Milan Broz committed
483 484 485
out:
	crypt_free(cd);
	crypt_safe_free(CONST_CAST(char*)params.passphrase);
486
	crypt_memzero(&params.veracrypt_pim, sizeof(params.veracrypt_pim));
Milan Broz's avatar
Milan Broz committed
487 488 489
	return r;
}

490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531
static int tcryptDump_with_volume_key(struct crypt_device *cd)
{
	char *vk = NULL;
	size_t vk_size;
	unsigned i;
	int r;

	crypt_set_confirm_callback(cd, yesDialog, NULL);
	if (!yesDialog(
	    _("Header dump with volume key is sensitive information\n"
	      "which allows access to encrypted partition without passphrase.\n"
	      "This dump should be always stored encrypted on safe place."),
	      NULL))
		return -EPERM;

	vk_size = crypt_get_volume_key_size(cd);
	vk = crypt_safe_alloc(vk_size);
	if (!vk)
		return -ENOMEM;

	r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, vk, &vk_size, NULL, 0);
	if (r < 0)
		goto out;

	log_std("TCRYPT header information for %s\n", crypt_get_device_name(cd));
	log_std("Cipher chain:  \t%s\n", crypt_get_cipher(cd));
	log_std("Cipher mode:   \t%s\n", crypt_get_cipher_mode(cd));
	log_std("Payload offset:\t%d\n", (int)crypt_get_data_offset(cd));
	log_std("MK bits:       \t%d\n", (int)vk_size * 8);
	log_std("MK dump:\t");

	for(i = 0; i < vk_size; i++) {
		if (i && !(i % 16))
			log_std("\n\t\t");
		log_std("%02hhx ", (char)vk[i]);
	}
	log_std("\n");
out:
	crypt_safe_free(vk);
	return r;
}

532
static int action_tcryptDump(void)
Milan Broz's avatar
Milan Broz committed
533 534 535 536 537
{
	struct crypt_device *cd = NULL;
	struct crypt_params_tcrypt params = {
		.keyfiles = opt_keyfiles,
		.keyfiles_count = opt_keyfiles_count,
538 539
		.flags = CRYPT_TCRYPT_LEGACY_MODES |
			 (opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0),
540
		.veracrypt_pim = (opt_veracrypt_pim > 0) ? opt_veracrypt_pim : 0,
Milan Broz's avatar
Milan Broz committed
541 542 543 544 545 546
	};
	int r;

	if ((r = crypt_init(&cd, action_argv[0])))
		goto out;

547
	r = tcrypt_load(cd, &params);
Milan Broz's avatar
Milan Broz committed
548 549 550
	if (r < 0)
		goto out;

551 552 553 554
	if (opt_dump_master_key)
		r = tcryptDump_with_volume_key(cd);
	else
		r = crypt_dump(cd);
Milan Broz's avatar
Milan Broz committed
555 556 557 558 559 560
out:
	crypt_free(cd);
	crypt_safe_free(CONST_CAST(char*)params.passphrase);
	return r;
}

561
static int action_close(void)
562
{
563
	struct crypt_device *cd = NULL;
564
	crypt_status_info ci;
565
	uint32_t flags = 0;
566 567
	int r;

568 569 570
	if (opt_deferred_remove)
		flags |= CRYPT_DEACTIVATE_DEFERRED;

571 572
	r = crypt_init_by_name(&cd, action_argv[0]);
	if (r == 0)
573
		r = crypt_deactivate_by_name(cd, action_argv[0], flags);
574

575 576 577 578 579 580 581
	if (!r && opt_deferred_remove) {
		ci = crypt_status(cd, action_argv[0]);
		if (ci == CRYPT_ACTIVE || ci == CRYPT_BUSY)
			log_std(_("Device %s is still active and scheduled for deferred removal.\n"),
				  action_argv[0]);
	}

582 583
	crypt_free(cd);
	return r;
584 585
}

586
static int action_resize(void)
587
{
588
	int r;
Milan Broz's avatar
Milan Broz committed
589 590 591 592
	size_t passwordLen;
	struct crypt_active_device cad;
	char *password = NULL;
	struct crypt_device *cd = NULL;
593

594
	r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device);
595 596
	if (r)
		goto out;
Milan Broz's avatar
Milan Broz committed
597

598
	/* FIXME: LUKS2 may enforce fixed size and it must not be changed */
599 600 601
	r = crypt_get_active_device(cd, action_argv[0], &cad);
	if (r)
		goto out;
Milan Broz's avatar
Milan Broz committed
602

603 604 605 606
	if (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) {
		if (opt_disable_keyring) {
			r = -EINVAL;
			log_err(_("Resize of active device requires volume key "
607
				  "in keyring but --disable-keyring option is set."));
608
				goto out;
Milan Broz's avatar
Milan Broz committed
609 610
		}

611 612 613
		/* try load VK in kernel keyring using token */
		r = crypt_activate_by_token(cd, NULL, opt_token, NULL,
					    CRYPT_ACTIVATE_KEYRING_KEY);
614
		tools_keyslot_msg(r, UNLOCKED);
615 616 617 618 619 620 621 622 623 624 625 626 627
		if (r < 0 && opt_token_only)
			goto out;

		r = tools_get_key(NULL, &password, &passwordLen,
				  opt_keyfile_offset, opt_keyfile_size, opt_key_file,
				  opt_timeout, _verify_passphrase(0), 0, cd);
		if (r < 0)
			goto out;

		r = crypt_activate_by_passphrase(cd, NULL, opt_key_slot,
						 password, passwordLen,
						 CRYPT_ACTIVATE_KEYRING_KEY);
		tools_passphrase_msg(r);
628
		tools_keyslot_msg(r, UNLOCKED);
629
		crypt_safe_free(password);
Milan Broz's avatar
Milan Broz committed
630
	}
631

632 633 634
	if (r >= 0)
		r = crypt_resize(cd, action_argv[0], opt_size);
out:
635 636
	crypt_free(cd);
	return r;
637 638
}

639
static int action_status(void)
640
{
641 642
	crypt_status_info ci;
	struct crypt_active_device cad;
Milan Broz's avatar
Milan Broz committed
643
	struct crypt_params_integrity ip = {};
644
	struct crypt_device *cd = NULL;
645 646
	char *backing_file;
	const char *device;
647 648 649
	int path = 0, r = 0;

	/* perhaps a path, not a dm device name */
650
	if (strchr(action_argv[0], '/'))
651
		path = 1;
652

653 654 655
	ci = crypt_status(NULL, action_argv[0]);
	switch (ci) {
	case CRYPT_INVALID:
656
		r = -EINVAL;
657 658
		break;
	case CRYPT_INACTIVE:
659 660 661 662
		if (path)
			log_std("%s is inactive.\n", action_argv[0]);
		else
			log_std("%s/%s is inactive.\n", crypt_get_dir(), action_argv[0]);
663
		r = -ENODEV;
664 665 666
		break;
	case CRYPT_ACTIVE:
	case CRYPT_BUSY:
667 668 669 670 671 672
		if (path)
			log_std("%s is active%s.\n", action_argv[0],
				ci == CRYPT_BUSY ? " and is in use" : "");
		else
			log_std("%s/%s is active%s.\n", crypt_get_dir(), action_argv[0],
				ci == CRYPT_BUSY ? " and is in use" : "");
673 674

		r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device);
675
		if (r < 0)
676
			goto out;
677

678
		log_std("  type:    %s\n", crypt_get_type(cd) ?: "n/a");
679 680 681 682 683

		r = crypt_get_active_device(cd, action_argv[0], &cad);
		if (r < 0)
			goto out;

Milan Broz's avatar
Milan Broz committed
684 685 686 687
		r = crypt_get_integrity_info(cd, &ip);
		if (r < 0 && r != -ENOTSUP)
			goto out;

688 689
		log_std("  cipher:  %s-%s\n", crypt_get_cipher(cd), crypt_get_cipher_mode(cd));
		log_std("  keysize: %d bits\n", crypt_get_volume_key_size(cd) * 8);
Milan Broz's avatar
Milan Broz committed
690 691 692 693 694
		log_std("  key location: %s\n", (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) ? "keyring" : "dm-crypt");
		if (ip.integrity)
			log_std("  integrity: %s\n", ip.integrity);
		if (ip.integrity_key_size)
			log_std("  integrity keysize: %d bits\n", ip.integrity_key_size * 8);
695 696 697 698 699 700 701
		device = crypt_get_device_name(cd);
		log_std("  device:  %s\n", device);
		if (crypt_loop_device(device)) {
			backing_file = crypt_loop_backing_file(device);
			log_std("  loop:    %s\n", backing_file);
			free(backing_file);
		}
Milan Broz's avatar
Milan Broz committed
702
		log_std("  sector size:  %d\n", crypt_get_sector_size(cd));
703 704 705 706 707 708
		log_std("  offset:  %" PRIu64 " sectors\n", cad.offset);
		log_std("  size:    %" PRIu64 " sectors\n", cad.size);
		if (cad.iv_offset)
			log_std("  skipped: %" PRIu64 " sectors\n", cad.iv_offset);
		log_std("  mode:    %s\n", cad.flags & CRYPT_ACTIVATE_READONLY ?
					   "readonly" : "read/write");
709
		if (cad.flags & (CRYPT_ACTIVATE_ALLOW_DISCARDS|
710
				 CRYPT_ACTIVATE_SAME_CPU_CRYPT|
711 712 713 714 715
				 CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS))
			log_std("  flags:   %s%s%s\n",
				(cad.flags & CRYPT_ACTIVATE_ALLOW_DISCARDS) ? "discards " : "",
				(cad.flags & CRYPT_ACTIVATE_SAME_CPU_CRYPT) ? "same_cpu_crypt " : "",
				(cad.flags & CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS) ? "submit_from_crypt_cpus" : "");
716
	}
717 718
out:
	crypt_free(cd);
719 720
	if (r == -ENOTSUP)
		r = 0;
721 722 723
	return r;
}

724
static int benchmark_callback(uint32_t time_ms, void *usrptr)
725 726 727 728 729 730
{
	struct crypt_pbkdf_type *pbkdf = usrptr;
	int r = 0;

	check_signal(&r);
	if (r)
731
		log_err(_("Benchmark interrupted."));
732 733
	else
		log_dbg("PBKDF benchmark: memory cost = %u, iterations = %u, "
734
			"threads = %u (took %u ms)", pbkdf->max_memory_kb,
735
			pbkdf->iterations, pbkdf->parallel_threads, time_ms);
736 737 738
	return r;
}

Milan Broz's avatar
Milan Broz committed
739
static int action_benchmark_kdf(const char *kdf, const char *hash, size_t key_size)
Milan Broz's avatar
Milan Broz committed
740 741
{
	int r;
Milan Broz's avatar
Milan Broz committed
742
	if (!strcmp(kdf, CRYPT_KDF_PBKDF2)) {
743
		struct crypt_pbkdf_type pbkdf = {
Milan Broz's avatar
Milan Broz committed
744 745 746 747 748 749
			.type = CRYPT_KDF_PBKDF2,
			.hash = hash,
			.time_ms = 1000,
		};

		r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3, "bar", 3, key_size,
750
					&benchmark_callback, &pbkdf);
Milan Broz's avatar
Milan Broz committed
751
		if (r < 0)
752
			log_std(_("PBKDF2-%-9s     N/A\n"), hash);
Milan Broz's avatar
Milan Broz committed
753
		else
754
			log_std(_("PBKDF2-%-9s %7u iterations per second for %zu-bit key\n"),
755
				hash, pbkdf.iterations, key_size * 8);
Milan Broz's avatar
Milan Broz committed
756
	} else {
757
		struct crypt_pbkdf_type pbkdf = {
Milan Broz's avatar
Milan Broz committed
758
			.type = kdf,
Milan Broz's avatar
Milan Broz committed
759
			.time_ms = opt_iteration_time ?: DEFAULT_LUKS2_ITER_TIME,
Milan Broz's avatar
Milan Broz committed
760 761 762 763 764
			.max_memory_kb = opt_pbkdf_memory,
			.parallel_threads = opt_pbkdf_parallel,
		};

		r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3,
765 766
			"0123456789abcdef0123456789abcdef", 32,
			key_size, &benchmark_callback, &pbkdf);
Milan Broz's avatar
Milan Broz committed
767
		if (r < 0)
768
			log_std(_("%-10s N/A\n"), kdf);
Milan Broz's avatar
Milan Broz committed
769
		else
770
			log_std(_("%-10s %4u iterations, %5u memory, "
Milan Broz's avatar
Milan Broz committed
771
				"%1u parallel threads (CPUs) for "
772
				"%zu-bit key (requested %u ms time)\n"), kdf,
773 774
				pbkdf.iterations, pbkdf.max_memory_kb, pbkdf.parallel_threads,
				key_size * 8, pbkdf.time_ms);
Milan Broz's avatar
Milan Broz committed
775
	}
Milan Broz's avatar
Milan Broz committed
776

Milan Broz's avatar
Milan Broz committed
777 778 779
	return r;
}

780 781 782 783 784 785 786 787 788 789 790 791 792 793
static int benchmark_cipher_loop(const char *cipher, const char *cipher_mode,
				 size_t volume_key_size, size_t iv_size,
				 double *encryption_mbs, double *decryption_mbs)
{
	int r, buffer_size = 1024 * 1024;

	do {
		r = crypt_benchmark(NULL, cipher, cipher_mode,
				    volume_key_size, iv_size, buffer_size,
				    encryption_mbs, decryption_mbs);
		if (r == -ERANGE) {
			if (buffer_size < 1024 * 1024 * 65)
				buffer_size *= 2;
			else {
794
				log_err(_("Result of benchmark is not reliable."));
795 796 797 798 799 800 801 802
				r = -ENOENT;
			}
		}
	} while (r == -ERANGE);

	return r;
}

803
static int action_benchmark(void)
804 805
{
	static struct {
806 807
		const char *cipher;
		const char *mode;
808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824
		size_t key_size;
		size_t iv_size;
	} bciphers[] = {
		{ "aes",     "cbc", 16, 16 },
		{ "serpent", "cbc", 16, 16 },
		{ "twofish", "cbc", 16, 16 },
		{ "aes",     "cbc", 32, 16 },
		{ "serpent", "cbc", 32, 16 },
		{ "twofish", "cbc", 32, 16 },
		{ "aes",     "xts", 32, 16 },
		{ "serpent", "xts", 32, 16 },
		{ "twofish", "xts", 32, 16 },
		{ "aes",     "xts", 64, 16 },
		{ "serpent", "xts", 64, 16 },
		{ "twofish", "xts", 64, 16 },
		{  NULL, NULL, 0, 0 }
	};
825 826 827 828 829 830 831 832 833 834 835 836
	static struct {
		const char *type;
		const char *hash;
	} bkdfs[] = {
		{ CRYPT_KDF_PBKDF2,   "sha1" },
		{ CRYPT_KDF_PBKDF2,   "sha256" },
		{ CRYPT_KDF_PBKDF2,   "sha512" },
		{ CRYPT_KDF_PBKDF2,   "ripemd160" },
		{ CRYPT_KDF_PBKDF2,   "whirlpool" },
		{ CRYPT_KDF_ARGON2I,  NULL },
		{ CRYPT_KDF_ARGON2ID, NULL },
		{ NULL, NULL }
837
	};
838 839
	char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
	double enc_mbr = 0, dec_mbr = 0;
Milan Broz's avatar
Milan Broz committed
840
	int key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8;
841
	int iv_size = 16, skipped = 0, width;
842 843 844
	char *c;
	int i, r;

845
	log_std(_("# Tests are approximate using memory only (no storage IO).\n"));
846 847 848
	if (opt_pbkdf || opt_hash) {
		if (!opt_pbkdf && opt_hash)
			opt_pbkdf = CRYPT_KDF_PBKDF2;
849
		r = action_benchmark_kdf(opt_pbkdf, opt_hash, key_size);
Milan Broz's avatar
Milan Broz committed
850
	} else if (opt_cipher) {
851
		r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mode);
852
		if (r < 0) {
853
			log_err(_("No known cipher specification pattern detected."));
854 855 856 857 858 859
			return r;
		}
		if ((c  = strchr(cipher_mode, '-')))
			*c = '\0';

		/* FIXME: not really clever :) */
Milan Broz's avatar
Milan Broz committed
860 861 862
		if (strstr(cipher, "des") ||
		    strstr(cipher, "blowfish") ||
		    strstr(cipher, "cast5"))
863 864
			iv_size = 8;

865 866 867
		if (!strcmp(cipher_mode, "ecb"))
			iv_size = 0;

868 869 870
		if (!strcmp(cipher_mode, "adiantum"))
			iv_size = 32;

871
		r = benchmark_cipher_loop(cipher, cipher_mode,
Milan Broz's avatar
Milan Broz committed
872
					  key_size, iv_size,
873
					  &enc_mbr, &dec_mbr);
874
		if (!r) {
875 876 877
			width = strlen(cipher) + strlen(cipher_mode) + 1;
			if (width < 11)
				width = 11;
878
			/* TRANSLATORS: The string is header of a table and must be exactly (right side) aligned. */
879 880
			log_std(_("#%*s Algorithm |       Key |      Encryption |      Decryption\n"), width - 11, "");
			log_std("%*s-%s  %9db  %10.1f MiB/s  %10.1f MiB/s\n", width - (int)strlen(cipher_mode) - 1,
Milan Broz's avatar
Milan Broz committed
881
				cipher, cipher_mode, key_size*8, enc_mbr, dec_mbr);
882
		} else if (r == -ENOENT)
883
			log_err(_("Cipher %s is not available."), opt_cipher);
884
	} else {
885 886
		for (i = 0; bkdfs[i].type; i++) {
			r = action_benchmark_kdf(bkdfs[i].type, bkdfs[i].hash, key_size);
887 888 889 890
			check_signal(&r);
			if (r == -EINTR)
				break;
		}
Milan Broz's avatar
Milan Broz committed
891

892
		for (i = 0; bciphers[i].cipher; i++) {
893
			r = benchmark_cipher_loop(bciphers[i].cipher, bciphers[i].mode,
894
					    bciphers[i].key_size, bciphers[i].iv_size,
895
					    &enc_mbr, &dec_mbr);
896 897
			check_signal(&r);
			if (r == -ENOTSUP || r == -EINTR)
898
				break;
899 900
			if (r == -ENOENT)
				skipped++;
901
			if (i == 0)
902 903
				/* TRANSLATORS: The string is header of a table and must be exactly (right side) aligned. */
				log_std(_("#     Algorithm |       Key |      Encryption |      Decryption\n"));
904

905 906 907
			snprintf(cipher, MAX_CIPHER_LEN, "%s-%s",
				 bciphers[i].cipher, bciphers[i].mode);
			if (!r)
908
				log_std("%15s  %9zub  %10.1f MiB/s  %10.1f MiB/s\n",
909 910
					cipher, bciphers[i].key_size*8, enc_mbr, dec_mbr);
			else
911
				log_std("%15s  %9zub %17s %17s\n", cipher,
912 913
					bciphers[i].key_size*8, _("N/A"), _("N/A"));
		}
914
		if (skipped && skipped == i)
915
			r = -ENOTSUP;
916 917
	}

918
	if (r == -ENOTSUP) {
919
		log_err(_("Required kernel crypto interface not available."));
920
#ifdef ENABLE_AF_ALG
921
		log_err( _("Ensure you have algif_skcipher kernel module loaded."));
922 923
#endif
	}
924 925 926
	return r;
}

927 928
static int set_pbkdf_params(struct crypt_device *cd, const char *dev_type)
{
929
	const struct crypt_pbkdf_type *pbkdf_default;
930 931
	struct crypt_pbkdf_type pbkdf = {};

932 933 934 935 936 937
	pbkdf_default = crypt_get_pbkdf_default(dev_type);
	if (!pbkdf_default)
		return -EINVAL;

	pbkdf.type = opt_pbkdf ?: pbkdf_default->type;
	pbkdf.hash = opt_hash ?: pbkdf_default->hash;
Milan Broz's avatar
Milan Broz committed
938
	pbkdf.time_ms = (uint32_t)opt_iteration_time ?: pbkdf_default->time_ms;
939 940 941 942
	if (strcmp(pbkdf.type, CRYPT_KDF_PBKDF2)) {
		pbkdf.max_memory_kb = opt_pbkdf_memory ?: pbkdf_default->max_memory_kb;
		pbkdf.parallel_threads = opt_pbkdf_parallel ?: pbkdf_default->parallel_threads;
	}
943 944 945 946 947 948 949 950 951

	if (opt_pbkdf_iterations) {
		pbkdf.iterations = opt_pbkdf_iterations;
		pbkdf.flags |= CRYPT_PBKDF_NO_BENCHMARK;
	}

	return crypt_set_pbkdf_type(cd, &pbkdf);
}

952
static int action_luksRepair(void)
953 954 955 956 957 958 959
{
	struct crypt_device *cd = NULL;
	int r;

	if ((r = crypt_init(&cd, action_argv[0])))
		goto out;

960
	crypt_set_log_callback(cd, quiet_log, NULL);
Milan Broz's avatar
Milan Broz committed
961
	r = crypt_load(cd, luksType(opt_type), NULL);
962
	crypt_set_log_callback(cd, tool_log, NULL);
963
	if (r == 0) {
964
		log_verbose(_("No known problems detected for LUKS header."));
965 966 967
		goto out;
	}

968 969 970 971
	r = tools_detect_signatures(action_argv[0], 1, NULL);
	if (r < 0)
		goto out;

972
	r = yesDialog(_("Really try to repair LUKS device header?"),
973
		       _("Operation aborted.\n")) ? 0 : -EINVAL;
974
	if (r == 0)
Milan Broz's avatar
Milan Broz committed
975
		r = crypt_repair(cd, luksType(opt_type), NULL);
976 977 978 979 980
out:
	crypt_free(cd);
	return r;
}

Milan Broz's avatar
Milan Broz committed
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
static int _wipe_data_device(struct crypt_device *cd)
{
	char tmp_name[64], tmp_path[128], tmp_uuid[40];
	uuid_t tmp_uuid_bin;
	int r;

	if (!opt_batch_mode)
		log_std(_("Wiping device to initialize integrity checksum.\n"
			"You can interrupt this by pressing CTRL+c "
			"(rest of not wiped device will contain invalid checksum).\n"));

	/* Activate the device a temporary one */
	uuid_generate(tmp_uuid_bin);
	uuid_unparse(tmp_uuid_bin, tmp_uuid);
	if (snprintf(tmp_name, sizeof(tmp_name), "temporary-cryptsetup-%s", tmp_uuid) < 0)
		return -EINVAL;
	if (snprintf(tmp_path, sizeof(tmp_path), "%s/%s", crypt_get_dir(), tmp_name) < 0)
		return -EINVAL;

	r = crypt_activate_by_volume_key(cd, tmp_name, NULL, 0,
		CRYPT_ACTIVATE_PRIVATE | CRYPT_ACTIVATE_NO_JOURNAL);
	if (r < 0)
		return r;

	/* Wipe the device */
	set_int_handler(0);
	r = crypt_wipe(cd, tmp_path, CRYPT_WIPE_ZERO, 0, 0, DEFAULT_WIPE_BLOCK,
		       0, &tools_wipe_progress, NULL);
	if (crypt_deactivate(cd, tmp_name))
1010
		log_err(_("Cannot deactivate temporary device %s."), tmp_path);
Milan Broz's avatar
Milan Broz committed
1011 1012 1013 1014 1015
	set_int_block(0);

	return r;
}

1016
static int action_luksFormat(void)
1017
{
1018
	int r = -EINVAL, keysize, integrity_keysize = 0, fd, created = 0;
1019
	struct stat st;
1020
	const char *header_device, *type;
Milan Broz's avatar
Milan Broz committed
1021 1022
	char *msg = NULL, *key = NULL, *password = NULL;
	char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN], integrity[MAX_CIPHER_LEN];
1023
	size_t passwordLen, signatures;
1024
	struct crypt_device *cd = NULL;
1025
	struct crypt_params_luks1 params1 = {
1026
		.hash = opt_hash ?: DEFAULT_LUKS1_HASH,
1027
		.data_alignment = opt_align_payload,
1028
		.data_device = opt_header_device ? action_argv[0] : NULL,
1029
	};
Milan Broz's avatar
Milan Broz committed
1030
	struct crypt_params_luks2 params2 = {
1031
		.data_alignment = params1.data_alignment,
1032
		.data_device = params1.data_device,
Milan Broz's avatar
Milan Broz committed
1033 1034 1035 1036
		.sector_size = opt_sector_size,
		.label = opt_label,
		.subsystem = opt_subsystem
	};
1037
	void *params;
Milan Broz's avatar
Milan Broz committed
1038

1039 1040
	type = luksType(opt_type);
	if (!type)
1041
		type = crypt_get_default_type();
Milan Broz's avatar
Milan Broz committed
1042

1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
	if (!strcmp(type, CRYPT_LUKS2)) {
		params = &params2;
	} else if (!strcmp(type, CRYPT_LUKS1)) {
		params = &params1;

		if (opt_sector_size > SECTOR_SIZE) {
			log_err(_("Unsupported encryption sector size."));
			return -EINVAL;
		}

		if (opt_integrity) {
			log_err(_("Integrity option can be used only for LUKS2 format."));
			return -EINVAL;
		}
1057 1058 1059 1060 1061

		if (opt_luks2_keyslots_size || opt_luks2_metadata_size) {
			log_err(_("Unsupported LUKS2 metadata size options."));
			return -EINVAL;
		}
1062
	} else
Milan Broz's avatar
Milan Broz committed
1063
		return -EINVAL;
1064

1065 1066 1067
	/* Create header file (must contain at least one sector)? */
	if (opt_header_device && stat(opt_header_device, &st) < 0 && errno == ENOENT) {
		if (!opt_batch_mode &&
1068 1069
		    !yesDialog("Header file does not exist, do you want to create it?",
			    _("Operation aborted.\n")))
1070 1071 1072
		    return -EPERM;

		log_dbg("Creating header file.");
1073
		/* coverity[toctou] */
1074 1075
		fd = open(opt_header_device, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
		if (fd == -1 || posix_fallocate(fd, 0, 4096))
1076
			log_err(_("Cannot create header file %s."), opt_header_device);
1077
		else {
1078
			r = 0;
1079 1080
			created = 1;
		}
1081 1082 1083 1084 1085 1086
		if (fd != -1)
			close(fd);
		if (r < 0)
			return r;
	}

1087 1088
	header_device = opt_header_device ?: action_argv[0];

1089
	r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1),
1090
				      cipher, NULL, cipher_mode);
1091
	if (r < 0) {
1092
		log_err(_("No known cipher specification pattern detected."));
1093
		goto out;
1094 1095
	}

1096
	if (opt_integrity) {
Milan Broz's avatar
Milan Broz committed
1097 1098
		r = crypt_parse_integrity_mode(opt_integrity, integrity, &integrity_keysize);
		if (r < 0) {
1099
			log_err(_("No known integrity specification pattern detected."));
Milan Broz's avatar
Milan Broz committed
1100 1101 1102 1103 1104 1105
			goto out;
		}
		params2.integrity = integrity;
		/* FIXME: we use default integrity_params (set to NULL) */
	}

1106 1107 1108 1109
	/* Never call pwquality if using null cipher */
	if (tools_is_cipher_null(cipher))
		opt_force_password = 1;

1110 1111
	if ((r = crypt_init(&cd, header_device))) {
		if (opt_header_device)
1112
			log_err(_("Cannot use %s as on-disk header."), header_device);
1113
		return r;
1114
	}
1115

1116 1117 1118 1119 1120 1121 1122 1123
	if (opt_luks2_keyslots_size || opt_luks2_metadata_size) {
		r = crypt_set_metadata_size(cd, opt_luks2_metadata_size, opt_luks2_keyslots_size);
		if (r < 0) {
			log_err(_("Unsupported LUKS2 metadata size options."));
			goto out;
		}
	}

1124 1125 1126 1127 1128 1129
	if (opt_offset) {
		r = crypt_set_data_offset(cd, opt_offset);
		if (r < 0)
			goto out;
	}

1130 1131 1132 1133 1134
	/* Print all present signatures in read-only mode */
	r = tools_detect_signatures(header_device, 0, &signatures);
	if (r < 0)
		goto out;

1135 1136 1137 1138 1139 1140
	if (!created) {
		r = asprintf(&msg, _("This will overwrite data on %s irrevocably."), header_device);
		if (r == -1) {
			r = -ENOMEM;
			goto out;
		}
1141

1142 1143 1144 1145 1146
		r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
		free(msg);
		if (r < 0)
			goto out;
	}
1147

1148 1149 1150 1151 1152 1153 1154 1155
#ifdef ENABLE_LUKS_ADJUST_XTS_KEYSIZE
	if (!opt_key_size && !strncmp(cipher_mode, "xts-", 4)) {
		if (DEFAULT_LUKS1_KEYBITS == 128)
			opt_key_size = 256;
		else if (DEFAULT_LUKS1_KEYBITS == 256)
			opt_key_size = 512;
	}
#endif
Milan Broz's avatar
Milan Broz committed
1156
	keysize = (opt_key_size ?: DEFAULT_LUKS1_KEYBITS) / 8 + integrity_keysize;
1157

1158 1159 1160 1161 1162
	if (opt_random)
		crypt_set_rng_type(cd, CRYPT_RNG_RANDOM);
	else if (opt_urandom)
		crypt_set_rng_type(cd, CRYPT_RNG_URANDOM);

1163
	r = tools_get_key(NULL, &password, &passwordLen,
1164
			  opt_keyfile_offset, opt_keyfile_size, opt_key_file,
1165
			  opt_timeout, _verify_passphrase(1), 1, cd);
1166
	if (r < 0)
1167 1168
		goto out;

1169
	if (opt_master_key_file) {
1170
		r = tools_read_mk(opt_master_key_file, &key, keysize);
1171 1172
		if (r < 0)
			goto out;
1173
	}
1174

1175
	r = set_pbkdf_params(cd, type);
1176
	if (r) {
1177
		log_err(_("Failed to set pbkdf parameters."));
1178 1179 1180
		goto out;
	}

1181 1182 1183 1184
	/* Signature candidates found */
	if (signatures && ((r =	tools_wipe_all_signatures(header_device)) < 0))
		goto out;

1185 1186
	r = crypt_format(cd, type, cipher, cipher_mode,
			 opt_uuid, key, keysize, params);
1187
	check_signal(&r);
1188 1189
	if (r < 0)
		goto out;
1190

1191 1192 1193 1194
	r = _set_keyslot_encryption_params(cd);
	if (r < 0)
		goto out;

1195 1196 1197
	r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot,
					    key, keysize,
					    password, passwordLen);
1198 1199
	if (r < 0) {
		(void) tools_wipe_all_signatures(header_device);
Milan Broz's avatar
Milan Broz committed
1200
		goto out;
1201
	}
1202
	tools_keyslot_msg(r, CREATED);
Milan Broz's avatar
Milan Broz committed
1203 1204 1205

	if (opt_integrity && !opt_integrity_no_wipe)
		r = _wipe_data_device(cd);
1206 1207 1208 1209
out:
	crypt_free(cd);
	crypt_safe_free(key);
	crypt_safe_free(password);
1210

1211
	return r;
1212 1213
}

1214
static int action_open_luks(void)
1215
{
1216
	struct crypt_active_device cad;
1217
	struct crypt_device *cd = NULL;
1218
	const char *data_device, *header_device, *activated_name;
1219
	char *key = NULL;
1220
	uint32_t activate_flags = 0;
1221
	int r, keysize, tries;
1222 1223
	char *password = NULL;
	size_t passwordLen;
1224

1225 1226 1227 1228 1229 1230 1231 1232
	if (opt_refresh) {
		activated_name = action_argc > 1 ? action_argv[1] : action_argv[0];
		r = crypt_init_by_name_and_header(&cd, activated_name, opt_header_device);
		if (r)
			goto out;
		activate_flags |= CRYPT_ACTIVATE_REFRESH;
	} else {
		header_device = uuid_or_device_header(&data_device);
1233

1234
		activated_name = opt_test_passphrase ? NULL : action_argv[1];
1235

1236 1237
		if ((r = crypt_init_data_device(&cd, header_device, data_device)))
			goto out;
1238

1239 1240 1241 1242 1243
		if ((r = crypt_load(cd, luksType(opt_type), NULL))) {
			log_err(_("Device %s is not a valid LUKS device."),
				header_device);
			goto out;
		}
1244

1245 1246 1247 1248 1249
		if (!data_device && (crypt_get_data_offset(cd)