"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/cryptsetup.c" between
cryptsetup-2.3.6.tar.xz and cryptsetup-2.4.0.tar.xz

About: cryptsetup is a utility used to conveniently setup disk encryption based on the dm-crypt kernel module. These include plain dm-crypt volumes, LUKS volumes, loop-AES and TrueCrypt compatible format.

cryptsetup.c  (cryptsetup-2.3.6.tar.xz):cryptsetup.c  (cryptsetup-2.4.0.tar.xz)
skipping to change at line 24 skipping to change at line 24
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/ */
#include "cryptsetup.h"
#include <uuid/uuid.h> #include <uuid/uuid.h>
static char *opt_cipher = NULL; #include "cryptsetup.h"
static char *opt_keyslot_cipher = NULL; #include "cryptsetup_args.h"
static char *opt_hash = NULL;
static char *opt_json_file = NULL; static char *keyfiles[MAX_KEYFILES];
static char *opt_key_file = NULL; static char *keyfile_stdin = NULL;
static char *opt_keyfile_stdin = NULL;
static char *opt_keyfiles[MAX_KEYFILES]; static int keyfiles_count = 0;
static char *opt_master_key_file = NULL; static int64_t data_shift = 0;
static char *opt_header_backup_file = NULL;
static char *opt_uuid = NULL;
static char *opt_header_device = NULL;
static char *opt_type = NULL;
static char *opt_pbkdf = NULL;
static char *opt_priority = NULL; /* normal */
static char *opt_integrity = NULL; /* none */
static char *opt_key_description = NULL;
static char *opt_label = NULL;
static char *opt_subsystem = NULL;
static char *opt_active_name = NULL;
static char *opt_resilience_mode = NULL; /* default value "checksum" */
static char *opt_resilience_hash = NULL; /* default value "sha256" */
/* helper strings converted to uint64_t later */
static char *opt_reduce_size_str = NULL;
static char *opt_hotzone_size_str = NULL;
static char *opt_device_size_str = NULL;
static char *opt_luks2_metadata_size_str = NULL;
static char *opt_luks2_keyslots_size_str = NULL;
static uint64_t opt_reduce_size = 0;
static uint64_t opt_hotzone_size = 0;
static uint64_t opt_device_size = 0;
static uint64_t opt_luks2_metadata_size = 0;
static uint64_t opt_luks2_keyslots_size = 0;
static int opt_keyfiles_count = 0;
static int opt_verify_passphrase = 0;
static int opt_key_size = 0;
static int opt_keyslot_key_size = 0;
static long opt_keyfile_size = 0;
static long opt_new_keyfile_size = 0;
static uint64_t opt_keyfile_offset = 0;
static uint64_t opt_new_keyfile_offset = 0;
static int opt_key_slot = CRYPT_ANY_SLOT;
static int opt_token = CRYPT_ANY_TOKEN;
static int opt_token_only = 0;
static uint64_t opt_size = 0;
static uint64_t opt_offset = 0;
static uint64_t opt_skip = 0;
static int opt_skip_valid = 0;
static int opt_readonly = 0;
static int opt_timeout = 0;
static int opt_tries = 3;
static int opt_align_payload = 0;
static int opt_random = 0;
static int opt_urandom = 0;
static int opt_dump_master_key = 0;
static int opt_shared = 0;
static int opt_allow_discards = 0;
static int opt_perf_same_cpu_crypt = 0;
static int opt_perf_submit_from_crypt_cpus = 0;
static int opt_perf_no_read_workqueue = 0;
static int opt_perf_no_write_workqueue = 0;
static int opt_test_passphrase = 0;
static int opt_tcrypt_hidden = 0;
static int opt_tcrypt_system = 0;
static int opt_tcrypt_backup = 0;
static int opt_veracrypt = 0;
static int opt_veracrypt_pim = -1;
static int opt_veracrypt_query_pim = 0;
static int opt_deferred_remove = 0;
static int opt_serialize_memory_hard_pbkdf = 0;
//FIXME: check uint32 overflow for long type
static long opt_pbkdf_memory = DEFAULT_LUKS2_MEMORY_KB;
static long opt_pbkdf_parallel = DEFAULT_LUKS2_PARALLEL_THREADS;
static long opt_pbkdf_iterations = 0;
static int opt_iteration_time = 0;
static int opt_disable_locks = 0;
static int opt_disable_keyring = 0;
static int opt_integrity_nojournal = 0;
static int opt_integrity_no_wipe = 0;
static int opt_integrity_legacy_padding = 0;
static int opt_sector_size = 0;
static int opt_iv_large_sectors = 0;
static int opt_persistent = 0;
static int opt_unbound = 0;
static int opt_refresh = 0;
/* LUKS2 reencryption parameters */
static int opt_encrypt = 0;
static int opt_reencrypt_init_only = 0;
static int opt_reencrypt_resume_only = 0;
static int opt_decrypt = 0;
/* do not set from command line, use helpers above */
static int64_t opt_data_shift;
static const char *device_type = "luks"; static const char *device_type = "luks";
static const char *set_pbkdf = NULL; static const char *set_pbkdf = NULL;
static const char **action_argv; static const char **action_argv;
static int action_argc; static int action_argc;
static const char *null_action_argv[] = {NULL, NULL}; static const char *null_action_argv[] = {NULL, NULL};
static int total_keyfiles = 0;
static struct tools_log_params log_parms;
void tools_cleanup(void) void tools_cleanup(void)
{ {
FREE_AND_NULL(opt_cipher); tools_args_free(tool_core_args, ARRAY_SIZE(tool_core_args));
FREE_AND_NULL(opt_keyslot_cipher);
FREE_AND_NULL(opt_hash); FREE_AND_NULL(keyfile_stdin);
FREE_AND_NULL(opt_json_file);
FREE_AND_NULL(opt_key_file);
FREE_AND_NULL(opt_keyfile_stdin);
FREE_AND_NULL(opt_master_key_file);
FREE_AND_NULL(opt_header_backup_file);
FREE_AND_NULL(opt_uuid);
FREE_AND_NULL(opt_header_device);
FREE_AND_NULL(opt_type);
FREE_AND_NULL(opt_pbkdf);
FREE_AND_NULL(opt_priority);
FREE_AND_NULL(opt_integrity);
FREE_AND_NULL(opt_key_description);
FREE_AND_NULL(opt_label);
FREE_AND_NULL(opt_subsystem);
FREE_AND_NULL(opt_active_name);
FREE_AND_NULL(opt_resilience_mode);
FREE_AND_NULL(opt_resilience_hash);
FREE_AND_NULL(opt_reduce_size_str);
FREE_AND_NULL(opt_hotzone_size_str);
FREE_AND_NULL(opt_device_size_str);
FREE_AND_NULL(opt_luks2_metadata_size_str);
FREE_AND_NULL(opt_luks2_keyslots_size_str);
while (opt_keyfiles_count) while (keyfiles_count)
free(opt_keyfiles[--opt_keyfiles_count]); free(keyfiles[--keyfiles_count]);
total_keyfiles = 0;
} }
static const char *uuid_or_device_header(const char **data_device) static const char *uuid_or_device_header(const char **data_device)
{ {
if (data_device) if (data_device)
*data_device = opt_header_device ? action_argv[0] : NULL; *data_device = ARG_SET(OPT_HEADER_ID) ? action_argv[0] : NULL;
return uuid_or_device(opt_header_device ?: action_argv[0]); return uuid_or_device(ARG_STR(OPT_HEADER_ID) ?: action_argv[0]);
} }
static const char *luksType(const char *type) static const char *luksType(const char *type)
{ {
if (type && !strcmp(type, "luks2")) if (type && !strcmp(type, "luks2"))
return CRYPT_LUKS2; return CRYPT_LUKS2;
if (type && !strcmp(type, "luks1")) if (type && !strcmp(type, "luks1"))
return CRYPT_LUKS1; return CRYPT_LUKS1;
if (type && !strcmp(type, "luks")) if (type && !strcmp(type, "luks"))
return CRYPT_LUKS; /* NULL */ return CRYPT_LUKS; /* NULL */
if (type && *type) if (type && *type)
return type; return type;
return CRYPT_LUKS; /* NULL */ return CRYPT_LUKS; /* NULL */
} }
static bool isLUKS1(const char *type)
{
return type && !strcmp(type, CRYPT_LUKS1);
}
static bool isLUKS2(const char *type)
{
return type && !strcmp(type, CRYPT_LUKS2);
}
static bool isLUKS(const char *type)
{
return isLUKS2(type) || isLUKS1(type);
}
static int _verify_passphrase(int def) static int _verify_passphrase(int def)
{ {
/* Batch mode switch off verify - if not overridden by -y */ /* Batch mode switch off verify - if not overridden by -y */
if (opt_verify_passphrase) if (ARG_SET(OPT_VERIFY_PASSPHRASE_ID))
def = 1; def = 1;
else if (opt_batch_mode) else if (ARG_SET(OPT_BATCH_MODE_ID))
def = 0; def = 0;
/* Non-tty input doesn't allow verify */ /* Non-tty input doesn't allow verify */
if (def && !isatty(STDIN_FILENO)) { if (def && !isatty(STDIN_FILENO)) {
if (opt_verify_passphrase) if (ARG_SET(OPT_VERIFY_PASSPHRASE_ID))
log_err(_("Can't do passphrase verification on non-tty in puts.")); log_err(_("Can't do passphrase verification on non-tty in puts."));
def = 0; def = 0;
} }
return def; return def;
} }
static void _set_activation_flags(uint32_t *flags) static void _set_activation_flags(uint32_t *flags)
{ {
if (opt_readonly) if (ARG_SET(OPT_READONLY_ID))
*flags |= CRYPT_ACTIVATE_READONLY; *flags |= CRYPT_ACTIVATE_READONLY;
if (opt_allow_discards) if (ARG_SET(OPT_ALLOW_DISCARDS_ID))
*flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS; *flags |= CRYPT_ACTIVATE_ALLOW_DISCARDS;
if (opt_perf_same_cpu_crypt) if (ARG_SET(OPT_PERF_SAME_CPU_CRYPT_ID))
*flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT; *flags |= CRYPT_ACTIVATE_SAME_CPU_CRYPT;
if (opt_perf_submit_from_crypt_cpus) if (ARG_SET(OPT_PERF_SUBMIT_FROM_CRYPT_CPUS_ID))
*flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS; *flags |= CRYPT_ACTIVATE_SUBMIT_FROM_CRYPT_CPUS;
if (opt_perf_no_read_workqueue) if (ARG_SET(OPT_PERF_NO_READ_WORKQUEUE_ID))
*flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE; *flags |= CRYPT_ACTIVATE_NO_READ_WORKQUEUE;
if (opt_perf_no_write_workqueue) if (ARG_SET(OPT_PERF_NO_WRITE_WORKQUEUE_ID))
*flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE; *flags |= CRYPT_ACTIVATE_NO_WRITE_WORKQUEUE;
if (opt_integrity_nojournal) if (ARG_SET(OPT_INTEGRITY_NO_JOURNAL_ID))
*flags |= CRYPT_ACTIVATE_NO_JOURNAL; *flags |= CRYPT_ACTIVATE_NO_JOURNAL;
/* In persistent mode, we use what is set on command line */ /* In persistent mode, we use what is set on command line */
if (opt_persistent) if (ARG_SET(OPT_PERSISTENT_ID))
*flags |= CRYPT_ACTIVATE_IGNORE_PERSISTENT; *flags |= CRYPT_ACTIVATE_IGNORE_PERSISTENT;
/* Only for LUKS2 but ignored elsewhere */ /* Only for LUKS2 but ignored elsewhere */
if (opt_test_passphrase) if (ARG_SET(OPT_TEST_PASSPHRASE_ID))
*flags |= CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY; *flags |= CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY;
if (opt_serialize_memory_hard_pbkdf) if (ARG_SET(OPT_SERIALIZE_MEMORY_HARD_PBKDF_ID))
*flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF; *flags |= CRYPT_ACTIVATE_SERIALIZE_MEMORY_HARD_PBKDF;
/* Only for plain */ /* Only for plain */
if (opt_iv_large_sectors) if (ARG_SET(OPT_IV_LARGE_SECTORS_ID))
*flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS; *flags |= CRYPT_ACTIVATE_IV_LARGE_SECTORS;
} }
static void _set_reencryption_flags(uint32_t *flags) static void _set_reencryption_flags(uint32_t *flags)
{ {
if (opt_reencrypt_init_only) if (ARG_SET(OPT_INIT_ONLY_ID))
*flags |= CRYPT_REENCRYPT_INITIALIZE_ONLY; *flags |= CRYPT_REENCRYPT_INITIALIZE_ONLY;
if (opt_reencrypt_resume_only) if (ARG_SET(OPT_RESUME_ONLY_ID))
*flags |= CRYPT_REENCRYPT_RESUME_ONLY; *flags |= CRYPT_REENCRYPT_RESUME_ONLY;
} }
static int _set_keyslot_encryption_params(struct crypt_device *cd) static int _set_keyslot_encryption_params(struct crypt_device *cd)
{ {
const char *type = crypt_get_type(cd); const char *type = crypt_get_type(cd);
if (!opt_keyslot_key_size && !opt_keyslot_cipher) if (!ARG_SET(OPT_KEYSLOT_KEY_SIZE_ID) && !ARG_SET(OPT_KEYSLOT_CIPHER_ID))
return 0; return 0;
if (!type || strcmp(type, CRYPT_LUKS2)) { if (!isLUKS2(type)) {
log_err(_("Keyslot encryption parameters can be set only for LUKS 2 device.")); log_err(_("Keyslot encryption parameters can be set only for LUKS 2 device."));
return -EINVAL; return -EINVAL;
} }
return crypt_keyslot_set_encryption(cd, opt_keyslot_cipher, opt_keyslot_k return crypt_keyslot_set_encryption(cd, ARG_STR(OPT_KEYSLOT_CIPHER_ID), A
ey_size / 8); RG_UINT32(OPT_KEYSLOT_KEY_SIZE_ID) / 8);
}
static int _set_tries_tty(void)
{
return (tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID)) && isatty(STDIN_FILENO))
? ARG_UINT32(OPT_TRIES_ID) : 1;
}
static int _try_token_pin_unlock(struct crypt_device *cd,
int token_id,
const char *activated_name,
const char *token_type,
uint32_t activate_flags,
int tries)
{
size_t pin_len;
char msg[64], *pin = NULL;
int r;
assert(tries >= 1);
assert(token_id >= 0 || token_id == CRYPT_ANY_TOKEN);
if (token_id == CRYPT_ANY_TOKEN)
r = snprintf(msg, sizeof(msg), _("Enter token PIN:"));
else
r = snprintf(msg, sizeof(msg), _("Enter token %d PIN:"), token_id
);
if (r < 0 || (size_t)r >= sizeof(msg))
return -EINVAL;
do {
r = tools_get_key(msg, &pin, &pin_len, 0, 0, NULL,
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(0)
, 0, cd);
if (r < 0)
break;
r = crypt_activate_by_token_pin(cd, activated_name, token_type, A
RG_INT32(OPT_TOKEN_ID_ID),
pin, pin_len, NULL, activate_flag
s);
crypt_safe_free(pin);
pin = NULL;
tools_keyslot_msg(r, UNLOCKED);
tools_token_error_msg(r, ARG_STR(OPT_TOKEN_TYPE_ID), ARG_INT32(OP
T_TOKEN_ID_ID), true);
check_signal(&r);
} while (r == -ENOANO && (--tries > 0));
return r;
} }
static int action_open_plain(void) static int action_open_plain(void)
{ {
struct crypt_device *cd = NULL, *cd1 = NULL; struct crypt_device *cd = NULL, *cd1 = NULL;
const char *pcipher, *pmode; const char *pcipher, *pmode;
char *msg, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN]; char *msg, cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
struct crypt_active_device cad; struct crypt_active_device cad;
struct crypt_params_plain params = { struct crypt_params_plain params = {
.hash = opt_hash ?: DEFAULT_PLAIN_HASH, .hash = ARG_SET(OPT_HASH_ID) ? ARG_STR(OPT_HASH_ID) : DEFAULT_PLA
.skip = opt_skip, IN_HASH,
.offset = opt_offset, .skip = ARG_UINT64(OPT_SKIP_ID),
.size = opt_size, .offset = ARG_UINT64(OPT_OFFSET_ID),
.sector_size = opt_sector_size ?: SECTOR_SIZE .size = ARG_UINT64(OPT_SIZE_ID),
.sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID) ?: SECTOR_SIZE
}; };
char *password = NULL; char *password = NULL;
const char *activated_name = NULL; const char *activated_name = NULL;
size_t passwordLen, key_size_max, signatures = 0, size_t passwordLen, key_size_max, signatures = 0,
key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8; key_size = (ARG_UINT32(OPT_KEY_SIZE_ID) ?: DEFAULT_PLAIN_KEYBITS) / 8;
uint32_t activate_flags = 0; uint32_t activate_flags = 0;
int r; int r;
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(PLAIN), r = crypt_parse_name_and_mode(ARG_STR(OPT_CIPHER_ID) ?: DEFAULT_CIPHER(PL AIN),
cipher, NULL, cipher_mode); cipher, NULL, cipher_mode);
if (r < 0) { if (r < 0) {
log_err(_("No known cipher specification pattern detected.")); log_err(_("No known cipher specification pattern detected."));
goto out; goto out;
} }
/* FIXME: temporary hack, no hashing for keyfiles in plain mode */ /* FIXME: temporary hack, no hashing for keyfiles in plain mode */
if (opt_key_file && !tools_is_stdin(opt_key_file)) { if (ARG_SET(OPT_KEY_FILE_ID) && !tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID)) ) {
params.hash = NULL; params.hash = NULL;
if (!opt_batch_mode && opt_hash) if (!ARG_SET(OPT_BATCH_MODE_ID) && ARG_SET(OPT_HASH_ID))
log_std(_("WARNING: The --hash parameter is being ignored " log_std(_("WARNING: The --hash parameter is being ignored "
"in plain mode with keyfile specified.\n")); "in plain mode with keyfile specified.\n"));
} }
if (params.hash && !strcmp(params.hash, "plain")) if (params.hash && !strcmp(params.hash, "plain"))
params.hash = NULL; params.hash = NULL;
if (!opt_batch_mode && !params.hash && opt_key_file && !tools_is_stdin(op t_key_file) && opt_keyfile_size) if (!ARG_SET(OPT_BATCH_MODE_ID) && !params.hash && ARG_SET(OPT_KEY_FILE_I D) && !tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID)) && ARG_SET(OPT_KEYFILE_SIZE_ID))
log_std(_("WARNING: The --keyfile-size option is being ignored, " log_std(_("WARNING: The --keyfile-size option is being ignored, "
"the read size is the same as the encryption key size.\n ")); "the read size is the same as the encryption key size.\n "));
if (opt_refresh) { if (ARG_SET(OPT_REFRESH_ID)) {
activated_name = action_argc > 1 ? action_argv[1] : action_argv[0 ]; activated_name = action_argc > 1 ? action_argv[1] : action_argv[0 ];
r = crypt_init_by_name_and_header(&cd1, activated_name, NULL); r = crypt_init_by_name_and_header(&cd1, activated_name, NULL);
if (r) if (r)
goto out; goto out;
r = crypt_get_active_device(cd1, activated_name, &cad); r = crypt_get_active_device(cd1, activated_name, &cad);
if (r) if (r)
goto out; goto out;
/* copy known parameters from existing device */ /* copy known parameters from existing device */
params.skip = crypt_get_iv_offset(cd1); params.skip = crypt_get_iv_offset(cd1);
skipping to change at line 339 skipping to change at line 293
activate_flags |= CRYPT_ACTIVATE_REFRESH; activate_flags |= CRYPT_ACTIVATE_REFRESH;
pcipher = crypt_get_cipher(cd1); pcipher = crypt_get_cipher(cd1);
pmode = crypt_get_cipher_mode(cd1); pmode = crypt_get_cipher_mode(cd1);
} else { } else {
activated_name = action_argv[1]; activated_name = action_argv[1];
if ((r = crypt_init(&cd, action_argv[0]))) if ((r = crypt_init(&cd, action_argv[0])))
goto out; goto out;
/* Skip blkid scan when activating plain device with offset */ /* Skip blkid scan when activating plain device with offset */
if (!opt_offset) { if (!ARG_UINT64(OPT_OFFSET_ID)) {
/* Print all present signatures in read-only mode */ /* Print all present signatures in read-only mode */
r = tools_detect_signatures(action_argv[0], 0, &signature s); r = tools_detect_signatures(action_argv[0], 0, &signature s, ARG_SET(OPT_BATCH_MODE_ID));
if (r < 0) if (r < 0)
goto out; goto out;
} }
if (signatures) { if (signatures && !ARG_SET(OPT_BATCH_MODE_ID)) {
r = asprintf(&msg, _("Detected device signature(s) on %s. Proceeding further may damage existing data."), action_argv[0]); r = asprintf(&msg, _("Detected device signature(s) on %s. Proceeding further may damage existing data."), action_argv[0]);
if (r == -1) { if (r == -1) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
} }
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINV AL; r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINV AL;
free(msg); free(msg);
if (r < 0) if (r < 0)
goto out; goto out;
skipping to change at line 372 skipping to change at line 326
r = crypt_format(cd, CRYPT_PLAIN, r = crypt_format(cd, CRYPT_PLAIN,
pcipher, pmode, pcipher, pmode,
NULL, NULL, NULL, NULL,
key_size, key_size,
&params); &params);
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
if (opt_shared) if (ARG_SET(OPT_SHARED_ID))
activate_flags |= CRYPT_ACTIVATE_SHARED; activate_flags |= CRYPT_ACTIVATE_SHARED;
_set_activation_flags(&activate_flags); _set_activation_flags(&activate_flags);
if (!tools_is_stdin(opt_key_file)) { if (!tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID))) {
/* If no hash, key is read directly, read size is always key_size /* If no hash, key is read directly, read size is always key_size
* (possible opt_keyfile_size is ignored. * (possible --keyfile_size is ignored.
* If hash is specified, opt_keyfile_size is applied. * If hash is specified, --keyfile_size is applied.
* The opt_keyfile_offset is applied always. * The --keyfile_offset is applied always.
*/ */
key_size_max = params.hash ? (size_t)opt_keyfile_size : key_size; key_size_max = params.hash ? ARG_UINT32(OPT_KEYFILE_SIZE_ID) : ke y_size;
r = crypt_activate_by_keyfile_device_offset(cd, action_argv[1], r = crypt_activate_by_keyfile_device_offset(cd, action_argv[1],
CRYPT_ANY_SLOT, opt_key_file, key_size_max, CRYPT_ANY_SLOT, ARG_STR(OPT_KEY_FILE_ID), key_size_max,
opt_keyfile_offset, activate_flags); ARG_UINT64(OPT_KEYFILE_OFFSET_ID), activate_flags);
} else { } else {
key_size_max = (opt_key_file && !params.hash) ? key_size : (size_ t)opt_keyfile_size; key_size_max = (ARG_SET(OPT_KEY_FILE_ID) && !params.hash) ? key_s ize : ARG_UINT32(OPT_KEYFILE_SIZE_ID);
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, key_size_max, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), key_size_max
opt_key_file, opt_timeout, ,
ARG_STR(OPT_KEY_FILE_ID), ARG_UINT32(OPT_TIMEOU
T_ID),
_verify_passphrase(0), 0, cd); _verify_passphrase(0), 0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_activate_by_passphrase(cd, activated_name, r = crypt_activate_by_passphrase(cd, activated_name,
CRYPT_ANY_SLOT, password, passwordLen, activate_flags); CRYPT_ANY_SLOT, password, passwordLen, activate_flags);
} }
out: out:
crypt_free(cd); crypt_free(cd);
crypt_free(cd1); crypt_free(cd1);
crypt_safe_free(password); crypt_safe_free(password);
return r; return r;
} }
static int action_open_loopaes(void) static int action_open_loopaes(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_loopaes params = { struct crypt_params_loopaes params = {
.hash = opt_hash ?: NULL, .hash = ARG_STR(OPT_HASH_ID),
.offset = opt_offset, .offset = ARG_UINT64(OPT_OFFSET_ID),
.skip = opt_skip_valid ? opt_skip : opt_offset, .skip = ARG_SET(OPT_SKIP_ID) ? ARG_UINT64(OPT_SKIP_ID) : ARG_UINT
64(OPT_OFFSET_ID)
}; };
unsigned int key_size = (opt_key_size ?: DEFAULT_LOOPAES_KEYBITS) / 8; unsigned int key_size = (ARG_UINT32(OPT_KEY_SIZE_ID) ?: DEFAULT_LOOPAES_K EYBITS) / 8;
uint32_t activate_flags = 0; uint32_t activate_flags = 0;
const char *activated_name = NULL; const char *activated_name = NULL;
int r; int r;
if (!opt_key_file) { if (!ARG_SET(OPT_KEY_FILE_ID)) {
log_err(_("Option --key-file is required.")); log_err(_("Option --key-file is required."));
return -EINVAL; return -EINVAL;
} }
if (opt_refresh) { if (ARG_SET(OPT_REFRESH_ID)) {
activated_name = action_argc > 1 ? action_argv[1] : action_argv[0 ]; activated_name = action_argc > 1 ? action_argv[1] : action_argv[0 ];
if ((r = crypt_init_by_name(&cd, activated_name))) if ((r = crypt_init_by_name(&cd, activated_name)))
goto out; goto out;
activate_flags |= CRYPT_ACTIVATE_REFRESH; activate_flags |= CRYPT_ACTIVATE_REFRESH;
} else { } else {
activated_name = action_argv[1]; activated_name = action_argv[1];
if ((r = crypt_init(&cd, action_argv[0]))) if ((r = crypt_init(&cd, action_argv[0])))
goto out; goto out;
r = crypt_format(cd, CRYPT_LOOPAES, opt_cipher ?: DEFAULT_LOOPAES _CIPHER, r = crypt_format(cd, CRYPT_LOOPAES, ARG_STR(OPT_CIPHER_ID) ?: DEF AULT_LOOPAES_CIPHER,
NULL, NULL, NULL, key_size, &params); NULL, NULL, NULL, key_size, &params);
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
} }
_set_activation_flags(&activate_flags); _set_activation_flags(&activate_flags);
r = crypt_activate_by_keyfile_device_offset(cd, activated_name, CRYPT_ANY _SLOT, r = crypt_activate_by_keyfile_device_offset(cd, activated_name, CRYPT_ANY _SLOT,
tools_is_stdin(opt_key_file) ? "/dev/stdin" : opt_key_file, opt_k tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID)) ? "/dev/stdin" : ARG_STR
eyfile_size, (OPT_KEY_FILE_ID), ARG_UINT32(OPT_KEYFILE_SIZE_ID),
opt_keyfile_offset, activate_flags); ARG_UINT64(OPT_KEYFILE_OFFSET_ID), activate_flags);
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int tcrypt_load(struct crypt_device *cd, struct crypt_params_tcrypt *para ms) static int tcrypt_load(struct crypt_device *cd, struct crypt_params_tcrypt *para ms)
{ {
int r, tries = opt_tries, eperm = 0; int r, tries, eperm = 0;
if (opt_keyfile_stdin)
tries = 1;
tries = _set_tries_tty();
do { do {
/* TCRYPT header is encrypted, get passphrase now */ /* TCRYPT header is encrypted, get passphrase now */
r = tools_get_key(NULL, CONST_CAST(char**)&params->passphrase, r = tools_get_key(NULL, CONST_CAST(char**)&params->passphrase,
&params->passphrase_size, 0, 0, opt_keyfile_std in, opt_timeout, &params->passphrase_size, 0, 0, keyfile_stdin, ARG_UINT32(OPT_TIMEOUT_ID),
_verify_passphrase(0), 0, cd); _verify_passphrase(0), 0, cd);
if (r < 0) if (r < 0)
continue; continue;
if (opt_veracrypt_query_pim) { if (ARG_SET(OPT_VERACRYPT_QUERY_PIM_ID)) {
char *tmp_pim_nptr = NULL; char *tmp_pim_nptr = NULL;
char *tmp_pim_end = NULL; char *tmp_pim_end = NULL;
size_t tmp_pim_size = 0; size_t tmp_pim_size = 0;
unsigned long long tmp_pim_ull = 0; unsigned long long tmp_pim_ull = 0;
r = tools_get_key(_("Enter VeraCrypt PIM: "), r = tools_get_key(_("Enter VeraCrypt PIM: "),
&tmp_pim_nptr, &tmp_pim_nptr,
&tmp_pim_size, 0, 0, opt_keyfile_stdin, o pt_timeout, &tmp_pim_size, 0, 0, keyfile_stdin, ARG_U INT32(OPT_TIMEOUT_ID),
_verify_passphrase(0), 0, cd); _verify_passphrase(0), 0, cd);
if (r < 0) if (r < 0)
continue; continue;
tmp_pim_ull = strtoull(tmp_pim_nptr, &tmp_pim_end, 10); tmp_pim_ull = strtoull(tmp_pim_nptr, &tmp_pim_end, 10);
if (*tmp_pim_nptr == '\0' || !tmp_pim_end || *tmp_pim_end != '\0') { if (*tmp_pim_nptr == '\0' || !tmp_pim_end || *tmp_pim_end != '\0') {
log_err(_("Invalid PIM value: parse error.")); log_err(_("Invalid PIM value: parse error."));
r = -EINVAL; r = -EINVAL;
} else if (tmp_pim_ull == 0) { } else if (tmp_pim_ull == 0) {
log_err(_("Invalid PIM value: 0.")); log_err(_("Invalid PIM value: 0."));
skipping to change at line 500 skipping to change at line 452
r = -ERANGE; r = -ERANGE;
} }
crypt_safe_free(tmp_pim_nptr); crypt_safe_free(tmp_pim_nptr);
if (r < 0) if (r < 0)
continue; continue;
params->veracrypt_pim = (uint32_t)tmp_pim_ull; params->veracrypt_pim = (uint32_t)tmp_pim_ull;
crypt_safe_memzero(&tmp_pim_ull, sizeof(tmp_pim_ull)); crypt_safe_memzero(&tmp_pim_ull, sizeof(tmp_pim_ull));
} }
if (opt_tcrypt_hidden) if (ARG_SET(OPT_TCRYPT_HIDDEN_ID))
params->flags |= CRYPT_TCRYPT_HIDDEN_HEADER; params->flags |= CRYPT_TCRYPT_HIDDEN_HEADER;
if (opt_tcrypt_system) if (ARG_SET(OPT_TCRYPT_SYSTEM_ID))
params->flags |= CRYPT_TCRYPT_SYSTEM_HEADER; params->flags |= CRYPT_TCRYPT_SYSTEM_HEADER;
if (opt_tcrypt_backup) if (ARG_SET(OPT_TCRYPT_BACKUP_ID))
params->flags |= CRYPT_TCRYPT_BACKUP_HEADER; params->flags |= CRYPT_TCRYPT_BACKUP_HEADER;
r = crypt_load(cd, CRYPT_TCRYPT, params); r = crypt_load(cd, CRYPT_TCRYPT, params);
if (r == -EPERM) { if (r == -EPERM) {
log_err(_("No device header detected with this passphrase .")); log_err(_("No device header detected with this passphrase ."));
eperm = 1; eperm = 1;
} }
if (r < 0) { if (r < 0) {
skipping to change at line 535 skipping to change at line 487
if (eperm && r == -EPIPE) if (eperm && r == -EPIPE)
r = -EPERM; r = -EPERM;
return r; return r;
} }
static int action_open_tcrypt(void) static int action_open_tcrypt(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_tcrypt params = { struct crypt_params_tcrypt params = {
.keyfiles = CONST_CAST(const char **)opt_keyfiles, .keyfiles = CONST_CAST(const char **)keyfiles,
.keyfiles_count = opt_keyfiles_count, .keyfiles_count = keyfiles_count,
.flags = CRYPT_TCRYPT_LEGACY_MODES | .flags = CRYPT_TCRYPT_LEGACY_MODES |
(opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0), (ARG_SET(OPT_DISABLE_VERACRYPT_ID) ? 0 : CRYPT_TCRYPT_VE
.veracrypt_pim = (opt_veracrypt_pim > 0) ? opt_veracrypt_pim : 0, RA_MODES),
.veracrypt_pim = ARG_UINT32(OPT_VERACRYPT_PIM_ID),
.hash_name = ARG_STR(OPT_HASH_ID),
.cipher = ARG_STR(OPT_CIPHER_ID),
}; };
const char *activated_name; const char *activated_name;
uint32_t activate_flags = 0; uint32_t activate_flags = 0;
int r; int r;
activated_name = opt_test_passphrase ? NULL : action_argv[1]; activated_name = ARG_SET(OPT_TEST_PASSPHRASE_ID) ? NULL : action_argv[1];
r = crypt_init_data_device(&cd, opt_header_device ?: action_argv[0], acti on_argv[0]); r = crypt_init_data_device(&cd, ARG_STR(OPT_HEADER_ID) ?: action_argv[0], action_argv[0]);
if (r < 0) if (r < 0)
goto out; goto out;
r = tcrypt_load(cd, &params); r = tcrypt_load(cd, &params);
if (r < 0) if (r < 0)
goto out; goto out;
_set_activation_flags(&activate_flags); _set_activation_flags(&activate_flags);
if (activated_name) if (activated_name)
skipping to change at line 571 skipping to change at line 525
crypt_safe_free(CONST_CAST(char*)params.passphrase); crypt_safe_free(CONST_CAST(char*)params.passphrase);
crypt_safe_memzero(&params.veracrypt_pim, sizeof(params.veracrypt_pim)); crypt_safe_memzero(&params.veracrypt_pim, sizeof(params.veracrypt_pim));
return r; return r;
} }
static int action_open_bitlk(void) static int action_open_bitlk(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
const char *activated_name; const char *activated_name;
uint32_t activate_flags = 0; uint32_t activate_flags = 0;
int r, tries; int r, tries, keysize;
char *password = NULL; char *password = NULL;
char *key = NULL;
size_t passwordLen; size_t passwordLen;
activated_name = opt_test_passphrase ? NULL : action_argv[1]; activated_name = ARG_SET(OPT_TEST_PASSPHRASE_ID) ? NULL : action_argv[1];
if ((r = crypt_init(&cd, action_argv[0]))) if ((r = crypt_init(&cd, action_argv[0])))
goto out; goto out;
r = crypt_load(cd, CRYPT_BITLK, NULL); r = crypt_load(cd, CRYPT_BITLK, NULL);
if (r < 0) { if (r < 0) {
log_err(_("Device %s is not a valid BITLK device."), action_argv[ 0]); log_err(_("Device %s is not a valid BITLK device."), action_argv[ 0]);
goto out; goto out;
} }
_set_activation_flags(&activate_flags); _set_activation_flags(&activate_flags);
tries = (tools_is_stdin(opt_key_file) && isatty(STDIN_FILENO)) ? opt_trie if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
s : 1; keysize = crypt_get_volume_key_size(cd);
do { if (!keysize && !ARG_SET(OPT_KEY_SIZE_ID)) {
r = tools_get_key(NULL, &password, &passwordLen, log_err(_("Cannot determine volume key size for BITLK, pl
opt_keyfile_offset, opt_keyfile_size, opt_key_fil ease use --key-size option."));
e, r = -EINVAL;
opt_timeout, _verify_passphrase(0), 0, cd); goto out;
} else if (!keysize)
keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize)
;
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_activate_by_volume_key(cd, activated_name,
key, keysize, activate_flags);
} else {
tries = _set_tries_tty();
do {
r = tools_get_key(NULL, &password, &passwordLen,
ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UI
NT32(OPT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passp
hrase(0), 0, cd);
if (r < 0)
goto out;
r = crypt_activate_by_passphrase(cd, activated_name, CRYPT_ANY_SL r = crypt_activate_by_passphrase(cd, activated_name, CRYP
OT, T_ANY_SLOT,
password, passwordLen, activate_ password, passwordLen, ac
flags); tivate_flags);
tools_passphrase_msg(r); tools_passphrase_msg(r);
check_signal(&r); check_signal(&r);
crypt_safe_free(password); crypt_safe_free(password);
password = NULL; password = NULL;
} while ((r == -EPERM || r == -ERANGE) && (--tries > 0)); } while ((r == -EPERM || r == -ERANGE) && (--tries > 0));
}
out: out:
crypt_safe_free(password); crypt_safe_free(password);
crypt_safe_free(key);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int tcryptDump_with_volume_key(struct crypt_device *cd) static int tcryptDump_with_volume_key(struct crypt_device *cd)
{ {
char *vk = NULL; char *vk = NULL;
size_t vk_size; size_t vk_size;
unsigned i; unsigned i;
int r; int r;
crypt_set_confirm_callback(cd, yesDialog, NULL); if (!ARG_SET(OPT_BATCH_MODE_ID) && !yesDialog(
if (!yesDialog(
_("Header dump with volume key is sensitive information\n" _("Header dump with volume key is sensitive information\n"
"which allows access to encrypted partition without passphrase.\n" "which allows access to encrypted partition without passphrase.\n"
"This dump should be always stored encrypted on safe place."), "This dump should be always stored encrypted on safe place."),
NULL)) NULL))
return -EPERM; return -EPERM;
vk_size = crypt_get_volume_key_size(cd); vk_size = crypt_get_volume_key_size(cd);
vk = crypt_safe_alloc(vk_size); vk = crypt_safe_alloc(vk_size);
if (!vk) if (!vk)
return -ENOMEM; return -ENOMEM;
skipping to change at line 654 skipping to change at line 625
log_std("\n"); log_std("\n");
out: out:
crypt_safe_free(vk); crypt_safe_free(vk);
return r; return r;
} }
static int action_tcryptDump(void) static int action_tcryptDump(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_tcrypt params = { struct crypt_params_tcrypt params = {
.keyfiles = CONST_CAST(const char **)opt_keyfiles, .keyfiles = CONST_CAST(const char **)keyfiles,
.keyfiles_count = opt_keyfiles_count, .keyfiles_count = keyfiles_count,
.flags = CRYPT_TCRYPT_LEGACY_MODES | .flags = CRYPT_TCRYPT_LEGACY_MODES |
(opt_veracrypt ? CRYPT_TCRYPT_VERA_MODES : 0), (ARG_SET(OPT_DISABLE_VERACRYPT_ID) ? 0: CRYPT_TCRYPT_VER
.veracrypt_pim = (opt_veracrypt_pim > 0) ? opt_veracrypt_pim : 0, A_MODES),
.veracrypt_pim = ARG_UINT32(OPT_VERACRYPT_PIM_ID),
.hash_name = ARG_STR(OPT_HASH_ID),
.cipher = ARG_STR(OPT_CIPHER_ID),
}; };
int r; int r;
r = crypt_init_data_device(&cd, opt_header_device ?: action_argv[0], acti on_argv[0]); r = crypt_init_data_device(&cd, ARG_STR(OPT_HEADER_ID) ?: action_argv[0], action_argv[0]);
if (r < 0) if (r < 0)
goto out; goto out;
r = tcrypt_load(cd, &params); r = tcrypt_load(cd, &params);
if (r < 0) if (r < 0)
goto out; goto out;
if (opt_dump_master_key) if (ARG_SET(OPT_DUMP_MASTER_KEY_ID))
r = tcryptDump_with_volume_key(cd); r = tcryptDump_with_volume_key(cd);
else else
r = crypt_dump(cd); r = crypt_dump(cd);
out: out:
crypt_free(cd); crypt_free(cd);
crypt_safe_free(CONST_CAST(char*)params.passphrase); crypt_safe_free(CONST_CAST(char*)params.passphrase);
return r; return r;
} }
static int bitlkDump_with_volume_key(struct crypt_device *cd)
{
char *vk = NULL, *password = NULL;
size_t passwordLen = 0;
size_t vk_size;
unsigned i;
int r;
if (!yesDialog(
_("The header dump with volume key is sensitive information\n"
"that allows access to encrypted partition without a passphrase.\n"
"This dump should be stored encrypted in a safe place."),
NULL))
return -EPERM;
vk_size = crypt_get_volume_key_size(cd);
vk = crypt_safe_alloc(vk_size);
if (!vk)
return -ENOMEM;
r = tools_get_key(NULL, &password, &passwordLen,
ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFI
LE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), 0, 0, cd);
if (r < 0)
goto out;
r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, vk, &vk_size,
password, passwordLen);
tools_passphrase_msg(r);
check_signal(&r);
if (r < 0)
goto out;
tools_keyslot_msg(r, UNLOCKED);
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
r = tools_write_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), vk, vk_size);
if (r < 0)
goto out;
}
log_std("BITLK header information for %s\n", crypt_get_device_name(cd));
log_std("Cipher name: \t%s\n", crypt_get_cipher(cd));
log_std("Cipher mode: \t%s\n", crypt_get_cipher_mode(cd));
log_std("UUID: \t%s\n", crypt_get_uuid(cd));
log_std("MK bits: \t%d\n", (int)vk_size * 8);
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
log_std("Key stored to file %s.\n", ARG_STR(OPT_MASTER_KEY_FILE_I
D));
goto out;
}
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(password);
crypt_safe_free(vk);
return r;
}
static int action_bitlkDump(void) static int action_bitlkDump(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
if ((r = crypt_init(&cd, action_argv[0]))) if ((r = crypt_init(&cd, action_argv[0])))
goto out; goto out;
r = crypt_load(cd, CRYPT_BITLK, NULL); r = crypt_load(cd, CRYPT_BITLK, NULL);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_dump(cd); if (ARG_SET(OPT_DUMP_MASTER_KEY_ID))
r = bitlkDump_with_volume_key(cd);
else
r = crypt_dump(cd);
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_close(void) static int action_close(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
crypt_status_info ci; crypt_status_info ci;
uint32_t flags = 0; uint32_t flags = 0;
int r; int r;
if (opt_deferred_remove) if (ARG_SET(OPT_DEFERRED_ID))
flags |= CRYPT_DEACTIVATE_DEFERRED; flags |= CRYPT_DEACTIVATE_DEFERRED;
if (ARG_SET(OPT_CANCEL_DEFERRED_ID))
flags |= CRYPT_DEACTIVATE_DEFERRED_CANCEL;
r = crypt_init_by_name(&cd, action_argv[0]); r = crypt_init_by_name(&cd, action_argv[0]);
if (r == 0) if (r == 0)
r = crypt_deactivate_by_name(cd, action_argv[0], flags); r = crypt_deactivate_by_name(cd, action_argv[0], flags);
if (!r && opt_deferred_remove) { if (!r && ARG_SET(OPT_DEFERRED_ID)) {
ci = crypt_status(cd, action_argv[0]); ci = crypt_status(cd, action_argv[0]);
if (ci == CRYPT_ACTIVE || ci == CRYPT_BUSY) if (ci == CRYPT_ACTIVE || ci == CRYPT_BUSY)
log_std(_("Device %s is still active and scheduled for de ferred removal.\n"), log_std(_("Device %s is still active and scheduled for de ferred removal.\n"),
action_argv[0]); action_argv[0]);
} }
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_resize(void) static int action_resize(void)
{ {
int r; int r;
size_t passwordLen; size_t passwordLen;
struct crypt_active_device cad; struct crypt_active_device cad;
uint64_t dev_size = 0;
char *password = NULL; char *password = NULL;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header_device) ; r = crypt_init_by_name_and_header(&cd, action_argv[0], ARG_STR(OPT_HEADER _ID));
if (r) if (r)
goto out; goto out;
/* FIXME: LUKS2 may enforce fixed size and it must not be changed */ /* FIXME: LUKS2 may enforce fixed size and it must not be changed */
r = crypt_get_active_device(cd, action_argv[0], &cad); r = crypt_get_active_device(cd, action_argv[0], &cad);
if (r) if (r)
goto out; goto out;
if (ARG_SET(OPT_DEVICE_SIZE_ID))
dev_size = ARG_UINT64(OPT_DEVICE_SIZE_ID) / SECTOR_SIZE;
else if (ARG_SET(OPT_SIZE_ID))
dev_size = ARG_UINT64(OPT_SIZE_ID);
if (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) { if (cad.flags & CRYPT_ACTIVATE_KEYRING_KEY) {
if (opt_disable_keyring) { if (ARG_SET(OPT_DISABLE_KEYRING_ID)) {
r = -EINVAL; r = -EINVAL;
log_err(_("Resize of active device requires volume key " log_err(_("Resize of active device requires volume key "
"in keyring but --disable-keyring option is set .")); "in keyring but --disable-keyring option is set ."));
goto out; goto out;
} }
/* try load VK in kernel keyring using token */ /* try load VK in kernel keyring using token */
r = crypt_activate_by_token(cd, NULL, opt_token, NULL, r = crypt_activate_by_token_pin(cd, NULL, ARG_STR(OPT_TOKEN_TYPE_
CRYPT_ACTIVATE_KEYRING_KEY); ID),
ARG_INT32(OPT_TOKEN_ID_ID), NULL,
0, NULL,
CRYPT_ACTIVATE_KEYRING_KEY);
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
if (r >= 0) tools_token_error_msg(r, ARG_STR(OPT_TOKEN_TYPE_ID), ARG_INT32(OP
goto resize; T_TOKEN_ID_ID), false);
else if (opt_token_only)
/* Token requires PIN, but ask only if there is no password query
later */
if (ARG_SET(OPT_TOKEN_ONLY_ID) && r == -ENOANO)
r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID),
NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY, 1);
if (r >= 0 || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out; goto out;
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_f ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(O
ile, PT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
opt_timeout, _verify_passphrase(0), 0, cd); ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(
0), 0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_activate_by_passphrase(cd, NULL, opt_key_slot, r = crypt_activate_by_passphrase(cd, NULL, ARG_INT32(OPT_KEY_SLOT _ID),
password, passwordLen, password, passwordLen,
CRYPT_ACTIVATE_KEYRING_KEY); CRYPT_ACTIVATE_KEYRING_KEY);
tools_passphrase_msg(r); tools_passphrase_msg(r);
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
crypt_safe_free(password);
} }
resize:
if (opt_device_size)
opt_size = opt_device_size / SECTOR_SIZE;
if (r >= 0)
r = crypt_resize(cd, action_argv[0], opt_size);
out: out:
if (r >= 0)
r = crypt_resize(cd, action_argv[0], dev_size);
crypt_safe_free(password);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_status(void) static int action_status(void)
{ {
crypt_status_info ci; crypt_status_info ci;
crypt_reencrypt_info ri; crypt_reencrypt_info ri;
struct crypt_active_device cad; struct crypt_active_device cad;
struct crypt_params_integrity ip = {}; struct crypt_params_integrity ip = {};
skipping to change at line 816 skipping to change at line 867
break; break;
case CRYPT_ACTIVE: case CRYPT_ACTIVE:
case CRYPT_BUSY: case CRYPT_BUSY:
if (path) if (path)
log_std("%s is active%s.\n", action_argv[0], log_std("%s is active%s.\n", action_argv[0],
ci == CRYPT_BUSY ? " and is in use" : ""); ci == CRYPT_BUSY ? " and is in use" : "");
else else
log_std("%s/%s is active%s.\n", crypt_get_dir(), action_a rgv[0], log_std("%s/%s is active%s.\n", crypt_get_dir(), action_a rgv[0],
ci == CRYPT_BUSY ? " and is in use" : ""); ci == CRYPT_BUSY ? " and is in use" : "");
r = crypt_init_by_name_and_header(&cd, action_argv[0], opt_header _device); r = crypt_init_by_name_and_header(&cd, action_argv[0], ARG_STR(OP T_HEADER_ID));
if (r < 0) if (r < 0)
goto out; goto out;
log_std(" type: %s\n", crypt_get_type(cd) ?: "n/a"); log_std(" type: %s\n", crypt_get_type(cd) ?: "n/a");
/* Print only CRYPT type devices */ /* Print only CRYPT type devices */
if (!crypt_get_cipher(cd)) if (!crypt_get_cipher(cd))
goto out; goto out;
ri = crypt_reencrypt_status(cd, NULL); ri = crypt_reencrypt_status(cd, NULL);
skipping to change at line 913 skipping to change at line 964
r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3, "bar", 3, key_s ize, r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3, "bar", 3, key_s ize,
&benchmark_callback, &pbkdf); &benchmark_callback, &pbkdf);
if (r < 0) if (r < 0)
log_std(_("PBKDF2-%-9s N/A\n"), hash); log_std(_("PBKDF2-%-9s N/A\n"), hash);
else else
log_std(_("PBKDF2-%-9s %7u iterations per second for %zu- bit key\n"), log_std(_("PBKDF2-%-9s %7u iterations per second for %zu- bit key\n"),
hash, pbkdf.iterations, key_size * 8); hash, pbkdf.iterations, key_size * 8);
} else { } else {
struct crypt_pbkdf_type pbkdf = { struct crypt_pbkdf_type pbkdf = {
.type = kdf, .type = kdf,
.time_ms = opt_iteration_time ?: DEFAULT_LUKS2_ITER_TIME, .time_ms = ARG_UINT32(OPT_ITER_TIME_ID) ?: DEFAULT_LUKS2_
.max_memory_kb = opt_pbkdf_memory, ITER_TIME,
.parallel_threads = opt_pbkdf_parallel, .max_memory_kb = ARG_UINT32(OPT_PBKDF_MEMORY_ID),
.parallel_threads = ARG_UINT32(OPT_PBKDF_PARALLEL_ID)
}; };
r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3, r = crypt_benchmark_pbkdf(NULL, &pbkdf, "foo", 3,
"0123456789abcdef0123456789abcdef", 32, "0123456789abcdef0123456789abcdef", 32,
key_size, &benchmark_callback, &pbkdf); key_size, &benchmark_callback, &pbkdf);
if (r < 0) if (r < 0)
log_std(_("%-10s N/A\n"), kdf); log_std(_("%-10s N/A\n"), kdf);
else else
log_std(_("%-10s %4u iterations, %5u memory, " log_std(_("%-10s %4u iterations, %5u memory, "
"%1u parallel threads (CPUs) for " "%1u parallel threads (CPUs) for "
skipping to change at line 993 skipping to change at line 1044
{ CRYPT_KDF_PBKDF2, "sha256" }, { CRYPT_KDF_PBKDF2, "sha256" },
{ CRYPT_KDF_PBKDF2, "sha512" }, { CRYPT_KDF_PBKDF2, "sha512" },
{ CRYPT_KDF_PBKDF2, "ripemd160" }, { CRYPT_KDF_PBKDF2, "ripemd160" },
{ CRYPT_KDF_PBKDF2, "whirlpool" }, { CRYPT_KDF_PBKDF2, "whirlpool" },
{ CRYPT_KDF_ARGON2I, NULL }, { CRYPT_KDF_ARGON2I, NULL },
{ CRYPT_KDF_ARGON2ID, NULL }, { CRYPT_KDF_ARGON2ID, NULL },
{ NULL, NULL } { NULL, NULL }
}; };
char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN]; char cipher[MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN];
double enc_mbr = 0, dec_mbr = 0; double enc_mbr = 0, dec_mbr = 0;
int key_size = (opt_key_size ?: DEFAULT_PLAIN_KEYBITS) / 8; int key_size = (ARG_UINT32(OPT_KEY_SIZE_ID) ?: DEFAULT_PLAIN_KEYBITS) / 8 ;
int skipped = 0, width; int skipped = 0, width;
char *c; char *c;
int i, r; int i, r;
log_std(_("# Tests are approximate using memory only (no storage IO).\n") ); log_std(_("# Tests are approximate using memory only (no storage IO).\n") );
if (set_pbkdf || opt_hash) { if (set_pbkdf || ARG_SET(OPT_HASH_ID)) {
if (!set_pbkdf && opt_hash) if (!set_pbkdf && ARG_SET(OPT_HASH_ID))
set_pbkdf = CRYPT_KDF_PBKDF2; set_pbkdf = CRYPT_KDF_PBKDF2;
r = action_benchmark_kdf(set_pbkdf, opt_hash, key_size); r = action_benchmark_kdf(set_pbkdf, ARG_STR(OPT_HASH_ID), key_siz
} else if (opt_cipher) { e);
r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, cipher_mo } else if (ARG_SET(OPT_CIPHER_ID)) {
de); r = crypt_parse_name_and_mode(ARG_STR(OPT_CIPHER_ID), cipher, NUL
L, cipher_mode);
if (r < 0) { if (r < 0) {
log_err(_("No known cipher specification pattern detected .")); log_err(_("No known cipher specification pattern detected ."));
return r; return r;
} }
if ((c = strchr(cipher_mode, '-'))) if ((c = strchr(cipher_mode, '-')))
*c = '\0'; *c = '\0';
r = benchmark_cipher_loop(cipher, cipher_mode, key_size, &enc_mbr , &dec_mbr); r = benchmark_cipher_loop(cipher, cipher_mode, key_size, &enc_mbr , &dec_mbr);
if (!r) { if (!r) {
width = strlen(cipher) + strlen(cipher_mode) + 1; width = strlen(cipher) + strlen(cipher_mode) + 1;
if (width < 11) if (width < 11)
width = 11; width = 11;
/* TRANSLATORS: The string is header of a table and must be exactly (right side) aligned. */ /* TRANSLATORS: The string is header of a table and must be exactly (right side) aligned. */
log_std(_("#%*s Algorithm | Key | Encryption | Decryption\n"), width - 11, ""); log_std(_("#%*s Algorithm | Key | Encryption | Decryption\n"), width - 11, "");
log_std("%*s-%s %9db %10.1f MiB/s %10.1f MiB/s\n", wid th - (int)strlen(cipher_mode) - 1, log_std("%*s-%s %9db %10.1f MiB/s %10.1f MiB/s\n", wid th - (int)strlen(cipher_mode) - 1,
cipher, cipher_mode, key_size*8, enc_mbr, dec_mbr ); cipher, cipher_mode, key_size*8, enc_mbr, dec_mbr );
} else if (r < 0) } else if (r < 0)
log_err(_("Cipher %s (with %i bits key) is not available. "), opt_cipher, key_size * 8); log_err(_("Cipher %s (with %i bits key) is not available. "), ARG_STR(OPT_CIPHER_ID), key_size * 8);
} else { } else {
for (i = 0; bkdfs[i].type; i++) { for (i = 0; bkdfs[i].type; i++) {
r = action_benchmark_kdf(bkdfs[i].type, bkdfs[i].hash, ke y_size); r = action_benchmark_kdf(bkdfs[i].type, bkdfs[i].hash, ke y_size);
check_signal(&r); check_signal(&r);
if (r == -EINTR) if (r == -EINTR)
break; break;
} }
for (i = 0; bciphers[i].cipher; i++) { for (i = 0; bciphers[i].cipher; i++) {
r = benchmark_cipher_loop(bciphers[i].cipher, bciphers[i] .mode, r = benchmark_cipher_loop(bciphers[i].cipher, bciphers[i] .mode,
skipping to change at line 1077 skipping to change at line 1128
static int set_pbkdf_params(struct crypt_device *cd, const char *dev_type) static int set_pbkdf_params(struct crypt_device *cd, const char *dev_type)
{ {
const struct crypt_pbkdf_type *pbkdf_default; const struct crypt_pbkdf_type *pbkdf_default;
struct crypt_pbkdf_type pbkdf = {}; struct crypt_pbkdf_type pbkdf = {};
pbkdf_default = crypt_get_pbkdf_default(dev_type); pbkdf_default = crypt_get_pbkdf_default(dev_type);
if (!pbkdf_default) if (!pbkdf_default)
return -EINVAL; return -EINVAL;
pbkdf.type = set_pbkdf ?: pbkdf_default->type; pbkdf.type = set_pbkdf ?: pbkdf_default->type;
pbkdf.hash = opt_hash ?: pbkdf_default->hash; pbkdf.hash = ARG_STR(OPT_HASH_ID) ?: pbkdf_default->hash;
pbkdf.time_ms = (uint32_t)opt_iteration_time ?: pbkdf_default->time_ms; pbkdf.time_ms = ARG_UINT32(OPT_ITER_TIME_ID) ?: pbkdf_default->time_ms;
if (strcmp(pbkdf.type, CRYPT_KDF_PBKDF2)) { if (strcmp(pbkdf.type, CRYPT_KDF_PBKDF2)) {
pbkdf.max_memory_kb = (uint32_t)opt_pbkdf_memory ?: pbkdf_default pbkdf.max_memory_kb = ARG_UINT32(OPT_PBKDF_MEMORY_ID) ?: pbkdf_de
->max_memory_kb; fault->max_memory_kb;
pbkdf.parallel_threads = (uint32_t)opt_pbkdf_parallel ?: pbkdf_de pbkdf.parallel_threads = ARG_UINT32(OPT_PBKDF_PARALLEL_ID) ?: pbk
fault->parallel_threads; df_default->parallel_threads;
} }
if (opt_pbkdf_iterations) { if (ARG_SET(OPT_PBKDF_FORCE_ITERATIONS_ID)) {
pbkdf.iterations = opt_pbkdf_iterations; pbkdf.iterations = ARG_UINT32(OPT_PBKDF_FORCE_ITERATIONS_ID);
pbkdf.time_ms = 0; pbkdf.time_ms = 0;
pbkdf.flags |= CRYPT_PBKDF_NO_BENCHMARK; pbkdf.flags |= CRYPT_PBKDF_NO_BENCHMARK;
} }
return crypt_set_pbkdf_type(cd, &pbkdf); return crypt_set_pbkdf_type(cd, &pbkdf);
} }
static int set_keyslot_params(struct crypt_device *cd, int keyslot) static int set_keyslot_params(struct crypt_device *cd, int keyslot)
{ {
const char *cipher; const char *cipher;
skipping to change at line 1113 skipping to change at line 1164
if (crypt_is_cipher_null(cipher)) { if (crypt_is_cipher_null(cipher)) {
log_dbg("Keyslot %d uses cipher_null. Replacing with default encr yption in new keyslot.", keyslot); log_dbg("Keyslot %d uses cipher_null. Replacing with default encr yption in new keyslot.", keyslot);
cipher = DEFAULT_LUKS2_KEYSLOT_CIPHER; cipher = DEFAULT_LUKS2_KEYSLOT_CIPHER;
key_size = DEFAULT_LUKS2_KEYSLOT_KEYBITS / 8; key_size = DEFAULT_LUKS2_KEYSLOT_KEYBITS / 8;
} }
if (crypt_keyslot_set_encryption(cd, cipher, key_size)) if (crypt_keyslot_set_encryption(cd, cipher, key_size))
return -EINVAL; return -EINVAL;
/* if requested any of those just reinitialize context pbkdf */ /* if requested any of those just reinitialize context pbkdf */
if (set_pbkdf || opt_hash || opt_pbkdf_iterations || opt_iteration_time) if (set_pbkdf || ARG_SET(OPT_HASH_ID) || ARG_SET(OPT_PBKDF_FORCE_ITERATIO NS_ID) || ARG_SET(OPT_ITER_TIME_ID))
return set_pbkdf_params(cd, CRYPT_LUKS2); return set_pbkdf_params(cd, CRYPT_LUKS2);
if (crypt_keyslot_get_pbkdf(cd, keyslot, &pbkdf)) if (crypt_keyslot_get_pbkdf(cd, keyslot, &pbkdf))
return -EINVAL; return -EINVAL;
pbkdf.flags |= CRYPT_PBKDF_NO_BENCHMARK; pbkdf.flags |= CRYPT_PBKDF_NO_BENCHMARK;
return crypt_set_pbkdf_type(cd, &pbkdf); return crypt_set_pbkdf_type(cd, &pbkdf);
} }
skipping to change at line 1138 skipping to change at line 1189
char *password = NULL; char *password = NULL;
struct crypt_params_reencrypt recovery_params = { struct crypt_params_reencrypt recovery_params = {
.flags = CRYPT_REENCRYPT_RECOVERY .flags = CRYPT_REENCRYPT_RECOVERY
}; };
crypt_reencrypt_info ri = crypt_reencrypt_status(cd, NULL); crypt_reencrypt_info ri = crypt_reencrypt_status(cd, NULL);
switch (ri) { switch (ri) {
case CRYPT_REENCRYPT_NONE: case CRYPT_REENCRYPT_NONE:
/* fall through */ /* fall through */
case CRYPT_REENCRYPT_CLEAN: case CRYPT_REENCRYPT_CLEAN:
r = noDialog(_("Seems device does not require reencryption recove if (ARG_SET(OPT_BATCH_MODE_ID) ||
ry.\n" !noDialog(_("Seems device does not require reencryption recov
"Do you want to proceed anyway?"), NULL); ery.\n"
if (!r) "Do you want to proceed anyway?"), NULL))
return 0; return 0;
break; break;
case CRYPT_REENCRYPT_CRASH: case CRYPT_REENCRYPT_CRASH:
r = yesDialog(_("Really proceed with LUKS2 reencryption recovery? if (!ARG_SET(OPT_BATCH_MODE_ID) &&
"), !yesDialog(_("Really proceed with LUKS2 reencryption recovery
_("Operation aborted.\n")); ?"),
if (!r) _("Operation aborted.\n")))
return -EINVAL; return -EINVAL;
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
r = tools_get_key(_("Enter passphrase for reencryption recovery: "), r = tools_get_key(_("Enter passphrase for reencryption recovery: "),
&password, &passwordLen, opt_keyfile_offset, &password, &passwordLen, ARG_UINT64(OPT_KEYFILE_OFFSET_
opt_keyfile_size, opt_key_file, opt_timeout, ID),
ARG_UINT32(OPT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_I
D), ARG_UINT32(OPT_TIMEOUT_ID),
_verify_passphrase(0), 0, cd); _verify_passphrase(0), 0, cd);
if (r < 0) if (r < 0)
return r; return r;
r = crypt_activate_by_passphrase(cd, NULL, opt_key_slot, r = crypt_activate_by_passphrase(cd, NULL, ARG_INT32(OPT_KEY_SLOT_ID),
password, passwordLen, 0); password, passwordLen, 0);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_reencrypt_init_by_passphrase(cd, NULL, password, passwordLen, r = crypt_reencrypt_init_by_passphrase(cd, NULL, password, passwordLen,
opt_key_slot, opt_key_slot, NULL, NULL, &recovery_params) ; ARG_INT32(OPT_KEY_SLOT_ID), ARG_INT32(OPT_KEY_SLOT_ID), N ULL, NULL, &recovery_params);
if (r > 0) if (r > 0)
r = 0; r = 0;
out: out:
crypt_safe_free(password); crypt_safe_free(password);
return r; return r;
} }
static int action_luksRepair(void) static int action_luksRepair(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
if ((r = crypt_init_data_device(&cd, opt_header_device ?: action_argv[0], if ((r = crypt_init_data_device(&cd, ARG_STR(OPT_HEADER_ID) ?: action_arg v[0],
action_argv[0]))) action_argv[0])))
goto out; goto out;
crypt_set_log_callback(cd, quiet_log, NULL); crypt_set_log_callback(cd, quiet_log, &log_parms);
r = crypt_load(cd, luksType(device_type), NULL); r = crypt_load(cd, luksType(device_type), NULL);
crypt_set_log_callback(cd, tool_log, NULL); crypt_set_log_callback(cd, tool_log, &log_parms);
if (r == 0) { if (r == 0) {
log_verbose(_("No known problems detected for LUKS header.")); log_verbose(_("No known problems detected for LUKS header."));
goto skip_repair; goto out;
} }
r = tools_detect_signatures(action_argv[0], 1, NULL); r = tools_detect_signatures(action_argv[0], 1, NULL, ARG_SET(OPT_BATCH_MO DE_ID));
if (r < 0) if (r < 0)
goto out; goto out;
r = yesDialog(_("Really try to repair LUKS device header?"), if (!ARG_SET(OPT_BATCH_MODE_ID) &&
_("Operation aborted.\n")) ? 0 : -EINVAL; !yesDialog(_("Really try to repair LUKS device header?"),
if (r == 0) _("Operation aborted.\n")))
r = -EINVAL;
else
r = crypt_repair(cd, luksType(device_type), NULL); r = crypt_repair(cd, luksType(device_type), NULL);
skip_repair:
if (!r && crypt_get_type(cd) && !strcmp(crypt_get_type(cd), CRYPT_LUKS2))
r = _do_luks2_reencrypt_recovery(cd);
out: out:
/* Header is ok, check if possible interrupted reencryption need repairs.
*/
if (!r && isLUKS2(crypt_get_type(cd)))
r = _do_luks2_reencrypt_recovery(cd);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int _wipe_data_device(struct crypt_device *cd) static int _wipe_data_device(struct crypt_device *cd)
{ {
char tmp_name[64], tmp_path[128], tmp_uuid[40]; char tmp_name[64], tmp_path[128], tmp_uuid[40];
uuid_t tmp_uuid_bin; uuid_t tmp_uuid_bin;
int r; int r;
struct tools_progress_params prog_parms = {
.frequency = ARG_UINT32(OPT_PROGRESS_FREQUENCY_ID),
.batch_mode = ARG_SET(OPT_BATCH_MODE_ID)
};
if (!opt_batch_mode) if (!ARG_SET(OPT_BATCH_MODE_ID))
log_std(_("Wiping device to initialize integrity checksum.\n" log_std(_("Wiping device to initialize integrity checksum.\n"
"You can interrupt this by pressing CTRL+c " "You can interrupt this by pressing CTRL+c "
"(rest of not wiped device will contain invalid checksum) .\n")); "(rest of not wiped device will contain invalid checksum) .\n"));
/* Activate the device a temporary one */ /* Activate the device a temporary one */
uuid_generate(tmp_uuid_bin); uuid_generate(tmp_uuid_bin);
uuid_unparse(tmp_uuid_bin, tmp_uuid); uuid_unparse(tmp_uuid_bin, tmp_uuid);
if (snprintf(tmp_name, sizeof(tmp_name), "temporary-cryptsetup-%s", tmp_u uid) < 0) if (snprintf(tmp_name, sizeof(tmp_name), "temporary-cryptsetup-%s", tmp_u uid) < 0)
return -EINVAL; return -EINVAL;
if (snprintf(tmp_path, sizeof(tmp_path), "%s/%s", crypt_get_dir(), tmp_na me) < 0) if (snprintf(tmp_path, sizeof(tmp_path), "%s/%s", crypt_get_dir(), tmp_na me) < 0)
return -EINVAL; return -EINVAL;
r = crypt_activate_by_volume_key(cd, tmp_name, NULL, 0, r = crypt_activate_by_volume_key(cd, tmp_name, NULL, 0,
CRYPT_ACTIVATE_PRIVATE | CRYPT_ACTIVATE_NO_JOURNAL); CRYPT_ACTIVATE_PRIVATE | CRYPT_ACTIVATE_NO_JOURNAL);
if (r < 0) if (r < 0)
return r; return r;
/* Wipe the device */ /* Wipe the device */
set_int_handler(0); set_int_handler(0);
r = crypt_wipe(cd, tmp_path, CRYPT_WIPE_ZERO, 0, 0, DEFAULT_WIPE_BLOCK, r = crypt_wipe(cd, tmp_path, CRYPT_WIPE_ZERO, 0, 0, DEFAULT_WIPE_BLOCK,
0, &tools_wipe_progress, NULL); 0, &tools_wipe_progress, &prog_parms);
if (crypt_deactivate(cd, tmp_name)) if (crypt_deactivate(cd, tmp_name))
log_err(_("Cannot deactivate temporary device %s."), tmp_path); log_err(_("Cannot deactivate temporary device %s."), tmp_path);
set_int_block(0); set_int_block(0);
return r; return r;
} }
static int strcmp_or_null(const char *str, const char *expected) static int strcmp_or_null(const char *str, const char *expected)
{ {
return !str ? 0 : strcmp(str, expected); return !str ? 0 : strcmp(str, expected);
} }
static int get_adjusted_key_size(const char *cipher_mode, uint32_t default_size_ bits, int integrity_keysize) static int get_adjusted_key_size(const char *cipher_mode, uint32_t default_size_ bits, int integrity_keysize)
{ {
uint32_t keysize_bits = opt_key_size; uint32_t keysize_bits = ARG_UINT32(OPT_KEY_SIZE_ID);
#ifdef ENABLE_LUKS_ADJUST_XTS_KEYSIZE #ifdef ENABLE_LUKS_ADJUST_XTS_KEYSIZE
if (!opt_key_size && !strncmp(cipher_mode, "xts-", 4)) { if (!ARG_SET(OPT_KEY_SIZE_ID) && !strncmp(cipher_mode, "xts-", 4)) {
if (default_size_bits == 128) if (default_size_bits == 128)
keysize_bits = 256; keysize_bits = 256;
else if (default_size_bits == 256) else if (default_size_bits == 256)
keysize_bits = 512; keysize_bits = 512;
} }
#endif #endif
return (keysize_bits ?: default_size_bits) / 8 + integrity_keysize; return (keysize_bits ?: default_size_bits) / 8 + integrity_keysize;
} }
static int _luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_ passwordLen) static int _luksFormat(struct crypt_device **r_cd, char **r_password, size_t *r_ passwordLen)
{ {
int r = -EINVAL, keysize, integrity_keysize = 0, fd, created = 0; int r = -EINVAL, keysize, integrity_keysize = 0, fd, created = 0;
struct stat st; struct stat st;
const char *header_device, *type; const char *header_device, *type;
char *msg = NULL, *key = NULL, *password = NULL; char *msg = NULL, *key = NULL, *password = NULL;
char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN], integrity[MAX_ CIPHER_LEN]; char cipher [MAX_CIPHER_LEN], cipher_mode[MAX_CIPHER_LEN], integrity[MAX_ CIPHER_LEN];
size_t passwordLen, signatures; size_t passwordLen, signatures;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_luks1 params1 = { struct crypt_params_luks1 params1 = {
.hash = opt_hash ?: DEFAULT_LUKS1_HASH, .hash = ARG_STR(OPT_HASH_ID) ?: DEFAULT_LUKS1_HASH,
.data_alignment = opt_align_payload, .data_alignment = ARG_UINT32(OPT_ALIGN_PAYLOAD_ID),
.data_device = opt_header_device ? action_argv[0] : NULL, .data_device = ARG_SET(OPT_HEADER_ID) ? action_argv[0] : NULL,
}; };
struct crypt_params_luks2 params2 = { struct crypt_params_luks2 params2 = {
.data_alignment = params1.data_alignment, .data_alignment = params1.data_alignment,
.data_device = params1.data_device, .data_device = params1.data_device,
.sector_size = opt_sector_size ?: SECTOR_SIZE, .sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID),
.label = opt_label, .label = ARG_STR(OPT_LABEL_ID),
.subsystem = opt_subsystem .subsystem = ARG_STR(OPT_SUBSYSTEM_ID)
}; };
void *params; void *params;
type = luksType(device_type); type = luksType(device_type);
if (!type) if (!type)
type = crypt_get_default_type(); type = crypt_get_default_type();
if (!strcmp(type, CRYPT_LUKS2)) { if (isLUKS2(type)) {
params = &params2; params = &params2;
} else if (!strcmp(type, CRYPT_LUKS1)) { } else if (isLUKS1(type)) {
params = &params1; params = &params1;
if (opt_sector_size > SECTOR_SIZE) { if (ARG_UINT32(OPT_SECTOR_SIZE_ID) > SECTOR_SIZE) {
log_err(_("Unsupported encryption sector size.")); log_err(_("Unsupported encryption sector size."));
return -EINVAL; return -EINVAL;
} }
if (opt_integrity) { if (ARG_SET(OPT_INTEGRITY_ID)) {
log_err(_("Integrity option can be used only for LUKS2 fo rmat.")); log_err(_("Integrity option can be used only for LUKS2 fo rmat."));
return -EINVAL; return -EINVAL;
} }
if (opt_luks2_keyslots_size || opt_luks2_metadata_size) { if (ARG_SET(OPT_LUKS2_KEYSLOTS_SIZE_ID) || ARG_SET(OPT_LUKS2_META DATA_SIZE_ID)) {
log_err(_("Unsupported LUKS2 metadata size options.")); log_err(_("Unsupported LUKS2 metadata size options."));
return -EINVAL; return -EINVAL;
} }
} else } else
return -EINVAL; return -EINVAL;
/* Create header file (must contain at least one sector)? */ /* Create header file (must contain at least one sector)? */
if (opt_header_device && stat(opt_header_device, &st) < 0 && errno == ENO if (ARG_SET(OPT_HEADER_ID) && stat(ARG_STR(OPT_HEADER_ID), &st) < 0 && er
ENT) { rno == ENOENT) {
if (!opt_batch_mode && if (!ARG_SET(OPT_BATCH_MODE_ID) &&
!yesDialog(_("Header file does not exist, do you want to crea te it?"), !yesDialog(_("Header file does not exist, do you want to crea te it?"),
_("Operation aborted.\n"))) _("Operation aborted.\n")))
return -EPERM; return -EPERM;
log_dbg("Creating header file."); log_dbg("Creating header file.");
/* coverity[toctou] */ /* coverity[toctou] */
fd = open(opt_header_device, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_I WUSR); fd = open(ARG_STR(OPT_HEADER_ID), O_CREAT|O_EXCL|O_WRONLY, S_IRUS R|S_IWUSR);
if (fd == -1 || posix_fallocate(fd, 0, 4096)) if (fd == -1 || posix_fallocate(fd, 0, 4096))
log_err(_("Cannot create header file %s."), opt_header_de vice); log_err(_("Cannot create header file %s."), ARG_STR(OPT_H EADER_ID));
else { else {
r = 0; r = 0;
created = 1; created = 1;
} }
if (fd != -1) if (fd != -1)
close(fd); close(fd);
if (r < 0) if (r < 0)
return r; return r;
} }
header_device = opt_header_device ?: action_argv[0]; header_device = ARG_STR(OPT_HEADER_ID) ?: action_argv[0];
r = crypt_parse_name_and_mode(opt_cipher ?: DEFAULT_CIPHER(LUKS1), r = crypt_parse_name_and_mode(ARG_STR(OPT_CIPHER_ID) ?: DEFAULT_CIPHER(LU KS1),
cipher, NULL, cipher_mode); cipher, NULL, cipher_mode);
if (r < 0) { if (r < 0) {
log_err(_("No known cipher specification pattern detected.")); log_err(_("No known cipher specification pattern detected."));
goto out; goto out;
} }
if (opt_integrity) { if (ARG_SET(OPT_INTEGRITY_ID)) {
r = crypt_parse_integrity_mode(opt_integrity, integrity, &integri r = crypt_parse_integrity_mode(ARG_STR(OPT_INTEGRITY_ID), integri
ty_keysize); ty, &integrity_keysize);
if (r < 0) { if (r < 0) {
log_err(_("No known integrity specification pattern detec ted.")); log_err(_("No known integrity specification pattern detec ted."));
goto out; goto out;
} }
params2.integrity = integrity; params2.integrity = integrity;
/* FIXME: we use default integrity_params (set to NULL) */ /* FIXME: we use default integrity_params (set to NULL) */
} }
/* Never call pwquality if using null cipher */ /* Never call pwquality if using null cipher */
if (crypt_is_cipher_null(cipher)) if (crypt_is_cipher_null(cipher))
opt_force_password = 1; ARG_SET_TRUE(OPT_FORCE_PASSWORD_ID);
if ((r = crypt_init(&cd, header_device))) { if ((r = crypt_init(&cd, header_device))) {
if (opt_header_device) if (ARG_SET(OPT_HEADER_ID))
log_err(_("Cannot use %s as on-disk header."), header_dev ice); log_err(_("Cannot use %s as on-disk header."), header_dev ice);
return r; return r;
} }
if (opt_luks2_keyslots_size || opt_luks2_metadata_size) { if (ARG_SET(OPT_LUKS2_KEYSLOTS_SIZE_ID) || ARG_SET(OPT_LUKS2_METADATA_SIZ
r = crypt_set_metadata_size(cd, opt_luks2_metadata_size, opt_luks E_ID)) {
2_keyslots_size); r = crypt_set_metadata_size(cd, ARG_UINT64(OPT_LUKS2_METADATA_SIZ
E_ID), ARG_UINT64(OPT_LUKS2_KEYSLOTS_SIZE_ID));
if (r < 0) { if (r < 0) {
log_err(_("Unsupported LUKS2 metadata size options.")); log_err(_("Unsupported LUKS2 metadata size options."));
goto out; goto out;
} }
} }
if (opt_offset) { if (ARG_SET(OPT_OFFSET_ID)) {
r = crypt_set_data_offset(cd, opt_offset); r = crypt_set_data_offset(cd, ARG_UINT64(OPT_OFFSET_ID));
if (r < 0) if (r < 0)
goto out; goto out;
} }
/* Print all present signatures in read-only mode */ /* Print all present signatures in read-only mode */
r = tools_detect_signatures(header_device, 0, &signatures); r = tools_detect_signatures(header_device, 0, &signatures, ARG_SET(OPT_BA TCH_MODE_ID));
if (r < 0) if (r < 0)
goto out; goto out;
if (!created) { if (!created && !ARG_SET(OPT_BATCH_MODE_ID)) {
r = asprintf(&msg, _("This will overwrite data on %s irrevocably. "), header_device); r = asprintf(&msg, _("This will overwrite data on %s irrevocably. "), header_device);
if (r == -1) { if (r == -1) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
} }
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL; r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
free(msg); free(msg);
if (r < 0) if (r < 0)
goto out; goto out;
} }
keysize = get_adjusted_key_size(cipher_mode, DEFAULT_LUKS1_KEYBITS, integ rity_keysize); keysize = get_adjusted_key_size(cipher_mode, DEFAULT_LUKS1_KEYBITS, integ rity_keysize);
if (opt_random) if (ARG_SET(OPT_USE_RANDOM_ID))
crypt_set_rng_type(cd, CRYPT_RNG_RANDOM); crypt_set_rng_type(cd, CRYPT_RNG_RANDOM);
else if (opt_urandom) else if (ARG_SET(OPT_USE_URANDOM_ID))
crypt_set_rng_type(cd, CRYPT_RNG_URANDOM); crypt_set_rng_type(cd, CRYPT_RNG_URANDOM);
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFI
opt_timeout, _verify_passphrase(1), 1, cd); LE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(1), !ARG
_SET(OPT_FORCE_PASSWORD_ID), cd);
if (r < 0) if (r < 0)
goto out; goto out;
if (opt_master_key_file) { if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
r = tools_read_mk(opt_master_key_file, &key, keysize); r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize)
;
if (r < 0) if (r < 0)
goto out; goto out;
} }
r = set_pbkdf_params(cd, type); r = set_pbkdf_params(cd, type);
if (r) { if (r) {
log_err(_("Failed to set pbkdf parameters.")); log_err(_("Failed to set pbkdf parameters."));
goto out; goto out;
} }
/* Signature candidates found */ /* Signature candidates found */
if (signatures && ((r = tools_wipe_all_signatures(header_device)) < 0)) if (signatures && ((r = tools_wipe_all_signatures(header_device)) < 0))
goto out; goto out;
if (opt_integrity_legacy_padding) if (ARG_SET(OPT_INTEGRITY_LEGACY_PADDING_ID))
crypt_set_compatibility(cd, CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING ); crypt_set_compatibility(cd, CRYPT_COMPAT_LEGACY_INTEGRITY_PADDING );
r = crypt_format(cd, type, cipher, cipher_mode, r = crypt_format(cd, type, cipher, cipher_mode,
opt_uuid, key, keysize, params); ARG_STR(OPT_UUID_ID), key, keysize, params);
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
r = _set_keyslot_encryption_params(cd); r = _set_keyslot_encryption_params(cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot, r = crypt_keyslot_add_by_volume_key(cd, ARG_INT32(OPT_KEY_SLOT_ID),
key, keysize, key, keysize,
password, passwordLen); password, passwordLen);
if (r < 0) { if (r < 0) {
(void) tools_wipe_all_signatures(header_device); (void) tools_wipe_all_signatures(header_device);
goto out; goto out;
} }
tools_keyslot_msg(r, CREATED); tools_keyslot_msg(r, CREATED);
if (opt_integrity && !opt_integrity_no_wipe && if (ARG_SET(OPT_INTEGRITY_ID) && !ARG_SET(OPT_INTEGRITY_NO_WIPE_ID) &&
strcmp_or_null(params2.integrity, "none")) strcmp_or_null(params2.integrity, "none"))
r = _wipe_data_device(cd); r = _wipe_data_device(cd);
out: out:
if (r >= 0 && r_cd && r_password && r_passwordLen) { if (r >= 0 && r_cd && r_password && r_passwordLen) {
*r_cd = cd; *r_cd = cd;
*r_password = password; *r_password = password;
*r_passwordLen = passwordLen; *r_passwordLen = passwordLen;
} else { } else {
crypt_free(cd); crypt_free(cd);
crypt_safe_free(password); crypt_safe_free(password);
skipping to change at line 1480 skipping to change at line 1538
{ {
struct crypt_active_device cad; struct crypt_active_device cad;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
const char *data_device, *header_device, *activated_name; const char *data_device, *header_device, *activated_name;
char *key = NULL; char *key = NULL;
uint32_t activate_flags = 0; uint32_t activate_flags = 0;
int r, keysize, tries; int r, keysize, tries;
char *password = NULL; char *password = NULL;
size_t passwordLen; size_t passwordLen;
if (opt_refresh) { if (ARG_SET(OPT_REFRESH_ID)) {
activated_name = action_argc > 1 ? action_argv[1] : action_argv[0 ]; activated_name = action_argc > 1 ? action_argv[1] : action_argv[0 ];
r = crypt_init_by_name_and_header(&cd, activated_name, opt_header _device); r = crypt_init_by_name_and_header(&cd, activated_name, ARG_STR(OP T_HEADER_ID));
if (r) if (r)
goto out; goto out;
activate_flags |= CRYPT_ACTIVATE_REFRESH; activate_flags |= CRYPT_ACTIVATE_REFRESH;
} else { } else {
header_device = uuid_or_device_header(&data_device); header_device = uuid_or_device_header(&data_device);
activated_name = opt_test_passphrase ? NULL : action_argv[1]; activated_name = ARG_SET(OPT_TEST_PASSPHRASE_ID) ? NULL : action_ argv[1];
if ((r = crypt_init_data_device(&cd, header_device, data_device)) ) if ((r = crypt_init_data_device(&cd, header_device, data_device)) )
goto out; goto out;
if ((r = crypt_load(cd, luksType(device_type), NULL))) { if ((r = crypt_load(cd, luksType(device_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
header_device); header_device);
goto out; goto out;
} }
if (!data_device && (crypt_get_data_offset(cd) < 8) && !opt_test_ passphrase) { if (!data_device && (crypt_get_data_offset(cd) < 8) && !ARG_SET(O PT_TEST_PASSPHRASE_ID)) {
log_err(_("Reduced data offset is allowed only for detach ed LUKS header.")); log_err(_("Reduced data offset is allowed only for detach ed LUKS header."));
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
} }
_set_activation_flags(&activate_flags); _set_activation_flags(&activate_flags);
if (opt_master_key_file) { if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
keysize = crypt_get_volume_key_size(cd); keysize = crypt_get_volume_key_size(cd);
if (!keysize && !opt_key_size) { if (!keysize && !ARG_SET(OPT_KEY_SIZE_ID)) {
log_err(_("Cannot determine volume key size for LUKS with out keyslots, please use --key-size option.")); log_err(_("Cannot determine volume key size for LUKS with out keyslots, please use --key-size option."));
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} else if (!keysize) } else if (!keysize)
keysize = opt_key_size / 8; keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
r = tools_read_mk(opt_master_key_file, &key, keysize); r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize) ;
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_activate_by_volume_key(cd, activated_name, r = crypt_activate_by_volume_key(cd, activated_name,
key, keysize, activate_flags); key, keysize, activate_flags);
} else { } else {
r = crypt_activate_by_token(cd, activated_name, opt_token, NULL, r = crypt_activate_by_token_pin(cd, activated_name, ARG_STR(OPT_T
activate_flags); OKEN_TYPE_ID),
ARG_INT32(OPT_TOKEN_ID_ID), NULL,
0, NULL, activate_flags);
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
if (r >= 0 || opt_token_only) tools_token_error_msg(r, ARG_STR(OPT_TOKEN_TYPE_ID), ARG_INT32(OP
T_TOKEN_ID_ID), false);
/* Token requires PIN, but ask only if there is no password query
later */
if (ARG_SET(OPT_TOKEN_ONLY_ID) && r == -ENOANO)
r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID),
activated_name, ARG_STR(OPT_TOKEN_TYPE_ID), activate_flags, _set_tries_tty());
if (r >= 0 || r == -EEXIST || ARG_SET(OPT_TOKEN_ONLY_ID))
goto out; goto out;
tries = (tools_is_stdin(opt_key_file) && isatty(STDIN_FILENO)) ? opt_tries : 1; tries = _set_tries_tty();
do { do {
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UI
_key_file, NT32(OPT_KEYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
opt_timeout, _verify_passphrase(0), 0, cd ARG_UINT32(OPT_TIMEOUT_ID), _verify_passp
); hrase(0), 0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_activate_by_passphrase(cd, activated_name, r = crypt_activate_by_passphrase(cd, activated_name,
opt_key_slot, password, passwordLen, activate_fla gs); ARG_INT32(OPT_KEY_SLOT_ID), password, passwordLen , activate_flags);
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
tools_passphrase_msg(r); tools_passphrase_msg(r);
check_signal(&r); check_signal(&r);
crypt_safe_free(password); crypt_safe_free(password);
password = NULL; password = NULL;
} while ((r == -EPERM || r == -ERANGE) && (--tries > 0)); } while ((r == -EPERM || r == -ERANGE) && (--tries > 0));
} }
out: out:
if (r >= 0 && opt_persistent && if (r >= 0 && ARG_SET(OPT_PERSISTENT_ID) &&
(crypt_get_active_device(cd, activated_name, &cad) || (crypt_get_active_device(cd, activated_name, &cad) ||
crypt_persistent_flags_set(cd, CRYPT_FLAGS_ACTIVATION, cad.flags & a ctivate_flags))) crypt_persistent_flags_set(cd, CRYPT_FLAGS_ACTIVATION, cad.flags & a ctivate_flags)))
log_err(_("Device activated but cannot make flags persistent.")); log_err(_("Device activated but cannot make flags persistent."));
crypt_safe_free(key); crypt_safe_free(key);
crypt_safe_free(password); crypt_safe_free(password);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int verify_keyslot(struct crypt_device *cd, int key_slot, crypt_keyslot_i nfo ki, static int verify_keyslot(struct crypt_device *cd, int key_slot, crypt_keyslot_i nfo ki,
char *msg_last, char *msg_pass, char *msg_fail, char *msg_last, char *msg_pass, char *msg_fail,
const char *key_file, uint64_t keyfile_offset, const char *key_file, uint64_t keyfile_offset,
int keyfile_size) int keyfile_size)
{ {
char *password = NULL; char *password = NULL;
size_t passwordLen; size_t passwordLen;
int i, max, r; int i, max, r;
if (ki == CRYPT_SLOT_ACTIVE_LAST && !opt_batch_mode && !key_file && if (ki == CRYPT_SLOT_ACTIVE_LAST && !ARG_SET(OPT_BATCH_MODE_ID) && !key_f
msg_last && !yesDialog(msg_last, msg_fail)) ile &&
msg_last && !ARG_SET(OPT_BATCH_MODE_ID) && !yesDialog(msg_last, msg_f
ail))
return -EPERM; return -EPERM;
r = tools_get_key(msg_pass, &password, &passwordLen, r = tools_get_key(msg_pass, &password, &passwordLen,
keyfile_offset, keyfile_size, key_file, opt_timeout, keyfile_offset, keyfile_size, key_file, ARG_UINT32(OPT_ TIMEOUT_ID),
_verify_passphrase(0), 0, cd); _verify_passphrase(0), 0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
if (ki == CRYPT_SLOT_ACTIVE_LAST) { if (ki == CRYPT_SLOT_ACTIVE_LAST) {
/* check the last keyslot */ /* check the last keyslot */
r = crypt_activate_by_passphrase(cd, NULL, key_slot, r = crypt_activate_by_passphrase(cd, NULL, key_slot,
password, passwordLen, 0); password, passwordLen, 0);
} else { } else {
/* try all other keyslots */ /* try all other keyslots */
skipping to change at line 1618 skipping to change at line 1683
static int action_luksKillSlot(void) static int action_luksKillSlot(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
crypt_keyslot_info ki; crypt_keyslot_info ki;
int r; int r;
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, luksType(device_type), NULL))) { if ((r = crypt_load(cd, luksType(device_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
ki = crypt_keyslot_status(cd, opt_key_slot); ki = crypt_keyslot_status(cd, ARG_INT32(OPT_KEY_SLOT_ID));
switch (ki) { switch (ki) {
case CRYPT_SLOT_ACTIVE_LAST: case CRYPT_SLOT_ACTIVE_LAST:
case CRYPT_SLOT_ACTIVE: case CRYPT_SLOT_ACTIVE:
case CRYPT_SLOT_UNBOUND: case CRYPT_SLOT_UNBOUND:
log_verbose(_("Keyslot %d is selected for deletion."), opt_key_sl ot); log_verbose(_("Keyslot %d is selected for deletion."), ARG_INT32( OPT_KEY_SLOT_ID));
break; break;
case CRYPT_SLOT_INACTIVE: case CRYPT_SLOT_INACTIVE:
log_err(_("Keyslot %d is not active."), opt_key_slot); log_err(_("Keyslot %d is not active."), ARG_INT32(OPT_KEY_SLOT_ID ));
/* fall through */ /* fall through */
case CRYPT_SLOT_INVALID: case CRYPT_SLOT_INVALID:
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
if (!opt_batch_mode || opt_key_file || !isatty(STDIN_FILENO)) { if (!ARG_SET(OPT_BATCH_MODE_ID) || ARG_SET(OPT_KEY_FILE_ID) || !isatty(ST
r = verify_keyslot(cd, opt_key_slot, ki, DIN_FILENO)) {
r = verify_keyslot(cd, ARG_INT32(OPT_KEY_SLOT_ID), ki,
_("This is the last keyslot. Device will become unusable after purging this key."), _("This is the last keyslot. Device will become unusable after purging this key."),
_("Enter any remaining passphrase: "), _("Enter any remaining passphrase: "),
_("Operation aborted, the keyslot was NOT wiped.\n"), _("Operation aborted, the keyslot was NOT wiped.\n"),
opt_key_file, opt_keyfile_offset, opt_keyfile_size); ARG_STR(OPT_KEY_FILE_ID), ARG_UINT64(OPT_KEYFILE_OFFSET_I D), ARG_UINT32(OPT_KEYFILE_SIZE_ID));
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
if (r == -EPIPE && (!opt_key_file || tools_is_stdin(opt_key_file) )) { if (r == -EPIPE && (!ARG_SET(OPT_KEY_FILE_ID) || tools_is_stdin(A RG_STR(OPT_KEY_FILE_ID)))) {
log_dbg("Failed read from input, ignoring passphrase."); log_dbg("Failed read from input, ignoring passphrase.");
r = 0; r = 0;
} }
if (r < 0) if (r < 0)
goto out; goto out;
} }
r = crypt_keyslot_destroy(cd, opt_key_slot); r = crypt_keyslot_destroy(cd, ARG_INT32(OPT_KEY_SLOT_ID));
tools_keyslot_msg(opt_key_slot, REMOVED); tools_keyslot_msg(ARG_INT32(OPT_KEY_SLOT_ID), REMOVED);
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksRemoveKey(void) static int action_luksRemoveKey(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
char *password = NULL; char *password = NULL;
size_t passwordLen; size_t passwordLen;
int r; int r;
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, luksType(device_type), NULL))) { if ((r = crypt_load(cd, luksType(device_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
r = tools_get_key(_("Enter passphrase to be deleted: "), r = tools_get_key(_("Enter passphrase to be deleted: "),
&password, &passwordLen, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFILE_S
opt_timeout, IZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID),
_verify_passphrase(0), 0, _verify_passphrase(0), 0,
cd); cd);
if(r < 0) if(r < 0)
goto out; goto out;
r = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, r = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT,
password, passwordLen, 0); password, passwordLen, 0);
tools_passphrase_msg(r); tools_passphrase_msg(r);
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
opt_key_slot = r; ARG_SET_INT32(OPT_KEY_SLOT_ID, r);
log_verbose(_("Keyslot %d is selected for deletion."), opt_key_slot); log_verbose(_("Keyslot %d is selected for deletion."), ARG_INT32(OPT_KEY_
SLOT_ID));
if (crypt_keyslot_status(cd, opt_key_slot) == CRYPT_SLOT_ACTIVE_LAST && if (crypt_keyslot_status(cd, ARG_INT32(OPT_KEY_SLOT_ID)) == CRYPT_SLOT_AC
TIVE_LAST &&
!ARG_SET(OPT_BATCH_MODE_ID) &&
!yesDialog(_("This is the last keyslot. " !yesDialog(_("This is the last keyslot. "
"Device will become unusable after purging this key."), "Device will become unusable after purging this key."),
_("Operation aborted, the keyslot was NOT wiped.\n"))) { _("Operation aborted, the keyslot was NOT wiped.\n"))) {
r = -EPERM; r = -EPERM;
goto out; goto out;
} }
r = crypt_keyslot_destroy(cd, opt_key_slot); r = crypt_keyslot_destroy(cd, ARG_INT32(OPT_KEY_SLOT_ID));
tools_keyslot_msg(opt_key_slot, REMOVED); tools_keyslot_msg(ARG_INT32(OPT_KEY_SLOT_ID), REMOVED);
out: out:
crypt_safe_free(password); crypt_safe_free(password);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int luksAddUnboundKey(void) static int luksAddUnboundKey(void)
{ {
int r = -EINVAL, keysize = 0; int r = -EINVAL, keysize = 0;
char *key = NULL; char *key = NULL;
const char *opt_new_key_file = (action_argc > 1 ? action_argv[1] : NULL); const char *new_key_file = (action_argc > 1 ? action_argv[1] : NULL);
char *password_new = NULL; char *password_new = NULL;
size_t password_new_size = 0; size_t password_new_size = 0;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) { if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
r = _set_keyslot_encryption_params(cd); r = _set_keyslot_encryption_params(cd);
if (r < 0) if (r < 0)
goto out; goto out;
/* Never call pwquality if using null cipher */ /* Never call pwquality if using null cipher */
if (crypt_is_cipher_null(crypt_get_cipher(cd))) if (crypt_is_cipher_null(crypt_get_cipher(cd)))
opt_force_password = 1; ARG_SET_TRUE(OPT_FORCE_PASSWORD_ID);
keysize = opt_key_size / 8; keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
r = set_pbkdf_params(cd, crypt_get_type(cd)); r = set_pbkdf_params(cd, crypt_get_type(cd));
if (r) { if (r) {
log_err(_("Failed to set pbkdf parameters.")); log_err(_("Failed to set pbkdf parameters."));
goto out; goto out;
} }
if (opt_master_key_file) { if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
r = tools_read_mk(opt_master_key_file, &key, keysize); r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize)
;
if (r < 0) if (r < 0)
goto out; goto out;
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
} }
r = tools_get_key(_("Enter new passphrase for key slot: "), r = tools_get_key(_("Enter new passphrase for key slot: "),
&password_new, &password_new_size, &password_new, &password_new_size,
opt_new_keyfile_offset, opt_new_keyfile_size, ARG_UINT64(OPT_NEW_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_N
opt_new_key_file, opt_timeout, EW_KEYFILE_SIZE_ID),
_verify_passphrase(1), 1, cd); new_key_file, ARG_UINT32(OPT_TIMEOUT_ID),
_verify_passphrase(1), !ARG_SET(OPT_FORCE_PASSWORD_ID),
cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_add_by_key(cd, opt_key_slot, key, keysize, r = crypt_keyslot_add_by_key(cd, ARG_INT32(OPT_KEY_SLOT_ID), key, keysize ,
password_new, password_new_size, CRYPT_VOLUME_KEY_NO_SEGM ENT); password_new, password_new_size, CRYPT_VOLUME_KEY_NO_SEGM ENT);
tools_keyslot_msg(r, CREATED); tools_keyslot_msg(r, CREATED);
out: out:
crypt_safe_free(password_new); crypt_safe_free(password_new);
crypt_safe_free(key); crypt_safe_free(key);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksAddKey(void) static int action_luksAddKey(void)
{ {
int r = -EINVAL, keysize = 0; int r = -EINVAL, keysize = 0;
char *key = NULL; char *key = NULL;
const char *opt_new_key_file = (action_argc > 1 ? action_argv[1] : NULL); const char *new_key_file = (action_argc > 1 ? action_argv[1] : NULL);
char *password = NULL, *password_new = NULL; char *password = NULL, *password_new = NULL;
size_t password_size = 0, password_new_size = 0; size_t password_size = 0, password_new_size = 0;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
/* Unbound keyslot (no assigned data segment) is special case */ /* Unbound keyslot (no assigned data segment) is special case */
if (opt_unbound) if (ARG_SET(OPT_UNBOUND_ID))
return luksAddUnboundKey(); return luksAddUnboundKey();
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, luksType(device_type), NULL))) { if ((r = crypt_load(cd, luksType(device_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
r = _set_keyslot_encryption_params(cd); r = _set_keyslot_encryption_params(cd);
if (r < 0) if (r < 0)
goto out; goto out;
/* Never call pwquality if using null cipher */ /* Never call pwquality if using null cipher */
if (crypt_is_cipher_null(crypt_get_cipher(cd))) if (crypt_is_cipher_null(crypt_get_cipher(cd)))
opt_force_password = 1; ARG_SET_TRUE(OPT_FORCE_PASSWORD_ID);
keysize = crypt_get_volume_key_size(cd); keysize = crypt_get_volume_key_size(cd);
r = set_pbkdf_params(cd, crypt_get_type(cd)); r = set_pbkdf_params(cd, crypt_get_type(cd));
if (r) { if (r) {
log_err(_("Failed to set pbkdf parameters.")); log_err(_("Failed to set pbkdf parameters."));
goto out; goto out;
} }
if (opt_master_key_file) { if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
if (!keysize && !opt_key_size) { if (!keysize && !ARG_SET(OPT_KEY_SIZE_ID)) {
log_err(_("Cannot determine volume key size for LUKS with out keyslots, please use --key-size option.")); log_err(_("Cannot determine volume key size for LUKS with out keyslots, please use --key-size option."));
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} else if (!keysize) } else if (!keysize)
keysize = opt_key_size / 8; keysize = ARG_UINT32(OPT_KEY_SIZE_ID) / 8;
r = tools_read_mk(opt_master_key_file, &key, keysize); r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &key, keysize) ;
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_volume_key_verify(cd, key, keysize); r = crypt_volume_key_verify(cd, key, keysize);
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
r = tools_get_key(_("Enter new passphrase for key slot: "), r = tools_get_key(_("Enter new passphrase for key slot: "),
&password_new, &password_new_size, &password_new, &password_new_size,
opt_new_keyfile_offset, opt_new_keyfile_size, ARG_UINT64(OPT_NEW_KEYFILE_OFFSET_ID), ARG_UINT
opt_new_key_file, opt_timeout, 32(OPT_NEW_KEYFILE_SIZE_ID),
_verify_passphrase(1), 1, cd); new_key_file, ARG_UINT32(OPT_TIMEOUT_ID),
_verify_passphrase(1), !ARG_SET(OPT_FORCE_PASSW
ORD_ID), cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_add_by_volume_key(cd, opt_key_slot, key, keysiz e, r = crypt_keyslot_add_by_volume_key(cd, ARG_INT32(OPT_KEY_SLOT_ID ), key, keysize,
password_new, password_new_si ze); password_new, password_new_si ze);
} else if (opt_key_file && !tools_is_stdin(opt_key_file) && } else if (ARG_SET(OPT_KEY_FILE_ID) && !tools_is_stdin(ARG_STR(OPT_KEY_FI
opt_new_key_file && !tools_is_stdin(opt_new_key_file)) { LE_ID)) &&
r = crypt_keyslot_add_by_keyfile_device_offset(cd, opt_key_slot, new_key_file && !tools_is_stdin(new_key_file)) {
opt_key_file, opt_keyfile_size, opt_keyfile_offset, r = crypt_keyslot_add_by_keyfile_device_offset(cd, ARG_INT32(OPT_
opt_new_key_file, opt_new_keyfile_size, opt_new_keyfile_o KEY_SLOT_ID),
ffset); ARG_STR(OPT_KEY_FILE_ID), ARG_UINT32(OPT_KEYFILE_SIZE_ID)
, ARG_UINT64(OPT_KEYFILE_OFFSET_ID),
new_key_file, ARG_UINT32(OPT_NEW_KEYFILE_SIZE_ID), ARG_UI
NT64(OPT_NEW_KEYFILE_OFFSET_ID));
tools_passphrase_msg(r); tools_passphrase_msg(r);
} else { } else {
r = tools_get_key(_("Enter any existing passphrase: "), r = tools_get_key(_("Enter any existing passphrase: "),
&password, &password_size, &password, &password_size,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_K
opt_timeout, _verify_passphrase(0), 0, cd); EYFILE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(0),
0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
/* Check password before asking for new one */ /* Check password before asking for new one */
r = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT, r = crypt_activate_by_passphrase(cd, NULL, CRYPT_ANY_SLOT,
password, password_size, 0); password, password_size, 0);
check_signal(&r); check_signal(&r);
tools_passphrase_msg(r); tools_passphrase_msg(r);
if (r < 0) if (r < 0)
goto out; goto out;
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
r = tools_get_key(_("Enter new passphrase for key slot: "), r = tools_get_key(_("Enter new passphrase for key slot: "),
&password_new, &password_new_size, &password_new, &password_new_size,
opt_new_keyfile_offset, opt_new_keyfile_size, o ARG_UINT64(OPT_NEW_KEYFILE_OFFSET_ID), ARG_UINT
pt_new_key_file, 32(OPT_NEW_KEYFILE_SIZE_ID), new_key_file,
opt_timeout, _verify_passphrase(1), 1, cd); ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(
1), !ARG_SET(OPT_FORCE_PASSWORD_ID), cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_add_by_passphrase(cd, opt_key_slot, r = crypt_keyslot_add_by_passphrase(cd, ARG_INT32(OPT_KEY_SLOT_ID ),
password, password_size, password, password_size,
password_new, password_new_si ze); password_new, password_new_si ze);
} }
out: out:
tools_keyslot_msg(r, CREATED); tools_keyslot_msg(r, CREATED);
crypt_safe_free(password); crypt_safe_free(password);
crypt_safe_free(password_new); crypt_safe_free(password_new);
crypt_safe_free(key); crypt_safe_free(key);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksChangeKey(void) static int action_luksChangeKey(void)
{ {
const char *opt_new_key_file = (action_argc > 1 ? action_argv[1] : NULL); const char *new_key_file = (action_argc > 1 ? action_argv[1] : NULL);
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
char *password = NULL, *password_new = NULL; char *password = NULL, *password_new = NULL;
size_t password_size = 0, password_new_size = 0; size_t password_size = 0, password_new_size = 0;
int r; int r;
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
if ((r = crypt_load(cd, luksType(device_type), NULL))) { if ((r = crypt_load(cd, luksType(device_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
r = _set_keyslot_encryption_params(cd); r = _set_keyslot_encryption_params(cd);
if (r < 0) if (r < 0)
goto out; goto out;
/* Never call pwquality if using null cipher */ /* Never call pwquality if using null cipher */
if (crypt_is_cipher_null(crypt_get_cipher(cd))) if (crypt_is_cipher_null(crypt_get_cipher(cd)))
opt_force_password = 1; ARG_SET_TRUE(OPT_FORCE_PASSWORD_ID);
r = set_pbkdf_params(cd, crypt_get_type(cd)); r = set_pbkdf_params(cd, crypt_get_type(cd));
if (r) { if (r) {
log_err(_("Failed to set pbkdf parameters.")); log_err(_("Failed to set pbkdf parameters."));
goto out; goto out;
} }
r = tools_get_key(_("Enter passphrase to be changed: "), r = tools_get_key(_("Enter passphrase to be changed: "),
&password, &password_size, &password, &password_size,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFILE_S
opt_timeout, _verify_passphrase(0), 0, cd); IZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(0), 0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
/* Check password before asking for new one */ /* Check password before asking for new one */
r = crypt_activate_by_passphrase(cd, NULL, opt_key_slot, r = crypt_activate_by_passphrase(cd, NULL, ARG_INT32(OPT_KEY_SLOT_ID),
password, password_size, CRYPT_ACTIVATE_ ALLOW_UNBOUND_KEY); password, password_size, CRYPT_ACTIVATE_ ALLOW_UNBOUND_KEY);
tools_passphrase_msg(r); tools_passphrase_msg(r);
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
r = tools_get_key(_("Enter new passphrase: "), r = tools_get_key(_("Enter new passphrase: "),
&password_new, &password_new_size, &password_new, &password_new_size,
opt_new_keyfile_offset, opt_new_keyfile_size, ARG_UINT64(OPT_NEW_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_N
opt_new_key_file, EW_KEYFILE_SIZE_ID),
opt_timeout, _verify_passphrase(1), 1, cd); new_key_file,
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(1), !ARG
_SET(OPT_FORCE_PASSWORD_ID), cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_change_by_passphrase(cd, opt_key_slot, opt_key_slot, r = crypt_keyslot_change_by_passphrase(cd, ARG_INT32(OPT_KEY_SLOT_ID), AR G_INT32(OPT_KEY_SLOT_ID),
password, password_size, password_new, password_new_size); password, password_size, password_new, password_new_size);
tools_keyslot_msg(r, CREATED); tools_keyslot_msg(r, CREATED);
out: out:
crypt_safe_free(password); crypt_safe_free(password);
crypt_safe_free(password_new); crypt_safe_free(password_new);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksConvertKey(void) static int action_luksConvertKey(void)
skipping to change at line 1977 skipping to change at line 2035
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) { if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
r = _set_keyslot_encryption_params(cd); r = _set_keyslot_encryption_params(cd);
if (r < 0) if (r < 0)
goto out; goto out;
if (crypt_keyslot_status(cd, opt_key_slot) == CRYPT_SLOT_INACTIVE) { if (crypt_keyslot_status(cd, ARG_INT32(OPT_KEY_SLOT_ID)) == CRYPT_SLOT_IN ACTIVE) {
r = -EINVAL; r = -EINVAL;
log_err(_("Keyslot %d is not active."), opt_key_slot); log_err(_("Keyslot %d is not active."), ARG_INT32(OPT_KEY_SLOT_ID ));
goto out; goto out;
} }
r = set_pbkdf_params(cd, crypt_get_type(cd)); r = set_pbkdf_params(cd, crypt_get_type(cd));
if (r) { if (r) {
log_err(_("Failed to set pbkdf parameters.")); log_err(_("Failed to set pbkdf parameters."));
goto out; goto out;
} }
r = tools_get_key(_("Enter passphrase for keyslot to be converted: "), r = tools_get_key(_("Enter passphrase for keyslot to be converted: "),
&password, &password_size, &password, &password_size,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFILE_S
opt_timeout, _verify_passphrase(0), 0, cd); IZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(0), 0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_keyslot_change_by_passphrase(cd, opt_key_slot, opt_key_slot, r = crypt_keyslot_change_by_passphrase(cd, ARG_INT32(OPT_KEY_SLOT_ID), AR G_INT32(OPT_KEY_SLOT_ID),
password, password_size, password, password_size); password, password_size, password, password_size);
tools_passphrase_msg(r); tools_passphrase_msg(r);
tools_keyslot_msg(r, CREATED); tools_keyslot_msg(r, CREATED);
out: out:
crypt_safe_free(password); crypt_safe_free(password);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_isLuks(void) static int action_isLuks(void)
skipping to change at line 2020 skipping to change at line 2078
/* FIXME: argc > max should be checked for other operations as well */ /* FIXME: argc > max should be checked for other operations as well */
if (action_argc > 1) { if (action_argc > 1) {
log_err(_("Only one device argument for isLuks operation is suppo rted.")); log_err(_("Only one device argument for isLuks operation is suppo rted."));
return -ENODEV; return -ENODEV;
} }
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_log_callback(cd, quiet_log, NULL); crypt_set_log_callback(cd, quiet_log, &log_parms);
r = crypt_load(cd, luksType(device_type), NULL); r = crypt_load(cd, luksType(device_type), NULL);
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksUUID(void) static int action_luksUUID(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
const char *existing_uuid = NULL; const char *existing_uuid = NULL;
int r; int r;
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_confirm_callback(cd, yesDialog, _("Operation aborted.\n")); if (!ARG_SET(OPT_BATCH_MODE_ID))
crypt_set_confirm_callback(cd, yesDialog, _("Operation aborted.\n
"));
if ((r = crypt_load(cd, luksType(device_type), NULL))) if ((r = crypt_load(cd, luksType(device_type), NULL)))
goto out; goto out;
if (opt_uuid) if (ARG_SET(OPT_UUID_ID))
r = crypt_set_uuid(cd, opt_uuid); r = crypt_set_uuid(cd, ARG_STR(OPT_UUID_ID));
else { else {
existing_uuid = crypt_get_uuid(cd); existing_uuid = crypt_get_uuid(cd);
log_std("%s\n", existing_uuid ?: ""); log_std("%s\n", existing_uuid ?: "");
r = existing_uuid ? 0 : 1; r = existing_uuid ? 0 : 1;
} }
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int luksDump_with_volume_key(struct crypt_device *cd) static int luksDump_with_volume_key(struct crypt_device *cd)
{ {
char *vk = NULL, *password = NULL; char *vk = NULL, *password = NULL;
size_t passwordLen = 0; size_t passwordLen = 0;
size_t vk_size; size_t vk_size;
unsigned i; unsigned i;
int r; int r;
crypt_set_confirm_callback(cd, yesDialog, NULL); if (!ARG_SET(OPT_BATCH_MODE_ID) && !yesDialog(
if (!yesDialog(
_("The header dump with volume key is sensitive information\n" _("The header dump with volume key is sensitive information\n"
"that allows access to encrypted partition without a passphrase.\n" "that allows access to encrypted partition without a passphrase.\n"
"This dump should be stored encrypted in a safe place."), "This dump should be stored encrypted in a safe place."),
NULL)) NULL))
return -EPERM; return -EPERM;
vk_size = crypt_get_volume_key_size(cd); vk_size = crypt_get_volume_key_size(cd);
vk = crypt_safe_alloc(vk_size); vk = crypt_safe_alloc(vk_size);
if (!vk) if (!vk)
return -ENOMEM; return -ENOMEM;
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFI
opt_timeout, 0, 0, cd); LE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), 0, 0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, vk, &vk_size, r = crypt_volume_key_get(cd, CRYPT_ANY_SLOT, vk, &vk_size,
password, passwordLen); password, passwordLen);
tools_passphrase_msg(r); tools_passphrase_msg(r);
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
if (opt_master_key_file) { if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
r = tools_write_mk(opt_master_key_file, vk, vk_size); r = tools_write_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), vk, vk_size);
if (r < 0) if (r < 0)
goto out; goto out;
} }
log_std("LUKS header information for %s\n", crypt_get_device_name(cd)); log_std("LUKS header information for %s\n", crypt_get_device_name(cd));
log_std("Cipher name: \t%s\n", crypt_get_cipher(cd)); log_std("Cipher name: \t%s\n", crypt_get_cipher(cd));
log_std("Cipher mode: \t%s\n", crypt_get_cipher_mode(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("Payload offset:\t%d\n", (int)crypt_get_data_offset(cd));
log_std("UUID: \t%s\n", crypt_get_uuid(cd)); log_std("UUID: \t%s\n", crypt_get_uuid(cd));
log_std("MK bits: \t%d\n", (int)vk_size * 8); log_std("MK bits: \t%d\n", (int)vk_size * 8);
if (opt_master_key_file) { if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
log_std("Key stored to file %s.\n", opt_master_key_file); log_std("Key stored to file %s.\n", ARG_STR(OPT_MASTER_KEY_FILE_I
D));
goto out; goto out;
} }
log_std("MK dump:\t"); log_std("MK dump:\t");
for(i = 0; i < vk_size; i++) { for(i = 0; i < vk_size; i++) {
if (i && !(i % 16)) if (i && !(i % 16))
log_std("\n\t\t"); log_std("\n\t\t");
log_std("%02hhx ", (char)vk[i]); log_std("%02hhx ", (char)vk[i]);
} }
log_std("\n"); log_std("\n");
skipping to change at line 2126 skipping to change at line 2184
return r; return r;
} }
static int luksDump_with_unbound_key(struct crypt_device *cd) static int luksDump_with_unbound_key(struct crypt_device *cd)
{ {
crypt_keyslot_info ki; crypt_keyslot_info ki;
char *uk = NULL, *password = NULL; char *uk = NULL, *password = NULL;
size_t uk_size, passwordLen = 0; size_t uk_size, passwordLen = 0;
int i, r; int i, r;
ki = crypt_keyslot_status(cd, opt_key_slot); ki = crypt_keyslot_status(cd, ARG_INT32(OPT_KEY_SLOT_ID));
if (ki != CRYPT_SLOT_UNBOUND) { if (ki != CRYPT_SLOT_UNBOUND) {
log_err(_("Keyslot %d does not contain unbound key."), opt_key_sl ot); log_err(_("Keyslot %d does not contain unbound key."), ARG_INT32( OPT_KEY_SLOT_ID));
return -EINVAL; return -EINVAL;
} }
crypt_set_confirm_callback(cd, yesDialog, NULL); if (!ARG_SET(OPT_BATCH_MODE_ID) && !yesDialog(
if (!yesDialog(
_("The header dump with unbound key is sensitive information.\n" _("The header dump with unbound key is sensitive information.\n"
"This dump should be stored encrypted in a safe place."), "This dump should be stored encrypted in a safe place."),
NULL)) NULL))
return -EPERM; return -EPERM;
r = crypt_keyslot_get_key_size(cd, opt_key_slot); r = crypt_keyslot_get_key_size(cd, ARG_INT32(OPT_KEY_SLOT_ID));
if (r < 0) if (r < 0)
return -EINVAL; return -EINVAL;
uk_size = r; uk_size = r;
uk = crypt_safe_alloc(uk_size); uk = crypt_safe_alloc(uk_size);
if (!uk) if (!uk)
return -ENOMEM; return -ENOMEM;
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFI
opt_timeout, 0, 0, cd); LE_SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), 0, 0, cd);
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_volume_key_get(cd, opt_key_slot, uk, &uk_size, r = crypt_volume_key_get(cd, ARG_INT32(OPT_KEY_SLOT_ID), uk, &uk_size,
password, passwordLen); password, passwordLen);
tools_passphrase_msg(r); tools_passphrase_msg(r);
check_signal(&r); check_signal(&r);
if (r < 0) if (r < 0)
goto out; goto out;
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
if (opt_master_key_file) { if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
r = tools_write_mk(opt_master_key_file, uk, uk_size); r = tools_write_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), uk, uk_size);
if (r < 0) if (r < 0)
goto out; goto out;
} }
log_std("LUKS header information for %s\n", crypt_get_device_name(cd)); log_std("LUKS header information for %s\n", crypt_get_device_name(cd));
log_std("UUID: \t%s\n", crypt_get_uuid(cd)); log_std("UUID: \t%s\n", crypt_get_uuid(cd));
log_std("Keyslot: \t%d\n", opt_key_slot); log_std("Keyslot: \t%d\n", ARG_INT32(OPT_KEY_SLOT_ID));
log_std("Key bits:\t%d\n", (int)uk_size * 8); log_std("Key bits:\t%d\n", (int)uk_size * 8);
if (opt_master_key_file) { if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
log_std("Key stored to file %s.\n", opt_master_key_file); log_std("Key stored to file %s.\n", ARG_STR(OPT_MASTER_KEY_FILE_I
D));
goto out; goto out;
} }
log_std("Unbound Key:\t"); log_std("Unbound Key:\t");
for(i = 0; i < (int)uk_size; i++) { for(i = 0; i < (int)uk_size; i++) {
if (i && !(i % 16)) if (i && !(i % 16))
log_std("\n\t\t"); log_std("\n\t\t");
log_std("%02hhx ", (char)uk[i]); log_std("%02hhx ", (char)uk[i]);
} }
log_std("\n"); log_std("\n");
skipping to change at line 2203 skipping to change at line 2260
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
if ((r = crypt_load(cd, luksType(device_type), NULL))) { if ((r = crypt_load(cd, luksType(device_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
if (opt_dump_master_key) if (ARG_SET(OPT_DUMP_MASTER_KEY_ID))
r = luksDump_with_volume_key(cd); r = luksDump_with_volume_key(cd);
else if (opt_unbound) else if (ARG_SET(OPT_UNBOUND_ID))
r = luksDump_with_unbound_key(cd); r = luksDump_with_unbound_key(cd);
else if (ARG_SET(OPT_DUMP_JSON_ID))
r = crypt_dump_json(cd, NULL, 0);
else else
r = crypt_dump(cd); r = crypt_dump(cd);
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksSuspend(void) static int action_luksSuspend(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_device(opt _header_device)); r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_device(ARG _STR(OPT_HEADER_ID)));
if (!r) { if (!r) {
r = crypt_suspend(cd, action_argv[0]); r = crypt_suspend(cd, action_argv[0]);
if (r == -ENODEV) if (r == -ENODEV)
log_err(_("%s is not active %s device name."), action_arg v[0], "LUKS"); log_err(_("%s is not active %s device name."), action_arg v[0], "LUKS");
} }
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksResume(void) static int action_luksResume(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
char *password = NULL; char *password = NULL;
size_t passwordLen; size_t passwordLen;
int r, tries; int r, tries;
const char *type, *req_type = luksType(device_type); const char *req_type = luksType(device_type);
if (req_type && strcmp(req_type, CRYPT_LUKS1) && strcmp(req_type, CRYPT_L UKS2)) if (req_type && !isLUKS(req_type))
return -EINVAL; return -EINVAL;
if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_devic e(opt_header_device)))) if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_devic e(ARG_STR(OPT_HEADER_ID)))))
return r; return r;
r = -EINVAL; r = -EINVAL;
type = crypt_get_type(cd); if (!isLUKS(crypt_get_type(cd))) {
if (!type || (strcmp(type, CRYPT_LUKS1) && strcmp(type, CRYPT_LUKS2))) {
log_err(_("%s is not active LUKS device name or header is missing ."), action_argv[0]); log_err(_("%s is not active LUKS device name or header is missing ."), action_argv[0]);
goto out; goto out;
} }
if (req_type && strcmp(req_type, crypt_get_type(cd))) { if (req_type && strcmp(req_type, crypt_get_type(cd))) {
log_err(_("%s is not active %s device name."), action_argv[0], re q_type); log_err(_("%s is not active %s device name."), action_argv[0], re q_type);
goto out; goto out;
} }
tries = (tools_is_stdin(opt_key_file) && isatty(STDIN_FILENO)) ? opt_trie s : 1; tries = _set_tries_tty();
do { do {
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFILE
opt_timeout, _verify_passphrase(0), 0, cd); _SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(0), 0, cd)
;
if (r < 0) if (r < 0)
goto out; goto out;
r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT , r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT ,
password, passwordLen); password, passwordLen);
tools_passphrase_msg(r); tools_passphrase_msg(r);
check_signal(&r); check_signal(&r);
tools_keyslot_msg(r, UNLOCKED); tools_keyslot_msg(r, UNLOCKED);
crypt_safe_free(password); crypt_safe_free(password);
skipping to change at line 2284 skipping to change at line 2342
crypt_safe_free(password); crypt_safe_free(password);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksBackup(void) static int action_luksBackup(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
if (!opt_header_backup_file) { if (!ARG_SET(OPT_HEADER_BACKUP_FILE_ID)) {
log_err(_("Option --header-backup-file is required.")); log_err(_("Option --header-backup-file is required."));
return -EINVAL; return -EINVAL;
} }
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL); r = crypt_header_backup(cd, NULL, ARG_STR(OPT_HEADER_BACKUP_FILE_ID));
r = crypt_header_backup(cd, NULL, opt_header_backup_file);
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int action_luksRestore(void) static int action_luksRestore(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r = 0; int r = 0;
if (!opt_header_backup_file) { if (!ARG_SET(OPT_HEADER_BACKUP_FILE_ID)) {
log_err(_("Option --header-backup-file is required.")); log_err(_("Option --header-backup-file is required."));
return -EINVAL; return -EINVAL;
} }
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL); if (!ARG_SET(OPT_BATCH_MODE_ID))
r = crypt_header_restore(cd, NULL, opt_header_backup_file); crypt_set_confirm_callback(cd, yesDialog, NULL);
r = crypt_header_restore(cd, NULL, ARG_STR(OPT_HEADER_BACKUP_FILE_ID));
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static const char *_get_device_type(void) static const char *_get_device_type(void)
{ {
const char *type, *name = NULL; const char *type, *name = NULL;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
if (action_argc > 1) if (action_argc > 1)
name = action_argv[1]; name = action_argv[1];
else if (action_argc == 1) else if (action_argc == 1)
name = action_argv[0]; name = action_argv[0];
if (crypt_init_by_name_and_header(&cd, name, opt_header_device)) if (crypt_init_by_name_and_header(&cd, name, ARG_STR(OPT_HEADER_ID)))
return NULL; return NULL;
type = crypt_get_type(cd); type = crypt_get_type(cd);
if (!type) { if (!type) {
crypt_free(cd); crypt_free(cd);
log_err(_("%s is not cryptsetup managed device."), name); log_err(_("%s is not cryptsetup managed device."), name);
return NULL; return NULL;
} }
if (!strncmp(type, "LUKS", 4)) if (!strncmp(type, "LUKS", 4))
skipping to change at line 2358 skipping to change at line 2415
type = NULL; type = NULL;
} }
crypt_free(cd); crypt_free(cd);
return type; return type;
} }
static int action_open(void) static int action_open(void)
{ {
if (opt_refresh && !device_type) int r = -EINVAL;
if (ARG_SET(OPT_REFRESH_ID) && !device_type)
/* read device type from active mapping */ /* read device type from active mapping */
device_type = _get_device_type(); device_type = _get_device_type();
if (!device_type) if (!device_type)
return -EINVAL; return -EINVAL;
if (!strcmp(device_type, "luks") || if (!strcmp(device_type, "luks") ||
!strcmp(device_type, "luks1") || !strcmp(device_type, "luks1") ||
!strcmp(device_type, "luks2")) { !strcmp(device_type, "luks2")) {
if (action_argc < 2 && (!opt_test_passphrase && !opt_refresh)) if (action_argc < 2 && (!ARG_SET(OPT_TEST_PASSPHRASE_ID) && !ARG_
goto args; SET(OPT_REFRESH_ID)))
goto out;
return action_open_luks(); return action_open_luks();
} else if (!strcmp(device_type, "plain")) { } else if (!strcmp(device_type, "plain")) {
if (action_argc < 2 && !opt_refresh) if (action_argc < 2 && !ARG_SET(OPT_REFRESH_ID))
goto args; goto out;
return action_open_plain(); return action_open_plain();
} else if (!strcmp(device_type, "loopaes")) { } else if (!strcmp(device_type, "loopaes")) {
if (action_argc < 2 && !opt_refresh) if (action_argc < 2 && !ARG_SET(OPT_REFRESH_ID))
goto args; goto out;
return action_open_loopaes(); return action_open_loopaes();
} else if (!strcmp(device_type, "tcrypt")) { } else if (!strcmp(device_type, "tcrypt")) {
if (action_argc < 2 && !opt_test_passphrase) if (action_argc < 2 && !ARG_SET(OPT_TEST_PASSPHRASE_ID))
goto args; goto out;
return action_open_tcrypt(); return action_open_tcrypt();
} else if (!strcmp(device_type, "bitlk")) { } else if (!strcmp(device_type, "bitlk")) {
if (action_argc < 2 && !opt_test_passphrase) if (action_argc < 2 && !ARG_SET(OPT_TEST_PASSPHRASE_ID))
goto args; goto out;
return action_open_bitlk(); return action_open_bitlk();
} } else
r = -ENOENT;
out:
if (r == -ENOENT)
log_err(_("Unrecognized metadata device type %s."), device_type);
else
log_err(_("Command requires device and mapped name as arguments."
));
log_err(_("Unrecognized metadata device type %s."), device_type); return r;
return -EINVAL;
args:
log_err(_("Command requires device and mapped name as arguments."));
return -EINVAL;
} }
static int action_luksErase(void) static int action_luksErase(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
crypt_keyslot_info ki; crypt_keyslot_info ki;
char *msg = NULL; char *msg = NULL;
int i, max, r; int i, max, r;
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
goto out; goto out;
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, luksType(device_type), NULL))) { if ((r = crypt_load(cd, luksType(device_type), NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
if(asprintf(&msg, _("This operation will erase all keyslots on device %s. \n" if(asprintf(&msg, _("This operation will erase all keyslots on device %s. \n"
"Device will become unusable after this operation."), "Device will become unusable after this operation."),
uuid_or_device_header(NULL)) == -1) { uuid_or_device_header(NULL)) == -1) {
r = -ENOMEM; r = -ENOMEM;
goto out; goto out;
} }
if (!yesDialog(msg, _("Operation aborted, keyslots were NOT wiped.\n"))) { if (!ARG_SET(OPT_BATCH_MODE_ID) && !yesDialog(msg, _("Operation aborted, keyslots were NOT wiped.\n"))) {
r = -EPERM; r = -EPERM;
goto out; goto out;
} }
/* Safety check */ /* Safety check */
max = crypt_keyslot_max(crypt_get_type(cd)); max = crypt_keyslot_max(crypt_get_type(cd));
if (max <= 0) { if (max <= 0) {
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
skipping to change at line 2467 skipping to change at line 2526
} else if (!strcmp(device_type, "luks1")) { } else if (!strcmp(device_type, "luks1")) {
to_type = CRYPT_LUKS1; to_type = CRYPT_LUKS1;
} else { } else {
log_err(_("Invalid LUKS type, only luks1 and luks2 are supported. ")); log_err(_("Invalid LUKS type, only luks1 and luks2 are supported. "));
return -EINVAL; return -EINVAL;
} }
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
return r; return r;
crypt_set_confirm_callback(cd, yesDialog, NULL);
if ((r = crypt_load(cd, CRYPT_LUKS, NULL)) || if ((r = crypt_load(cd, CRYPT_LUKS, NULL)) ||
!(from_type = crypt_get_type(cd))) { !(from_type = crypt_get_type(cd))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
if (!strcmp(from_type, to_type)) { if (!strcmp(from_type, to_type)) {
log_err(_("Device is already %s type."), to_type); log_err(_("Device is already %s type."), to_type);
crypt_free(cd); crypt_free(cd);
return -EINVAL; return -EINVAL;
} }
if (asprintf(&msg, _("This operation will convert %s to %s format.\n"), r = 0;
uuid_or_device_header(NULL), to_type) == -1) { if (!ARG_SET(OPT_BATCH_MODE_ID)) {
crypt_free(cd); if (asprintf(&msg, _("This operation will convert %s to %s format
return -ENOMEM; .\n"),
uuid_or_device_header(NULL), to_type) == -1)
r = -ENOMEM;
else if (!yesDialog(msg, _("Operation aborted, device was NOT con
verted.\n")))
r = -EPERM;
} }
if (yesDialog(msg, _("Operation aborted, device was NOT converted.\n"))) r = r ?: crypt_convert(cd, to_type, NULL);
r = crypt_convert(cd, to_type, NULL);
else
r = -EPERM;
free(msg); free(msg);
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int _config_priority(struct crypt_device *cd) static int _config_priority(struct crypt_device *cd)
{ {
crypt_keyslot_info cs; crypt_keyslot_info cs;
crypt_keyslot_priority priority = CRYPT_SLOT_PRIORITY_INVALID; crypt_keyslot_priority priority = CRYPT_SLOT_PRIORITY_INVALID;
if (!strcmp("normal", opt_priority)) if (!strcmp("normal", ARG_STR(OPT_PRIORITY_ID)))
priority = CRYPT_SLOT_PRIORITY_NORMAL; priority = CRYPT_SLOT_PRIORITY_NORMAL;
else if (!strcmp("prefer", opt_priority)) else if (!strcmp("prefer", ARG_STR(OPT_PRIORITY_ID)))
priority = CRYPT_SLOT_PRIORITY_PREFER; priority = CRYPT_SLOT_PRIORITY_PREFER;
else if (!strcmp("ignore", opt_priority)) else if (!strcmp("ignore", ARG_STR(OPT_PRIORITY_ID)))
priority = CRYPT_SLOT_PRIORITY_IGNORE; priority = CRYPT_SLOT_PRIORITY_IGNORE;
cs = crypt_keyslot_status(cd, opt_key_slot); cs = crypt_keyslot_status(cd, ARG_INT32(OPT_KEY_SLOT_ID));
if (cs != CRYPT_SLOT_INVALID) if (cs != CRYPT_SLOT_INVALID)
return crypt_keyslot_set_priority(cd, opt_key_slot, priority); return crypt_keyslot_set_priority(cd, ARG_INT32(OPT_KEY_SLOT_ID),
priority);
return -EINVAL; return -EINVAL;
} }
static int _config_labels(struct crypt_device *cd) static int _config_labels(struct crypt_device *cd)
{ {
return crypt_set_label(cd, opt_label, opt_subsystem); return crypt_set_label(cd, ARG_STR(OPT_LABEL_ID), ARG_STR(OPT_SUBSYSTEM_I D));
} }
static int action_luksConfig(void) static int action_luksConfig(void)
{ {
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
int r; int r;
if (!opt_priority && !opt_label && !opt_subsystem) { if (!ARG_SET(OPT_PRIORITY_ID) && !ARG_SET(OPT_LABEL_ID) && !ARG_SET(OPT_S UBSYSTEM_ID)) {
log_err(_("Option --priority, --label or --subsystem is missing." )); log_err(_("Option --priority, --label or --subsystem is missing." ));
return -EINVAL; return -EINVAL;
} }
if ((r = crypt_init(&cd, uuid_or_device_header(NULL)))) if ((r = crypt_init(&cd, uuid_or_device_header(NULL))))
return r; return r;
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) { if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device_header(NULL)); uuid_or_device_header(NULL));
goto out; goto out;
} }
if (opt_priority && (r = _config_priority(cd))) if (ARG_SET(OPT_PRIORITY_ID) && (r = _config_priority(cd)))
goto out; goto out;
if ((opt_label || opt_subsystem) && (r = _config_labels(cd))) if ((ARG_SET(OPT_LABEL_ID) || ARG_SET(OPT_SUBSYSTEM_ID)) && (r = _config_ labels(cd)))
goto out; goto out;
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int _token_add(struct crypt_device *cd) static int _token_add(struct crypt_device *cd)
{ {
int r, token; int r, token;
crypt_token_info token_info; crypt_token_info token_info;
const struct crypt_token_params_luks2_keyring params = { const struct crypt_token_params_luks2_keyring params = {
.key_description = opt_key_description .key_description = ARG_STR(OPT_KEY_DESCRIPTION_ID)
}; };
if (opt_token != CRYPT_ANY_TOKEN) { if (ARG_INT32(OPT_TOKEN_ID_ID) != CRYPT_ANY_TOKEN) {
token_info = crypt_token_status(cd, opt_token, NULL); token_info = crypt_token_status(cd, ARG_INT32(OPT_TOKEN_ID_ID), N
ULL);
if (token_info < CRYPT_TOKEN_INACTIVE) { if (token_info < CRYPT_TOKEN_INACTIVE) {
log_err(_("Token %d is invalid."), opt_token); log_err(_("Token %d is invalid."), ARG_INT32(OPT_TOKEN_ID _ID));
return -EINVAL; return -EINVAL;
} else if (token_info > CRYPT_TOKEN_INACTIVE) { } else if (token_info > CRYPT_TOKEN_INACTIVE) {
log_err(_("Token %d in use."), opt_token); log_err(_("Token %d in use."), ARG_INT32(OPT_TOKEN_ID_ID) );
return -EINVAL; return -EINVAL;
} }
} }
r = crypt_token_luks2_keyring_set(cd, opt_token, &params); r = crypt_token_luks2_keyring_set(cd, ARG_INT32(OPT_TOKEN_ID_ID), &params );
if (r < 0) { if (r < 0) {
log_err(_("Failed to add luks2-keyring token %d."), opt_token); log_err(_("Failed to add luks2-keyring token %d."), ARG_INT32(OPT _TOKEN_ID_ID));
return r; return r;
} }
token = r; token = r;
tools_token_msg(token, CREATED);
r = crypt_token_assign_keyslot(cd, token, opt_key_slot); r = crypt_token_assign_keyslot(cd, token, ARG_INT32(OPT_KEY_SLOT_ID));
if (r < 0) { if (r < 0) {
log_err(_("Failed to assign token %d to keyslot %d."), token, opt _key_slot); log_err(_("Failed to assign token %d to keyslot %d."), token, ARG _INT32(OPT_KEY_SLOT_ID));
(void) crypt_token_json_set(cd, token, NULL); (void) crypt_token_json_set(cd, token, NULL);
return r;
} }
return r; return token;
} }
static int _token_remove(struct crypt_device *cd) static int _token_remove(struct crypt_device *cd)
{ {
crypt_token_info token_info; crypt_token_info token_info;
int r;
token_info = crypt_token_status(cd, opt_token, NULL); token_info = crypt_token_status(cd, ARG_INT32(OPT_TOKEN_ID_ID), NULL);
if (token_info < CRYPT_TOKEN_INACTIVE) { if (token_info < CRYPT_TOKEN_INACTIVE) {
log_err(_("Token %d is invalid."), opt_token); log_err(_("Token %d is invalid."), ARG_INT32(OPT_TOKEN_ID_ID));
return -EINVAL; return -EINVAL;
} else if (token_info == CRYPT_TOKEN_INACTIVE) { } else if (token_info == CRYPT_TOKEN_INACTIVE) {
log_err(_("Token %d is not in use."), opt_token); log_err(_("Token %d is not in use."), ARG_INT32(OPT_TOKEN_ID_ID)) ;
return -EINVAL; return -EINVAL;
} }
r = crypt_token_json_set(cd, opt_token, NULL); return crypt_token_json_set(cd, ARG_INT32(OPT_TOKEN_ID_ID), NULL);
tools_token_msg(r, REMOVED);
return r;
} }
static int _token_import(struct crypt_device *cd) static int _token_import(struct crypt_device *cd)
{ {
char *json; char *json;
size_t json_length; size_t json_length;
crypt_token_info token_info; crypt_token_info token_info;
int r, token; int r, token;
if (opt_token != CRYPT_ANY_TOKEN) { if (ARG_INT32(OPT_TOKEN_ID_ID) != CRYPT_ANY_TOKEN) {
token_info = crypt_token_status(cd, opt_token, NULL); token_info = crypt_token_status(cd, ARG_INT32(OPT_TOKEN_ID_ID), N
ULL);
if (token_info < CRYPT_TOKEN_INACTIVE) { if (token_info < CRYPT_TOKEN_INACTIVE) {
log_err(_("Token %d is invalid."), opt_token); log_err(_("Token %d is invalid."), ARG_INT32(OPT_TOKEN_ID _ID));
return -EINVAL; return -EINVAL;
} else if (token_info > CRYPT_TOKEN_INACTIVE) { } else if (token_info > CRYPT_TOKEN_INACTIVE) {
log_err(_("Token %d in use."), opt_token); log_err(_("Token %d in use."), ARG_INT32(OPT_TOKEN_ID_ID) );
return -EINVAL; return -EINVAL;
} }
} }
r = tools_read_json_file(cd, opt_json_file, &json, &json_length); r = tools_read_json_file(ARG_STR(OPT_JSON_FILE_ID), &json, &json_length, ARG_SET(OPT_BATCH_MODE_ID));
if (r) if (r)
return r; return r;
r = crypt_token_json_set(cd, opt_token, json); r = crypt_token_json_set(cd, ARG_INT32(OPT_TOKEN_ID_ID), json);
free(json); free(json);
if (r < 0) { if (r < 0) {
log_err(_("Failed to import token from file.")); log_err(_("Failed to import token from file."));
return r; return r;
} }
token = r; token = r;
tools_token_msg(token, CREATED);
if (opt_key_slot != CRYPT_ANY_SLOT) { if (ARG_INT32(OPT_KEY_SLOT_ID) != CRYPT_ANY_SLOT) {
r = crypt_token_assign_keyslot(cd, token, opt_key_slot); r = crypt_token_assign_keyslot(cd, token, ARG_INT32(OPT_KEY_SLOT_
ID));
if (r < 0) { if (r < 0) {
log_err(_("Failed to assign token %d to keyslot %d."), to ken, opt_key_slot); log_err(_("Failed to assign token %d to keyslot %d."), to ken, ARG_INT32(OPT_KEY_SLOT_ID));
(void) crypt_token_json_set(cd, token, NULL); (void) crypt_token_json_set(cd, token, NULL);
return r;
} }
} }
return r; return token;
} }
static int _token_export(struct crypt_device *cd) static int _token_export(struct crypt_device *cd)
{ {
const char *json; const char *json;
int r; int r;
r = crypt_token_json_get(cd, opt_token, &json); r = crypt_token_json_get(cd, ARG_INT32(OPT_TOKEN_ID_ID), &json);
if (r < 0) { if (r < 0) {
log_err(_("Failed to get token %d for export."), opt_token); log_err(_("Failed to get token %d for export."), ARG_INT32(OPT_TO KEN_ID_ID));
return r; return r;
} }
return tools_write_json_file(cd, opt_json_file, json); return tools_write_json_file(ARG_STR(OPT_JSON_FILE_ID), json);
} }
static int action_token(void) static int action_token(void)
{ {
int r; int r;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
enum { ADD = 0, REMOVE, IMPORT, EXPORT } action;
if (!strcmp(action_argv[0], "add")) {
if (!opt_key_description) {
log_err(_("--key-description parameter is mandatory for t
oken add action."));
return -EINVAL;
}
action = ADD;
} else if (!strcmp(action_argv[0], "remove")) {
if (opt_token == CRYPT_ANY_TOKEN) {
log_err(_("Action requires specific token. Use --token-id
parameter."));
return -EINVAL;
}
action = REMOVE;
} else if (!strcmp(action_argv[0], "import")) {
action = IMPORT;
} else if (!strcmp(action_argv[0], "export")) {
if (opt_token == CRYPT_ANY_TOKEN) {
log_err(_("Action requires specific token. Use --token-id
parameter."));
return -EINVAL;
}
action = EXPORT;
} else {
log_err(_("Invalid token operation %s."), action_argv[0]);
return -EINVAL;
}
if ((r = crypt_init(&cd, uuid_or_device(opt_header_device ?: action_argv[ 1])))) if ((r = crypt_init(&cd, uuid_or_device(ARG_STR(OPT_HEADER_ID) ?: action_ argv[1]))))
return r; return r;
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) { if ((r = crypt_load(cd, CRYPT_LUKS2, NULL))) {
log_err(_("Device %s is not a valid LUKS device."), log_err(_("Device %s is not a valid LUKS device."),
uuid_or_device(opt_header_device ?: action_argv[1])); uuid_or_device(ARG_STR(OPT_HEADER_ID) ?: action_argv[1])) ;
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
if (action == ADD) r = -EINVAL;
if (!strcmp(action_argv[0], "add")) {
r = _token_add(cd); /* adds only luks2-keyring type */ r = _token_add(cd); /* adds only luks2-keyring type */
else if (action == REMOVE) tools_token_msg(r, CREATED);
} else if (!strcmp(action_argv[0], "remove")) {
r = _token_remove(cd); r = _token_remove(cd);
else if (action == IMPORT) tools_token_msg(r, REMOVED);
} else if (!strcmp(action_argv[0], "import")) {
r = _token_import(cd); r = _token_import(cd);
else if (action == EXPORT) tools_token_msg(r, CREATED);
} else if (!strcmp(action_argv[0], "export"))
r = _token_export(cd); r = _token_export(cd);
else {
log_dbg("Internal token action error.");
r = -EINVAL;
}
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static int auto_detect_active_name(struct crypt_device *cd, const char *data_dev ice, char *dm_name, size_t dm_name_len) static int auto_detect_active_name(struct crypt_device *cd, const char *data_dev ice, char *dm_name, size_t dm_name_len)
{ {
int r; int r;
skipping to change at line 2747 skipping to change at line 2774
{ {
char *msg; char *msg;
int r; int r;
r = auto_detect_active_name(cd, action_argv[0], buffer, buffer_size); r = auto_detect_active_name(cd, action_argv[0], buffer, buffer_size);
if (r > 0) { if (r > 0) {
if (*buffer == '\0') { if (*buffer == '\0') {
log_err(_("Device %s is still in use."), data_device); log_err(_("Device %s is still in use."), data_device);
return -EINVAL; return -EINVAL;
} }
if (!opt_batch_mode) if (!ARG_SET(OPT_BATCH_MODE_ID))
log_std(_("Auto-detected active dm device '%s' for data d evice %s.\n"), buffer, data_device); log_std(_("Auto-detected active dm device '%s' for data d evice %s.\n"), buffer, data_device);
} }
if (r < 0) { if (r < 0) {
if (r == -ENOTBLK) if (r == -ENOTBLK)
log_std(_("Device %s is not a block device.\n"), data_dev ice); log_std(_("Device %s is not a block device.\n"), data_dev ice);
else else
log_err(_("Failed to auto-detect device %s holders."), da ta_device); log_err(_("Failed to auto-detect device %s holders."), da ta_device);
r = asprintf(&msg, _("Unable to decide if device %s is activated r = -EINVAL;
or not.\n" if (!ARG_SET(OPT_BATCH_MODE_ID)) {
"Are you sure you want to proceed with reenc r = asprintf(&msg, _("Unable to decide if device %s is ac
ryption in offline mode?\n" tivated or not.\n"
"It may lead to data corruption if the devic "Are you sure you want to proceed wi
e is actually activated.\n" th reencryption in offline mode?\n"
"To run reencryption in online mode, use --a "It may lead to data corruption if t
ctive-name parameter instead.\n"), data_device); he device is actually activated.\n"
if (r < 0) "To run reencryption in online mode,
return -ENOMEM; use --active-name parameter instead.\n"), data_device);
r = noDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL; if (r < 0)
free(msg); return -ENOMEM;
r = noDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVA
L;
free(msg);
}
} }
return r; return r;
} }
static int action_reencrypt_load(struct crypt_device *cd) static int action_reencrypt_load(struct crypt_device *cd)
{ {
int r; int r;
size_t passwordLen; size_t passwordLen;
char dm_name[PATH_MAX] = {}, *password = NULL; char dm_name[PATH_MAX] = {}, *password = NULL;
const char *active_name = NULL; const char *active_name = NULL;
struct crypt_params_reencrypt params = { struct crypt_params_reencrypt params = {
.resilience = opt_resilience_mode ?: "checksum", .resilience = ARG_STR(OPT_RESILIENCE_ID) ?: "checksum",
.hash = opt_resilience_hash ?: "sha256", .hash = ARG_STR(OPT_RESILIENCE_HASH_ID) ?: "sha256",
.max_hotzone_size = opt_hotzone_size / SECTOR_SIZE, .max_hotzone_size = ARG_UINT64(OPT_HOTZONE_SIZE_ID) / SECTOR_SIZE
.device_size = opt_device_size / SECTOR_SIZE, ,
.device_size = ARG_UINT64(OPT_DEVICE_SIZE_ID) / SECTOR_SIZE,
.flags = CRYPT_REENCRYPT_RESUME_ONLY .flags = CRYPT_REENCRYPT_RESUME_ONLY
}; };
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFILE
opt_timeout, _verify_passphrase(0), 0, cd); _SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(0), 0, cd)
;
if (r < 0) if (r < 0)
return r; return r;
if (!opt_active_name) { if (!ARG_SET(OPT_ACTIVE_NAME_ID)) {
r = _get_device_active_name(cd, action_argv[0], dm_name, sizeof(d m_name)); r = _get_device_active_name(cd, action_argv[0], dm_name, sizeof(d m_name));
if (r > 0) if (r > 0)
active_name = dm_name; active_name = dm_name;
if (r < 0) { if (r < 0) {
crypt_safe_free(password); crypt_safe_free(password);
return -EINVAL; return -EINVAL;
} }
} else } else
active_name = opt_active_name; active_name = ARG_STR(OPT_ACTIVE_NAME_ID);
r = crypt_reencrypt_init_by_passphrase(cd, active_name, password, passwor dLen, opt_key_slot, opt_key_slot, NULL, NULL, &params); r = crypt_reencrypt_init_by_passphrase(cd, active_name, password, passwor dLen, ARG_INT32(OPT_KEY_SLOT_ID), ARG_INT32(OPT_KEY_SLOT_ID), NULL, NULL, &param s);
crypt_safe_free(password); crypt_safe_free(password);
return r; return r;
} }
static int action_encrypt_luks2(struct crypt_device **cd) static int action_encrypt_luks2(struct crypt_device **cd)
{ {
char *tmp;
const char *type, *activated_name = NULL; const char *type, *activated_name = NULL;
int keyslot, r, fd; int keyslot, r, fd;
uuid_t uuid; uuid_t uuid;
size_t passwordLen; size_t passwordLen;
char *msg, uuid_str[37], header_file[PATH_MAX] = { 0 }, *password = NULL; char *msg, uuid_str[37], header_file[PATH_MAX] = { 0 }, *password = NULL;
uint32_t activate_flags = 0; uint32_t activate_flags = 0;
const struct crypt_params_luks2 luks2_params = { const struct crypt_params_luks2 luks2_params = {
.sector_size = opt_sector_size ?: SECTOR_SIZE .sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID) ?: SECTOR_SIZE
}; };
struct crypt_params_reencrypt params = { struct crypt_params_reencrypt params = {
.mode = CRYPT_REENCRYPT_ENCRYPT, .mode = CRYPT_REENCRYPT_ENCRYPT,
.direction = opt_data_shift < 0 ? CRYPT_REENCRYPT_BACKWARD : CRYP .direction = data_shift < 0 ? CRYPT_REENCRYPT_BACKWARD : CRYPT_RE
T_REENCRYPT_FORWARD, ENCRYPT_FORWARD,
.resilience = opt_resilience_mode ?: "checksum", .resilience = ARG_STR(OPT_RESILIENCE_ID) ?: "checksum",
.hash = opt_resilience_hash ?: "sha256", .hash = ARG_STR(OPT_RESILIENCE_HASH_ID) ?: "sha256",
.max_hotzone_size = opt_hotzone_size / SECTOR_SIZE, .max_hotzone_size = ARG_UINT64(OPT_HOTZONE_SIZE_ID) / SECTOR_SIZE
.device_size = opt_device_size / SECTOR_SIZE, ,
.device_size = ARG_UINT64(OPT_DEVICE_SIZE_ID) / SECTOR_SIZE,
.luks2 = &luks2_params, .luks2 = &luks2_params,
.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY .flags = CRYPT_REENCRYPT_INITIALIZE_ONLY
}; };
_set_reencryption_flags(&params.flags); _set_reencryption_flags(&params.flags);
type = luksType(device_type); type = luksType(device_type);
if (!type) if (!type)
type = crypt_get_default_type(); type = crypt_get_default_type();
if (strcmp(type, CRYPT_LUKS2)) { if (!isLUKS2(type)) {
log_err(_("Invalid LUKS device type.")); log_err(_("Encryption is supported only for LUKS2 format."));
return -EINVAL; return -EINVAL;
} }
if (!opt_data_shift && !opt_header_device) { if (!data_shift && !ARG_SET(OPT_HEADER_ID)) {
log_err(_("Encryption without detached header (--header) is not p ossible without data device size reduction (--reduce-device-size).")); log_err(_("Encryption without detached header (--header) is not p ossible without data device size reduction (--reduce-device-size)."));
return -ENOTSUP; return -ENOTSUP;
} }
if (!opt_header_device && opt_offset && opt_data_shift && (opt_offset > ( imaxabs(opt_data_shift) / (2 * SECTOR_SIZE)))) { if (!ARG_SET(OPT_HEADER_ID) && ARG_UINT64(OPT_OFFSET_ID) && data_shift && (ARG_UINT64(OPT_OFFSET_ID) > (imaxabs(data_shift) / (2 * SECTOR_SIZE)))) {
log_err(_("Requested data offset must be less than or equal to ha lf of --reduce-device-size parameter.")); log_err(_("Requested data offset must be less than or equal to ha lf of --reduce-device-size parameter."));
return -EINVAL; return -EINVAL;
} }
/* TODO: ask user to confirm. It's useless to do data device reduction an d than use smaller value */ /* TODO: ask user to confirm. It's useless to do data device reduction an d than use smaller value */
if (!opt_header_device && opt_offset && opt_data_shift && (opt_offset < ( if (!ARG_SET(OPT_HEADER_ID) && ARG_UINT64(OPT_OFFSET_ID) && data_shift &&
imaxabs(opt_data_shift) / (2 * SECTOR_SIZE)))) { (ARG_UINT64(OPT_OFFSET_ID) < (imaxabs(data_shift) / (2 * SECTOR_SIZE)))) {
opt_data_shift = -(opt_offset * 2 * SECTOR_SIZE); data_shift = -(ARG_UINT64(OPT_OFFSET_ID) * 2 * SECTOR_SIZE);
if (opt_data_shift >= 0) if (data_shift >= 0)
return -EINVAL; return -EINVAL;
log_std(_("Adjusting --reduce-device-size value to twice the --of log_std(_("Adjusting --reduce-device-size value to twice the --of
fset %" PRIu64 " (sectors).\n"), opt_offset * 2); fset %" PRIu64 " (sectors).\n"), ARG_UINT64(OPT_OFFSET_ID) * 2);
}
if (strncmp(type, CRYPT_LUKS2, strlen(CRYPT_LUKS2))) {
log_err(_("Encryption is supported only for LUKS2 format."));
return -EINVAL;
} }
if (opt_uuid && uuid_parse(opt_uuid, uuid) == -1) { if (ARG_SET(OPT_UUID_ID) && uuid_parse(ARG_STR(OPT_UUID_ID), uuid) == -1) {
log_err(_("Wrong LUKS UUID format provided.")); log_err(_("Wrong LUKS UUID format provided."));
return -EINVAL; return -EINVAL;
} }
if (!opt_uuid) { if (!ARG_SET(OPT_UUID_ID)) {
uuid_generate(uuid); uuid_generate(uuid);
uuid_unparse(uuid, uuid_str); uuid_unparse(uuid, uuid_str);
if (!(opt_uuid = strdup(uuid_str))) if (!(tmp = strdup(uuid_str)))
return -ENOMEM; return -ENOMEM;
ARG_SET_STR(OPT_UUID_ID, tmp);
} }
/* Check the data device is not LUKS device already */ /* Check the data device is not LUKS device already */
if ((r = crypt_init(cd, action_argv[0]))) if ((r = crypt_init(cd, action_argv[0])))
return r; return r;
r = crypt_load(*cd, CRYPT_LUKS, NULL); r = crypt_load(*cd, CRYPT_LUKS, NULL);
crypt_free(*cd); crypt_free(*cd);
*cd = NULL; *cd = NULL;
if (!r) { if (!r && !ARG_SET(OPT_BATCH_MODE_ID)) {
r = asprintf(&msg, _("Detected LUKS device on %s. Do you want to encrypt that LUKS device again?"), action_argv[0]); r = asprintf(&msg, _("Detected LUKS device on %s. Do you want to encrypt that LUKS device again?"), action_argv[0]);
if (r == -1) if (r == -1)
return -ENOMEM; return -ENOMEM;
r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL; r = yesDialog(msg, _("Operation aborted.\n")) ? 0 : -EINVAL;
free(msg); free(msg);
if (r < 0) if (r < 0)
return r; return r;
} }
if (!opt_header_device) { if (!ARG_SET(OPT_HEADER_ID)) {
r = snprintf(header_file, sizeof(header_file), "LUKS2-temp-%s.new r = snprintf(header_file, sizeof(header_file), "LUKS2-temp-%s.new
", opt_uuid); ", ARG_STR(OPT_UUID_ID));
if (r < 0 || (size_t)r >= sizeof(header_file)) if (r < 0 || (size_t)r >= sizeof(header_file))
return -EINVAL; return -EINVAL;
fd = open(header_file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR); fd = open(header_file, O_CREAT|O_EXCL|O_WRONLY, S_IRUSR|S_IWUSR);
if (fd == -1) { if (fd == -1) {
if (errno == EEXIST) if (errno == EEXIST)
log_err(_("Temporary header file %s already exist s. Aborting."), header_file); log_err(_("Temporary header file %s already exist s. Aborting."), header_file);
else else
log_err(_("Cannot create temporary header file %s ."), header_file); log_err(_("Cannot create temporary header file %s ."), header_file);
return -EINVAL; return -EINVAL;
} }
r = posix_fallocate(fd, 0, 4096); r = posix_fallocate(fd, 0, 4096);
close(fd); close(fd);
if (r) { if (r) {
log_err(_("Cannot create temporary header file %s."), hea der_file); log_err(_("Cannot create temporary header file %s."), hea der_file);
r = -EINVAL; r = -EINVAL;
goto err; goto out;
} }
if (!(opt_header_device = strdup(header_file))) { if (!(tmp = strdup(header_file))) {
r = -ENOMEM; r = -ENOMEM;
goto err; goto out;
} }
ARG_SET_STR(OPT_HEADER_ID, tmp);
/* /*
* FIXME: just override offset here, but we should support both. * FIXME: just override offset here, but we should support both.
* offset and implicit offset via data shift (lvprepend?) * offset and implicit offset via data shift (lvprepend?)
*/ */
if (!opt_offset) if (!ARG_UINT64(OPT_OFFSET_ID))
opt_offset = imaxabs(opt_data_shift) / (2 * SECTOR_SIZE); ARG_SET_UINT64(OPT_OFFSET_ID, imaxabs(data_shift) / (2 *
opt_data_shift >>= 1; SECTOR_SIZE));
data_shift >>= 1;
params.flags |= CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT; params.flags |= CRYPT_REENCRYPT_MOVE_FIRST_SEGMENT;
} else if (opt_data_shift < 0) { } else if (data_shift < 0) {
if (!opt_luks2_metadata_size) if (!ARG_SET(OPT_LUKS2_METADATA_SIZE_ID))
opt_luks2_metadata_size = 0x4000; /* missing default here ARG_SET_UINT64(OPT_LUKS2_METADATA_SIZE_ID, 0x4000); /* mi
*/ ssing default here */
if (!opt_luks2_keyslots_size) if (!ARG_SET(OPT_LUKS2_KEYSLOTS_SIZE_ID))
opt_luks2_keyslots_size = -opt_data_shift - 2 * opt_luks2 ARG_SET_UINT64(OPT_LUKS2_KEYSLOTS_SIZE_ID, -data_shift -
_metadata_size; 2 * ARG_UINT64(OPT_LUKS2_METADATA_SIZE_ID));
if (2 * ARG_UINT64(OPT_LUKS2_METADATA_SIZE_ID) + ARG_UINT64(OPT_L
if (2 * opt_luks2_metadata_size + opt_luks2_keyslots_size > (uint UKS2_KEYSLOTS_SIZE_ID) > (uint64_t)-data_shift) {
64_t)-opt_data_shift) {
log_err("LUKS2 metadata size is larger than data shift va lue."); log_err("LUKS2 metadata size is larger than data shift va lue.");
return -EINVAL; return -EINVAL;
} }
} }
r = _luksFormat(cd, &password, &passwordLen); r = _luksFormat(cd, &password, &passwordLen);
if (r < 0) if (r < 0)
goto err; goto out;
if (opt_data_shift) { if (data_shift) {
params.data_shift = imaxabs(opt_data_shift) / SECTOR_SIZE, params.data_shift = imaxabs(data_shift) / SECTOR_SIZE,
params.resilience = "datashift"; params.resilience = "datashift";
} }
keyslot = opt_key_slot < 0 ? 0 : opt_key_slot; keyslot = !ARG_SET(OPT_KEY_SLOT_ID) ? 0 : ARG_INT32(OPT_KEY_SLOT_ID);
r = crypt_reencrypt_init_by_passphrase(*cd, NULL, password, passwordLen, r = crypt_reencrypt_init_by_passphrase(*cd, NULL, password, passwordLen,
CRYPT_ANY_SLOT, keyslot, crypt_get_cipher(*cd), CRYPT_ANY_SLOT, keyslot, crypt_get_cipher(*cd),
crypt_get_cipher_mode(*cd), &params); crypt_get_cipher_mode(*cd), &params);
if (r < 0) { if (r < 0) {
crypt_keyslot_destroy(*cd, keyslot); crypt_keyslot_destroy(*cd, keyslot);
goto err; goto out;
} }
/* Restore temporary header in head of data device */ /* Restore temporary header in head of data device */
if (*header_file) { if (*header_file) {
crypt_free(*cd); crypt_free(*cd);
*cd = NULL; *cd = NULL;
r = crypt_init(cd, action_argv[0]); r = crypt_init(cd, action_argv[0]);
if (!r) if (!r)
r = crypt_header_restore(*cd, CRYPT_LUKS2, header_file); r = crypt_header_restore(*cd, CRYPT_LUKS2, header_file);
if (r) { if (r) {
log_err("Failed to place new header at head of device %s. ", action_argv[0]); log_err("Failed to place new header at head of device %s. ", action_argv[0]);
goto err; goto out;
} }
} }
/* activate device */ /* activate device */
if (action_argc > 1) { if (action_argc > 1) {
activated_name = action_argv[1]; activated_name = action_argv[1];
_set_activation_flags(&activate_flags); _set_activation_flags(&activate_flags);
r = crypt_activate_by_passphrase(*cd, activated_name, opt_key_slo t, password, passwordLen, activate_flags); r = crypt_activate_by_passphrase(*cd, activated_name, ARG_INT32(O PT_KEY_SLOT_ID), password, passwordLen, activate_flags);
if (r >= 0) if (r >= 0)
log_std(_("%s/%s is now active and ready for online encry ption.\n"), crypt_get_dir(), activated_name); log_std(_("%s/%s is now active and ready for online encry ption.\n"), crypt_get_dir(), activated_name);
} }
if (r < 0) if (r < 0)
goto err; goto out;
/* just load reencryption context to continue reencryption */ /* just load reencryption context to continue reencryption */
if (!opt_reencrypt_init_only) { if (!ARG_SET(OPT_INIT_ONLY_ID)) {
params.flags &= ~CRYPT_REENCRYPT_INITIALIZE_ONLY; params.flags &= ~CRYPT_REENCRYPT_INITIALIZE_ONLY;
r = crypt_reencrypt_init_by_passphrase(*cd, activated_name, passw ord, passwordLen, r = crypt_reencrypt_init_by_passphrase(*cd, activated_name, passw ord, passwordLen,
CRYPT_ANY_SLOT, keyslot, NULL, NULL, &params); CRYPT_ANY_SLOT, keyslot, NULL, NULL, &params);
} }
err: out:
crypt_safe_free(password); crypt_safe_free(password);
if (*header_file) if (*header_file)
unlink(header_file); unlink(header_file);
return r; return r;
} }
static int action_decrypt_luks2(struct crypt_device *cd) static int action_decrypt_luks2(struct crypt_device *cd)
{ {
int r; int r;
char dm_name[PATH_MAX], *password = NULL; char dm_name[PATH_MAX], *password = NULL;
const char *active_name = NULL; const char *active_name = NULL;
struct crypt_params_reencrypt params = { struct crypt_params_reencrypt params = {
.mode = CRYPT_REENCRYPT_DECRYPT, .mode = CRYPT_REENCRYPT_DECRYPT,
.direction = opt_data_shift > 0 ? CRYPT_REENCRYPT_FORWARD : CRYPT .direction = data_shift > 0 ? CRYPT_REENCRYPT_FORWARD : CRYPT_REE
_REENCRYPT_BACKWARD, NCRYPT_BACKWARD,
.resilience = opt_data_shift ? "datashift" : (opt_resilience_mode .resilience = data_shift ? "datashift" : (ARG_STR(OPT_RESILIENCE_
?: "checksum"), ID) ?: "checksum"),
.hash = opt_resilience_hash ?: "sha256", .hash = ARG_STR(OPT_RESILIENCE_HASH_ID) ?: "sha256",
.data_shift = imaxabs(opt_data_shift) / SECTOR_SIZE, .data_shift = imaxabs(data_shift) / SECTOR_SIZE,
.device_size = opt_device_size / SECTOR_SIZE, .device_size = ARG_UINT64(OPT_DEVICE_SIZE_ID) / SECTOR_SIZE,
.max_hotzone_size = opt_hotzone_size / SECTOR_SIZE, .max_hotzone_size = ARG_UINT64(OPT_HOTZONE_SIZE_ID) / SECTOR_SIZE
,
}; };
size_t passwordLen; size_t passwordLen;
if (!crypt_get_metadata_device_name(cd) || !crypt_get_device_name(cd) || if (!crypt_get_metadata_device_name(cd) || crypt_header_is_detached(cd) <
!strcmp(crypt_get_metadata_device_name(cd), crypt_get_device_name(cd) = 0) {
)) {
log_err(_("LUKS2 decryption is supported with detached header dev ice only.")); log_err(_("LUKS2 decryption is supported with detached header dev ice only."));
return -ENOTSUP; return -ENOTSUP;
} }
_set_reencryption_flags(&params.flags); _set_reencryption_flags(&params.flags);
r = tools_get_key(NULL, &password, &passwordLen, r = tools_get_key(NULL, &password, &passwordLen,
opt_keyfile_offset, opt_keyfile_size, opt_key_file, ARG_UINT64(OPT_KEYFILE_OFFSET_ID), ARG_UINT32(OPT_KEYFILE
opt_timeout, _verify_passphrase(0), 0, cd); _SIZE_ID), ARG_STR(OPT_KEY_FILE_ID),
ARG_UINT32(OPT_TIMEOUT_ID), _verify_passphrase(0), 0, cd)
;
if (r < 0) if (r < 0)
return r; return r;
if (!opt_active_name) { if (!ARG_SET(OPT_ACTIVE_NAME_ID)) {
r = _get_device_active_name(cd, action_argv[0], dm_name, sizeof(d m_name)); r = _get_device_active_name(cd, action_argv[0], dm_name, sizeof(d m_name));
if (r > 0) if (r > 0)
active_name = dm_name; active_name = dm_name;
if (r < 0) if (r < 0)
goto err; goto out;
} else } else
active_name = opt_active_name; active_name = ARG_STR(OPT_ACTIVE_NAME_ID);
if (!active_name) if (!active_name)
log_dbg("Device %s seems unused. Proceeding with offline operatio n.", action_argv[0]); log_dbg("Device %s seems unused. Proceeding with offline operatio n.", action_argv[0]);
r = crypt_reencrypt_init_by_passphrase(cd, active_name, password, r = crypt_reencrypt_init_by_passphrase(cd, active_name, password,
passwordLen, opt_key_slot, CRYPT_ANY_SLOT, NULL, NULL, &p passwordLen, ARG_INT32(OPT_KEY_SLOT_ID), CRYPT_ANY_SLOT,
arams); NULL, NULL, &params);
err: out:
crypt_safe_free(password); crypt_safe_free(password);
return r; return r;
} }
struct keyslot_passwords { struct keyslot_passwords {
char *password; char *password;
size_t passwordLen; size_t passwordLen;
int new; int new;
}; };
skipping to change at line 3078 skipping to change at line 3105
char *password; char *password;
int r = -EINVAL, retry_count; int r = -EINVAL, retry_count;
size_t passwordLen; size_t passwordLen;
if (slot_to_check != CRYPT_ANY_SLOT) { if (slot_to_check != CRYPT_ANY_SLOT) {
ki = crypt_keyslot_status(cd, slot_to_check); ki = crypt_keyslot_status(cd, slot_to_check);
if (ki < CRYPT_SLOT_ACTIVE || ki == CRYPT_SLOT_UNBOUND) if (ki < CRYPT_SLOT_ACTIVE || ki == CRYPT_SLOT_UNBOUND)
return -ENOENT; return -ENOENT;
} }
retry_count = (opt_tries && !opt_key_file) ? opt_tries : 1; retry_count = _set_tries_tty();
while (retry_count--) { while (retry_count--) {
r = tools_get_key(msg, &password, &passwordLen, 0, 0, r = tools_get_key(msg, &password, &passwordLen, 0, 0,
opt_key_file, 0, 0, 0 /*pwquality*/, cd); ARG_STR(OPT_KEY_FILE_ID), 0, 0, 0 /*pwquality*/ , cd);
if (r < 0) if (r < 0)
return r; return r;
if (quit) { if (quit) {
crypt_safe_free(password); crypt_safe_free(password);
password = NULL; password = NULL;
passwordLen = 0; passwordLen = 0;
return -EAGAIN; return -EAGAIN;
} }
r = crypt_activate_by_passphrase(cd, NULL, slot_to_check, r = crypt_activate_by_passphrase(cd, NULL, slot_to_check,
skipping to change at line 3150 skipping to change at line 3178
break; break;
} }
} }
/* at least one keyslot for reencryption plus new volume key */ /* at least one keyslot for reencryption plus new volume key */
if (active + unbound > max - 2) { if (active + unbound > max - 2) {
log_err(_("Not enough free keyslots for reencryption.")); log_err(_("Not enough free keyslots for reencryption."));
return -EINVAL; return -EINVAL;
} }
if ((opt_key_slot == CRYPT_ANY_SLOT) && if ((ARG_INT32(OPT_KEY_SLOT_ID) == CRYPT_ANY_SLOT) &&
(2 * active + unbound > max - 1)) { (2 * active + unbound > max - 1)) {
log_err(_("Not enough free keyslots for reencryption.")); log_err(_("Not enough free keyslots for reencryption."));
return -EINVAL; return -EINVAL;
} }
return 0; return 0;
} }
static int fill_keyslot_passwords(struct crypt_device *cd, static int fill_keyslot_passwords(struct crypt_device *cd,
struct keyslot_passwords *kp, size_t kp_size) struct keyslot_passwords *kp, size_t kp_size)
{ {
char msg[128]; char msg[128];
crypt_keyslot_info ki; crypt_keyslot_info ki;
int i, r = 0; int i, r = 0;
if (opt_key_slot == CRYPT_ANY_SLOT && opt_key_file) { if (ARG_INT32(OPT_KEY_SLOT_ID) == CRYPT_ANY_SLOT && ARG_SET(OPT_KEY_FILE_ ID)) {
for (i = 0; (size_t)i < kp_size; i++) { for (i = 0; (size_t)i < kp_size; i++) {
ki = crypt_keyslot_status(cd, i); ki = crypt_keyslot_status(cd, i);
if (ki == CRYPT_SLOT_INVALID) if (ki == CRYPT_SLOT_INVALID)
return -EINVAL; return -EINVAL;
if (ki == CRYPT_SLOT_ACTIVE) { if (ki == CRYPT_SLOT_ACTIVE) {
log_err(_("Key file can be used only with --key-s lot or with " log_err(_("Key file can be used only with --key-s lot or with "
"exactly one key slot active.")); "exactly one key slot active."));
return -EINVAL; return -EINVAL;
} }
} }
} }
if (opt_key_slot == CRYPT_ANY_SLOT) { if (ARG_INT32(OPT_KEY_SLOT_ID) == CRYPT_ANY_SLOT) {
for (i = 0; (size_t)i < kp_size; i++) { for (i = 0; (size_t)i < kp_size; i++) {
if (snprintf(msg, sizeof(msg), _("Enter passphrase for ke y slot %d: "), i) < 0) if (snprintf(msg, sizeof(msg), _("Enter passphrase for ke y slot %d: "), i) < 0)
return -EINVAL; return -EINVAL;
r = init_passphrase(kp, kp_size, cd, msg, i); r = init_passphrase(kp, kp_size, cd, msg, i);
if (r == -ENOENT) if (r == -ENOENT)
r = 0; r = 0;
if (r < 0) if (r < 0)
break; break;
} }
} else { } else {
if (snprintf(msg, sizeof(msg), _("Enter passphrase for key slot % u: "), opt_key_slot) < 0) if (snprintf(msg, sizeof(msg), _("Enter passphrase for key slot % u: "), ARG_INT32(OPT_KEY_SLOT_ID)) < 0)
return -EINVAL; return -EINVAL;
r = init_passphrase(kp, kp_size, cd, msg, opt_key_slot); r = init_passphrase(kp, kp_size, cd, msg, ARG_INT32(OPT_KEY_SLOT_ ID));
} }
return r < 0 ? r : 0; return r < 0 ? r : 0;
} }
static int assign_tokens(struct crypt_device *cd, int keyslot_old, int keyslot_n ew) static int assign_tokens(struct crypt_device *cd, int keyslot_old, int keyslot_n ew)
{ {
int token = 0, r = crypt_token_is_assigned(cd, token, keyslot_old); int token = 0, r = crypt_token_is_assigned(cd, token, keyslot_old);
while (r != -EINVAL) { while (r != -EINVAL) {
skipping to change at line 3223 skipping to change at line 3251
static int action_reencrypt_luks2(struct crypt_device *cd) static int action_reencrypt_luks2(struct crypt_device *cd)
{ {
size_t i, vk_size, kp_size; size_t i, vk_size, kp_size;
int r, keyslot_old = CRYPT_ANY_SLOT, keyslot_new = CRYPT_ANY_SLOT, key_si ze; int r, keyslot_old = CRYPT_ANY_SLOT, keyslot_new = CRYPT_ANY_SLOT, key_si ze;
char dm_name[PATH_MAX], cipher [MAX_CIPHER_LEN], mode[MAX_CIPHER_LEN], *v k = NULL; char dm_name[PATH_MAX], cipher [MAX_CIPHER_LEN], mode[MAX_CIPHER_LEN], *v k = NULL;
const char *active_name = NULL; const char *active_name = NULL;
struct keyslot_passwords *kp; struct keyslot_passwords *kp;
struct crypt_params_luks2 luks2_params = {}; struct crypt_params_luks2 luks2_params = {};
struct crypt_params_reencrypt params = { struct crypt_params_reencrypt params = {
.mode = CRYPT_REENCRYPT_REENCRYPT, .mode = CRYPT_REENCRYPT_REENCRYPT,
.direction = opt_data_shift < 0 ? CRYPT_REENCRYPT_BACKWARD : CRYP .direction = data_shift < 0 ? CRYPT_REENCRYPT_BACKWARD : CRYPT_RE
T_REENCRYPT_FORWARD, ENCRYPT_FORWARD,
.resilience = opt_data_shift ? "datashift" : (opt_resilience_mode .resilience = data_shift ? "datashift" : (ARG_STR(OPT_RESILIENCE_
?: "checksum"), ID) ?: "checksum"),
.hash = opt_resilience_hash ?: "sha256", .hash = ARG_STR(OPT_RESILIENCE_HASH_ID) ?: "sha256",
.data_shift = imaxabs(opt_data_shift) / SECTOR_SIZE, .data_shift = imaxabs(data_shift) / SECTOR_SIZE,
.max_hotzone_size = opt_hotzone_size / SECTOR_SIZE, .max_hotzone_size = ARG_UINT64(OPT_HOTZONE_SIZE_ID) / SECTOR_SIZE
.device_size = opt_device_size / SECTOR_SIZE, ,
.device_size = ARG_UINT64(OPT_DEVICE_SIZE_ID) / SECTOR_SIZE,
.luks2 = &luks2_params, .luks2 = &luks2_params,
}; };
_set_reencryption_flags(&params.flags); _set_reencryption_flags(&params.flags);
if (!opt_cipher && crypt_is_cipher_null(crypt_get_cipher(cd))) { if (!ARG_SET(OPT_CIPHER_ID) && crypt_is_cipher_null(crypt_get_cipher(cd))
opt_cipher = strdup(DEFAULT_CIPHER(LUKS1)); ) {
log_std(_("Switching data encryption cipher to %s.\n"), opt_ciphe log_std(_("Switching data encryption cipher to %s.\n"), DEFAULT_C
r); IPHER(LUKS1));
ARG_SET_STR(OPT_CIPHER_ID, strdup(DEFAULT_CIPHER(LUKS1)));
} }
if (!opt_cipher) { if (!ARG_SET(OPT_CIPHER_ID)) {
strncpy(cipher, crypt_get_cipher(cd), MAX_CIPHER_LEN - 1); strncpy(cipher, crypt_get_cipher(cd), MAX_CIPHER_LEN - 1);
strncpy(mode, crypt_get_cipher_mode(cd), MAX_CIPHER_LEN - 1); strncpy(mode, crypt_get_cipher_mode(cd), MAX_CIPHER_LEN - 1);
cipher[MAX_CIPHER_LEN-1] = '\0'; cipher[MAX_CIPHER_LEN-1] = '\0';
mode[MAX_CIPHER_LEN-1] = '\0'; mode[MAX_CIPHER_LEN-1] = '\0';
} else if ((r = crypt_parse_name_and_mode(opt_cipher, cipher, NULL, mode) )) { } else if ((r = crypt_parse_name_and_mode(ARG_STR(OPT_CIPHER_ID), cipher, NULL, mode))) {
log_err(_("No known cipher specification pattern detected.")); log_err(_("No known cipher specification pattern detected."));
return r; return r;
} }
luks2_params.sector_size = opt_sector_size ?: crypt_get_sector_size(cd); luks2_params.sector_size = ARG_UINT32(OPT_SECTOR_SIZE_ID) ?: (uint32_t)cr ypt_get_sector_size(cd);
r = _check_luks2_keyslots(cd); r = _check_luks2_keyslots(cd);
if (r) if (r)
return r; return r;
if (opt_key_size || opt_cipher) if (ARG_SET(OPT_KEY_SIZE_ID) || ARG_SET(OPT_CIPHER_ID))
key_size = get_adjusted_key_size(mode, DEFAULT_LUKS1_KEYBITS, 0); key_size = get_adjusted_key_size(mode, DEFAULT_LUKS1_KEYBITS, 0);
else else
key_size = crypt_get_volume_key_size(cd); key_size = crypt_get_volume_key_size(cd);
if (!key_size) if (!key_size)
return -EINVAL; return -EINVAL;
vk_size = key_size; vk_size = key_size;
r = crypt_keyslot_max(CRYPT_LUKS2); r = crypt_keyslot_max(CRYPT_LUKS2);
if (r < 0) if (r < 0)
return r; return r;
kp_size = r; kp_size = r;
kp = init_keyslot_passwords(kp_size); kp = init_keyslot_passwords(kp_size);
if (!kp) if (!kp)
return -ENOMEM; return -ENOMEM;
r = fill_keyslot_passwords(cd, kp, kp_size); r = fill_keyslot_passwords(cd, kp, kp_size);
if (r) if (r)
goto err; goto out;
if (opt_master_key_file) {
r = tools_read_mk(opt_master_key_file, &vk, key_size);
if (ARG_SET(OPT_MASTER_KEY_FILE_ID)) {
r = tools_read_mk(ARG_STR(OPT_MASTER_KEY_FILE_ID), &vk, key_size)
;
if (r < 0) if (r < 0)
goto err; goto out;
} }
r = -ENOENT; r = -ENOENT;
for (i = 0; i < kp_size; i++) { for (i = 0; i < kp_size; i++) {
if (kp[i].password && keyslot_new < 0) { if (kp[i].password && keyslot_new < 0) {
r = set_keyslot_params(cd, i); r = set_keyslot_params(cd, i);
if (r < 0) if (r < 0)
break; break;
r = crypt_keyslot_add_by_key(cd, CRYPT_ANY_SLOT, vk, key_ size, r = crypt_keyslot_add_by_key(cd, CRYPT_ANY_SLOT, vk, key_ size,
skipping to change at line 3331 skipping to change at line 3358
if (r < 0) if (r < 0)
break; break;
kp[i].new = r; kp[i].new = r;
r = assign_tokens(cd, i, r); r = assign_tokens(cd, i, r);
if (r < 0) if (r < 0)
break; break;
} }
} }
if (r < 0) if (r < 0)
goto err; goto out;
if (!opt_active_name && !opt_reencrypt_init_only) { if (!ARG_SET(OPT_ACTIVE_NAME_ID) && !ARG_SET(OPT_INIT_ONLY_ID)) {
r = _get_device_active_name(cd, action_argv[0], dm_name, sizeof(d m_name)); r = _get_device_active_name(cd, action_argv[0], dm_name, sizeof(d m_name));
if (r > 0) if (r > 0)
active_name = dm_name; active_name = dm_name;
if (r < 0) if (r < 0)
goto err; goto out;
} else if (opt_active_name) } else if (ARG_SET(OPT_ACTIVE_NAME_ID))
active_name = opt_active_name; active_name = ARG_STR(OPT_ACTIVE_NAME_ID);
if (!active_name && !opt_reencrypt_init_only) if (!active_name && !ARG_SET(OPT_INIT_ONLY_ID))
log_dbg("Device %s seems unused. Proceeding with offline operatio n.", action_argv[0]); log_dbg("Device %s seems unused. Proceeding with offline operatio n.", action_argv[0]);
r = crypt_reencrypt_init_by_passphrase(cd, active_name, kp[keyslot_old].p assword, r = crypt_reencrypt_init_by_passphrase(cd, active_name, kp[keyslot_old].p assword,
kp[keyslot_old].passwordLen, keyslot_old, kp[keyslot_old] .new, kp[keyslot_old].passwordLen, keyslot_old, kp[keyslot_old] .new,
cipher, mode, &params); cipher, mode, &params);
err: out:
crypt_safe_free(vk); crypt_safe_free(vk);
for (i = 0; i < kp_size; i++) { for (i = 0; i < kp_size; i++) {
crypt_safe_free(kp[i].password); crypt_safe_free(kp[i].password);
if (r < 0 && kp[i].new >= 0 && if (r < 0 && kp[i].new >= 0 &&
crypt_reencrypt_status(cd, NULL) == CRYPT_REENCRYPT_NONE && crypt_reencrypt_status(cd, NULL) == CRYPT_REENCRYPT_NONE &&
crypt_keyslot_destroy(cd, kp[i].new)) crypt_keyslot_destroy(cd, kp[i].new))
log_dbg("Failed to remove keyslot %d with unbound key.", kp[i].new); log_dbg("Failed to remove keyslot %d with unbound key.", kp[i].new);
} }
free(kp); free(kp);
return r; return r;
} }
static int action_reencrypt(void) static int action_reencrypt(void)
{ {
uint32_t flags; uint32_t flags;
struct crypt_device *cd = NULL; struct crypt_device *cd = NULL;
struct crypt_params_integrity ip = { 0 }; struct crypt_params_integrity ip = { 0 };
int r = 0; int r = 0;
struct tools_progress_params prog_parms = {
.frequency = ARG_UINT32(OPT_PROGRESS_FREQUENCY_ID),
.batch_mode = ARG_SET(OPT_BATCH_MODE_ID)
};
if (action_argc < 1 && (!opt_active_name || opt_encrypt)) { if (action_argc < 1 && (!ARG_SET(OPT_ACTIVE_NAME_ID) || ARG_SET(OPT_ENCRY PT_ID))) {
log_err(_("Command requires device as argument.")); log_err(_("Command requires device as argument."));
return -EINVAL; return -EINVAL;
} }
if (!opt_encrypt || opt_reencrypt_resume_only) { if (!ARG_SET(OPT_ENCRYPT_ID) || ARG_SET(OPT_RESUME_ONLY_ID)) {
if (opt_active_name) { if (ARG_SET(OPT_ACTIVE_NAME_ID)) {
r = crypt_init_by_name_and_header(&cd, opt_active_name, o r = crypt_init_by_name_and_header(&cd, ARG_STR(OPT_ACTIVE
pt_header_device); _NAME_ID), ARG_STR(OPT_HEADER_ID));
if (r || !crypt_get_type(cd) || strcmp(crypt_get_type(cd) if (r || !isLUKS2(crypt_get_type(cd))) {
, CRYPT_LUKS2)) { log_err(_("Device %s is not a valid LUKS device."
log_err(_("Device %s is not a valid LUKS device." ), ARG_STR(OPT_ACTIVE_NAME_ID));
), opt_active_name);
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
} else { } else {
if ((r = crypt_init_data_device(&cd, uuid_or_device(opt_h eader_device ?: action_argv[0]), action_argv[0]))) if ((r = crypt_init_data_device(&cd, uuid_or_device(ARG_S TR(OPT_HEADER_ID) ?: action_argv[0]), action_argv[0])))
return r; return r;
if ((r = crypt_load(cd, CRYPT_LUKS, NULL))) { if ((r = crypt_load(cd, CRYPT_LUKS, NULL))) {
log_err(_("Device %s is not a valid LUKS device." ), log_err(_("Device %s is not a valid LUKS device." ),
uuid_or_device(opt_header_device ?: actio n_argv[0])); uuid_or_device(ARG_STR(OPT_HEADER_ID) ?: action_argv[0]));
goto out; goto out;
} }
if (strcmp(crypt_get_type(cd), CRYPT_LUKS2)) { if (strcmp(crypt_get_type(cd), CRYPT_LUKS2)) {
log_err(_("Only LUKS2 format is currently support ed. Please use cryptsetup-reencrypt tool for LUKS1.")); log_err(_("Only LUKS2 format is currently support ed. Please use cryptsetup-reencrypt tool for LUKS1."));
r = -EINVAL; r = -EINVAL;
goto out; goto out;
} }
} }
if (crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &fla gs)) { if (crypt_persistent_flags_get(cd, CRYPT_FLAGS_REQUIREMENTS, &fla gs)) {
skipping to change at line 3420 skipping to change at line 3451
/* raw integrity info is available since 2.0 */ /* raw integrity info is available since 2.0 */
if (crypt_get_integrity_info(cd, &ip) || ip.tag_size) { if (crypt_get_integrity_info(cd, &ip) || ip.tag_size) {
log_err(_("Reencryption of device with integrity profile is not supported.")); log_err(_("Reencryption of device with integrity profile is not supported."));
r = -ENOTSUP; r = -ENOTSUP;
goto out; goto out;
} }
} }
if (r == -EBUSY) { if (r == -EBUSY) {
if (opt_reencrypt_init_only) if (ARG_SET(OPT_INIT_ONLY_ID))
log_err(_("LUKS2 reencryption already initialized. Aborti ng operation.")); log_err(_("LUKS2 reencryption already initialized. Aborti ng operation."));
else else
r = action_reencrypt_load(cd); r = action_reencrypt_load(cd);
} else if (!r && opt_reencrypt_resume_only) { } else if (!r && ARG_SET(OPT_RESUME_ONLY_ID)) {
log_err(_("LUKS2 device is not in reencryption.")); log_err(_("LUKS2 device is not in reencryption."));
r = -EINVAL; r = -EINVAL;
} else if (opt_decrypt) } else if (ARG_SET(OPT_DECRYPT_ID))
r = action_decrypt_luks2(cd); r = action_decrypt_luks2(cd);
else if (opt_encrypt && !opt_reencrypt_resume_only) else if (ARG_SET(OPT_ENCRYPT_ID) && !ARG_SET(OPT_RESUME_ONLY_ID))
r = action_encrypt_luks2(&cd); r = action_encrypt_luks2(&cd);
else else
r = action_reencrypt_luks2(cd); r = action_reencrypt_luks2(cd);
if (r >= 0 && !opt_reencrypt_init_only) { if (r >= 0 && !ARG_SET(OPT_INIT_ONLY_ID)) {
set_int_handler(0); set_int_handler(0);
r = crypt_reencrypt(cd, tools_reencrypt_progress); r = crypt_reencrypt_run(cd, tools_reencrypt_progress, &prog_parms );
} }
out: out:
crypt_free(cd); crypt_free(cd);
return r; return r;
} }
static struct action_type { static struct action_type {
const char *type; const char *type;
int (*handler)(void); int (*handler)(void);
int required_action_argc; int required_action_argc;
int required_memlock; int required_memlock;
const char *arg_desc; const char *arg_desc;
const char *desc; const char *desc;
} action_types[] = { } action_types[] = {
{ "open", action_open, 1, 1, N_("<device> [--type <type>] { OPEN_ACTION, action_open, 1, 1, N_("<device> [--typ
[<name>]"),N_("open device as <name>") }, e <type>] [<name>]"),N_("open device as <name>") },
{ "close", action_close, 1, 1, N_("<name>"), N_("close devi { CLOSE_ACTION, action_close, 1, 1, N_("<name>"), N_("c
ce (remove mapping)") }, lose device (remove mapping)") },
{ "resize", action_resize, 1, 1, N_("<name>"), N_("resize act { RESIZE_ACTION, action_resize, 1, 1, N_("<name>"), N_("r
ive device") }, esize active device") },
{ "status", action_status, 1, 0, N_("<name>"), N_("show devic { STATUS_ACTION, action_status, 1, 0, N_("<name>"), N_("s
e status") }, how device status") },
{ "benchmark", action_benchmark, 0, 0, N_("[--cipher <cipher>]"), N { BENCHMARK_ACTION, action_benchmark, 0, 0, N_("[--cipher <ciph
_("benchmark cipher") }, er>]"), N_("benchmark cipher") },
{ "repair", action_luksRepair, 1, 1, N_("<device>"), N_("try to r { REPAIR_ACTION, action_luksRepair, 1, 1, N_("<device>"), N_(
epair on-disk metadata") }, "try to repair on-disk metadata") },
{ "reencrypt", action_reencrypt, 0, 0, N_("<device>"), N_("reencryp { REENCRYPT_ACTION, action_reencrypt, 0, 0, N_("<device>"), N_(
t LUKS2 device") }, "reencrypt LUKS2 device") },
{ "erase", action_luksErase , 1, 1, N_("<device>"), N_("erase al { ERASE_ACTION, action_luksErase, 1, 1, N_("<device>"), N_(
l keyslots (remove encryption key)") }, "erase all keyslots (remove encryption key)") },
{ "convert", action_luksConvert, 1, 1, N_("<device>"), N_("convert { CONVERT_ACTION, action_luksConvert, 1, 1, N_("<device>"), N_(
LUKS from/to LUKS2 format") }, "convert LUKS from/to LUKS2 format") },
{ "config", action_luksConfig, 1, 1, N_("<device>"), N_("set perm { CONFIG_ACTION, action_luksConfig, 1, 1, N_("<device>"), N_(
anent configuration options for LUKS2") }, "set permanent configuration options for LUKS2") },
{ "luksFormat", action_luksFormat, 1, 1, N_("<device> [<new key file> { FORMAT_ACTION, action_luksFormat, 1, 1, N_("<device> [<new
]"), N_("formats a LUKS device") }, key file>]"), N_("formats a LUKS device") },
{ "luksAddKey", action_luksAddKey, 1, 1, N_("<device> [<new key file> { ADDKEY_ACTION, action_luksAddKey, 1, 1, N_("<device> [<new
]"), N_("add key to LUKS device") }, key file>]"), N_("add key to LUKS device") },
{ "luksRemoveKey",action_luksRemoveKey,1, 1, N_("<device> [<key file>]"), { REMOVEKEY_ACTION, action_luksRemoveKey, 1, 1, N_("<device> [<key
N_("removes supplied key or key file from LUKS device") }, file>]"), N_("removes supplied key or key file from LUKS device") },
{ "luksChangeKey",action_luksChangeKey,1, 1, N_("<device> [<key file>]"), { CHANGEKEY_ACTION, action_luksChangeKey, 1, 1, N_("<device> [<key
N_("changes supplied key or key file of LUKS device") }, file>]"), N_("changes supplied key or key file of LUKS device") },
{ "luksConvertKey",action_luksConvertKey,1, 1, N_("<device> [<key file>]" { CONVERTKEY_ACTION, action_luksConvertKey, 1, 1, N_("<device> [<key
), N_("converts a key to new pbkdf parameters") }, file>]"), N_("converts a key to new pbkdf parameters") },
{ "luksKillSlot", action_luksKillSlot, 2, 1, N_("<device> <key slot>"), N { KILLKEY_ACTION, action_luksKillSlot, 2, 1, N_("<device> <key s
_("wipes key with number <key slot> from LUKS device") }, lot>"), N_("wipes key with number <key slot> from LUKS device") },
{ "luksUUID", action_luksUUID, 1, 0, N_("<device>"), N_("print UU { UUID_ACTION, action_luksUUID, 1, 0, N_("<device>"), N_(
ID of LUKS device") }, "print UUID of LUKS device") },
{ "isLuks", action_isLuks, 1, 0, N_("<device>"), N_("tests <d { ISLUKS_ACTION, action_isLuks, 1, 0, N_("<device>"), N_(
evice> for LUKS partition header") }, "tests <device> for LUKS partition header") },
{ "luksDump", action_luksDump, 1, 1, N_("<device>"), N_("dump LUK { LUKSDUMP_ACTION, action_luksDump, 1, 1, N_("<device>"), N_(
S partition information") }, "dump LUKS partition information") },
{ "tcryptDump", action_tcryptDump, 1, 1, N_("<device>"), N_("dump TCR { TCRYPTDUMP_ACTION, action_tcryptDump, 1, 1, N_("<device>"), N_(
YPT device information") }, "dump TCRYPT device information") },
{ "bitlkDump", action_bitlkDump, 1, 1, N_("<device>"), N_("dump BIT { BITLKDUMP_ACTION, action_bitlkDump, 1, 1, N_("<device>"), N_(
LK device information") }, "dump BITLK device information") },
{ "luksSuspend", action_luksSuspend, 1, 1, N_("<device>"), N_("Suspend { SUSPEND_ACTION, action_luksSuspend, 1, 1, N_("<device>"), N_(
LUKS device and wipe key (all IOs are frozen)") }, "Suspend LUKS device and wipe key (all IOs are frozen)") },
{ "luksResume", action_luksResume, 1, 1, N_("<device>"), N_("Resume s { RESUME_ACTION, action_luksResume, 1, 1, N_("<device>"), N_(
uspended LUKS device") }, "Resume suspended LUKS device") },
{ "luksHeaderBackup", action_luksBackup,1,1, N_("<device>"), N_("Backup L { HEADERBACKUP_ACTION, action_luksBackup, 1, 1, N_("<device>"), N_(
UKS device header and keyslots") }, "Backup LUKS device header and keyslots") },
{ "luksHeaderRestore",action_luksRestore,1,1,N_("<device>"), N_("Restore { HEADERRESTORE_ACTION, action_luksRestore, 1, 1, N_("<device>"), N_(
LUKS device header and keyslots") }, "Restore LUKS device header and keyslots") },
{ "token", action_token, 2, 0, N_("<add|remove|import|expor { TOKEN_ACTION, action_token, 2, 0, N_("<add|remove|imp
t> <device>"), N_("Manipulate LUKS2 tokens") }, ort|export> <device>"), N_("Manipulate LUKS2 tokens") },
{} {}
}; };
static void help(poptContext popt_context, static void help(poptContext popt_context,
enum poptCallbackReason reason __attribute__((unused)), enum poptCallbackReason reason __attribute__((unused)),
struct poptOption *key, struct poptOption *key,
const char *arg __attribute__((unused)), const char *arg __attribute__((unused)),
void *data __attribute__((unused))) void *data __attribute__((unused)))
{ {
const char *path;
if (key->shortName == '?') { if (key->shortName == '?') {
struct action_type *action; struct action_type *action;
const struct crypt_pbkdf_type *pbkdf_luks1, *pbkdf_luks2; const struct crypt_pbkdf_type *pbkdf_luks1, *pbkdf_luks2;
log_std("%s\n",PACKAGE_STRING); log_std("%s\n",PACKAGE_STRING);
poptPrintHelp(popt_context, stdout, 0); poptPrintHelp(popt_context, stdout, 0);
log_std(_("\n" log_std(_("\n"
"<action> is one of:\n")); "<action> is one of:\n"));
skipping to change at line 3515 skipping to change at line 3548
log_std(_("\n" log_std(_("\n"
"<name> is the device to create under %s\n" "<name> is the device to create under %s\n"
"<device> is the encrypted device\n" "<device> is the encrypted device\n"
"<key slot> is the LUKS key slot number to modify\n" "<key slot> is the LUKS key slot number to modify\n"
"<key file> optional key file for the new key for luksAd dKey action\n"), "<key file> optional key file for the new key for luksAd dKey action\n"),
crypt_get_dir()); crypt_get_dir());
log_std(_("\nDefault compiled-in metadata format is %s (for luksF ormat action).\n"), log_std(_("\nDefault compiled-in metadata format is %s (for luksF ormat action).\n"),
crypt_get_default_type()); crypt_get_default_type());
path = crypt_token_external_path();
if (path) {
log_std(_("\nLUKS2 external token plugin support is %s.\n
"), _("compiled-in"));
log_std(_("LUKS2 external token plugin path: %s.\n"), pat
h);
} else
log_std(_("\nLUKS2 external token plugin support is %s.\n
"), _("disabled"));
pbkdf_luks1 = crypt_get_pbkdf_default(CRYPT_LUKS1); pbkdf_luks1 = crypt_get_pbkdf_default(CRYPT_LUKS1);
pbkdf_luks2 = crypt_get_pbkdf_default(CRYPT_LUKS2); pbkdf_luks2 = crypt_get_pbkdf_default(CRYPT_LUKS2);
log_std(_("\nDefault compiled-in key and passphrase parameters:\n " log_std(_("\nDefault compiled-in key and passphrase parameters:\n "
"\tMaximum keyfile size: %dkB, " "\tMaximum keyfile size: %dkB, "
"Maximum interactive passphrase length %d (characters)\n " "Maximum interactive passphrase length %d (characters)\n "
"Default PBKDF for LUKS1: %s, iteration time: %d (ms)\n" "Default PBKDF for LUKS1: %s, iteration time: %d (ms)\n"
"Default PBKDF for LUKS2: %s\n" "Default PBKDF for LUKS2: %s\n"
"\tIteration time: %d, Memory required: %dkB, Parallel t hreads: %d\n"), "\tIteration time: %d, Memory required: %dkB, Parallel t hreads: %d\n"),
DEFAULT_KEYFILE_SIZE_MAXKB, DEFAULT_PASSPHRASE_SIZE_MAX, DEFAULT_KEYFILE_SIZE_MAXKB, DEFAULT_PASSPHRASE_SIZE_MAX,
pbkdf_luks1->type, pbkdf_luks1->time_ms, pbkdf_luks1->type, pbkdf_luks1->time_ms,
skipping to change at line 3583 skipping to change at line 3623
/* Some functions returns keyslot # */ /* Some functions returns keyslot # */
if (r > 0) if (r > 0)
r = 0; r = 0;
check_signal(&r); check_signal(&r);
show_status(r); show_status(r);
return translate_errno(r); return translate_errno(r);
} }
static bool needs_size_conversion(unsigned arg_id)
{
return (arg_id == OPT_DEVICE_SIZE_ID || arg_id == OPT_HOTZONE_SIZE_ID ||
arg_id == OPT_LUKS2_KEYSLOTS_SIZE_ID || arg_id == OPT_LUKS2_METAD
ATA_SIZE_ID ||
arg_id == OPT_REDUCE_DEVICE_SIZE_ID);
}
static void check_key_slot_value(poptContext popt_context)
{
if (ARG_INT32(OPT_KEY_SLOT_ID) < 0)
usage(popt_context, EXIT_FAILURE, _("Key slot is invalid."),
poptGetInvocationName(popt_context));
}
static void basic_options_cb(poptContext popt_context,
enum poptCallbackReason reason __attribute__((unused)),
struct poptOption *key,
const char *arg,
void *data __attribute__((unused)))
{
tools_parse_arg_value(popt_context, tool_core_args[key->val].type, tool_c
ore_args + key->val, arg, key->val, needs_size_conversion);
/* special cases additional handling */
switch (key->val) {
case OPT_DEBUG_JSON_ID:
/* fall through */
case OPT_DEBUG_ID:
log_parms.debug = true;
/* fall through */
case OPT_VERBOSE_ID:
log_parms.verbose = true;
break;
case OPT_DEVICE_SIZE_ID:
if (ARG_UINT64(OPT_DEVICE_SIZE_ID) == 0)
usage(popt_context, EXIT_FAILURE, poptStrerror(POPT_ERROR
_BADNUMBER),
poptGetInvocationName(popt_context));
if (ARG_UINT64(OPT_DEVICE_SIZE_ID) % SECTOR_SIZE)
usage(popt_context, EXIT_FAILURE, _("Device size must be
multiple of 512 bytes sector."),
poptGetInvocationName(popt_context));
break;
case OPT_HOTZONE_SIZE_ID:
if (ARG_UINT64(OPT_HOTZONE_SIZE_ID) == 0)
usage(popt_context, EXIT_FAILURE, _("Invalid max reencryp
tion hotzone size specification."),
poptGetInvocationName(popt_context));
break;
case OPT_KEY_FILE_ID:
if (tools_is_stdin(ARG_STR(OPT_KEY_FILE_ID))) {
free(keyfile_stdin);
keyfile_stdin = strdup(ARG_STR(OPT_KEY_FILE_ID));
} else if (keyfiles_count < MAX_KEYFILES)
keyfiles[keyfiles_count++] = strdup(ARG_STR(OPT_KEY_FILE_
ID));
total_keyfiles++;
break;
case OPT_KEY_SIZE_ID:
if (ARG_UINT32(OPT_KEY_SIZE_ID) % 8)
usage(popt_context, EXIT_FAILURE,
_("Key size must be a multiple of 8 bits"),
poptGetInvocationName(popt_context));
break;
case OPT_KEY_SLOT_ID:
check_key_slot_value(popt_context);
break;
case OPT_KEYSLOT_KEY_SIZE_ID:
if (ARG_UINT32(OPT_KEYSLOT_KEY_SIZE_ID) == 0)
usage(popt_context, EXIT_FAILURE, poptStrerror(POPT_ERROR
_BADNUMBER),
poptGetInvocationName(popt_context));
if (ARG_UINT32(OPT_KEYSLOT_KEY_SIZE_ID) % 8)
usage(popt_context, EXIT_FAILURE,
_("Key size must be a multiple of 8 bits"),
poptGetInvocationName(popt_context));
break;
case OPT_REDUCE_DEVICE_SIZE_ID:
if (ARG_UINT64(OPT_REDUCE_DEVICE_SIZE_ID) > 1024 * 1024 * 1024)
usage(popt_context, EXIT_FAILURE, _("Maximum device reduc
e size is 1 GiB."),
poptGetInvocationName(popt_context));
if (ARG_UINT64(OPT_REDUCE_DEVICE_SIZE_ID) % SECTOR_SIZE)
usage(popt_context, EXIT_FAILURE, _("Reduce size must be
multiple of 512 bytes sector."),
poptGetInvocationName(popt_context));
data_shift = -(int64_t)ARG_UINT64(OPT_REDUCE_DEVICE_SIZE_ID);
break;
case OPT_SECTOR_SIZE_ID:
if (ARG_UINT32(OPT_SECTOR_SIZE_ID) < SECTOR_SIZE ||
ARG_UINT32(OPT_SECTOR_SIZE_ID) > MAX_SECTOR_SIZE ||
(ARG_UINT32(OPT_SECTOR_SIZE_ID) & (ARG_UINT32(OPT_SECTOR_SIZE
_ID) - 1)))
usage(popt_context, EXIT_FAILURE,
_("Unsupported encryption sector size."),
poptGetInvocationName(popt_context));
break;
case OPT_PRIORITY_ID:
if (strcmp(ARG_STR(OPT_PRIORITY_ID), "normal") &&
strcmp(ARG_STR(OPT_PRIORITY_ID), "prefer") &&
strcmp(ARG_STR(OPT_PRIORITY_ID), "ignore"))
usage(popt_context, EXIT_FAILURE,
_("Option --priority can be only ignore/normal/prefer."),
poptGetInvocationName(popt_context));
break;
}
}
int main(int argc, const char **argv) int main(int argc, const char **argv)
{ {
static struct poptOption popt_help_options[] = { static struct poptOption popt_help_options[] = {
{ NULL, '\0', POPT_ARG_CALLBACK, help, 0, NULL, NULL }, { NULL, '\0', POPT_ARG_CALLBACK, help, 0, NULL, NULL },
{ "help", '?', POPT_ARG_NONE, NULL, 0, N_("Show this help m essage"), NULL }, { "help", '?', POPT_ARG_NONE, NULL, 0, N_("Show this help m essage"), NULL },
{ "usage", '\0', POPT_ARG_NONE, NULL, 0, N_("Display brief us age"), NULL }, { "usage", '\0', POPT_ARG_NONE, NULL, 0, N_("Display brief us age"), NULL },
{ "version",'V', POPT_ARG_NONE, NULL, 0, N_("Print package ve rsion"), NULL }, { "version",'V', POPT_ARG_NONE, NULL, 0, N_("Print package ve rsion"), NULL },
POPT_TABLEEND POPT_TABLEEND
}; };
static struct poptOption popt_basic_options[] = {
{ NULL, '\0', POPT_ARG_CALLBACK, basic_options_cb, 0, NULL, NU
LL },
#define ARG(A, B, C, D, E, F, G, H) { A, B, C, NULL, A ## _ID, D, E },
#include "cryptsetup_arg_list.h"
#undef arg
POPT_TABLEEND
};
static struct poptOption popt_options[] = { static struct poptOption popt_options[] = {
{ NULL, '\0', POPT_ARG_INCLUDE_TABLE, popt_help_op { NULL, '\0', POPT_ARG_INCLUDE_TABLE, popt_help_options, 0, N_("
tions, 0, N_("Help options:"), NULL }, Help options:"), NULL },
{ "verbose", 'v', POPT_ARG_NONE, &opt_verbose, { NULL, '\0', POPT_ARG_INCLUDE_TABLE, popt_basic_options, 0, NULL
0, N_("Shows more detailed error messages"), NULL }, , NULL },
{ "debug", '\0', POPT_ARG_NONE, &opt_debug,
0, N_("Show debug messages"), NULL },
{ "debug-json", '\0', POPT_ARG_NONE, &opt_debug_json,
0, N_("Show debug messages including JSON metadata"), NULL },
{ "cipher", 'c', POPT_ARG_STRING, &opt_cipher,
0, N_("The cipher used to encrypt the disk (see /proc/crypto)"), NULL },
{ "hash", 'h', POPT_ARG_STRING, &opt_hash,
0, N_("The hash used to create the encryption key from the passphrase"),
NULL },
{ "verify-passphrase", 'y', POPT_ARG_NONE, &opt_verify_passphras
e, 0, N_("Verifies the passphrase by asking for it twice"), NULL },
{ "key-file", 'd', POPT_ARG_STRING, NULL,
6, N_("Read the key from a file"), NULL },
{ "master-key-file", '\0', POPT_ARG_STRING, &opt_master_key_fil
e, 0, N_("Read the volume (master) key from file."), NULL },
{ "dump-master-key", '\0', POPT_ARG_NONE, &opt_dump_master_key,
0, N_("Dump volume (master) key instead of keyslots info"), NULL },
{ "key-size", 's', POPT_ARG_INT, &opt_key_size,
0, N_("The size of the encryption key"), N_("BITS") },
{ "keyfile-size", 'l', POPT_ARG_LONG, &opt_keyfile_size,
0, N_("Limits the read from keyfile"), N_("bytes") },
{ "keyfile-offset", '\0', POPT_ARG_STRING, NULL,
4, N_("Number of bytes to skip in keyfile"), N_("bytes") },
{ "new-keyfile-size", '\0', POPT_ARG_LONG, &opt_new_keyfile_size
, 0, N_("Limits the read from newly added keyfile"), N_("bytes") },
{ "new-keyfile-offset",'\0', POPT_ARG_STRING, NULL,
5, N_("Number of bytes to skip in newly added keyfile"), N_("bytes") },
{ "key-slot", 'S', POPT_ARG_INT, &opt_key_slot,
0, N_("Slot number for new key (default is first free)"), NULL },
{ "size", 'b', POPT_ARG_STRING, NULL,
1, N_("The size of the device"), N_("SECTORS") },
{ "device-size", '\0', POPT_ARG_STRING, &opt_device_size_st
r, 0, N_("Use only specified device size (ignore rest of device). DANGEROUS!
"), N_("bytes") },
{ "offset", 'o', POPT_ARG_STRING, NULL,
2, N_("The start offset in the backend device"), N_("SECTORS") },
{ "skip", 'p', POPT_ARG_STRING, NULL,
3, N_("How many sectors of the encrypted data to skip at the beginning"),
N_("SECTORS") },
{ "readonly", 'r', POPT_ARG_NONE, &opt_readonly,
0, N_("Create a readonly mapping"), NULL },
{ "batch-mode", 'q', POPT_ARG_NONE, &opt_batch_mode,
0, N_("Do not ask for confirmation"), NULL },
{ "timeout", 't', POPT_ARG_INT, &opt_timeout,
0, N_("Timeout for interactive passphrase prompt (in seconds)"), N_("secs
") },
{ "progress-frequency",'\0', POPT_ARG_INT, &opt_progress_frequenc
y, 0, N_("Progress line update (in seconds)"), N_("secs") },
{ "tries", 'T', POPT_ARG_INT, &opt_tries,
0, N_("How often the input of the passphrase can be retried"), NULL },
{ "align-payload", '\0', POPT_ARG_INT, &opt_align_payload,
0, N_("Align payload at <n> sector boundaries - for luksFormat"), N_("SEC
TORS") },
{ "header-backup-file",'\0', POPT_ARG_STRING, &opt_header_backup_
file, 0, N_("File with LUKS header and keyslots backup"), NULL },
{ "use-random", '\0', POPT_ARG_NONE, &opt_random,
0, N_("Use /dev/random for generating volume key"), NULL },
{ "use-urandom", '\0', POPT_ARG_NONE, &opt_urandom,
0, N_("Use /dev/urandom for generating volume key"), NULL },
{ "shared", '\0', POPT_ARG_NONE, &opt_shared,
0, N_("Share device with another non-overlapping crypt segment"), NULL },
{ "uuid", '\0', POPT_ARG_STRING, &opt_uuid,
0, N_("UUID for device to use"), NULL },
{ "allow-discards", '\0', POPT_ARG_NONE, &opt_allow_discards,
0, N_("Allow discards (aka TRIM) requests for device"), NULL },
{ "header", '\0', POPT_ARG_STRING, &opt_header_device,
0, N_("Device or file with separated LUKS header"), NULL },
{ "test-passphrase", '\0', POPT_ARG_NONE, &opt_test_passphrase,
0, N_("Do not activate device, just check passphrase"), NULL },
{ "tcrypt-hidden", '\0', POPT_ARG_NONE, &opt_tcrypt_hidden,
0, N_("Use hidden header (hidden TCRYPT device)"), NULL },
{ "tcrypt-system", '\0', POPT_ARG_NONE, &opt_tcrypt_system,
0, N_("Device is system TCRYPT drive (with bootloader)"), NULL },
{ "tcrypt-backup", '\0', POPT_ARG_NONE, &opt_tcrypt_backup,
0, N_("Use backup (secondary) TCRYPT header"), NULL },
{ "veracrypt", '\0', POPT_ARG_NONE, &opt_veracrypt,
0, N_("Scan also for VeraCrypt compatible device"), NULL },
{ "veracrypt-pim", '\0', POPT_ARG_INT, &opt_veracrypt_pim,
0, N_("Personal Iteration Multiplier for VeraCrypt compatible device"), N
ULL },
{ "veracrypt-query-pim", '\0', POPT_ARG_NONE, &opt_veracrypt_quer
y_pim, 0, N_("Query Personal Iteration Multiplier for VeraCrypt compatible devic
e"), NULL },
{ "type", 'M', POPT_ARG_STRING, &opt_type,
0, N_("Type of device metadata: luks, luks1, luks2, plain, loopaes, tcryp
t, bitlk"), NULL },
{ "force-password", '\0', POPT_ARG_NONE, &opt_force_password,
0, N_("Disable password quality check (if enabled)"), NULL },
{ "perf-same_cpu_crypt",'\0', POPT_ARG_NONE, &opt_perf_same_cpu_c
rypt, 0, N_("Use dm-crypt same_cpu_crypt performance compatibility option"), NU
LL },
{ "perf-submit_from_crypt_cpus",'\0', POPT_ARG_NONE, &opt_perf_su
bmit_from_crypt_cpus,0,N_("Use dm-crypt submit_from_crypt_cpus performance compa
tibility option"), NULL },
{ "perf-no_read_workqueue",'\0', POPT_ARG_NONE, &opt_perf_no_read
_workqueue,0,N_("Bypass dm-crypt workqueue and process read requests synchronous
ly"), NULL },
{ "perf-no_write_workqueue",'\0', POPT_ARG_NONE, &opt_perf_no_wri
te_workqueue,0,N_("Bypass dm-crypt workqueue and process write requests synchron
ously"), NULL },
{ "deferred", '\0', POPT_ARG_NONE, &opt_deferred_remove,
0, N_("Device removal is deferred until the last user closes it"), NULL }
,
{ "serialize-memory-hard-pbkdf", '\0', POPT_ARG_NONE, &opt_serial
ize_memory_hard_pbkdf, 0, N_("Use global lock to serialize memory hard PBKDF (OO
M workaround)"), NULL },
{ "iter-time", 'i', POPT_ARG_INT, &opt_iteration_time,
0, N_("PBKDF iteration time for LUKS (in ms)"), N_("msecs") },
{ "pbkdf", '\0', POPT_ARG_STRING, &opt_pbkdf,
0, N_("PBKDF algorithm (for LUKS2): argon2i, argon2id, pbkdf2"), NULL },
{ "pbkdf-memory", '\0', POPT_ARG_LONG, &opt_pbkdf_memory,
0, N_("PBKDF memory cost limit"), N_("kilobytes") },
{ "pbkdf-parallel", '\0', POPT_ARG_LONG, &opt_pbkdf_parallel,
0, N_("PBKDF parallel cost"), N_("threads") },
{ "pbkdf-force-iterations",'\0',POPT_ARG_LONG, &opt_pbkdf_iterati
ons, 0, N_("PBKDF iterations cost (forced, disables benchmark)"), NULL },
{ "priority", '\0', POPT_ARG_STRING, &opt_priority,
0, N_("Keyslot priority: ignore, normal, prefer"), NULL },
{ "disable-locks", '\0', POPT_ARG_NONE, &opt_disable_locks,
0, N_("Disable locking of on-disk metadata"), NULL },
{ "disable-keyring", '\0', POPT_ARG_NONE, &opt_disable_keyring,
0, N_("Disable loading volume keys via kernel keyring"), NULL },
{ "integrity", 'I', POPT_ARG_STRING, &opt_integrity,
0, N_("Data integrity algorithm (LUKS2 only)"), NULL },
{ "integrity-no-journal",'\0',POPT_ARG_NONE, &opt_integrity_nojou
rnal, 0, N_("Disable journal for integrity device"), NULL },
{ "integrity-no-wipe", '\0', POPT_ARG_NONE, &opt_integrity_no_wip
e, 0, N_("Do not wipe device after format"), NULL },
{ "integrity-legacy-padding",'\0', POPT_ARG_NONE, &opt_integrity_
legacy_padding,0, N_("Use inefficient legacy padding (old kernels)"), NULL },
{ "token-only", '\0', POPT_ARG_NONE, &opt_token_only,
0, N_("Do not ask for passphrase if activation by token fails"), NULL },
{ "token-id", '\0', POPT_ARG_INT, &opt_token,
0, N_("Token number (default: any)"), NULL },
{ "key-description", '\0', POPT_ARG_STRING, &opt_key_descriptio
n, 0, N_("Key description"), NULL },
{ "sector-size", '\0', POPT_ARG_INT, &opt_sector_size,
0, N_("Encryption sector size (default: 512 bytes)"), NULL },
{ "iv-large-sectors", '\0', POPT_ARG_NONE, &opt_iv_large_sectors
, 0, N_("Use IV counted in sector size (not in 512 bytes)"), NULL },
{ "persistent", '\0', POPT_ARG_NONE, &opt_persistent,
0, N_("Set activation flags persistent for device"), NULL },
{ "label", '\0', POPT_ARG_STRING, &opt_label,
0, N_("Set label for the LUKS2 device"), NULL },
{ "subsystem", '\0', POPT_ARG_STRING, &opt_subsystem,
0, N_("Set subsystem label for the LUKS2 device"), NULL },
{ "unbound", '\0', POPT_ARG_NONE, &opt_unbound,
0, N_("Create or dump unbound (no assigned data segment) LUKS2 keyslot"),
NULL },
{ "json-file", '\0', POPT_ARG_STRING, &opt_json_file,
0, N_("Read or write the json from or to a file"), NULL },
{ "luks2-metadata-size",'\0',POPT_ARG_STRING,&opt_luks2_metadata_
size_str,0,N_("LUKS2 header metadata area size"), N_("bytes") },
{ "luks2-keyslots-size",'\0',POPT_ARG_STRING,&opt_luks2_keyslots_
size_str,0,N_("LUKS2 header keyslots area size"), N_("bytes") },
{ "refresh", '\0', POPT_ARG_NONE, &opt_refresh,
0, N_("Refresh (reactivate) device with new parameters"), NULL },
{ "keyslot-key-size", '\0', POPT_ARG_INT, &opt_keyslot_key_size,
0, N_("LUKS2 keyslot: The size of the encryption key"), N_("BITS") },
{ "keyslot-cipher", '\0', POPT_ARG_STRING, &opt_keyslot_cipher
, 0, N_("LUKS2 keyslot: The cipher used for keyslot encryption"), NULL },
{ "encrypt", '\0', POPT_ARG_NONE, &opt_encrypt,
0, N_("Encrypt LUKS2 device (in-place encryption)."), NULL },
{ "decrypt", '\0', POPT_ARG_NONE, &opt_decrypt,
0, N_("Decrypt LUKS2 device (remove encryption)."), NULL },
{ "init-only", '\0', POPT_ARG_NONE, &opt_reencrypt_init_o
nly, 0, N_("Initialize LUKS2 reencryption in metadata only."), NULL },
{ "resume-only", '\0', POPT_ARG_NONE, &opt_reencrypt_resume
_only, 0, N_("Resume initialized LUKS2 reencryption only."), NULL },
{ "reduce-device-size",'\0', POPT_ARG_STRING, &opt_reduce_size_st
r, 0, N_("Reduce data device size (move data offset). DANGEROUS!"), N_("byte
s") },
{ "hotzone-size", '\0', POPT_ARG_STRING, &opt_hotzone_size_s
tr, 0, N_("Maximal reencryption hotzone size."), N_("bytes") },
{ "resilience", '\0', POPT_ARG_STRING, &opt_resilience_mod
e, 0, N_("Reencryption hotzone resilience type (checksum,journal,none)"), NU
LL },
{ "resilience-hash", '\0', POPT_ARG_STRING, &opt_resilience_has
h, 0, N_("Reencryption hotzone checksums hash"), NULL },
{ "active-name", '\0', POPT_ARG_STRING, &opt_active_name,
0, N_("Override device autodetection of dm device to be reencrypted"), NU
LL },
POPT_TABLEEND POPT_TABLEEND
}; };
poptContext popt_context; poptContext popt_context;
struct action_type *action; struct action_type *action;
const char *aname; const char *aname;
int r, total_keyfiles = 0; int r;
crypt_set_log_callback(NULL, tool_log, NULL); crypt_set_log_callback(NULL, tool_log, &log_parms);
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR); bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE); textdomain(PACKAGE);
popt_context = poptGetContext(PACKAGE, argc, argv, popt_options, 0); popt_context = poptGetContext(PACKAGE, argc, argv, popt_options, 0);
poptSetOtherOptionHelp(popt_context, poptSetOtherOptionHelp(popt_context,
_("[OPTION...] <action> <action-specific>")); _("[OPTION...] <action> <action-specific>"));
while((r = poptGetNextOpt(popt_context)) > 0) { while ((r = poptGetNextOpt(popt_context)) > 0) {}
unsigned long long ull_value;
char *endp, *str = poptGetOptArg(popt_context);
if (r == 6) {
free(opt_key_file);
opt_key_file = str;
if (tools_is_stdin(str)) {
free(opt_keyfile_stdin);
opt_keyfile_stdin = strdup(str);
} else if (opt_keyfiles_count < MAX_KEYFILES)
opt_keyfiles[opt_keyfiles_count++] = strdup(str);
total_keyfiles++;
continue;
}
errno = 0;
ull_value = strtoull(str, &endp, 0);
if (*endp || !*str || !isdigit(*str) ||
(errno == ERANGE && ull_value == ULLONG_MAX) ||
(errno != 0 && ull_value == 0))
r = POPT_ERROR_BADNUMBER;
free(str);
switch(r) {
case 1:
opt_size = ull_value;
break;
case 2:
opt_offset = ull_value;
break;
case 3:
opt_skip = ull_value;
opt_skip_valid = 1;
break;
case 4:
opt_keyfile_offset = ull_value;
break;
case 5:
opt_new_keyfile_offset = ull_value;
break;
}
if (r < 0)
break;
}
if (r < -1) if (r < -1)
usage(popt_context, EXIT_FAILURE, poptStrerror(r), usage(popt_context, EXIT_FAILURE, poptStrerror(r),
poptBadOption(popt_context, POPT_BADOPTION_NOALIAS)); poptBadOption(popt_context, POPT_BADOPTION_NOALIAS));
if (!(aname = poptGetArg(popt_context))) if (!(aname = poptGetArg(popt_context)))
usage(popt_context, EXIT_FAILURE, _("Argument <action> missing.") , usage(popt_context, EXIT_FAILURE, _("Argument <action> missing.") ,
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
action_argc = 0; action_argc = 0;
skipping to change at line 3768 skipping to change at line 3786
action_argc++; action_argc++;
/* Handle aliases */ /* Handle aliases */
if (!strcmp(aname, "create")) { if (!strcmp(aname, "create")) {
/* create command had historically switched arguments */ /* create command had historically switched arguments */
if (action_argv[0] && action_argv[1]) { if (action_argv[0] && action_argv[1]) {
const char *tmp = action_argv[0]; const char *tmp = action_argv[0];
action_argv[0] = action_argv[1]; action_argv[0] = action_argv[1];
action_argv[1] = tmp; action_argv[1] = tmp;
} }
aname = "open"; aname = OPEN_ACTION;
device_type = "plain"; device_type = "plain";
} else if (!strcmp(aname, "plainOpen")) { } else if (!strcmp(aname, "plainOpen")) {
aname = "open"; aname = OPEN_ACTION;
device_type = "plain"; device_type = "plain";
} else if (!strcmp(aname, "luksOpen")) { } else if (!strcmp(aname, "luksOpen")) {
aname = "open"; aname = OPEN_ACTION;
device_type = "luks"; device_type = "luks";
} else if (!strcmp(aname, "loopaesOpen")) { } else if (!strcmp(aname, "loopaesOpen")) {
aname = "open"; aname = OPEN_ACTION;
device_type = "loopaes"; device_type = "loopaes";
} else if (!strcmp(aname, "tcryptOpen")) { } else if (!strcmp(aname, "tcryptOpen")) {
aname = "open"; aname = OPEN_ACTION;
device_type = "tcrypt"; device_type = "tcrypt";
} else if (!strcmp(aname, "bitlkOpen")) { } else if (!strcmp(aname, "bitlkOpen")) {
aname = "open"; aname = OPEN_ACTION;
device_type = "bitlk"; device_type = "bitlk";
} else if (!strcmp(aname, "tcryptDump")) { } else if (!strcmp(aname, "tcryptDump")) {
device_type = "tcrypt"; device_type = "tcrypt";
} else if (!strcmp(aname, "bitlkDump")) { } else if (!strcmp(aname, "bitlkDump")) {
device_type = "bitlk"; device_type = "bitlk";
} else if (!strcmp(aname, "remove") || } else if (!strcmp(aname, "remove") ||
!strcmp(aname, "plainClose") || !strcmp(aname, "plainClose") ||
!strcmp(aname, "luksClose") || !strcmp(aname, "luksClose") ||
!strcmp(aname, "loopaesClose") || !strcmp(aname, "loopaesClose") ||
!strcmp(aname, "tcryptClose") || !strcmp(aname, "tcryptClose") ||
!strcmp(aname, "bitlkClose")) { !strcmp(aname, "bitlkClose")) {
aname = "close"; aname = CLOSE_ACTION;
} else if (!strcmp(aname, "luksErase")) { } else if (!strcmp(aname, "luksErase")) {
aname = "erase"; aname = ERASE_ACTION;
device_type = "luks"; device_type = "luks";
} else if (!strcmp(aname, "luksConfig")) { } else if (!strcmp(aname, "luksConfig")) {
aname = "config"; aname = CONFIG_ACTION;
device_type = "luks2"; device_type = "luks2";
} else if (!strcmp(aname, "refresh")) { } else if (!strcmp(aname, "refresh")) {
aname = "open"; aname = OPEN_ACTION;
opt_refresh = 1; ARG_SET_TRUE(OPT_REFRESH_ID);
} else if (opt_type) } else if (ARG_SET(OPT_TYPE_ID))
device_type = opt_type; device_type = ARG_STR(OPT_TYPE_ID);
/* ignore user supplied type and query device type instead */ /* ignore user supplied type and query device type instead */
if (opt_refresh) if (ARG_SET(OPT_REFRESH_ID))
device_type = NULL; device_type = NULL;
for(action = action_types; action->type; action++) for(action = action_types; action->type; action++)
if (strcmp(action->type, aname) == 0) if (strcmp(action->type, aname) == 0)
break; break;
if (!action->type) if (!action->type)
usage(popt_context, EXIT_FAILURE, _("Unknown action."), usage(popt_context, EXIT_FAILURE, _("Unknown action."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (action_argc < action->required_action_argc) if (action_argc < action->required_action_argc)
help_args(action, popt_context); help_args(action, popt_context);
/* FIXME: rewrite this from scratch */ /* this routine short circuits to exit() on error */
tools_check_args(action->type, tool_core_args, ARRAY_SIZE(tool_core_args)
, popt_context);
if (opt_refresh && opt_test_passphrase) if (ARG_SET(OPT_REFRESH_ID) && ARG_SET(OPT_TEST_PASSPHRASE_ID))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Options --refresh and --test-passphrase are mutually exc lusive."), _("Options --refresh and --test-passphrase are mutually exc lusive."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_deferred_remove && strcmp(aname, "close")) if (ARG_SET(OPT_CANCEL_DEFERRED_ID) && ARG_SET(OPT_DEFERRED_ID))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --deferred is allowed only for close command."), _("Options --cancel-deferred and --deferred cannot be used at the same time."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_shared && (strcmp(aname, "open") || strcmp_or_null(device_type, " /* open action specific check */
plain"))) if (ARG_SET(OPT_SHARED_ID) && strcmp_or_null(device_type, "plain"))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --shared is allowed only for open of plain device ."), _("Option --shared is allowed only for open of plain device ."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_allow_discards && strcmp(aname, "open")) if (ARG_SET(OPT_PERSISTENT_ID) && ARG_SET(OPT_TEST_PASSPHRASE_ID))
usage(popt_context, EXIT_FAILURE,
_("Option --allow-discards is allowed only for open operati
on."),
poptGetInvocationName(popt_context));
if (opt_persistent && strcmp(aname, "open"))
usage(popt_context, EXIT_FAILURE,
_("Option --persistent is allowed only for open operation."
),
poptGetInvocationName(popt_context));
if (opt_serialize_memory_hard_pbkdf && strcmp(aname, "open"))
usage(popt_context, EXIT_FAILURE,
_("Option --serialize-memory-hard-pbkdf is allowed only for
open operation."),
poptGetInvocationName(popt_context));
if (opt_persistent && opt_test_passphrase)
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --persistent is not allowed with --test-passphras e."), _("Option --persistent is not allowed with --test-passphras e."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_key_size && if (ARG_SET(OPT_INTEGRITY_NO_WIPE_ID) && !ARG_SET(OPT_INTEGRITY_ID))
strcmp(aname, "reencrypt") &&
strcmp(aname, "luksFormat") &&
strcmp(aname, "open") &&
strcmp(aname, "benchmark") &&
strcmp(aname, "luksAddKey"))
usage(popt_context, EXIT_FAILURE,
_("Option --key-size is allowed only for luksFormat, luksAd
dKey,\n"
"open and benchmark actions. To limit read from keyfile u
se --keyfile-size=(bytes)."),
poptGetInvocationName(popt_context));
if (opt_integrity && strcmp(aname, "luksFormat"))
usage(popt_context, EXIT_FAILURE,
_("Option --integrity is allowed only for luksFormat (LUKS2
)."),
poptGetInvocationName(popt_context));
if (opt_integrity_no_wipe && !opt_integrity)
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --integrity-no-wipe" _("Option --integrity-no-wipe"
" can be used only for format action with integrity exten sion."), " can be used only for format action with integrity exten sion."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if ((opt_label || opt_subsystem) && strcmp(aname, "luksFormat") && strcmp if (ARG_SET(OPT_TEST_PASSPHRASE_ID) && (strcmp(aname, OPEN_ACTION) || !de
(aname, "config")) vice_type ||
usage(popt_context, EXIT_FAILURE,
_("Options --label and --subsystem are allowed only for luk
sFormat and config LUKS2 operations."),
poptGetInvocationName(popt_context));
if (opt_test_passphrase && (strcmp(aname, "open") || !device_type ||
(strncmp(device_type, "luks", 4) && strcmp(device_type, "tcrypt") && strcmp(device_type, "bitlk")))) (strncmp(device_type, "luks", 4) && strcmp(device_type, "tcrypt") && strcmp(device_type, "bitlk"))))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --test-passphrase is allowed only for open of LUK S, TCRYPT and BITLK devices."), _("Option --test-passphrase is allowed only for open of LUK S, TCRYPT and BITLK devices."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_key_size % 8 || opt_keyslot_key_size % 8) if (!strcmp(aname, KILLKEY_ACTION) && action_argc > 1) {
usage(popt_context, EXIT_FAILURE, ARG_SET_INT32(OPT_KEY_SLOT_ID, atoi(action_argv[1]));
_("Key size must be a multiple of 8 bits"), check_key_slot_value(popt_context);
poptGetInvocationName(popt_context)); }
if (!strcmp(aname, "luksKillSlot") && action_argc > 1)
opt_key_slot = atoi(action_argv[1]);
if (opt_key_slot != CRYPT_ANY_SLOT && opt_key_slot < 0)
usage(popt_context, EXIT_FAILURE, _("Key slot is invalid."),
poptGetInvocationName(popt_context));
if ((!strcmp(aname, "luksRemoveKey") || if ((!strcmp(aname, REMOVEKEY_ACTION) ||
!strcmp(aname, "luksFormat")) && !strcmp(aname, FORMAT_ACTION)) &&
action_argc > 1) { action_argc > 1) {
if (opt_key_file) if (ARG_SET(OPT_KEY_FILE_ID))
log_err(_("Option --key-file takes precedence over specif ied key file argument.")); log_err(_("Option --key-file takes precedence over specif ied key file argument."));
else else
opt_key_file = strdup(action_argv[1]); ARG_SET_STR(OPT_KEY_FILE_ID, strdup(action_argv[1]));
} }
if (opt_keyfile_size < 0 || opt_new_keyfile_size < 0 || opt_key_size < 0)
usage(popt_context, EXIT_FAILURE,
_("Negative number for option not permitted."),
poptGetInvocationName(popt_context));
if (total_keyfiles > 1 && (strcmp_or_null(device_type, "tcrypt"))) if (total_keyfiles > 1 && (strcmp_or_null(device_type, "tcrypt")))
usage(popt_context, EXIT_FAILURE, _("Only one --key-file argument is allowed."), usage(popt_context, EXIT_FAILURE, _("Only one --key-file argument is allowed."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_random && opt_urandom) if (ARG_SET(OPT_USE_RANDOM_ID) && ARG_SET(OPT_USE_URANDOM_ID))
usage(popt_context, EXIT_FAILURE, _("Only one of --use-[u]random options is allowed."), usage(popt_context, EXIT_FAILURE, _("Only one of --use-[u]random options is allowed."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if ((opt_random || opt_urandom) && strcmp(aname, "luksFormat")) if (ARG_SET(OPT_ALIGN_PAYLOAD_ID) && ARG_SET(OPT_OFFSET_ID))
usage(popt_context, EXIT_FAILURE, _("Option --use-[u]random is al
lowed only for luksFormat."),
poptGetInvocationName(popt_context));
if (opt_uuid && strcmp(aname, "luksFormat") && strcmp(aname, "luksUUID"))
usage(popt_context, EXIT_FAILURE, _("Option --uuid is allowed onl
y for luksFormat and luksUUID."),
poptGetInvocationName(popt_context));
if (opt_align_payload && strcmp(aname, "luksFormat"))
usage(popt_context, EXIT_FAILURE, _("Option --align-payload is al
lowed only for luksFormat."),
poptGetInvocationName(popt_context));
if ((opt_luks2_metadata_size_str || opt_luks2_keyslots_size_str) && strcm
p(aname, "luksFormat") && strcmp(aname, "reencrypt"))
usage(popt_context, EXIT_FAILURE, _("Options --luks2-metadata-siz
e and --opt-luks2-keyslots-size "
"are allowed only for luksFormat with LUKS2."),
poptGetInvocationName(popt_context));
if (opt_luks2_metadata_size_str &&
tools_string_to_size(NULL, opt_luks2_metadata_size_str, &opt_luks2_me
tadata_size))
usage(popt_context, EXIT_FAILURE, _("Invalid LUKS2 metadata size
specification."),
poptGetInvocationName(popt_context));
if (opt_luks2_keyslots_size_str &&
tools_string_to_size(NULL, opt_luks2_keyslots_size_str, &opt_luks2_ke
yslots_size))
usage(popt_context, EXIT_FAILURE, _("Invalid LUKS2 keyslots size
specification."),
poptGetInvocationName(popt_context));
if (opt_align_payload && opt_offset)
usage(popt_context, EXIT_FAILURE, _("Options --align-payload and --offset cannot be combined."), usage(popt_context, EXIT_FAILURE, _("Options --align-payload and --offset cannot be combined."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_skip && (strcmp(aname, "open") || /* open action specific check */
(strcmp_or_null(device_type, "plain") && strcmp(device_type, "loopaes if (ARG_SET(OPT_SKIP_ID) && strcmp_or_null(device_type, "plain") && strcm
")))) p(device_type, "loopaes"))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --skip is supported only for open of plain and loopaes devices."), _("Option --skip is supported only for open of plain and loopaes devices."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_offset && ((strcmp(aname, "reencrypt") && strcmp(aname, "open") & /* open action specific check */
& strcmp(aname, "luksFormat")) || if (ARG_SET(OPT_OFFSET_ID) && !strcmp(aname, OPEN_ACTION) && strcmp_or_nu
(!strcmp(aname, "open") && strcmp_or_null(device_type, "plain") && st ll(device_type, "plain") && strcmp(device_type, "loopaes"))
rcmp(device_type, "loopaes")) ||
(!strcmp(aname, "luksFormat") && device_type && strncmp(device_type,
"luks", 4))))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --offset is supported only for open of plain and loopae s devices, luksFormat and device reencryption."), _("Option --offset with open action is only supported for plain a nd loopaes devices."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if ((opt_tcrypt_hidden || opt_tcrypt_system || opt_tcrypt_backup) && strc /* open action specific check */
mp(aname, "tcryptDump") && if ((ARG_SET(OPT_TCRYPT_HIDDEN_ID) || ARG_SET(OPT_TCRYPT_SYSTEM_ID) || AR
(strcmp(aname, "open") || !device_type || strcmp(device_type, "tcrypt G_SET(OPT_TCRYPT_BACKUP_ID)) && !strcmp(aname, OPEN_ACTION) && (!device_type ||
"))) strcmp(device_type, "tcrypt")))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --tcrypt-hidden, --tcrypt-system or --tcrypt-backup is supported only for TCRYPT device."), _("Option --tcrypt-hidden, --tcrypt-system or --tcrypt-backup is supported only for TCRYPT device."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_tcrypt_hidden && opt_allow_discards) if (ARG_SET(OPT_TCRYPT_HIDDEN_ID) && ARG_SET(OPT_ALLOW_DISCARDS_ID))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --tcrypt-hidden cannot be combined with --allow-discard s."), _("Option --tcrypt-hidden cannot be combined with --allow-discard s."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_veracrypt && (!device_type || strcmp(device_type, "tcrypt"))) if ((ARG_SET(OPT_VERACRYPT_ID) || ARG_SET(OPT_DISABLE_VERACRYPT_ID)) && ( !device_type || strcmp(device_type, "tcrypt")))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --veracrypt is supported only for TCRYPT device type.") , _("Option --veracrypt or --disable-veracrypt is supported only fo r TCRYPT device type."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_veracrypt_pim != -1) { if (ARG_SET(OPT_VERACRYPT_PIM_ID) && ARG_SET(OPT_DISABLE_VERACRYPT_ID))
if (opt_veracrypt_pim < -1) { usage(popt_context, EXIT_FAILURE,
usage(popt_context, EXIT_FAILURE, _("Option --veracrypt-pim is supported only for VeraCrypt compati
_("Invalid argument for parameter --veracrypt-pim supplie ble devices."),
d."), poptGetInvocationName(popt_context));
poptGetInvocationName(popt_context));
} else if (!opt_veracrypt) {
usage(popt_context, EXIT_FAILURE,
_("Option --veracrypt-pim is supported only for VeraCrypt
compatible devices."),
poptGetInvocationName(popt_context));
}
}
if (opt_veracrypt_query_pim) { if (ARG_SET(OPT_VERACRYPT_QUERY_PIM_ID)) {
if (!opt_veracrypt) { if (ARG_SET(OPT_DISABLE_VERACRYPT_ID)) {
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Option --veracrypt-query-pim is supported only for Ver aCrypt compatible devices."), _("Option --veracrypt-query-pim is supported only for Ver aCrypt compatible devices."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
} else if (opt_veracrypt_pim != -1) { } else if (ARG_SET(OPT_VERACRYPT_PIM_ID)) {
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("The options --veracrypt-pim and --veracrypt-query-pim are mutually exclusive."), _("The options --veracrypt-pim and --veracrypt-query-pim are mutually exclusive."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
} }
} }
if (opt_priority && strcmp(opt_priority, "normal") && strcmp(opt_priority /* config action specific check */
, "prefer") && strcmp(opt_priority, "ignore")) if (!strcmp(aname, CONFIG_ACTION) && ARG_SET(OPT_PRIORITY_ID) && ARG_INT3
usage(popt_context, EXIT_FAILURE, 2(OPT_KEY_SLOT_ID) == CRYPT_ANY_SLOT)
_("Option --priority can be only ignore/normal/prefer."),
poptGetInvocationName(popt_context));
if (!strcmp(aname, "config") && opt_priority && opt_key_slot == CRYPT_ANY
_SLOT)
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Keyslot specification is required."), _("Keyslot specification is required."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_pbkdf && crypt_parse_pbkdf(opt_pbkdf, &set_pbkdf)) if (ARG_SET(OPT_PBKDF_ID) && crypt_parse_pbkdf(ARG_STR(OPT_PBKDF_ID), &se t_pbkdf))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Password-based key derivation function (PBKDF) can be only pbk df2 or argon2i/argon2id."), _("Password-based key derivation function (PBKDF) can be only pbk df2 or argon2i/argon2id."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_pbkdf_iterations && opt_iteration_time) if (ARG_SET(OPT_PBKDF_FORCE_ITERATIONS_ID) && ARG_SET(OPT_ITER_TIME_ID))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("PBKDF forced iterations cannot be combined with iteration time option."), _("PBKDF forced iterations cannot be combined with iteration time option."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_sector_size && strcmp(aname, "reencrypt") && strcmp(aname, "luksF /* open action specific check */
ormat") && if (ARG_SET(OPT_SECTOR_SIZE_ID) && !strcmp(aname, OPEN_ACTION) &&
(strcmp(aname, "open") || strcmp_or_null(device_type, "plain"))) (!device_type || strcmp(device_type, "plain")))
usage(popt_context, EXIT_FAILURE,
_("Sector size option is not supported for this command."),
poptGetInvocationName(popt_context));
if (opt_sector_size && (opt_sector_size < SECTOR_SIZE || opt_sector_size
> MAX_SECTOR_SIZE ||
(opt_sector_size & (opt_sector_size - 1))))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Unsupported encryption sector size."), _("Sector size option with open action is supported only fo r plain devices."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_iv_large_sectors && (strcmp(aname, "open") || strcmp_or_null(opt_ /* open action specific check */
type, "plain") || if (ARG_SET(OPT_IV_LARGE_SECTORS_ID) && (!device_type || strcmp(device_ty
opt_sector_size <= SECTOR_SIZE)) pe, "plain") ||
ARG_UINT32(OPT_SECTOR_SIZE_ID) <= SECTOR_SIZE))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Large IV sectors option is supported only for opening pl ain type device with sector size larger than 512 bytes."), _("Large IV sectors option is supported only for opening pl ain type device with sector size larger than 512 bytes."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_unbound && !opt_key_size && !strcmp(aname, "luksAddKey")) /* luksAddKey action specific check */
if (ARG_SET(OPT_UNBOUND_ID) && !ARG_UINT32(OPT_KEY_SIZE_ID) && !strcmp(an
ame, ADDKEY_ACTION))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Key size is required with --unbound option."), _("Key size is required with --unbound option."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_unbound && !strcmp(aname, "luksDump") && opt_key_slot == CRYPT_AN /* luksDump action specific check */
Y_SLOT) if (ARG_SET(OPT_UNBOUND_ID) && ARG_INT32(OPT_KEY_SLOT_ID) == CRYPT_ANY_SL
OT && !strcmp(aname, LUKSDUMP_ACTION))
usage(popt_context, EXIT_FAILURE, usage(popt_context, EXIT_FAILURE,
_("Keyslot specification is required."), _("Keyslot specification is required."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_unbound && strcmp(aname, "luksAddKey") && strcmp(aname, "luksDump if (ARG_SET(OPT_DEBUG_ID) || ARG_SET(OPT_DEBUG_JSON_ID)) {
")) crypt_set_debug_level(ARG_SET(OPT_DEBUG_JSON_ID)? CRYPT_DEBUG_JSO
usage(popt_context, EXIT_FAILURE, N : CRYPT_DEBUG_ALL);
_("Option --unbound may be used only with luksAddKey and lu
ksDump actions."),
poptGetInvocationName(popt_context));
if (opt_refresh && strcmp(aname, "open"))
usage(popt_context, EXIT_FAILURE,
_("Option --refresh may be used only with open action."),
poptGetInvocationName(popt_context));
if (opt_debug || opt_debug_json) {
opt_debug = 1;
opt_verbose = 1;
crypt_set_debug_level(opt_debug_json? CRYPT_DEBUG_JSON : CRYPT_DE
BUG_ALL);
dbg_version_and_cmd(argc, argv); dbg_version_and_cmd(argc, argv);
} }
if (opt_disable_locks && crypt_metadata_locking(NULL, 0)) { /* reencrypt action specific check */
log_std(_("Cannot disable metadata locking.")); if (ARG_SET(OPT_DECRYPT_ID) && !ARG_SET(OPT_HEADER_ID))
tools_cleanup(); usage(popt_context, EXIT_FAILURE, _("LUKS2 decryption requires op
poptFreeContext(popt_context); tion --header."),
exit(EXIT_FAILURE);
}
if (opt_disable_keyring)
(void) crypt_volume_key_keyring(NULL, 0);
if (opt_hotzone_size_str &&
(tools_string_to_size(NULL, opt_hotzone_size_str, &opt_hotzone_size)
|| !opt_hotzone_size))
usage(popt_context, EXIT_FAILURE, _("Invalid max reencryption hot
zone size specification."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (!opt_hotzone_size && opt_resilience_mode && !strcmp(opt_resilience_mo if (ARG_SET(OPT_REDUCE_DEVICE_SIZE_ID) && ARG_SET(OPT_DEVICE_SIZE_ID))
de, "none")) usage(popt_context, EXIT_FAILURE, _("Options --reduce-device-size
opt_hotzone_size = 50 * 1024 * 1024; and --data-size cannot be combined."),
if (opt_reduce_size_str &&
tools_string_to_size(NULL, opt_reduce_size_str, &opt_reduce_size))
usage(popt_context, EXIT_FAILURE, _("Invalid device size specific
ation."),
poptGetInvocationName(popt_context));
if (opt_reduce_size > 1024 * 1024 * 1024)
usage(popt_context, EXIT_FAILURE, _("Maximum device reduce size i
s 1 GiB."),
poptGetInvocationName(popt_context));
if (opt_reduce_size % SECTOR_SIZE)
usage(popt_context, EXIT_FAILURE, _("Reduce size must be multiple
of 512 bytes sector."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_device_size_str && if (ARG_SET(OPT_DEVICE_SIZE_ID) && ARG_SET(OPT_SIZE_ID))
tools_string_to_size(NULL, opt_device_size_str, &opt_device_size)) usage(popt_context, EXIT_FAILURE, _("Options --device-size and --
usage(popt_context, EXIT_FAILURE, _("Invalid data size specificat size cannot be combined."),
ion."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
opt_data_shift = -(int64_t)opt_reduce_size; if (ARG_SET(OPT_KEYSLOT_CIPHER_ID) != ARG_SET(OPT_KEYSLOT_KEY_SIZE_ID))
if (opt_data_shift > 0) usage(popt_context, EXIT_FAILURE, _("Options --keyslot-cipher and
usage(popt_context, EXIT_FAILURE, _("Reduce size overflow."), --keyslot-key-size must be used together."),
poptGetInvocationName(popt_context)); poptGetInvocationName(popt_context));
if (opt_decrypt && !opt_header_device) if (ARG_SET(OPT_TEST_ARGS_ID)) {
usage(popt_context, EXIT_FAILURE, _("LUKS2 decryption requires op log_std(_("No action taken. Invoked with --test-args option.\n"))
tion --header."), ;
poptGetInvocationName(popt_context)); tools_cleanup();
poptFreeContext(popt_context);
return 0;
}
if (opt_device_size % SECTOR_SIZE) /* token action specific check */
usage(popt_context, EXIT_FAILURE, _("Device size must be multiple if (!strcmp(aname, TOKEN_ACTION)) {
of 512 bytes sector."), if (strcmp(action_argv[0], "add") &&
poptGetInvocationName(popt_context)); strcmp(action_argv[0], "remove") &&
strcmp(action_argv[0], "import") &&
strcmp(action_argv[0], "export"))
usage(popt_context, EXIT_FAILURE, _("Invalid token action
."),
poptGetInvocationName(popt_context));
if (opt_data_shift && opt_device_size) if (!ARG_SET(OPT_KEY_DESCRIPTION_ID) && !strcmp(action_argv[0], "
usage(popt_context, EXIT_FAILURE, _("Options --reduce-device-size add"))
and --data-size cannot be combined."), usage(popt_context, EXIT_FAILURE,
poptGetInvocationName(popt_context)); _("--key-description parameter is mandatory for tok
en add action."),
poptGetInvocationName(popt_context));
if (opt_device_size && opt_size) if (ARG_INT32(OPT_TOKEN_ID_ID) == CRYPT_ANY_TOKEN &&
usage(popt_context, EXIT_FAILURE, _("Options --device-size and -- (!strcmp(action_argv[0], "remove") || !strcmp(action_argv[0],
size cannot be combined."), "export")))
poptGetInvocationName(popt_context)); usage(popt_context, EXIT_FAILURE,
_("Action requires specific token. Use --token-id p
arameter."),
poptGetInvocationName(popt_context));
}
if ((opt_keyslot_cipher && !opt_keyslot_key_size) || (!opt_keyslot_cipher if (ARG_SET(OPT_DISABLE_KEYRING_ID))
&& opt_keyslot_key_size)) (void) crypt_volume_key_keyring(NULL, 0);
usage(popt_context, EXIT_FAILURE, _("Options --keyslot-cipher and
--keyslot-key-size must be used together."), if (ARG_SET(OPT_DISABLE_EXTERNAL_TOKENS_ID))
poptGetInvocationName(popt_context)); (void) crypt_token_external_disable();
if (ARG_SET(OPT_DISABLE_LOCKS_ID) && crypt_metadata_locking(NULL, 0)) {
log_std(_("Cannot disable metadata locking."));
r = EXIT_FAILURE;
} else {
r = run_action(action);
}
r = run_action(action);
tools_cleanup(); tools_cleanup();
poptFreeContext(popt_context); poptFreeContext(popt_context);
return r; return r;
} }
 End of changes. 436 change blocks. 
1273 lines changed or deleted 1160 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)