mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Make reencryption flag and keyslot inseparable.
LUKS2 validation code now requires reencrypt keyslot together with online-reencryption flag or none of those.
This commit is contained in:
committed by
Milan Broz
parent
59e39e484a
commit
6c8314b297
@@ -884,10 +884,17 @@ int LUKS2_keyslots_validate(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
const keyslot_handler *h;
|
||||
int keyslot;
|
||||
json_object *jobj_keyslots, *jobj_type;
|
||||
uint32_t reqs, reencrypt_count = 0;
|
||||
struct luks2_hdr dummy = {
|
||||
.jobj = hdr_jobj
|
||||
};
|
||||
|
||||
if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
|
||||
return -EINVAL;
|
||||
|
||||
if (LUKS2_config_get_requirements(cd, &dummy, &reqs))
|
||||
return -EINVAL;
|
||||
|
||||
json_object_object_foreach(jobj_keyslots, slot, val) {
|
||||
keyslot = atoi(slot);
|
||||
json_object_object_get_ex(val, "type", &jobj_type);
|
||||
@@ -903,6 +910,24 @@ int LUKS2_keyslots_validate(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
log_dbg(cd, "Keyslot %d is not assigned to exactly 1 digest.", keyslot);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!strcmp(h->name, "reencrypt"))
|
||||
reencrypt_count++;
|
||||
}
|
||||
|
||||
if ((reqs & CRYPT_REQUIREMENT_ONLINE_REENCRYPT) && reencrypt_count == 0) {
|
||||
log_dbg(cd, "Missing reencryption keyslot.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(reqs & CRYPT_REQUIREMENT_ONLINE_REENCRYPT) && reencrypt_count) {
|
||||
log_dbg(cd, "Missing reencryption requirement flag.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (reencrypt_count > 1) {
|
||||
log_dbg(cd, "Too many reencryption keyslots.");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -3288,15 +3288,20 @@ static int reencrypt_teardown_ok(struct crypt_device *cd, struct luks2_hdr *hdr,
|
||||
log_dbg(cd, "Failed to set new keyslots area size.");
|
||||
if (rh->digest_old >= 0 && rh->digest_new != rh->digest_old)
|
||||
for (i = 0; i < LUKS2_KEYSLOTS_MAX; i++)
|
||||
if (LUKS2_digest_by_keyslot(hdr, i) == rh->digest_old)
|
||||
crypt_keyslot_destroy(cd, i);
|
||||
crypt_keyslot_destroy(cd, rh->reenc_keyslot);
|
||||
if (LUKS2_digest_by_keyslot(hdr, i) == rh->digest_old && crypt_keyslot_destroy(cd, i))
|
||||
log_err(cd, _("Failed to remove unused (unbound) keyslot %d."), i);
|
||||
|
||||
if (reencrypt_erase_backup_segments(cd, hdr))
|
||||
log_dbg(cd, "Failed to erase backup segments");
|
||||
|
||||
/* do we need atomic erase? */
|
||||
if (reencrypt_update_flag(cd, 0, true))
|
||||
log_err(cd, _("Failed to disable reencryption requirement flag."));
|
||||
if (reencrypt_update_flag(cd, 0, false))
|
||||
log_dbg(cd, "Failed to disable reencryption requirement flag.");
|
||||
|
||||
/* metadata commit point also removing reencryption flag on-disk */
|
||||
if (crypt_keyslot_destroy(cd, rh->reenc_keyslot)) {
|
||||
log_err(cd, _("Failed to remove reencryption keyslot."));
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user