mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 16:30:04 +01:00
Allow crypt_reencrypt_init_by_keyslot_contexts with no active keyslots.
With this commit reencryption can run without any active keyslot containing current (or optional future) volume key. In such case new volume key must be provided via CRYPT_KC_TYPE_KEY keyslot context and by adding CRYPT_REENCRYPT_CREATE_NEW_DIGEST flag in reencryption parameters during reencryption initialization in crypt_reencrypt_init_by_keyslot_contexts. The new flag can not be combined with CRYPT_REENCRYPT_RESUME_ONLY flag.
This commit is contained in:
@@ -2922,6 +2922,12 @@ int crypt_activate_by_token_pin(struct crypt_device *cd,
|
|||||||
#define CRYPT_REENCRYPT_RECOVERY (UINT32_C(1) << 3)
|
#define CRYPT_REENCRYPT_RECOVERY (UINT32_C(1) << 3)
|
||||||
/** Reencryption requires metadata protection. (in/out) */
|
/** Reencryption requires metadata protection. (in/out) */
|
||||||
#define CRYPT_REENCRYPT_REPAIR_NEEDED (UINT32_C(1) << 4)
|
#define CRYPT_REENCRYPT_REPAIR_NEEDED (UINT32_C(1) << 4)
|
||||||
|
/**
|
||||||
|
* Calculate new (future) volume key digest directly during
|
||||||
|
* reencryption initialization. The keyslot context for new
|
||||||
|
* volume key must be CRYPT_KC_TYPE_KEY or
|
||||||
|
* CRYPT_KC_TYPE_VK_KEYRING. (in) */
|
||||||
|
#define CRYPT_REENCRYPT_CREATE_NEW_DIGEST (UINT32_C(1) << 5)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reencryption direction
|
* Reencryption direction
|
||||||
|
|||||||
@@ -485,9 +485,12 @@ static int keyslot_context_open_all_segments(struct crypt_device *cd,
|
|||||||
log_dbg(cd, "Checking current volume key (digest %d, segment: %d) using keyslot %d.",
|
log_dbg(cd, "Checking current volume key (digest %d, segment: %d) using keyslot %d.",
|
||||||
digest_old, segment_old, keyslot_old);
|
digest_old, segment_old, keyslot_old);
|
||||||
|
|
||||||
r = LUKS2_keyslot_for_segment(hdr, keyslot_old, segment_old);
|
/* key and key in keyring types do not have association with any keyslot */
|
||||||
if (r < 0)
|
if (kc_old->type != CRYPT_KC_TYPE_KEY && kc_old->type != CRYPT_KC_TYPE_VK_KEYRING) {
|
||||||
goto out;
|
r = LUKS2_keyslot_for_segment(hdr, keyslot_old, segment_old);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
r = kc_old->get_luks2_key(cd, kc_old, keyslot_old, segment_old, &vk);
|
r = kc_old->get_luks2_key(cd, kc_old, keyslot_old, segment_old, &vk);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@@ -505,9 +508,12 @@ static int keyslot_context_open_all_segments(struct crypt_device *cd,
|
|||||||
log_dbg(cd, "Checking new volume key (digest %d, segment: %d) using keyslot %d.",
|
log_dbg(cd, "Checking new volume key (digest %d, segment: %d) using keyslot %d.",
|
||||||
digest_new, segment_new, keyslot_new);
|
digest_new, segment_new, keyslot_new);
|
||||||
|
|
||||||
r = LUKS2_keyslot_for_segment(hdr, keyslot_new, segment_new);
|
/* key and key in keyring types do not have association with any keyslot */
|
||||||
if (r < 0)
|
if (kc_new->type != CRYPT_KC_TYPE_KEY && kc_new->type != CRYPT_KC_TYPE_VK_KEYRING) {
|
||||||
goto out;
|
r = LUKS2_keyslot_for_segment(hdr, keyslot_new, segment_new);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
r = kc_new->get_luks2_key(cd, kc_new, keyslot_new, segment_new, &vk);
|
r = kc_new->get_luks2_key(cd, kc_new, keyslot_new, segment_new, &vk);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
|||||||
@@ -2468,23 +2468,20 @@ out:
|
|||||||
|
|
||||||
static int reencrypt_make_backup_segments(struct crypt_device *cd,
|
static int reencrypt_make_backup_segments(struct crypt_device *cd,
|
||||||
struct luks2_hdr *hdr,
|
struct luks2_hdr *hdr,
|
||||||
int keyslot_new,
|
int digest_new,
|
||||||
const char *cipher,
|
const char *cipher,
|
||||||
uint64_t data_offset,
|
uint64_t data_offset,
|
||||||
const struct crypt_params_reencrypt *params)
|
const struct crypt_params_reencrypt *params)
|
||||||
{
|
{
|
||||||
const char *type;
|
const char *type;
|
||||||
int r, segment, moved_segment = -1, digest_old = -1, digest_new = -1;
|
int r, segment, moved_segment = -1, digest_old = -1;
|
||||||
json_object *jobj_tmp, *jobj_segment_new = NULL, *jobj_segment_old = NULL, *jobj_segment_bcp = NULL;
|
json_object *jobj_tmp, *jobj_segment_new = NULL, *jobj_segment_old = NULL, *jobj_segment_bcp = NULL;
|
||||||
uint32_t sector_size = params->luks2 ? params->luks2->sector_size : SECTOR_SIZE;
|
uint32_t sector_size = params->luks2 ? params->luks2->sector_size : SECTOR_SIZE;
|
||||||
uint64_t segment_offset, tmp, data_shift = params->data_shift << SECTOR_SHIFT,
|
uint64_t segment_offset, tmp, data_shift = params->data_shift << SECTOR_SHIFT,
|
||||||
device_size = params->device_size << SECTOR_SHIFT;
|
device_size = params->device_size << SECTOR_SHIFT;
|
||||||
|
|
||||||
if (params->mode != CRYPT_REENCRYPT_DECRYPT) {
|
if (params->mode != CRYPT_REENCRYPT_DECRYPT && digest_new < 0)
|
||||||
digest_new = LUKS2_digest_by_keyslot(hdr, keyslot_new);
|
return -EINVAL;
|
||||||
if (digest_new < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (params->mode != CRYPT_REENCRYPT_ENCRYPT) {
|
if (params->mode != CRYPT_REENCRYPT_ENCRYPT) {
|
||||||
digest_old = LUKS2_digest_by_segment(hdr, CRYPT_DEFAULT_SEGMENT);
|
digest_old = LUKS2_digest_by_segment(hdr, CRYPT_DEFAULT_SEGMENT);
|
||||||
@@ -2851,7 +2848,7 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd,
|
|||||||
if (r)
|
if (r)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
r = reencrypt_make_backup_segments(cd, hdr, CRYPT_ANY_SLOT, NULL, data_offset, params);
|
r = reencrypt_make_backup_segments(cd, hdr, CRYPT_ANY_DIGEST, NULL, data_offset, params);
|
||||||
if (r) {
|
if (r) {
|
||||||
log_dbg(cd, "Failed to create reencryption backup device segments.");
|
log_dbg(cd, "Failed to create reencryption backup device segments.");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -2997,8 +2994,9 @@ static int reencrypt_init(struct crypt_device *cd,
|
|||||||
bool move_first_segment;
|
bool move_first_segment;
|
||||||
char _cipher[128];
|
char _cipher[128];
|
||||||
uint32_t check_sector_size, new_sector_size, old_sector_size;
|
uint32_t check_sector_size, new_sector_size, old_sector_size;
|
||||||
int r, reencrypt_keyslot, devfd = -1;
|
int digest_new, r, reencrypt_keyslot, devfd = -1;
|
||||||
uint64_t data_offset, data_size = 0;
|
uint64_t data_offset, data_size = 0;
|
||||||
|
struct volume_key *vk;
|
||||||
struct crypt_dm_active_device dmd_target, dmd_source = {
|
struct crypt_dm_active_device dmd_target, dmd_source = {
|
||||||
.uuid = crypt_get_uuid(cd),
|
.uuid = crypt_get_uuid(cd),
|
||||||
.flags = CRYPT_ACTIVATE_SHARED /* turn off exclusive open checks */
|
.flags = CRYPT_ACTIVATE_SHARED /* turn off exclusive open checks */
|
||||||
@@ -3011,7 +3009,8 @@ static int reencrypt_init(struct crypt_device *cd,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (params->mode != CRYPT_REENCRYPT_DECRYPT &&
|
if (params->mode != CRYPT_REENCRYPT_DECRYPT &&
|
||||||
(!params->luks2 || !(cipher && cipher_mode) || keyslot_new < 0))
|
(!params->luks2 || !(cipher && cipher_mode) ||
|
||||||
|
(keyslot_new < 0 && !(params->flags & CRYPT_REENCRYPT_CREATE_NEW_DIGEST))))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
log_dbg(cd, "Initializing reencryption (mode: %s) in LUKS2 metadata.",
|
log_dbg(cd, "Initializing reencryption (mode: %s) in LUKS2 metadata.",
|
||||||
@@ -3118,7 +3117,25 @@ static int reencrypt_init(struct crypt_device *cd,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = reencrypt_make_backup_segments(cd, hdr, keyslot_new, _cipher, data_offset, params);
|
if (params->flags & CRYPT_REENCRYPT_CREATE_NEW_DIGEST) {
|
||||||
|
assert(kc_new->get_luks2_key);
|
||||||
|
r = kc_new->get_luks2_key(cd, kc_new, CRYPT_ANY_SLOT, CRYPT_ANY_SEGMENT, &vk);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* do not create new digest in case it matches the current one */
|
||||||
|
r = LUKS2_digest_verify_by_segment(cd, hdr, CRYPT_DEFAULT_SEGMENT, vk);
|
||||||
|
if (r == -EPERM)
|
||||||
|
r = LUKS2_digest_create(cd, "pbkdf2", hdr, vk);
|
||||||
|
|
||||||
|
crypt_free_volume_key(vk);
|
||||||
|
if (r < 0)
|
||||||
|
goto out;
|
||||||
|
digest_new = r;
|
||||||
|
} else
|
||||||
|
digest_new = LUKS2_digest_by_keyslot(hdr, keyslot_new);
|
||||||
|
|
||||||
|
r = reencrypt_make_backup_segments(cd, hdr, digest_new, _cipher, data_offset, params);
|
||||||
if (r) {
|
if (r) {
|
||||||
log_dbg(cd, "Failed to create reencryption backup device segments.");
|
log_dbg(cd, "Failed to create reencryption backup device segments.");
|
||||||
goto out;
|
goto out;
|
||||||
@@ -3812,10 +3829,16 @@ static int reencrypt_init_by_keyslot_context(struct crypt_device *cd,
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
crypt_reencrypt_info ri;
|
crypt_reencrypt_info ri;
|
||||||
|
size_t key_length;
|
||||||
struct volume_key *vks = NULL;
|
struct volume_key *vks = NULL;
|
||||||
uint32_t flags = params ? params->flags : 0;
|
uint32_t flags = params ? params->flags : 0;
|
||||||
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
|
struct luks2_hdr *hdr = crypt_get_hdr(cd, CRYPT_LUKS2);
|
||||||
|
|
||||||
|
if (params && (params->flags & CRYPT_REENCRYPT_CREATE_NEW_DIGEST) &&
|
||||||
|
(!kc_new || !kc_new->get_luks2_key || !kc_new->get_key_size ||
|
||||||
|
(params->flags & CRYPT_REENCRYPT_RESUME_ONLY)))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* short-circuit in reencryption metadata update and finish immediately. */
|
/* short-circuit in reencryption metadata update and finish immediately. */
|
||||||
if (flags & CRYPT_REENCRYPT_REPAIR_NEEDED)
|
if (flags & CRYPT_REENCRYPT_REPAIR_NEEDED)
|
||||||
return reencrypt_repair(cd, hdr, keyslot_old, keyslot_new, kc_old, kc_new);
|
return reencrypt_repair(cd, hdr, keyslot_old, keyslot_new, kc_old, kc_new);
|
||||||
@@ -3832,10 +3855,15 @@ static int reencrypt_init_by_keyslot_context(struct crypt_device *cd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cipher && !crypt_cipher_wrapped_key(cipher, cipher_mode)) {
|
if (cipher && !crypt_cipher_wrapped_key(cipher, cipher_mode)) {
|
||||||
r = crypt_keyslot_get_key_size(cd, keyslot_new);
|
if (keyslot_new == CRYPT_ANY_SLOT && kc_new && kc_new->get_key_size)
|
||||||
|
r = kc_new->get_key_size(cd, kc_new, &key_length);
|
||||||
|
else {
|
||||||
|
r = crypt_keyslot_get_key_size(cd, keyslot_new);
|
||||||
|
key_length = r;
|
||||||
|
}
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
r = LUKS2_check_cipher(cd, r, cipher, cipher_mode);
|
r = LUKS2_check_cipher(cd, key_length, cipher, cipher_mode);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_err(cd, _("Unable to use cipher specification %s-%s for LUKS2."), cipher, cipher_mode);
|
log_err(cd, _("Unable to use cipher specification %s-%s for LUKS2."), cipher, cipher_mode);
|
||||||
return r;
|
return r;
|
||||||
|
|||||||
@@ -4132,11 +4132,12 @@ static void Luks2Reencryption(void)
|
|||||||
struct crypt_keyslot_context *kc_pass12 = NULL, *kc_pass21 = NULL, *kc_file12 = NULL, *kc_file21 = NULL,
|
struct crypt_keyslot_context *kc_pass12 = NULL, *kc_pass21 = NULL, *kc_file12 = NULL, *kc_file21 = NULL,
|
||||||
*kc_token12 = NULL, *kc_token21 = NULL, *kc_key = NULL, *kc_key2 = NULL;
|
*kc_token12 = NULL, *kc_token21 = NULL, *kc_key = NULL, *kc_key2 = NULL;
|
||||||
|
|
||||||
const char *vk_hex = "bb21babe733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a",
|
const char *vk_hex = "bb21babe733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a",
|
||||||
*vk_hex2 = "bb21bebe733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a";
|
*vk_hex2 = "bb21bebe733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a" \
|
||||||
|
"cc21cfcf733229347ce4f681891f213d94d685cf6b5b84818baf7b78b6rf7b1b";
|
||||||
size_t key_size = strlen(vk_hex) / 2,
|
size_t key_size = strlen(vk_hex) / 2,
|
||||||
key_size2 = strlen(vk_hex2) / 2;
|
key_size2 = strlen(vk_hex2) / 2;
|
||||||
char key[128], key2[32];
|
char key[128], key2[64];
|
||||||
|
|
||||||
crypt_decode_key(key, vk_hex, key_size);
|
crypt_decode_key(key, vk_hex, key_size);
|
||||||
crypt_decode_key(key2, vk_hex2, key_size2);
|
crypt_decode_key(key2, vk_hex2, key_size2);
|
||||||
@@ -4624,6 +4625,38 @@ static void Luks2Reencryption(void)
|
|||||||
EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE);
|
EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE);
|
||||||
CRYPT_FREE(cd);
|
CRYPT_FREE(cd);
|
||||||
|
|
||||||
|
/* wipe existing header from previous run */
|
||||||
|
_system("dd if=/dev/zero of=" DMDIR L_DEVICE_OK " bs=4K count=5 2>/dev/null", 1);
|
||||||
|
|
||||||
|
/* offline in-place encryption with reserved space in the head of data device (using no keyslot, by volume key) */
|
||||||
|
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
|
||||||
|
rparams = (struct crypt_params_reencrypt) {
|
||||||
|
.mode = CRYPT_REENCRYPT_ENCRYPT,
|
||||||
|
.direction = CRYPT_REENCRYPT_FORWARD,
|
||||||
|
.resilience = "checksum",
|
||||||
|
.hash = "sha256",
|
||||||
|
.luks2 = &(struct crypt_params_luks2){ .sector_size = 512 },
|
||||||
|
.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY | CRYPT_REENCRYPT_CREATE_NEW_DIGEST
|
||||||
|
};
|
||||||
|
/* key does not matter. the new one from encrypt will be used */
|
||||||
|
OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, ¶ms2));
|
||||||
|
CRYPT_FREE(cd);
|
||||||
|
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
|
||||||
|
OK_(crypt_load(cd, CRYPT_LUKS2, NULL));
|
||||||
|
OK_(crypt_keyslot_context_init_by_volume_key(cd, key, key_size, &kc_key));
|
||||||
|
OK_(crypt_reencrypt_init_by_keyslot_context(cd, NULL, NULL, kc_key, CRYPT_ANY_SLOT, CRYPT_ANY_SLOT, "aes", "xts-plain64", &rparams));
|
||||||
|
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc_key, CRYPT_ANY_SLOT, NULL, 0));
|
||||||
|
FAIL_(crypt_reencrypt_run(cd, NULL, NULL), "context not initialized");
|
||||||
|
rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY | CRYPT_REENCRYPT_CREATE_NEW_DIGEST;
|
||||||
|
FAIL_(crypt_reencrypt_init_by_keyslot_context(cd, NULL, NULL, kc_key, CRYPT_ANY_SLOT, CRYPT_ANY_SLOT, "aes", "xts-plain64", &rparams), "Can not use direct key flag with resume only.");
|
||||||
|
rparams.flags = CRYPT_REENCRYPT_RESUME_ONLY;
|
||||||
|
OK_(crypt_reencrypt_init_by_keyslot_context(cd, NULL, NULL, kc_key, CRYPT_ANY_SLOT, CRYPT_ANY_SLOT, NULL, NULL, &rparams));
|
||||||
|
OK_(crypt_reencrypt_run(cd, NULL, NULL));
|
||||||
|
EQ_(crypt_reencrypt_status(cd, NULL), CRYPT_REENCRYPT_NONE);
|
||||||
|
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc_key, CRYPT_ANY_SLOT, NULL, 0));
|
||||||
|
crypt_keyslot_context_free(kc_key);
|
||||||
|
CRYPT_FREE(cd);
|
||||||
|
|
||||||
/* wipe existing header from previous run */
|
/* wipe existing header from previous run */
|
||||||
_system("dd if=/dev/zero of=" DMDIR L_DEVICE_OK " bs=4K count=5 2>/dev/null", 1);
|
_system("dd if=/dev/zero of=" DMDIR L_DEVICE_OK " bs=4K count=5 2>/dev/null", 1);
|
||||||
/* open existing device from kernel (simulate active filesystem) */
|
/* open existing device from kernel (simulate active filesystem) */
|
||||||
@@ -5132,14 +5165,14 @@ static void Luks2Reencryption(void)
|
|||||||
OK_(crypt_reencrypt_run(cd, NULL, NULL));
|
OK_(crypt_reencrypt_run(cd, NULL, NULL));
|
||||||
EQ_(crypt_keyslot_status(cd, 13), CRYPT_SLOT_UNBOUND);
|
EQ_(crypt_keyslot_status(cd, 13), CRYPT_SLOT_UNBOUND);
|
||||||
|
|
||||||
// add previous key as unbound key.
|
// reencrypt just by volume keys (new key is passed directly w/o being stored in any keyslot)
|
||||||
EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, kc_key2, 12, kc_token12, CRYPT_VOLUME_KEY_NO_SEGMENT), 12);
|
rparams.flags |= CRYPT_REENCRYPT_CREATE_NEW_DIGEST;
|
||||||
|
NOTFAIL_(crypt_reencrypt_init_by_keyslot_context(cd, NULL, kc_key, kc_key2, CRYPT_ANY_SLOT, CRYPT_ANY_SLOT, "aes", "xts-plain64", &rparams), "Reencrypt init failed");
|
||||||
// FIXME: This should not require the previous step of adding a keyslot.
|
|
||||||
// reencrypt just by volume keys
|
|
||||||
NOTFAIL_(crypt_reencrypt_init_by_keyslot_context(cd, NULL, kc_key, kc_key2, CRYPT_ANY_SLOT, 12, "aes", "xts-plain64", &rparams), "Reencrypt init failed");
|
|
||||||
OK_(crypt_reencrypt_run(cd, NULL, NULL));
|
OK_(crypt_reencrypt_run(cd, NULL, NULL));
|
||||||
EQ_(crypt_keyslot_status(cd, 13), CRYPT_SLOT_UNBOUND);
|
EQ_(crypt_keyslot_status(cd, 13), CRYPT_SLOT_UNBOUND);
|
||||||
|
rparams.flags &= ~CRYPT_REENCRYPT_CREATE_NEW_DIGEST;
|
||||||
|
// store new key in a keyslot
|
||||||
|
EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, kc_key2, 12, kc_token12, 0), 12);
|
||||||
|
|
||||||
// add previous key as unbound key.
|
// add previous key as unbound key.
|
||||||
EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, kc_key, 21, kc_token21, CRYPT_VOLUME_KEY_NO_SEGMENT), 21);
|
EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, kc_key, 21, kc_token21, CRYPT_VOLUME_KEY_NO_SEGMENT), 21);
|
||||||
@@ -5182,10 +5215,7 @@ static void Luks2Reencryption(void)
|
|||||||
|
|
||||||
EQ_(crypt_keyslot_status(cd, 13), CRYPT_SLOT_UNBOUND);
|
EQ_(crypt_keyslot_status(cd, 13), CRYPT_SLOT_UNBOUND);
|
||||||
|
|
||||||
crypt_keyslot_context_free(kc_pass12);
|
|
||||||
crypt_keyslot_context_free(kc_pass21);
|
crypt_keyslot_context_free(kc_pass21);
|
||||||
crypt_keyslot_context_free(kc_key);
|
|
||||||
crypt_keyslot_context_free(kc_key2);
|
|
||||||
crypt_keyslot_context_free(kc_file12);
|
crypt_keyslot_context_free(kc_file12);
|
||||||
crypt_keyslot_context_free(kc_file21);
|
crypt_keyslot_context_free(kc_file21);
|
||||||
crypt_keyslot_context_free(kc_token12);
|
crypt_keyslot_context_free(kc_token12);
|
||||||
@@ -5193,6 +5223,40 @@ static void Luks2Reencryption(void)
|
|||||||
|
|
||||||
CRYPT_FREE(cd);
|
CRYPT_FREE(cd);
|
||||||
|
|
||||||
|
/* specifically test reencryption of device with no active keyslots */
|
||||||
|
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
|
||||||
|
OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, key, key_size, &(struct crypt_params_luks2){ .sector_size = 512 }));
|
||||||
|
FAIL_(crypt_reencrypt_init_by_keyslot_context(cd, NULL, kc_key, kc_key2, CRYPT_ANY_SLOT, CRYPT_ANY_SLOT, "aes", "xts-plain64", &rparams), "Reencrypt init failed due to missing new key keyslot.");
|
||||||
|
rparams.flags |= CRYPT_REENCRYPT_CREATE_NEW_DIGEST;
|
||||||
|
NOTFAIL_(crypt_reencrypt_init_by_keyslot_context(cd, NULL, kc_key, kc_key2, CRYPT_ANY_SLOT, CRYPT_ANY_SLOT, "aes", "xts-plain64", &rparams), "Reencrypt init failed.");
|
||||||
|
|
||||||
|
FAIL_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc_key, CRYPT_ANY_SLOT, NULL, 0), "Missing key for device in reencryption.");
|
||||||
|
FAIL_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc_key2, CRYPT_ANY_SLOT, NULL, 0), "Missing key for device in reencryption.");
|
||||||
|
|
||||||
|
/* after reencryption gets initialized the order in which user provides keyslot contexts does not matter */
|
||||||
|
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc_key, CRYPT_ANY_SLOT, kc_key2, 0));
|
||||||
|
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc_key2, CRYPT_ANY_SLOT, kc_key, 0));
|
||||||
|
|
||||||
|
OK_(crypt_reencrypt_run(cd, NULL, NULL));
|
||||||
|
CRYPT_FREE(cd);
|
||||||
|
|
||||||
|
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
|
||||||
|
OK_(crypt_load(cd, CRYPT_LUKS2, NULL));
|
||||||
|
|
||||||
|
/* check digest was properly stored in mda */
|
||||||
|
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc_key2, CRYPT_ANY_SLOT, NULL, 0));
|
||||||
|
FAIL_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc_key, CRYPT_ANY_SLOT, NULL, 0), "Not valid volume key");
|
||||||
|
|
||||||
|
/* add keyslot by new volume key */
|
||||||
|
EQ_(crypt_keyslot_add_by_keyslot_context(cd, CRYPT_ANY_SLOT, kc_key2, 12, kc_pass12, 0), 12);
|
||||||
|
EQ_(crypt_activate_by_keyslot_context(cd, NULL, 12, kc_pass12, CRYPT_ANY_SLOT, NULL, 0), 12);
|
||||||
|
|
||||||
|
crypt_keyslot_context_free(kc_pass12);
|
||||||
|
crypt_keyslot_context_free(kc_key);
|
||||||
|
crypt_keyslot_context_free(kc_key2);
|
||||||
|
|
||||||
|
CRYPT_FREE(cd);
|
||||||
|
|
||||||
NOTFAIL_(keyctl_unlink(kid, KEY_SPEC_THREAD_KEYRING), "Test or kernel keyring are broken.");
|
NOTFAIL_(keyctl_unlink(kid, KEY_SPEC_THREAD_KEYRING), "Test or kernel keyring are broken.");
|
||||||
NOTFAIL_(keyctl_unlink(kid1, KEY_SPEC_THREAD_KEYRING), "Test or kernel keyring are broken.");
|
NOTFAIL_(keyctl_unlink(kid1, KEY_SPEC_THREAD_KEYRING), "Test or kernel keyring are broken.");
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user