mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-06 16:30:04 +01:00
Add proper version data to reencryption verification digest.
LUKS2 decryption requires new online-reencrypt version flag (v3). The verification digest performs coding for version suffix in "online-reencrypt-v" flag string as follows: 'v1' : unused (no digest) 'v2' : 0x30 + 2 = 0x32 = '2' 'v3' : 0x30 + 3 = 0x33 = '3' (...) 'v10': 0x30 + 10 = 0x3A = ':' 'v11': 0x30 + 11 = 0x3B = ';' (...) 'v207': 0x30 + 207 = 0xFF
This commit is contained in:
@@ -62,6 +62,13 @@
|
||||
/* 1 GiB */
|
||||
#define LUKS2_REENCRYPT_MAX_HOTZONE_LENGTH 0x40000000
|
||||
|
||||
/* supported reencryption requirement versions */
|
||||
#define LUKS2_REENCRYPT_REQ_VERSION UINT8_C(2)
|
||||
#define LUKS2_DECRYPT_DATASHIFT_REQ_VERSION UINT8_C(3)
|
||||
|
||||
/* see reencrypt_assembly_verification_data() in luks2_reencrypt_digest.c */
|
||||
/* LUKS2_REENCRYPT_MAX_VERSION UINT8_C(207) */
|
||||
|
||||
struct device;
|
||||
struct luks2_reencrypt;
|
||||
struct reenc_protection;
|
||||
|
||||
@@ -278,6 +278,7 @@ int LUKS2_keyslot_reencrypt_load(struct crypt_device *cd,
|
||||
|
||||
int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
uint8_t version,
|
||||
struct volume_key *vks);
|
||||
|
||||
int LUKS2_keyslot_dump(struct crypt_device *cd,
|
||||
|
||||
@@ -676,6 +676,7 @@ int LUKS2_keyslot_reencrypt_update(struct crypt_device *cd,
|
||||
struct volume_key *vks)
|
||||
{
|
||||
int r;
|
||||
uint8_t version;
|
||||
uint64_t max_size, moved_segment_size;
|
||||
json_object *jobj_type, *jobj_keyslot = LUKS2_get_keyslot_jobj(hdr, keyslot);
|
||||
struct reenc_protection check_rp = {};
|
||||
@@ -685,6 +686,9 @@ int LUKS2_keyslot_reencrypt_update(struct crypt_device *cd,
|
||||
strcmp(json_object_get_string(jobj_type), "reencrypt"))
|
||||
return -EINVAL;
|
||||
|
||||
if (LUKS2_config_get_reencrypt_version(hdr, &version))
|
||||
return -EINVAL;
|
||||
|
||||
/* verify existing reencryption metadata before updating */
|
||||
r = LUKS2_reencrypt_digest_verify(cd, hdr, vks);
|
||||
if (r < 0)
|
||||
@@ -715,7 +719,7 @@ int LUKS2_keyslot_reencrypt_update(struct crypt_device *cd,
|
||||
}
|
||||
}
|
||||
|
||||
r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, vks);
|
||||
r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, version, vks);
|
||||
if (r < 0)
|
||||
log_err(cd, _("Failed to refresh reencryption verification digest."));
|
||||
|
||||
|
||||
@@ -24,9 +24,6 @@
|
||||
#include "luks2_internal.h"
|
||||
#include "utils_device_locking.h"
|
||||
|
||||
#define LUKS2_REENCRYPT_REQ_VERSION 2
|
||||
#define LUKS2_DECRYPT_DATASHIFT_REQ_VERSION 3
|
||||
|
||||
struct luks2_reencrypt {
|
||||
/* reencryption window attributes */
|
||||
uint64_t offset;
|
||||
@@ -2810,7 +2807,7 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, *vks);
|
||||
r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, LUKS2_DECRYPT_DATASHIFT_REQ_VERSION, *vks);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -3055,7 +3052,7 @@ static int reencrypt_init(struct crypt_device *cd,
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, *vks);
|
||||
r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, LUKS2_REENCRYPT_REQ_VERSION, *vks);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
@@ -3652,16 +3649,6 @@ static int reencrypt_repair_by_passphrase(
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = LUKS2_keyslot_open_all_segments(cd, keyslot_old, keyslot_new, passphrase, passphrase_size, &vks);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, vks);
|
||||
crypt_free_volume_key(vks);
|
||||
vks = NULL;
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
resilience = reencrypt_resilience_type(hdr);
|
||||
if (!resilience) {
|
||||
r = -EINVAL;
|
||||
@@ -3675,6 +3662,16 @@ static int reencrypt_repair_by_passphrase(
|
||||
else
|
||||
requirement_version = LUKS2_REENCRYPT_REQ_VERSION;
|
||||
|
||||
r = LUKS2_keyslot_open_all_segments(cd, keyslot_old, keyslot_new, passphrase, passphrase_size, &vks);
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
r = LUKS2_keyslot_reencrypt_digest_create(cd, hdr, requirement_version, vks);
|
||||
crypt_free_volume_key(vks);
|
||||
vks = NULL;
|
||||
if (r < 0)
|
||||
goto out;
|
||||
|
||||
/* replaces old online-reencrypt flag with updated version and commits metadata */
|
||||
r = reencrypt_update_flag(cd, requirement_version, true, true);
|
||||
out:
|
||||
|
||||
@@ -265,6 +265,7 @@ static size_t blob_serialize(void *blob, size_t length, uint8_t *buffer)
|
||||
static int reencrypt_assembly_verification_data(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
struct volume_key *vks,
|
||||
uint8_t version,
|
||||
struct volume_key **verification_data)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
@@ -272,6 +273,11 @@ static int reencrypt_assembly_verification_data(struct crypt_device *cd,
|
||||
struct volume_key *data = NULL, *vk_old = NULL, *vk_new = NULL;
|
||||
size_t keyslot_data_len, segments_data_len, data_len = 2;
|
||||
|
||||
/*
|
||||
* This works up to (including) version v207.
|
||||
*/
|
||||
assert(version < (UINT8_MAX - 0x2F));
|
||||
|
||||
/* Keys - calculate length */
|
||||
digest_new = LUKS2_reencrypt_digest_new(hdr);
|
||||
digest_old = LUKS2_reencrypt_digest_old(hdr);
|
||||
@@ -313,9 +319,8 @@ static int reencrypt_assembly_verification_data(struct crypt_device *cd,
|
||||
|
||||
ptr = (uint8_t*)data->key;
|
||||
|
||||
/* v2 */
|
||||
*ptr++ = 0x76;
|
||||
*ptr++ = 0x32;
|
||||
*ptr++ = 0x30 + version;
|
||||
|
||||
if (vk_old)
|
||||
ptr += blob_serialize(vk_old->key, vk_old->keylength, ptr);
|
||||
@@ -343,6 +348,7 @@ bad:
|
||||
|
||||
int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd,
|
||||
struct luks2_hdr *hdr,
|
||||
uint8_t version,
|
||||
struct volume_key *vks)
|
||||
{
|
||||
int digest_reencrypt, keyslot_reencrypt, r;
|
||||
@@ -352,7 +358,7 @@ int LUKS2_keyslot_reencrypt_digest_create(struct crypt_device *cd,
|
||||
if (keyslot_reencrypt < 0)
|
||||
return keyslot_reencrypt;
|
||||
|
||||
r = reencrypt_assembly_verification_data(cd, hdr, vks, &data);
|
||||
r = reencrypt_assembly_verification_data(cd, hdr, vks, version, &data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -376,6 +382,7 @@ int LUKS2_reencrypt_digest_verify(struct crypt_device *cd,
|
||||
{
|
||||
int r, keyslot_reencrypt;
|
||||
struct volume_key *data;
|
||||
uint8_t version;
|
||||
|
||||
log_dbg(cd, "Verifying reencryption metadata.");
|
||||
|
||||
@@ -383,7 +390,10 @@ int LUKS2_reencrypt_digest_verify(struct crypt_device *cd,
|
||||
if (keyslot_reencrypt < 0)
|
||||
return keyslot_reencrypt;
|
||||
|
||||
r = reencrypt_assembly_verification_data(cd, hdr, vks, &data);
|
||||
if (LUKS2_config_get_reencrypt_version(hdr, &version))
|
||||
return -EINVAL;
|
||||
|
||||
r = reencrypt_assembly_verification_data(cd, hdr, vks, version, &data);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user