114 lines
3.9 KiB
Diff
114 lines
3.9 KiB
Diff
diff -rupN cryptsetup-2.3.3.old/lib/luks2/luks2_internal.h cryptsetup-2.3.3/lib/luks2/luks2_internal.h
|
|
--- cryptsetup-2.3.3.old/lib/luks2/luks2_internal.h 2022-01-17 16:14:07.530136302 +0100
|
|
+++ cryptsetup-2.3.3/lib/luks2/luks2_internal.h 2022-01-17 16:15:29.134422136 +0100
|
|
@@ -207,5 +207,6 @@ static inline const char *crypt_reencryp
|
|
}
|
|
|
|
bool json_segment_contains_flag(json_object *jobj_segment, const char *flag_str, size_t len);
|
|
+bool json_segment_cmp(json_object *jobj_segment_1, json_object *jobj_segment_2);
|
|
|
|
#endif
|
|
diff -rupN cryptsetup-2.3.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.3.3/lib/luks2/luks2_json_metadata.c
|
|
--- cryptsetup-2.3.3.old/lib/luks2/luks2_json_metadata.c 2022-01-17 16:14:07.530136302 +0100
|
|
+++ cryptsetup-2.3.3/lib/luks2/luks2_json_metadata.c 2022-01-17 16:16:34.382650680 +0100
|
|
@@ -606,6 +606,63 @@ static int reqs_reencrypt_online(uint32_
|
|
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;
|
|
@@ -732,7 +789,7 @@ static int hdr_validate_segments(struct
|
|
}
|
|
}
|
|
|
|
- return 0;
|
|
+ return validate_reencrypt_segments(cd, hdr_jobj, jobj_segments, first_backup, count);
|
|
}
|
|
|
|
uint64_t LUKS2_metadata_size(json_object *jobj)
|
|
diff -rupN cryptsetup-2.3.3.old/lib/luks2/luks2_segment.c cryptsetup-2.3.3/lib/luks2/luks2_segment.c
|
|
--- cryptsetup-2.3.3.old/lib/luks2/luks2_segment.c 2022-01-17 16:14:07.531136305 +0100
|
|
+++ cryptsetup-2.3.3/lib/luks2/luks2_segment.c 2022-01-17 16:14:43.952263876 +0100
|
|
@@ -410,3 +410,23 @@ json_object *LUKS2_get_segment_by_flag(s
|
|
|
|
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;
|
|
+}
|