summaryrefslogtreecommitdiff
path: root/lib/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/setup.c')
-rw-r--r--lib/setup.c323
1 files changed, 192 insertions, 131 deletions
diff --git a/lib/setup.c b/lib/setup.c
index 567f262..376b920 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -3,8 +3,8 @@
*
* Copyright (C) 2004 Jana Saout <jana@saout.de>
* Copyright (C) 2004-2007 Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2009-2020 Red Hat, Inc. All rights reserved.
- * Copyright (C) 2009-2020 Milan Broz
+ * Copyright (C) 2009-2021 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2009-2021 Milan Broz
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -78,7 +78,7 @@ struct crypt_device {
char cipher_mode[MAX_CIPHER_LEN]; /* only for compatibility */
char *keyslot_cipher;
unsigned int keyslot_key_size;
- struct luks2_reenc_context *rh;
+ struct luks2_reencrypt *rh;
} luks2;
struct { /* used in CRYPT_PLAIN */
struct crypt_params_plain hdr;
@@ -657,12 +657,12 @@ int crypt_set_data_device(struct crypt_device *cd, const char *device)
log_dbg(cd, "Setting ciphertext data device to %s.", device ?: "(none)");
if (!isLUKS1(cd->type) && !isLUKS2(cd->type) && !isVERITY(cd->type) &&
- !isINTEGRITY(cd->type)) {
+ !isINTEGRITY(cd->type) && !isTCRYPT(cd->type)) {
log_err(cd, _("This operation is not supported for this device type."));
return -EINVAL;
}
- if (isLUKS2(cd->type) && crypt_get_reenc_context(cd)) {
+ if (isLUKS2(cd->type) && crypt_get_luks2_reencrypt(cd)) {
log_err(cd, _("Illegal operation with reencryption in-progress."));
return -EINVAL;
}
@@ -845,11 +845,6 @@ static int _crypt_load_tcrypt(struct crypt_device *cd, struct crypt_params_tcryp
if (!params)
return -EINVAL;
- if (cd->metadata_device) {
- log_err(cd, _("Detached metadata device is not supported for this crypt type."));
- return -EINVAL;
- }
-
r = init_crypto(cd);
if (r < 0)
return r;
@@ -1084,10 +1079,15 @@ static int _init_by_name_crypt_none(struct crypt_device *cd)
_mode);
if (!r) {
- snprintf(cd->u.none.cipher_spec, sizeof(cd->u.none.cipher_spec),
+ r = snprintf(cd->u.none.cipher_spec, sizeof(cd->u.none.cipher_spec),
"%s-%s", cd->u.none.cipher, _mode);
- cd->u.none.cipher_mode = cd->u.none.cipher_spec + strlen(cd->u.none.cipher) + 1;
- cd->u.none.key_size = tgt->u.crypt.vk->keylength;
+ if (r < 0 || (size_t)r >= sizeof(cd->u.none.cipher_spec))
+ r = -EINVAL;
+ else {
+ cd->u.none.cipher_mode = cd->u.none.cipher_spec + strlen(cd->u.none.cipher) + 1;
+ cd->u.none.key_size = tgt->u.crypt.vk->keylength;
+ r = 0;
+ }
}
dm_targets_free(cd, &dmd);
@@ -1113,7 +1113,7 @@ static void crypt_free_type(struct crypt_device *cd)
free(cd->u.plain.cipher);
free(cd->u.plain.cipher_spec);
} else if (isLUKS2(cd->type)) {
- LUKS2_reenc_context_free(cd, cd->u.luks2.rh);
+ LUKS2_reencrypt_free(cd, cd->u.luks2.rh);
LUKS2_hdr_free(cd, &cd->u.luks2.hdr);
free(cd->u.luks2.keyslot_cipher);
} else if (isLUKS1(cd->type)) {
@@ -1210,7 +1210,7 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name)
}
/* do not try to lookup LUKS2 header in detached header mode */
- if (!cd->metadata_device && !found) {
+ if (dmd.uuid && !cd->metadata_device && !found) {
while (*dep && !found) {
r = dm_query_device(cd, *dep, DM_ACTIVE_DEVICE, &dmdep);
if (r < 0)
@@ -1850,13 +1850,13 @@ static int _crypt_format_luks2(struct crypt_device *cd,
if (dev_size < (crypt_get_data_offset(cd) * SECTOR_SIZE))
log_std(cd, _("WARNING: Data offset is outside of currently available data device.\n"));
- if (cd->metadata_size && (cd->metadata_size != LUKS2_metadata_size(cd->u.luks2.hdr.jobj)))
+ if (cd->metadata_size && (cd->metadata_size != LUKS2_metadata_size(&cd->u.luks2.hdr)))
log_std(cd, _("WARNING: LUKS2 metadata size changed to %" PRIu64 " bytes.\n"),
- LUKS2_metadata_size(cd->u.luks2.hdr.jobj));
+ LUKS2_metadata_size(&cd->u.luks2.hdr));
- if (cd->keyslots_size && (cd->keyslots_size != LUKS2_keyslots_size(cd->u.luks2.hdr.jobj)))
+ if (cd->keyslots_size && (cd->keyslots_size != LUKS2_keyslots_size(&cd->u.luks2.hdr)))
log_std(cd, _("WARNING: LUKS2 keyslots area size changed to %" PRIu64 " bytes.\n"),
- LUKS2_keyslots_size(cd->u.luks2.hdr.jobj));
+ LUKS2_keyslots_size(&cd->u.luks2.hdr));
if (!integrity && sector_size > SECTOR_SIZE) {
dev_size -= (crypt_get_data_offset(cd) * SECTOR_SIZE);
@@ -1874,11 +1874,11 @@ static int _crypt_format_luks2(struct crypt_device *cd,
goto out;
}
- r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr);
+ r = LUKS2_wipe_header_areas(cd, &cd->u.luks2.hdr, cd->metadata_device != NULL);
if (r < 0) {
log_err(cd, _("Cannot wipe header on device %s."),
mdata_device_path(cd));
- if (dev_size < LUKS2_hdr_and_areas_size(cd->u.luks2.hdr.jobj))
+ if (dev_size < LUKS2_hdr_and_areas_size(&cd->u.luks2.hdr))
log_err(cd, _("Device %s is too small."), device_path(crypt_metadata_device(cd)));
goto out;
}
@@ -2035,7 +2035,7 @@ static int _crypt_format_verity(struct crypt_device *cd,
} else
cd->u.verity.hdr.data_size = params->data_size;
- if (device_is_identical(crypt_metadata_device(cd), crypt_data_device(cd)) &&
+ if (device_is_identical(crypt_metadata_device(cd), crypt_data_device(cd)) > 0 &&
(cd->u.verity.hdr.data_size * params->data_block_size) > params->hash_area_offset) {
log_err(cd, _("Data area overlaps with hash area."));
return -EINVAL;
@@ -2060,14 +2060,14 @@ static int _crypt_format_verity(struct crypt_device *cd,
}
hash_blocks_size = VERITY_hash_blocks(cd, params) * params->hash_block_size;
- if (device_is_identical(crypt_metadata_device(cd), fec_device) &&
+ if (device_is_identical(crypt_metadata_device(cd), fec_device) > 0 &&
(params->hash_area_offset + hash_blocks_size) > params->fec_area_offset) {
log_err(cd, _("Hash area overlaps with FEC area."));
r = -EINVAL;
goto err;
}
- if (device_is_identical(crypt_data_device(cd), fec_device) &&
+ if (device_is_identical(crypt_data_device(cd), fec_device) > 0 &&
(cd->u.verity.hdr.data_size * params->data_block_size) > params->fec_area_offset) {
log_err(cd, _("Data area overlaps with FEC area."));
r = -EINVAL;
@@ -2388,11 +2388,6 @@ static int _compare_crypt_devices(struct crypt_device *cd,
if (!src->u.crypt.vk || !tgt->u.crypt.vk)
return -EINVAL;
- if (_compare_volume_keys(src->u.crypt.vk, 0, tgt->u.crypt.vk, tgt->u.crypt.vk->key_description != NULL)) {
- log_dbg(cd, "Keys in context and target device do not match.");
- return -EINVAL;
- }
-
/* CIPHER checks */
if (!src->u.crypt.cipher || !tgt->u.crypt.cipher)
return -EINVAL;
@@ -2400,6 +2395,14 @@ static int _compare_crypt_devices(struct crypt_device *cd,
log_dbg(cd, "Cipher specs do not match.");
return -EINVAL;
}
+
+ if (tgt->u.crypt.vk->keylength == 0 && crypt_is_cipher_null(tgt->u.crypt.cipher))
+ log_dbg(cd, "Existing device uses cipher null. Skipping key comparison.");
+ else if (_compare_volume_keys(src->u.crypt.vk, 0, tgt->u.crypt.vk, tgt->u.crypt.vk->key_description != NULL)) {
+ log_dbg(cd, "Keys in context and target device do not match.");
+ return -EINVAL;
+ }
+
if (crypt_strcmp(src->u.crypt.integrity, tgt->u.crypt.integrity)) {
log_dbg(cd, "Integrity parameters do not match.");
return -EINVAL;
@@ -2413,7 +2416,7 @@ static int _compare_crypt_devices(struct crypt_device *cd,
return -EINVAL;
}
- if (!device_is_identical(src->data_device, tgt->data_device)) {
+ if (device_is_identical(src->data_device, tgt->data_device) <= 0) {
log_dbg(cd, "Data devices do not match.");
return -EINVAL;
}
@@ -2467,7 +2470,7 @@ static int _compare_integrity_devices(struct crypt_device *cd,
return -EINVAL;
}
- if (!device_is_identical(src->data_device, tgt->data_device)) {
+ if (device_is_identical(src->data_device, tgt->data_device) <= 0) {
log_dbg(cd, "Data devices do not match.");
return -EINVAL;
}
@@ -2770,6 +2773,11 @@ int crypt_resize(struct crypt_device *cd, const char *name, uint64_t new_size)
if (!cd || !cd->type || !name)
return -EINVAL;
+ if (isTCRYPT(cd->type) || isBITLK(cd->type)) {
+ log_err(cd, _("This operation is not supported for this device type."));
+ return -ENOTSUP;
+ }
+
log_dbg(cd, "Resizing device %s to %" PRIu64 " sectors.", name, new_size);
r = dm_query_device(cd, name, DM_ACTIVE_CRYPT_KEYSIZE | DM_ACTIVE_CRYPT_KEY, &dmdq);
@@ -3090,6 +3098,45 @@ out:
return r;
}
+/* key must be properly verified */
+static int resume_by_volume_key(struct crypt_device *cd,
+ struct volume_key *vk,
+ const char *name)
+{
+ int digest, r;
+ struct volume_key *zerokey = NULL;
+
+ if (crypt_is_cipher_null(crypt_get_cipher_spec(cd))) {
+ zerokey = crypt_alloc_volume_key(0, NULL);
+ if (!zerokey)
+ return -ENOMEM;
+ vk = zerokey;
+ } else if (crypt_use_keyring_for_vk(cd)) {
+ /* LUKS2 path only */
+ digest = LUKS2_digest_by_segment(&cd->u.luks2.hdr, CRYPT_DEFAULT_SEGMENT);
+ if (digest < 0)
+ return -EINVAL;
+ r = LUKS2_volume_key_load_in_keyring_by_digest(cd,
+ &cd->u.luks2.hdr, vk, digest);
+ if (r < 0)
+ return r;
+ }
+
+ r = dm_resume_and_reinstate_key(cd, name, vk);
+
+ if (r == -ENOTSUP)
+ log_err(cd, _("Resume is not supported for device %s."), name);
+ else if (r)
+ log_err(cd, _("Error during resuming device %s."), name);
+
+ if (r < 0)
+ crypt_drop_keyring_key(cd, vk);
+
+ crypt_free_volume_key(zerokey);
+
+ return r;
+}
+
int crypt_resume_by_passphrase(struct crypt_device *cd,
const char *name,
int keyslot,
@@ -3125,32 +3172,13 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
r = LUKS2_keyslot_open(cd, keyslot, CRYPT_DEFAULT_SEGMENT, passphrase, passphrase_size, &vk);
if (r < 0)
- goto out;
+ return r;
keyslot = r;
- if (crypt_use_keyring_for_vk(cd)) {
- if (!isLUKS2(cd->type)) {
- r = -EINVAL;
- goto out;
- }
- r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd,
- &cd->u.luks2.hdr, vk, keyslot);
- if (r < 0)
- goto out;
- }
-
- r = dm_resume_and_reinstate_key(cd, name, vk);
+ r = resume_by_volume_key(cd, vk, name);
- if (r == -ENOTSUP)
- log_err(cd, _("Resume is not supported for device %s."), name);
- else if (r)
- log_err(cd, _("Error during resuming device %s."), name);
-out:
- if (r < 0)
- crypt_drop_keyring_key(cd, vk);
crypt_free_volume_key(vk);
-
return r < 0 ? r : keyslot;
}
@@ -3189,35 +3217,22 @@ int crypt_resume_by_keyfile_device_offset(struct crypt_device *cd,
&passphrase_read, &passphrase_size_read,
keyfile_offset, keyfile_size, 0);
if (r < 0)
- goto out;
+ return r;
if (isLUKS1(cd->type))
r = LUKS_open_key_with_hdr(keyslot, passphrase_read, passphrase_size_read,
&cd->u.luks1.hdr, &vk, cd);
else
r = LUKS2_keyslot_open(cd, keyslot, CRYPT_DEFAULT_SEGMENT, passphrase_read, passphrase_size_read, &vk);
+
+ crypt_safe_free(passphrase_read);
if (r < 0)
- goto out;
+ return r;
+
keyslot = r;
- if (crypt_use_keyring_for_vk(cd)) {
- if (!isLUKS2(cd->type)) {
- r = -EINVAL;
- goto out;
- }
- r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd,
- &cd->u.luks2.hdr, vk, keyslot);
- if (r < 0)
- goto out;
- }
+ r = resume_by_volume_key(cd, vk, name);
- r = dm_resume_and_reinstate_key(cd, name, vk);
- if (r < 0)
- log_err(cd, _("Error during resuming device %s."), name);
-out:
- crypt_safe_free(passphrase_read);
- if (r < 0)
- crypt_drop_keyring_key(cd, vk);
crypt_free_volume_key(vk);
return r < 0 ? r : keyslot;
}
@@ -3280,24 +3295,10 @@ int crypt_resume_by_volume_key(struct crypt_device *cd,
r = -EINVAL;
if (r == -EPERM || r == -ENOENT)
log_err(cd, _("Volume key does not match the volume."));
- if (r < 0)
- goto out;
- r = 0;
- if (crypt_use_keyring_for_vk(cd)) {
- r = LUKS2_key_description_by_segment(cd, &cd->u.luks2.hdr, vk, CRYPT_DEFAULT_SEGMENT);
- if (!r)
- r = crypt_volume_key_load_in_keyring(cd, vk);
- }
- if (r < 0)
- goto out;
+ if (r >= 0)
+ r = resume_by_volume_key(cd, vk, name);
- r = dm_resume_and_reinstate_key(cd, name, vk);
- if (r < 0)
- log_err(cd, _("Error during resuming device %s."), name);
-out:
- if (r < 0)
- crypt_drop_keyring_key(cd, vk);
crypt_free_volume_key(vk);
return r;
}
@@ -3459,6 +3460,9 @@ int crypt_keyslot_change_by_passphrase(struct crypt_device *cd,
r = LUKS2_digest_assign(cd, &cd->u.luks2.hdr, keyslot_new, digest, 1, 0);
if (r < 0)
goto out;
+ r = LUKS2_token_assignment_copy(cd, &cd->u.luks2.hdr, keyslot_old, keyslot_new, 0);
+ if (r < 0)
+ goto out;
} else {
log_dbg(cd, "Key slot %d is going to be overwritten.", keyslot_old);
/* FIXME: improve return code so that we can detect area is damaged */
@@ -3686,7 +3690,7 @@ static int _check_header_data_overlap(struct crypt_device *cd, const char *name)
if (!name || !isLUKS(cd->type))
return 0;
- if (!device_is_identical(crypt_data_device(cd), crypt_metadata_device(cd)))
+ if (device_is_identical(crypt_data_device(cd), crypt_metadata_device(cd)) <= 0)
return 0;
/* FIXME: check real header size */
@@ -3853,21 +3857,6 @@ out:
return r;
}
-static int load_all_keys(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks)
-{
- int r;
- struct volume_key *vk = vks;
-
- while (vk) {
- r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
- if (r < 0)
- return r;
- vk = crypt_volume_key_next(vk);
- }
-
- return 0;
-}
-
/* See fixmes in _open_and_activate_luks2 */
int update_reencryption_flag(struct crypt_device *cd, int enable, bool commit);
@@ -3879,6 +3868,7 @@ static int _open_and_activate(struct crypt_device *cd,
size_t passphrase_size,
uint32_t flags)
{
+ bool use_keyring;
int r;
struct volume_key *vk = NULL;
@@ -3890,8 +3880,13 @@ static int _open_and_activate(struct crypt_device *cd,
return r;
keyslot = r;
- if ((name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) &&
- crypt_use_keyring_for_vk(cd)) {
+ if (!crypt_use_keyring_for_vk(cd))
+ use_keyring = false;
+ else
+ use_keyring = ((name && !crypt_is_cipher_null(crypt_get_cipher(cd))) ||
+ (flags & CRYPT_ACTIVATE_KEYRING_KEY));
+
+ if (use_keyring) {
r = LUKS2_volume_key_load_in_keyring_by_keyslot(cd,
&cd->u.luks2.hdr, vk, keyslot);
if (r < 0)
@@ -3909,6 +3904,22 @@ out:
return r < 0 ? r : keyslot;
}
+#if USE_LUKS2_REENCRYPTION
+static int load_all_keys(struct crypt_device *cd, struct luks2_hdr *hdr, struct volume_key *vks)
+{
+ int r;
+ struct volume_key *vk = vks;
+
+ while (vk) {
+ r = LUKS2_volume_key_load_in_keyring_by_digest(cd, hdr, vk, crypt_volume_key_get_id(vk));
+ if (r < 0)
+ return r;
+ vk = crypt_volume_key_next(vk);
+ }
+
+ return 0;
+}
+
static int _open_all_keys(struct crypt_device *cd,
struct luks2_hdr *hdr,
int keyslot,
@@ -3919,7 +3930,7 @@ static int _open_all_keys(struct crypt_device *cd,
{
int r, segment;
struct volume_key *_vks = NULL;
- crypt_reencrypt_info ri = LUKS2_reenc_status(hdr);
+ crypt_reencrypt_info ri = LUKS2_reencrypt_status(hdr);
segment = (flags & CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY) ? CRYPT_ANY_SEGMENT : CRYPT_DEFAULT_SEGMENT;
@@ -3975,7 +3986,7 @@ static int _open_and_activate_reencrypt_device(struct crypt_device *cd,
if (crypt_use_keyring_for_vk(cd))
flags |= CRYPT_ACTIVATE_KEYRING_KEY;
- r = crypt_reencrypt_lock(cd, &reencrypt_lock);
+ r = LUKS2_reencrypt_lock(cd, &reencrypt_lock);
if (r) {
if (r == -EBUSY)
log_err(cd, _("Reencryption in-progress. Cannot activate device."));
@@ -3987,7 +3998,7 @@ static int _open_and_activate_reencrypt_device(struct crypt_device *cd,
if ((r = crypt_load(cd, CRYPT_LUKS2, NULL)))
goto err;
- ri = LUKS2_reenc_status(hdr);
+ ri = LUKS2_reencrypt_status(hdr);
if (ri == CRYPT_REENCRYPT_CRASH) {
r = LUKS2_reencrypt_locked_recovery_by_passphrase(cd, keyslot,
@@ -3998,14 +4009,14 @@ static int _open_and_activate_reencrypt_device(struct crypt_device *cd,
}
keyslot = r;
- ri = LUKS2_reenc_status(hdr);
+ ri = LUKS2_reencrypt_status(hdr);
}
/* recovery finished reencryption or it's already finished */
if (ri == CRYPT_REENCRYPT_NONE) {
crypt_drop_keyring_key(cd, vks);
crypt_free_volume_key(vks);
- crypt_reencrypt_unlock(cd, reencrypt_lock);
+ LUKS2_reencrypt_unlock(cd, reencrypt_lock);
return _open_and_activate(cd, keyslot, name, passphrase, passphrase_size, flags);
}
@@ -4023,15 +4034,21 @@ static int _open_and_activate_reencrypt_device(struct crypt_device *cd,
keyslot = r;
}
+ if (r >= 0) {
+ r = LUKS2_reencrypt_digest_verify(cd, hdr, vks);
+ if (r < 0)
+ goto err;
+ }
+
log_dbg(cd, "Entering clean reencryption state mode.");
if (r >= 0)
- r = luks2_check_device_size(cd, hdr, minimal_size, &device_size, true, dynamic_size);
+ r = LUKS2_reencrypt_check_device_size(cd, hdr, minimal_size, &device_size, true, dynamic_size);
if (r >= 0)
r = LUKS2_activate_multi(cd, name, vks, device_size >> SECTOR_SHIFT, flags);
err:
- crypt_reencrypt_unlock(cd, reencrypt_lock);
+ LUKS2_reencrypt_unlock(cd, reencrypt_lock);
if (r < 0)
crypt_drop_keyring_key(cd, vks);
crypt_free_volume_key(vks);
@@ -4050,10 +4067,11 @@ static int _open_and_activate_luks2(struct crypt_device *cd,
uint32_t flags)
{
crypt_reencrypt_info ri;
- int r;
+ int r, rv;
struct luks2_hdr *hdr = &cd->u.luks2.hdr;
+ struct volume_key *vks = NULL;
- ri = LUKS2_reenc_status(hdr);
+ ri = LUKS2_reencrypt_status(hdr);
if (ri == CRYPT_REENCRYPT_INVALID)
return -EINVAL;
@@ -4061,15 +4079,45 @@ static int _open_and_activate_luks2(struct crypt_device *cd,
if (name)
r = _open_and_activate_reencrypt_device(cd, hdr, keyslot, name, passphrase,
passphrase_size, flags);
- else
+ else {
r = _open_all_keys(cd, hdr, keyslot, passphrase,
- passphrase_size, flags, NULL);
+ passphrase_size, flags, &vks);
+ if (r < 0)
+ return r;
+
+ rv = LUKS2_reencrypt_digest_verify(cd, hdr, vks);
+ crypt_free_volume_key(vks);
+ if (rv < 0)
+ return rv;
+ }
} else
r = _open_and_activate(cd, keyslot, name, passphrase,
passphrase_size, flags);
return r;
}
+#else
+static int _open_and_activate_luks2(struct crypt_device *cd,
+ int keyslot,
+ const char *name,
+ const char *passphrase,
+ size_t passphrase_size,
+ uint32_t flags)
+{
+ crypt_reencrypt_info ri;
+
+ ri = LUKS2_reencrypt_status(&cd->u.luks2.hdr);
+ if (ri == CRYPT_REENCRYPT_INVALID)
+ return -EINVAL;
+
+ if (ri > CRYPT_REENCRYPT_NONE) {
+ log_err(cd, _("This operation is not supported for this device type."));
+ return -ENOTSUP;
+ }
+
+ return _open_and_activate(cd, keyslot, name, passphrase, passphrase_size, flags);
+}
+#endif
static int _activate_by_passphrase(struct crypt_device *cd,
const char *name,
@@ -4161,21 +4209,26 @@ static int _activate_loopaes(struct crypt_device *cd,
static int _activate_check_status(struct crypt_device *cd, const char *name, unsigned reload)
{
- crypt_status_info ci;
+ int r;
if (!name)
return 0;
- ci = crypt_status(cd, name);
- if (ci == CRYPT_INVALID) {
- log_err(cd, _("Cannot use device %s, name is invalid or still in use."), name);
- return -EINVAL;
- } else if (ci >= CRYPT_ACTIVE && !reload) {
+ r = dm_status_device(cd, name);
+
+ if (r >= 0 && reload)
+ return 0;
+
+ if (r >= 0 || r == -EEXIST) {
log_err(cd, _("Device %s already exists."), name);
return -EEXIST;
}
- return 0;
+ if (r == -ENODEV)
+ return 0;
+
+ log_err(cd, _("Cannot use device %s, name is invalid or still in use."), name);
+ return r;
}
// activation/deactivation of device mapping
@@ -4269,6 +4322,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
size_t volume_key_size,
uint32_t flags)
{
+ bool use_keyring;
struct volume_key *vk = NULL;
int r;
@@ -4344,8 +4398,12 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
if (r > 0)
r = 0;
- if (!r && (name || (flags & CRYPT_ACTIVATE_KEYRING_KEY)) &&
- crypt_use_keyring_for_vk(cd)) {
+ if (!crypt_use_keyring_for_vk(cd))
+ use_keyring = false;
+ else
+ use_keyring = (name && !crypt_is_cipher_null(crypt_get_cipher(cd))) || (flags & CRYPT_ACTIVATE_KEYRING_KEY);
+
+ if (!r && use_keyring) {
r = LUKS2_key_description_by_segment(cd,
&cd->u.luks2.hdr, vk, CRYPT_DEFAULT_SEGMENT);
if (!r)
@@ -4406,7 +4464,7 @@ int crypt_activate_by_signed_key(struct crypt_device *cd,
return -EINVAL;
}
- log_dbg(cd, "%s volume %s by signed key.", name ? "Activating" : "Checking", name ?: "");
+ log_dbg(cd, "%s volume %s by %skey.", name ? "Activating" : "Checking", name ?: "", signature ? "signed " : "");
if (cd->u.verity.hdr.flags & CRYPT_VERITY_ROOT_HASH_SIGNATURE && !signature) {
log_err(cd, _("Root hash signature required."));
@@ -4956,6 +5014,9 @@ const char *crypt_get_cipher_mode(struct crypt_device *cd)
/* INTERNAL only */
const char *crypt_get_integrity(struct crypt_device *cd)
{
+ if (!cd)
+ return NULL;
+
if (isINTEGRITY(cd->type))
return cd->u.integrity.params.integrity;
@@ -5235,8 +5296,8 @@ int crypt_get_metadata_size(struct crypt_device *cd,
msize = LUKS_ALIGN_KEYSLOTS;
ksize = LUKS_device_sectors(&cd->u.luks1.hdr) * SECTOR_SIZE - msize;
} else if (isLUKS2(cd->type)) {
- msize = LUKS2_metadata_size(cd->u.luks2.hdr.jobj);
- ksize = LUKS2_keyslots_size(cd->u.luks2.hdr.jobj);
+ msize = LUKS2_metadata_size(&cd->u.luks2.hdr);
+ ksize = LUKS2_keyslots_size(&cd->u.luks2.hdr);
} else
return -EINVAL;
@@ -5510,13 +5571,13 @@ void *crypt_get_hdr(struct crypt_device *cd, const char *type)
}
/* internal only */
-struct luks2_reenc_context *crypt_get_reenc_context(struct crypt_device *cd)
+struct luks2_reencrypt *crypt_get_luks2_reencrypt(struct crypt_device *cd)
{
return cd->u.luks2.rh;
}
/* internal only */
-void crypt_set_reenc_context(struct crypt_device *cd, struct luks2_reenc_context *rh)
+void crypt_set_luks2_reencrypt(struct crypt_device *cd, struct luks2_reencrypt *rh)
{
cd->u.luks2.rh = rh;
}
@@ -6039,7 +6100,7 @@ crypt_reencrypt_info crypt_reencrypt_status(struct crypt_device *cd,
if (_onlyLUKS2(cd, CRYPT_CD_QUIET, CRYPT_REQUIREMENT_ONLINE_REENCRYPT))
return CRYPT_REENCRYPT_INVALID;
- return LUKS2_reencrypt_status(cd, params);
+ return LUKS2_reencrypt_get_params(&cd->u.luks2.hdr, params);
}
static void __attribute__((destructor)) libcryptsetup_exit(void)