mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-05 16:00:05 +01:00
Add segments validation for reencryption.
Effective segments during LUKS2 reencryption must match key characteristics of backup segment (cipher, sector_size, segment type).
This commit is contained in:
committed by
Milan Broz
parent
7420f879e0
commit
b61ec23e48
@@ -263,6 +263,7 @@ uint64_t json_segments_get_minimal_offset(json_object *jobj_segments, unsigned b
|
||||
json_object *json_segment_create_linear(uint64_t offset, const uint64_t *length, unsigned reencryption);
|
||||
json_object *json_segment_create_crypt(uint64_t offset, uint64_t iv_offset, const uint64_t *length, const char *cipher, uint32_t sector_size, unsigned reencryption);
|
||||
int json_segments_segment_in_reencrypt(json_object *jobj_segments);
|
||||
bool json_segment_cmp(json_object *jobj_segment_1, json_object *jobj_segment_2);
|
||||
bool json_segment_contains_flag(json_object *jobj_segment, const char *flag_str, size_t len);
|
||||
|
||||
int LUKS2_assembly_multisegment_dmd(struct crypt_device *cd,
|
||||
|
||||
@@ -607,6 +607,63 @@ static int reqs_reencrypt_online(uint32_t reqs)
|
||||
return reqs & CRYPT_REQUIREMENT_ONLINE_REENCRYPT;
|
||||
}
|
||||
|
||||
/*
|
||||
* Config section requirements object must be valid.
|
||||
* Also general segments section must be validated first.
|
||||
*/
|
||||
static int validate_reencrypt_segments(struct crypt_device *cd, json_object *hdr_jobj, json_object *jobj_segments, int first_backup, int segments_count)
|
||||
{
|
||||
json_object *jobj, *jobj_backup_previous = NULL, *jobj_backup_final = NULL;
|
||||
uint32_t reqs;
|
||||
int i, r;
|
||||
struct luks2_hdr dummy = {
|
||||
.jobj = hdr_jobj
|
||||
};
|
||||
|
||||
r = LUKS2_config_get_requirements(cd, &dummy, &reqs);
|
||||
if (r)
|
||||
return 1;
|
||||
|
||||
if (reqs_reencrypt_online(reqs)) {
|
||||
for (i = first_backup; i < segments_count; i++) {
|
||||
jobj = json_segments_get_segment(jobj_segments, i);
|
||||
if (!jobj)
|
||||
return 1;
|
||||
if (json_segment_contains_flag(jobj, "backup-final", 0))
|
||||
jobj_backup_final = jobj;
|
||||
else if (json_segment_contains_flag(jobj, "backup-previous", 0))
|
||||
jobj_backup_previous = jobj;
|
||||
}
|
||||
|
||||
if (!jobj_backup_final || !jobj_backup_previous) {
|
||||
log_dbg(cd, "Backup segment is missing.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < first_backup; i++) {
|
||||
jobj = json_segments_get_segment(jobj_segments, i);
|
||||
if (!jobj)
|
||||
return 1;
|
||||
|
||||
if (json_segment_contains_flag(jobj, "in-reencryption", 0)) {
|
||||
if (!json_segment_cmp(jobj, jobj_backup_final)) {
|
||||
log_dbg(cd, "Segment in reencryption does not match backup final segment.");
|
||||
return 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!json_segment_cmp(jobj, jobj_backup_final) &&
|
||||
!json_segment_cmp(jobj, jobj_backup_previous)) {
|
||||
log_dbg(cd, "Segment does not match neither backup final or backup previous segment.");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
{
|
||||
json_object *jobj_segments, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type, *jobj_flags, *jobj;
|
||||
@@ -733,7 +790,7 @@ static int hdr_validate_segments(struct crypt_device *cd, json_object *hdr_jobj)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return validate_reencrypt_segments(cd, hdr_jobj, jobj_segments, first_backup, count);
|
||||
}
|
||||
|
||||
static uint64_t LUKS2_metadata_size_jobj(json_object *jobj)
|
||||
|
||||
@@ -410,3 +410,23 @@ json_object *LUKS2_get_segment_by_flag(struct luks2_hdr *hdr, const char *flag)
|
||||
|
||||
return jobj_segment;
|
||||
}
|
||||
|
||||
/* compares key characteristics of both segments */
|
||||
bool json_segment_cmp(json_object *jobj_segment_1, json_object *jobj_segment_2)
|
||||
{
|
||||
const char *type = json_segment_type(jobj_segment_1);
|
||||
const char *type2 = json_segment_type(jobj_segment_2);
|
||||
|
||||
if (!type || !type2)
|
||||
return false;
|
||||
|
||||
if (strcmp(type, type2))
|
||||
return false;
|
||||
|
||||
if (!strcmp(type, "crypt"))
|
||||
return (json_segment_get_sector_size(jobj_segment_1) == json_segment_get_sector_size(jobj_segment_2) &&
|
||||
!strcmp(json_segment_get_cipher(jobj_segment_1),
|
||||
json_segment_get_cipher(jobj_segment_2)));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user