diff --git a/.cryptsetup.metadata b/.cryptsetup.metadata
index c725069..ff5999b 100644
--- a/.cryptsetup.metadata
+++ b/.cryptsetup.metadata
@@ -1,2 +1,4 @@
 1f06d268aee0adff931a39fe6709af7804e4f4f6 SOURCES/cryptsetup-1.7.4.tar.xz
 d24bdd0d55be8b27769b07531950ffe60589274b SOURCES/cryptsetup-2.0.3.tar.xz
+4da4e0728f59b42ac7ca7645c483ee554f0da821 SOURCES/luks2_mda_images.tar.xz
+839899b3821d4a5d8a8196c8fdd2dd0bd1f582f7 SOURCES/luks2_valid_hdr.tar.xz
diff --git a/.gitignore b/.gitignore
index 3eb9f13..7c79481 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 SOURCES/cryptsetup-1.7.4.tar.xz
 SOURCES/cryptsetup-2.0.3.tar.xz
+SOURCES/luks2_mda_images.tar.xz
+SOURCES/luks2_valid_hdr.tar.xz
diff --git a/SOURCES/cryptsetup-2.0.4-fix-LUKS2-api-test.patch b/SOURCES/cryptsetup-2.0.4-fix-LUKS2-api-test.patch
new file mode 100644
index 0000000..1c80967
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-fix-LUKS2-api-test.patch
@@ -0,0 +1,14 @@
+diff -rupN cryptsetup-2.0.3.old/tests/api-test-2.c cryptsetup-2.0.3/tests/api-test-2.c
+--- cryptsetup-2.0.3.old/tests/api-test-2.c	2019-03-27 21:31:18.684160803 +0100
++++ cryptsetup-2.0.3/tests/api-test-2.c	2019-03-27 21:32:14.762630391 +0100
+@@ -2514,8 +2514,8 @@ static void Luks2Requirements(void)
+ 	FAIL_((r = crypt_set_label(cd, "label", "subsystem")), "Unmet requirements detected");
+ 	EQ_(r, -ETXTBSY);
+ 
+-	/* crypt_repair (not implemented for luks2) */
+-	FAIL_(crypt_repair(cd, CRYPT_LUKS2, NULL), "Not implemented");
++	/* crypt_repair (with current repair capabilities it's unrestricted) */
++	OK_(crypt_repair(cd, CRYPT_LUKS2, NULL));
+ 
+ 	/* crypt_keyslot_add_passphrase (restricted) */
+ 	FAIL_((r = crypt_keyslot_add_by_passphrase(cd, CRYPT_ANY_SLOT, "aaa", 3, "bbb", 3)), "Unmet requirements detected");
diff --git a/SOURCES/cryptsetup-2.0.5-fix-miscalculation-of-device-alignment-offset.patch b/SOURCES/cryptsetup-2.0.5-fix-miscalculation-of-device-alignment-offset.patch
new file mode 100644
index 0000000..d3caad8
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.5-fix-miscalculation-of-device-alignment-offset.patch
@@ -0,0 +1,28 @@
+From dd36d56d472e1ea1db74d64d2e6a8d8ece2e7a76 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Thu, 9 Aug 2018 10:26:38 +0200
+Subject: [PATCH] Fix miscalculation of device alignment offset.
+
+device_topology_alignment routine already returns alignment offset
+in bytes. There's no need to divide it by sector size, since LUKS2
+format have all offsets and sizes stored in bytes.
+---
+ lib/setup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/setup.c b/lib/setup.c
+index ff944c9..1a78d2e 100644
+--- a/lib/setup.c
++++ b/lib/setup.c
+@@ -1602,7 +1602,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,
+ 			       integrity, uuid,
+ 			       sector_size,
+ 			       required_alignment / sector_size,
+-			       alignment_offset / sector_size,
++			       alignment_offset,
+ 			       cd->metadata_device ? 1 : 0);
+ 	if (r < 0)
+ 		goto out;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.5-remove-useless-division-followed-by-multiplication-b.patch b/SOURCES/cryptsetup-2.0.5-remove-useless-division-followed-by-multiplication-b.patch
new file mode 100644
index 0000000..a03d842
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.5-remove-useless-division-followed-by-multiplication-b.patch
@@ -0,0 +1,58 @@
+From d2f0773eb8482f754d9a7599d26697efcdd25cd6 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Thu, 9 Aug 2018 10:34:17 +0200
+Subject: [PATCH] Remove useless division followed by multiplication by same
+ base.
+
+---
+ lib/luks2/luks2_json_format.c | 10 +++++-----
+ lib/setup.c                   |  2 +-
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/lib/luks2/luks2_json_format.c b/lib/luks2/luks2_json_format.c
+index a0b72ab..4b50f89 100644
+--- a/lib/luks2/luks2_json_format.c
++++ b/lib/luks2/luks2_json_format.c
+@@ -122,9 +122,9 @@ int LUKS2_generate_hdr(
+ 	const char *cipherMode,
+ 	const char *integrity,
+ 	const char *uuid,
+-	unsigned int sector_size,
+-	unsigned int alignPayload,
+-	unsigned int alignOffset,
++	unsigned int sector_size,  /* in bytes */
++	unsigned int alignPayload, /* in bytes */
++	unsigned int alignOffset,  /* in bytes */
+ 	int detached_metadata_device)
+ {
+ 	struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_segments, *jobj_config;
+@@ -182,11 +182,11 @@ int LUKS2_generate_hdr(
+ 	jobj_segment = json_object_new_object();
+ 	json_object_object_add(jobj_segment, "type", json_object_new_string("crypt"));
+ 	if (detached_metadata_device)
+-		offset = (uint64_t)alignPayload * sector_size;
++		offset = (uint64_t)alignPayload;
+ 	else {
+ 		//FIXME
+ 		//offset = size_round_up(areas[7].offset + areas[7].length, alignPayload * SECTOR_SIZE);
+-		offset = size_round_up(LUKS2_HDR_DEFAULT_LEN, (size_t)alignPayload * sector_size);
++		offset = size_round_up(LUKS2_HDR_DEFAULT_LEN, (size_t)alignPayload);
+ 		offset += alignOffset;
+ 	}
+ 
+diff --git a/lib/setup.c b/lib/setup.c
+index 1a78d2e..61bf3da 100644
+--- a/lib/setup.c
++++ b/lib/setup.c
+@@ -1601,7 +1601,7 @@ static int _crypt_format_luks2(struct crypt_device *cd,
+ 			       cipher, cipher_mode,
+ 			       integrity, uuid,
+ 			       sector_size,
+-			       required_alignment / sector_size,
++			       required_alignment,
+ 			       alignment_offset,
+ 			       cd->metadata_device ? 1 : 0);
+ 	if (r < 0)
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.6-LUKS2-metadata-variation-fixes.patch b/SOURCES/cryptsetup-2.0.6-LUKS2-metadata-variation-fixes.patch
new file mode 100644
index 0000000..d78bd28
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.6-LUKS2-metadata-variation-fixes.patch
@@ -0,0 +1,202 @@
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c	2019-04-03 18:55:44.392182454 +0200
++++ cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c	2019-04-03 18:56:22.567106063 +0200
+@@ -429,6 +429,7 @@ int LUKS2_token_validate(json_object *hd
+ {
+ 	json_object *jarr, *jobj_keyslots;
+ 
++	/* keyslots are not yet validated, but we need to know token doesn't reference missing keyslot */
+ 	if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
+ 		return 1;
+ 
+@@ -505,12 +506,57 @@ static int hdr_validate_tokens(json_obje
+ 	return 0;
+ }
+ 
+-static int hdr_validate_segments(json_object *hdr_jobj)
++static int hdr_validate_crypt_segment(json_object *jobj, const char *key, json_object *jobj_digests,
++	uint64_t offset, uint64_t size)
+ {
+-	json_object *jobj, *jobj_digests, *jobj_offset, *jobj_ivoffset,
+-		    *jobj_length, *jobj_sector_size, *jobj_type, *jobj_integrity;
++	json_object *jobj_ivoffset, *jobj_sector_size, *jobj_integrity;
+ 	uint32_t sector_size;
+-	uint64_t ivoffset, offset, length;
++	uint64_t ivoffset;
++
++	if (!(jobj_ivoffset = json_contains(jobj, key, "Segment", "iv_tweak", json_type_string)) ||
++	    !json_contains(jobj, key, "Segment", "encryption", json_type_string) ||
++	    !(jobj_sector_size = json_contains(jobj, key, "Segment", "sector_size", json_type_int)))
++		return 1;
++
++	/* integrity */
++	if (json_object_object_get_ex(jobj, "integrity", &jobj_integrity)) {
++		if (!json_contains(jobj, key, "Segment", "integrity", json_type_object) ||
++		    !json_contains(jobj_integrity, key, "Segment integrity", "type", json_type_string) ||
++		    !json_contains(jobj_integrity, key, "Segment integrity", "journal_encryption", json_type_string) ||
++		    !json_contains(jobj_integrity, key, "Segment integrity", "journal_integrity", json_type_string))
++			return 1;
++	}
++
++	/* enforce uint32_t type */
++	if (!validate_json_uint32(jobj_sector_size)) {
++		log_dbg("Illegal field \"sector_size\":%s.",
++			json_object_get_string(jobj_sector_size));
++		return 1;
++	}
++
++	sector_size = json_object_get_uint32(jobj_sector_size);
++	if (!sector_size || sector_size % SECTOR_SIZE) {
++		log_dbg("Illegal sector size: %" PRIu32, sector_size);
++		return 1;
++	}
++
++	if (!numbered("iv_tweak", json_object_get_string(jobj_ivoffset)) ||
++	    !json_str_to_uint64(jobj_ivoffset, &ivoffset))
++		return 1;
++
++	if (size % sector_size) {
++		log_dbg("Size field has to be aligned to sector size: %" PRIu32, sector_size);
++		return 1;
++	}
++
++	return !segment_has_digest(key, jobj_digests);
++}
++
++static int hdr_validate_segments(json_object *hdr_jobj)
++{
++	json_object *jobj, *jobj_digests, *jobj_offset, *jobj_size, *jobj_type, *jobj_flags;
++	int i;
++	uint64_t offset, size;
+ 
+ 	if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj)) {
+ 		log_dbg("Missing segments section.");
+@@ -530,70 +576,46 @@ static int hdr_validate_segments(json_ob
+ 		if (!numbered("Segment", key))
+ 			return 1;
+ 
+-		if (!json_contains(val, key, "Segment", "type", json_type_string) ||
++		/* those fields are mandatory for all segment types */
++		if (!(jobj_type =   json_contains(val, key, "Segment", "type",   json_type_string)) ||
+ 		    !(jobj_offset = json_contains(val, key, "Segment", "offset", json_type_string)) ||
+-		    !(jobj_ivoffset = json_contains(val, key, "Segment", "iv_tweak", json_type_string)) ||
+-		    !(jobj_length = json_contains(val, key, "Segment", "size", json_type_string)) ||
+-		    !json_contains(val, key, "Segment", "encryption", json_type_string) ||
+-		    !(jobj_sector_size = json_contains(val, key, "Segment", "sector_size", json_type_int)))
+-			return 1;
+-
+-		/* integrity */
+-		if (json_object_object_get_ex(val, "integrity", &jobj_integrity)) {
+-			if (!json_contains(val, key, "Segment", "integrity", json_type_object) ||
+-			    !json_contains(jobj_integrity, key, "Segment integrity", "type", json_type_string) ||
+-			    !json_contains(jobj_integrity, key, "Segment integrity", "journal_encryption", json_type_string) ||
+-			    !json_contains(jobj_integrity, key, "Segment integrity", "journal_integrity", json_type_string))
+-				return 1;
+-		}
+-
+-		/* enforce uint32_t type */
+-		if (!validate_json_uint32(jobj_sector_size)) {
+-			log_dbg("Illegal field \"sector_size\":%s.",
+-				json_object_get_string(jobj_sector_size));
+-			return 1;
+-		}
+-
+-		sector_size = json_object_get_uint32(jobj_sector_size);
+-		if (!sector_size || sector_size % 512) {
+-			log_dbg("Illegal sector size: %" PRIu32, sector_size);
++		    !(jobj_size =   json_contains(val, key, "Segment", "size",   json_type_string)))
+ 			return 1;
+-		}
+ 
+ 		if (!numbered("offset", json_object_get_string(jobj_offset)) ||
+-		    !numbered("iv_tweak", json_object_get_string(jobj_ivoffset)))
++		    !json_str_to_uint64(jobj_offset, &offset))
+ 			return 1;
+ 
+-		/* rule out values > UINT64_MAX */
+-		if (!json_str_to_uint64(jobj_offset, &offset) ||
+-		    !json_str_to_uint64(jobj_ivoffset, &ivoffset))
+-			return 1;
++		/* size "dynamic" means whole device starting at 'offset' */
++		if (strcmp(json_object_get_string(jobj_size), "dynamic")) {
++			if (!numbered("size", json_object_get_string(jobj_size)) ||
++			    !json_str_to_uint64(jobj_size, &size) || !size)
++				return 1;
++		} else
++			size = 0;
+ 
+-		if (offset % sector_size) {
+-			log_dbg("Offset field has to be aligned to sector size: %" PRIu32, sector_size);
++		/* all device-mapper devices are aligned to 512 sector size */
++		if (offset % SECTOR_SIZE) {
++			log_dbg("Offset field has to be aligned to sector size: %" PRIu32, SECTOR_SIZE);
+ 			return 1;
+ 		}
+-
+-		if (ivoffset % sector_size) {
+-			log_dbg("IV offset field has to be aligned to sector size: %" PRIu32, sector_size);
++		if (size % SECTOR_SIZE) {
++			log_dbg("Size field has to be aligned to sector size: %" PRIu32, SECTOR_SIZE);
+ 			return 1;
+ 		}
+ 
+-		/* length "dynamic" means whole device starting at 'offset' */
+-		if (strcmp(json_object_get_string(jobj_length), "dynamic")) {
+-			if (!numbered("size", json_object_get_string(jobj_length)) ||
+-			    !json_str_to_uint64(jobj_length, &length))
++		/* flags array is optional and must contain strings */
++		if (json_object_object_get_ex(val, "flags", NULL)) {
++			if (!(jobj_flags = json_contains(val, key, "Segment", "flags", json_type_array)))
+ 				return 1;
+-
+-			if (length % sector_size) {
+-				log_dbg("Length field has to be aligned to sector size: %" PRIu32, sector_size);
+-				return 1;
+-			}
++			for (i = 0; i < (int) json_object_array_length(jobj_flags); i++)
++				if (!json_object_is_type(json_object_array_get_idx(jobj_flags, i), json_type_string))
++					return 1;
+ 		}
+ 
+-		json_object_object_get_ex(val, "type", &jobj_type);
++		/* crypt */
+ 		if (!strcmp(json_object_get_string(jobj_type), "crypt") &&
+-		    !segment_has_digest(key, jobj_digests))
++		    hdr_validate_crypt_segment(val, key, jobj_digests, offset, size))
+ 			return 1;
+ 	}
+ 
+@@ -610,6 +632,7 @@ static int hdr_validate_areas(json_objec
+ 	if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
+ 		return 1;
+ 
++	/* segments are already validated */
+ 	if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments))
+ 		return 1;
+ 
+@@ -674,11 +697,11 @@ static int hdr_validate_digests(json_obj
+ 		return 1;
+ 	}
+ 
+-	/* keyslots should already be validated */
++	/* keyslots are not yet validated, but we need to know digest doesn't reference missing keyslot */
+ 	if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
+ 		return 1;
+ 
+-	/* segments are not validated atm, but we need to know digest doesn't reference missing segment */
++	/* segments are not yet validated, but we need to know digest doesn't reference missing segment */
+ 	if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments))
+ 		return 1;
+ 
+@@ -813,10 +836,10 @@ int LUKS2_hdr_validate(json_object *hdr_
+ 	struct {
+ 		int (*validate)(json_object *);
+ 	} checks[] = {
+-		{ hdr_validate_keyslots },
+ 		{ hdr_validate_tokens   },
+ 		{ hdr_validate_digests  },
+ 		{ hdr_validate_segments },
++		{ hdr_validate_keyslots },
+ 		{ hdr_validate_areas    },
+ 		{ hdr_validate_config   },
+ 		{ NULL }
diff --git a/SOURCES/cryptsetup-2.0.6-check-json-size-matches-value-from-binary-LUKS2-head.patch b/SOURCES/cryptsetup-2.0.6-check-json-size-matches-value-from-binary-LUKS2-head.patch
new file mode 100644
index 0000000..6862f4e
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.6-check-json-size-matches-value-from-binary-LUKS2-head.patch
@@ -0,0 +1,139 @@
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_disk_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_disk_metadata.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_disk_metadata.c	2019-03-27 21:06:52.048172644 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_disk_metadata.c	2019-03-27 21:07:12.068978543 +0100
+@@ -204,6 +204,12 @@ static int hdr_disk_sanity_check_pre(str
+ 		return -EINVAL;
+ 	}
+ 
++	if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) {
++		log_dbg("LUKS2 offset 0x%04x in secondary header doesn't match size 0x%04x.",
++			(unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size));
++		return -EINVAL;
++	}
++
+ 	/* FIXME: sanity check checksum alg. */
+ 
+ 	log_dbg("LUKS2 header version %u of size %u bytes, checksum %s.",
+@@ -476,7 +482,7 @@ static int validate_json_area(const char
+ 	return 0;
+ }
+ 
+-static int validate_luks2_json_object(json_object *jobj_hdr)
++static int validate_luks2_json_object(json_object *jobj_hdr, uint64_t length)
+ {
+ 	int r;
+ 
+@@ -487,14 +493,14 @@ static int validate_luks2_json_object(js
+ 		return r;
+ 	}
+ 
+-	r = LUKS2_hdr_validate(jobj_hdr);
++	r = LUKS2_hdr_validate(jobj_hdr, length);
+ 	if (r) {
+ 		log_dbg("Repairing JSON metadata.");
+ 		/* try to correct known glitches */
+ 		LUKS2_hdr_repair(jobj_hdr);
+ 
+ 		/* run validation again */
+-		r = LUKS2_hdr_validate(jobj_hdr);
++		r = LUKS2_hdr_validate(jobj_hdr, length);
+ 	}
+ 
+ 	if (r)
+@@ -516,7 +522,7 @@ static json_object *parse_and_validate_j
+ 
+ 	r = validate_json_area(json_area, offset, length);
+ 	if (!r)
+-		r = validate_luks2_json_object(jobj);
++		r = validate_luks2_json_object(jobj, length);
+ 
+ 	if (r) {
+ 		json_object_put(jobj);
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_internal.h cryptsetup-2.0.3/lib/luks2/luks2_internal.h
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_internal.h	2019-03-27 21:06:52.048172644 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_internal.h	2019-03-27 21:07:12.070978524 +0100
+@@ -73,7 +73,7 @@ void JSON_DBG(json_object *jobj, const c
+ json_object *json_contains(json_object *jobj, const char *name, const char *section,
+ 		      const char *key, json_type type);
+ 
+-int LUKS2_hdr_validate(json_object *hdr_jobj);
++int LUKS2_hdr_validate(json_object *hdr_jobj, uint64_t length);
+ int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, const char *key);
+ int LUKS2_check_json_size(const struct luks2_hdr *hdr);
+ int LUKS2_token_validate(json_object *hdr_jobj, json_object *jobj_token, const char *key);
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c	2019-03-27 21:06:52.049172634 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c	2019-03-27 21:07:44.937659885 +0100
+@@ -446,7 +446,7 @@ int LUKS2_token_validate(json_object *hd
+ 	return 0;
+ }
+ 
+-static int hdr_validate_json_size(json_object *hdr_jobj)
++static int hdr_validate_json_size(json_object *hdr_jobj, uint64_t hdr_json_size)
+ {
+ 	json_object *jobj, *jobj1;
+ 	const char *json;
+@@ -460,12 +460,22 @@ static int hdr_validate_json_size(json_o
+ 	json_area_size = json_object_get_uint64(jobj1);
+ 	json_size = (uint64_t)strlen(json);
+ 
+-	return json_size > json_area_size ? 1 : 0;
++	if (hdr_json_size != json_area_size) {
++		log_dbg("JSON area size doesn't match value in binary header.");
++		return 1;
++	}
++
++	if (json_size > json_area_size) {
++		log_dbg("JSON doesn't fit in the designated area.");
++		return 1;
++	}
++
++	return 0;
+ }
+ 
+ int LUKS2_check_json_size(const struct luks2_hdr *hdr)
+ {
+-	return hdr_validate_json_size(hdr->jobj);
++	return hdr_validate_json_size(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN);
+ }
+ 
+ static int hdr_validate_keyslots(json_object *hdr_jobj)
+@@ -830,7 +840,7 @@ static int hdr_validate_config(json_obje
+ 	return 0;
+ }
+ 
+-int LUKS2_hdr_validate(json_object *hdr_jobj)
++int LUKS2_hdr_validate(json_object *hdr_jobj, uint64_t json_size)
+ {
+ 	struct {
+ 		int (*validate)(json_object *);
+@@ -852,10 +862,8 @@ int LUKS2_hdr_validate(json_object *hdr_
+ 		if (checks[i].validate && checks[i].validate(hdr_jobj))
+ 			return 1;
+ 
+-	if (hdr_validate_json_size(hdr_jobj)) {
+-		log_dbg("Json header is too large.");
++	if (hdr_validate_json_size(hdr_jobj, json_size))
+ 		return 1;
+-	}
+ 
+ 	/* validate keyslot implementations */
+ 	if (LUKS2_keyslots_validate(hdr_jobj))
+@@ -903,7 +911,7 @@ int LUKS2_hdr_write(struct crypt_device
+ 	/* erase unused digests (no assigned keyslot or segment) */
+ 	LUKS2_digests_erase_unused(cd, hdr);
+ 
+-	if (LUKS2_hdr_validate(hdr->jobj))
++	if (LUKS2_hdr_validate(hdr->jobj, hdr->hdr_size - LUKS2_HDR_BIN_LEN))
+ 		return -EINVAL;
+ 
+ 	return LUKS2_disk_hdr_write(cd, hdr, crypt_metadata_device(cd));
+@@ -1650,7 +1658,7 @@ const char *LUKS2_get_cipher(struct luks
+ 		return NULL;
+ 
+ 	if (!json_object_object_get_ex(jobj2, "encryption", &jobj3))
+-		return NULL;
++		return "null";
+ 
+ 	return json_object_get_string(jobj3);
+ }
diff --git a/SOURCES/cryptsetup-2.0.6-do-not-validate-keyslot-areas-so-frantically.patch b/SOURCES/cryptsetup-2.0.6-do-not-validate-keyslot-areas-so-frantically.patch
new file mode 100644
index 0000000..3730909
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.6-do-not-validate-keyslot-areas-so-frantically.patch
@@ -0,0 +1,21 @@
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c	2019-03-27 15:10:10.869610792 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c	2019-03-27 15:32:38.202382332 +0100
+@@ -402,7 +402,6 @@ static json_bool validate_intervals(int
+ 	return TRUE;
+ }
+ 
+-static int hdr_validate_areas(json_object *hdr_jobj);
+ int LUKS2_keyslot_validate(json_object *hdr_jobj, json_object *hdr_keyslot, const char *key)
+ {
+ 	json_object *jobj_key_size;
+@@ -419,9 +418,6 @@ int LUKS2_keyslot_validate(json_object *
+ 		return 1;
+ 	}
+ 
+-	if (hdr_validate_areas(hdr_jobj))
+-		return 1;
+-
+ 	return 0;
+ }
+ 
diff --git a/SOURCES/cryptsetup-2.0.6-enable-all-supported-metadata-sizes-in-LUKS2-validat.patch b/SOURCES/cryptsetup-2.0.6-enable-all-supported-metadata-sizes-in-LUKS2-validat.patch
new file mode 100644
index 0000000..5a5b065
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.6-enable-all-supported-metadata-sizes-in-LUKS2-validat.patch
@@ -0,0 +1,142 @@
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_disk_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_disk_metadata.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_disk_metadata.c	2019-03-27 15:48:28.316632526 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_disk_metadata.c	2019-03-27 15:48:48.093594565 +0100
+@@ -387,11 +387,6 @@ int LUKS2_disk_hdr_write(struct crypt_de
+ 		return -EINVAL;
+ 	}
+ 
+-	if (hdr->hdr_size != LUKS2_HDR_16K_LEN) {
+-		log_dbg("Unsupported LUKS2 header size (%zu).", hdr->hdr_size);
+-		return -EINVAL;
+-	}
+-
+ 	r = LUKS2_check_device_size(cd, crypt_metadata_device(cd), LUKS2_hdr_and_areas_size(hdr->jobj), 1);
+ 	if (r)
+ 		return r;
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2.h cryptsetup-2.0.3/lib/luks2/luks2.h
+--- cryptsetup-2.0.3.old/lib/luks2/luks2.h	2019-03-27 15:48:28.316632526 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2.h	2019-03-27 15:49:37.033500625 +0100
+@@ -326,6 +326,9 @@ int LUKS2_generate_hdr(
+ 	unsigned int alignOffset,
+ 	int detached_metadata_device);
+ 
++int LUKS2_check_metadata_area_size(uint64_t metadata_size);
++int LUKS2_check_keyslots_area_size(uint64_t keyslots_size);
++
+ uint64_t LUKS2_get_data_offset(struct luks2_hdr *hdr);
+ int LUKS2_get_sector_size(struct luks2_hdr *hdr);
+ const char *LUKS2_get_cipher(struct luks2_hdr *hdr, int segment);
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_format.c cryptsetup-2.0.3/lib/luks2/luks2_json_format.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_format.c	2019-03-27 15:48:28.317632524 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_json_format.c	2019-03-27 15:48:48.094594563 +0100
+@@ -114,6 +114,22 @@ int LUKS2_find_area_gap(struct crypt_dev
+ 	return 0;
+ }
+ 
++int LUKS2_check_metadata_area_size(uint64_t metadata_size)
++{
++	/* see LUKS2_HDR2_OFFSETS */
++	return (metadata_size != 0x004000 &&
++		metadata_size != 0x008000 && metadata_size != 0x010000 &&
++		metadata_size != 0x020000 && metadata_size != 0x040000 &&
++		metadata_size != 0x080000 && metadata_size != 0x100000 &&
++		metadata_size != 0x200000 && metadata_size != 0x400000);
++}
++
++int LUKS2_check_keyslots_area_size(uint64_t keyslots_size)
++{
++	return (!keyslots_size || (keyslots_size % 4096) ||
++		keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE);
++}
++
+ int LUKS2_generate_hdr(
+ 	struct crypt_device *cd,
+ 	struct luks2_hdr *hdr,
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c	2019-03-27 15:48:28.317632524 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c	2019-03-27 15:57:44.322526763 +0100
+@@ -701,30 +701,18 @@ static int hdr_validate_digests(json_obj
+ }
+ 
+ /* requires keyslots and segments sections being already validated */
+-static int validate_keyslots_size(json_object *hdr_jobj, json_object *jobj_keyslots_size)
++static int validate_keyslots_size(json_object *hdr_jobj, uint64_t metadata_size, uint64_t keyslots_size)
+ {
+ 	json_object *jobj_keyslots, *jobj, *jobj1;
+-	uint64_t keyslots_size, segment_offset, keyslots_area_sum = 0;
+-
+-	if (!json_str_to_uint64(jobj_keyslots_size, &keyslots_size))
+-		return 1;
+-
+-	if (keyslots_size % 4096) {
+-		log_dbg("keyslots_size is not 4 KiB aligned");
+-		return 1;
+-	}
+-
+-	if (keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE) {
+-		log_dbg("keyslots_size is too large. The cap is %" PRIu64 " bytes", (uint64_t) LUKS2_MAX_KEYSLOTS_SIZE);
+-		return 1;
+-	}
++	uint64_t segment_offset, keyslots_area_sum = 0;
+ 
+ 	json_object_object_get_ex(hdr_jobj, "segments", &jobj);
+ 	segment_offset = get_first_data_offset(jobj, "crypt");
+ 	if (segment_offset &&
+ 	    (segment_offset < keyslots_size ||
+-	     (segment_offset - keyslots_size) < (2 * LUKS2_HDR_16K_LEN))) {
+-		log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64 ", keyslots offset: %d", keyslots_size, segment_offset, 2 * LUKS2_HDR_16K_LEN);
++	     (segment_offset - keyslots_size) < (2 * metadata_size))) {
++		log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64
++			", keyslots offset: %" PRIu64, keyslots_size, segment_offset, 2 * metadata_size);
+ 		return 1;
+ 	}
+ 
+@@ -738,7 +726,8 @@ static int validate_keyslots_size(json_o
+ 	}
+ 
+ 	if (keyslots_area_sum > keyslots_size) {
+-		log_dbg("Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %" PRIu64, keyslots_area_sum, keyslots_size);
++		log_dbg("Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %"
++			PRIu64, keyslots_area_sum, keyslots_size);
+ 		return 1;
+ 	}
+ 
+@@ -749,7 +738,7 @@ static int hdr_validate_config(json_obje
+ {
+ 	json_object *jobj_config, *jobj, *jobj1;
+ 	int i;
+-	uint64_t json_size;
++	uint64_t json_size, keyslots_size;
+ 
+ 	if (!json_object_object_get_ex(hdr_jobj, "config", &jobj_config)) {
+ 		log_dbg("Missing config section.");
+@@ -760,21 +749,21 @@ static int hdr_validate_config(json_obje
+ 	    !json_str_to_uint64(jobj, &json_size))
+ 		return 1;
+ 
+-	/* currently it's hardcoded */
+-	if (json_size != (LUKS2_HDR_16K_LEN - LUKS2_HDR_BIN_LEN)) {
+-		log_dbg("Invalid json_size %" PRIu64, json_size);
++	if (!(jobj = json_contains(jobj_config, "section", "Config", "keyslots_size", json_type_string)) ||
++	    !json_str_to_uint64(jobj, &keyslots_size))
+ 		return 1;
+-	}
+ 
+-	if (json_size % 4096) {
+-		log_dbg("Json area is not properly aligned to 4 KiB.");
++	if (LUKS2_check_metadata_area_size(json_size + LUKS2_HDR_BIN_LEN)) {
++		log_dbg("Unsupported LUKS2 header size (%" PRIu64 ").", json_size + LUKS2_HDR_BIN_LEN);
+ 		return 1;
+ 	}
+ 
+-	if (!(jobj = json_contains(jobj_config, "section", "Config", "keyslots_size", json_type_string)))
++	if (LUKS2_check_keyslots_area_size(keyslots_size)) {
++		log_dbg("Unsupported LUKS2 keyslots size (%" PRIu64 ").", keyslots_size);
+ 		return 1;
++	}
+ 
+-	if (validate_keyslots_size(hdr_jobj, jobj))
++	if (validate_keyslots_size(hdr_jobj, json_size + LUKS2_HDR_BIN_LEN, keyslots_size))
+ 		return 1;
+ 
+ 	/* Flags array is optional */
diff --git a/SOURCES/cryptsetup-2.0.6-fix-keyslot-areas-validation.patch b/SOURCES/cryptsetup-2.0.6-fix-keyslot-areas-validation.patch
new file mode 100644
index 0000000..03f6519
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.6-fix-keyslot-areas-validation.patch
@@ -0,0 +1,94 @@
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c	2019-03-27 16:14:49.790420791 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c	2019-03-27 16:23:50.499187212 +0100
+@@ -363,12 +363,13 @@ static json_bool segment_has_digest(cons
+ 	return FALSE;
+ }
+ 
+-static json_bool validate_intervals(int length, const struct interval *ix, uint64_t *data_offset)
++static json_bool validate_intervals(int length, const struct interval *ix,
++				    uint64_t metadata_size, uint64_t keyslots_area_end)
+ {
+ 	int j, i = 0;
+ 
+ 	while (i < length) {
+-		if (ix[i].offset < 2 * LUKS2_HDR_16K_LEN) {
++		if (ix[i].offset < 2 * metadata_size) {
+ 			log_dbg("Illegal area offset: %" PRIu64 ".", ix[i].offset);
+ 			return FALSE;
+ 		}
+@@ -378,10 +379,9 @@ static json_bool validate_intervals(int
+ 			return FALSE;
+ 		}
+ 
+-		/* first segment at offset 0 means we have detached header. Do not check then. */
+-		if (*data_offset && (ix[i].offset + ix[i].length) > *data_offset) {
+-			log_dbg("Area [%" PRIu64 ", %" PRIu64 "] intersects with segment starting at offset: %" PRIu64,
+-				ix[i].offset, ix[i].offset + ix[i].length, *data_offset);
++		if ((ix[i].offset + ix[i].length) > keyslots_area_end) {
++			log_dbg("Area [%" PRIu64 ", %" PRIu64 "] overflows binary keyslots area (ends at offset: %" PRIu64 ").",
++				ix[i].offset, ix[i].offset + ix[i].length, keyslots_area_end);
+ 			return FALSE;
+ 		}
+ 
+@@ -596,12 +596,24 @@ static int hdr_validate_segments(json_ob
+ 	return 0;
+ }
+ 
++static uint64_t LUKS2_metadata_size(json_object *jobj)
++{
++	json_object *jobj1, *jobj2;
++	uint64_t json_size;
++
++	json_object_object_get_ex(jobj, "config", &jobj1);
++	json_object_object_get_ex(jobj1, "json_size", &jobj2);
++	json_str_to_uint64(jobj2, &json_size);
++
++	return json_size + LUKS2_HDR_BIN_LEN;
++}
++
+ static int hdr_validate_areas(json_object *hdr_jobj)
+ {
+ 	struct interval *intervals;
+ 	json_object *jobj_keyslots, *jobj_offset, *jobj_length, *jobj_segments, *jobj_area;
+ 	int length, ret, i = 0;
+-	uint64_t first_offset, keyslots_size, keyslots_area_sum = 0;
++	uint64_t keyslots_size, metadata_size, keyslots_area_sum = 0;
+ 
+ 	if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
+ 		return 1;
+@@ -611,6 +623,7 @@ static int hdr_validate_areas(json_objec
+ 
+ 	/* config is already validated */
+ 	keyslots_size = LUKS2_keyslots_size(hdr_jobj);
++	metadata_size = LUKS2_metadata_size(hdr_jobj);
+ 
+ 	length = json_object_object_length(jobj_keyslots);
+ 
+@@ -663,9 +676,7 @@ static int hdr_validate_areas(json_objec
+ 		return 1;
+ 	}
+ 
+-	first_offset = get_first_data_offset(jobj_segments, NULL);
+-
+-	ret = validate_intervals(length, intervals, &first_offset) ? 0 : 1;
++	ret = validate_intervals(length, intervals, metadata_size, LUKS2_hdr_and_areas_size(hdr_jobj)) ? 0 : 1;
+ 
+ 	free(intervals);
+ 
+@@ -918,14 +929,7 @@ uint64_t LUKS2_keyslots_size(json_object
+ 
+ uint64_t LUKS2_hdr_and_areas_size(json_object *jobj)
+ {
+-	json_object *jobj1, *jobj2;
+-	uint64_t json_size;
+-
+-	json_object_object_get_ex(jobj, "config", &jobj1);
+-	json_object_object_get_ex(jobj1, "json_size", &jobj2);
+-	json_str_to_uint64(jobj2, &json_size);
+-
+-	return 2 * (json_size + LUKS2_HDR_BIN_LEN) + LUKS2_keyslots_size(jobj);
++	return 2 * LUKS2_metadata_size(jobj) + LUKS2_keyslots_size(jobj);
+ }
+ 
+ int LUKS2_hdr_backup(struct crypt_device *cd, struct luks2_hdr *hdr,
diff --git a/SOURCES/cryptsetup-2.0.6-reshuffle-config-and-keyslots-areas-validation-code.patch b/SOURCES/cryptsetup-2.0.6-reshuffle-config-and-keyslots-areas-validation-code.patch
new file mode 100644
index 0000000..775b59a
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.6-reshuffle-config-and-keyslots-areas-validation-code.patch
@@ -0,0 +1,147 @@
+diff -rupN cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c
+--- cryptsetup-2.0.3.old/lib/luks2/luks2_json_metadata.c	2019-03-28 11:32:18.850058719 +0100
++++ cryptsetup-2.0.3/lib/luks2/luks2_json_metadata.c	2019-03-28 11:33:07.610800041 +0100
+@@ -643,7 +643,7 @@ static int hdr_validate_areas(json_objec
+ 	struct interval *intervals;
+ 	json_object *jobj_keyslots, *jobj_offset, *jobj_length, *jobj_segments, *jobj_area;
+ 	int length, ret, i = 0;
+-	uint64_t first_offset;
++	uint64_t first_offset, keyslots_size, keyslots_area_sum = 0;
+ 
+ 	if (!json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots))
+ 		return 1;
+@@ -652,6 +652,9 @@ static int hdr_validate_areas(json_objec
+ 	if (!json_object_object_get_ex(hdr_jobj, "segments", &jobj_segments))
+ 		return 1;
+ 
++	/* config is already validated */
++	keyslots_size = LUKS2_keyslots_size(hdr_jobj);
++
+ 	length = json_object_object_length(jobj_keyslots);
+ 
+ 	/* Empty section */
+@@ -687,6 +690,8 @@ static int hdr_validate_areas(json_objec
+ 			return 1;
+ 		}
+ 
++		keyslots_area_sum += intervals[i].length;
++
+ 		i++;
+ 	}
+ 
+@@ -694,6 +699,13 @@ static int hdr_validate_areas(json_objec
+ 		free(intervals);
+ 		return 1;
+ 	}
++ 
++	if (keyslots_area_sum > keyslots_size) {
++		log_dbg("Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %"
++			PRIu64, keyslots_area_sum, keyslots_size);
++		free(intervals);
++		return 1;
++	}
+ 
+ 	first_offset = get_first_data_offset(jobj_segments, NULL);
+ 
+@@ -739,45 +751,11 @@ static int hdr_validate_digests(json_obj
+ 	return 0;
+ }
+ 
+-/* requires keyslots and segments sections being already validated */
+-static int validate_keyslots_size(json_object *hdr_jobj, uint64_t metadata_size, uint64_t keyslots_size)
+-{
+-	json_object *jobj_keyslots, *jobj, *jobj1;
+-	uint64_t segment_offset, keyslots_area_sum = 0;
+-
+-	json_object_object_get_ex(hdr_jobj, "segments", &jobj);
+-	segment_offset = get_first_data_offset(jobj, "crypt");
+-	if (segment_offset &&
+-	    (segment_offset < keyslots_size ||
+-	     (segment_offset - keyslots_size) < (2 * metadata_size))) {
+-		log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64
+-			", keyslots offset: %" PRIu64, keyslots_size, segment_offset, 2 * metadata_size);
+-		return 1;
+-	}
+-
+-	json_object_object_get_ex(hdr_jobj, "keyslots", &jobj_keyslots);
+-
+-	json_object_object_foreach(jobj_keyslots, key, val) {
+-		UNUSED(key);
+-		json_object_object_get_ex(val, "area", &jobj);
+-		json_object_object_get_ex(jobj, "size", &jobj1);
+-		keyslots_area_sum += json_object_get_uint64(jobj1);
+-	}
+-
+-	if (keyslots_area_sum > keyslots_size) {
+-		log_dbg("Sum of all keyslot area sizes (%" PRIu64 ") is greater than value in config section %"
+-			PRIu64, keyslots_area_sum, keyslots_size);
+-		return 1;
+-	}
+-
+-	return 0;
+-}
+-
+ static int hdr_validate_config(json_object *hdr_jobj)
+ {
+ 	json_object *jobj_config, *jobj, *jobj1;
+ 	int i;
+-	uint64_t json_size, keyslots_size;
++	uint64_t keyslots_size, metadata_size, segment_offset;
+ 
+ 	if (!json_object_object_get_ex(hdr_jobj, "config", &jobj_config)) {
+ 		log_dbg("Missing config section.");
+@@ -785,15 +763,19 @@ static int hdr_validate_config(json_obje
+ 	}
+ 
+ 	if (!(jobj = json_contains(jobj_config, "section", "Config", "json_size", json_type_string)) ||
+-	    !json_str_to_uint64(jobj, &json_size))
++	    !json_str_to_uint64(jobj, &metadata_size))
+ 		return 1;
+ 
++	/* single metadata instance is assembled from json area size plus
++	 * binary header size */
++	metadata_size += LUKS2_HDR_BIN_LEN;
++
+ 	if (!(jobj = json_contains(jobj_config, "section", "Config", "keyslots_size", json_type_string)) ||
+ 	    !json_str_to_uint64(jobj, &keyslots_size))
+ 		return 1;
+ 
+-	if (LUKS2_check_metadata_area_size(json_size + LUKS2_HDR_BIN_LEN)) {
+-		log_dbg("Unsupported LUKS2 header size (%" PRIu64 ").", json_size + LUKS2_HDR_BIN_LEN);
++	if (LUKS2_check_metadata_area_size(metadata_size)) {
++		log_dbg("Unsupported LUKS2 header size (%" PRIu64 ").", metadata_size);
+ 		return 1;
+ 	}
+ 
+@@ -802,8 +784,19 @@ static int hdr_validate_config(json_obje
+ 		return 1;
+ 	}
+ 
+-	if (validate_keyslots_size(hdr_jobj, json_size + LUKS2_HDR_BIN_LEN, keyslots_size))
+-		return 1;
++	/*
++	 * validate keyslots_size fits in between (2 * metadata_size) and first
++	 * segment_offset (except detached header)
++	 */
++	json_object_object_get_ex(hdr_jobj, "segments", &jobj);
++	segment_offset = get_first_data_offset(jobj, "crypt");
++	if (segment_offset &&
++	    (segment_offset < keyslots_size ||
++	     (segment_offset - keyslots_size) < (2 * metadata_size))) {
++		log_dbg("keyslots_size is too large %" PRIu64 " (bytes). Data offset: %" PRIu64
++			", keyslots offset: %" PRIu64, keyslots_size, segment_offset, 2 * metadata_size);
++ 		return 1;
++	}
+ 
+ 	/* Flags array is optional */
+ 	if (json_object_object_get_ex(jobj_config, "flags", &jobj)) {
+@@ -845,8 +838,8 @@ int LUKS2_hdr_validate(json_object *hdr_
+ 		{ hdr_validate_digests  },
+ 		{ hdr_validate_segments },
+ 		{ hdr_validate_keyslots },
+-		{ hdr_validate_areas    },
+ 		{ hdr_validate_config   },
++		{ hdr_validate_areas    },
+ 		{ NULL }
+ 	};
+ 	int i;
diff --git a/SOURCES/cryptsetup-2.0.6-test-cryptsetup-can-handle-all-LUKS2-metadata-varian.patch b/SOURCES/cryptsetup-2.0.6-test-cryptsetup-can-handle-all-LUKS2-metadata-varian.patch
new file mode 100644
index 0000000..d612bb5
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.6-test-cryptsetup-can-handle-all-LUKS2-metadata-varian.patch
@@ -0,0 +1,39 @@
+diff -rupN cryptsetup-2.0.3.old/tests/compat-test2 cryptsetup-2.0.3/tests/compat-test2
+--- cryptsetup-2.0.3.old/tests/compat-test2	2019-03-27 17:03:58.788037100 +0100
++++ cryptsetup-2.0.3/tests/compat-test2	2019-03-27 17:14:19.432280547 +0100
+@@ -22,6 +22,7 @@ PWD0="compatkey"
+ PWD1="93R4P4pIqAH8"
+ PWD2="mymJeD8ivEhE"
+ PWD3="ocMakf3fAcQO"
++PWD4="Qx3qn46vq0v"
+ PWDW="rUkL4RUryBom"
+ TEST_KEYRING_NAME="compattest2_keyring"
+ TEST_TOKEN0="compattest2_desc0"
+@@ -46,7 +47,7 @@ function remove_mapping()
+ 	[ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove $DEV_NAME2
+ 	[ -b /dev/mapper/$DEV_NAME ] && dmsetup remove $DEV_NAME
+ 	losetup -d $LOOPDEV >/dev/null 2>&1
+-	rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE >/dev/null 2>&1
++	rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE copy_test_image* >/dev/null 2>&1
+ 
+ 	# unlink whole test keyring
+ 	[ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null
+@@ -817,5 +818,18 @@ $CRYPTSETUP luksDump $LOOPDEV | grep -q
+ $CRYPTSETUP luksKillSlot -q $LOOPDEV 3
+ $CRYPTSETUP luksDump $LOOPDEV | grep -q "3: luks2 (unbound)" && fail
+ 
++prepare "[39] LUKS2 metadata variants" wipe
++for mda in 16 32 64 128 256 512 1024 2048 4096 ; do
++	cp test_image_$mda copy_test_image_$mda || fail
++	echo -n "[$mda KiB]"
++	echo $PWD4 | $CRYPTSETUP open copy_test_image_$mda $DEV_NAME || fail
++	$CRYPTSETUP close $DEV_NAME || fail
++	echo -e "$PWD4\n$PWD3" | $CRYPTSETUP luksAddKey -S9 $FAST_PBKDF_OPT copy_test_image_$mda || fail
++	echo $PWD4 | $CRYPTSETUP open --test-passphrase copy_test_image_$mda || fail
++	echo $PWD3 | $CRYPTSETUP open -S9 --test-passphrase copy_test_image_$mda || fail
++	echo -n "[OK]"
++done
++echo
++
+ remove_mapping
+ exit 0
diff --git a/SOURCES/cryptsetup-2.1.0-sync-LUKS2-validation-tests.patch b/SOURCES/cryptsetup-2.1.0-sync-LUKS2-validation-tests.patch
new file mode 100644
index 0000000..746d7a7
--- /dev/null
+++ b/SOURCES/cryptsetup-2.1.0-sync-LUKS2-validation-tests.patch
@@ -0,0 +1,3818 @@
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-invalid-json-size-c2.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-invalid-json-size-c2.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-invalid-json-size-c2.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-invalid-json-size-c2.img.sh	2019-03-27 20:59:49.443269763 +0100
+@@ -0,0 +1,85 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with config json size mismatching
++# value in binary header
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	JS=$(((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE)*512))
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++
++	json_str=$(jq -c '.' $TMPDIR/json0)
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0
++	local str_res1=$(head -c 4 $TMPDIR/hdr_res0)
++	test "$str_res1" = "LUKS" || exit 2
++
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 4 $TMPDIR/hdr_res1)
++	test "$str_res1" = "SKUL" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c --arg js $JS 'if .config.json_size != ( $js | tostring )
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-1m.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-1m.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-1m.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-1m.img.sh	2019-03-27 20:59:49.444269753 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 1 MiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-1m-secondary.img.sh	2019-03-27 20:59:49.444269753 +0100
+@@ -0,0 +1,97 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate secondary header with one of allowed json area
++# size values. Test whether auto-recovery code is able
++# to validate secondary header with non-default json area
++# size.
++#
++# primary header is corrupted on purpose.
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 1 MiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-128k.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-128k.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-128k.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-128k.img.sh	2019-03-27 20:59:49.445269743 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 128KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_128K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-128k-secondary.img.sh	2019-03-27 20:59:49.445269743 +0100
+@@ -0,0 +1,97 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate secondary header with one of allowed json area
++# size values. Test whether auto-recovery code is able
++# to validate secondary header with non-default json area
++# size.
++#
++# primary header is corrupted on purpose.
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 128 KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_128K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-16k-secondary.img.sh	2019-03-27 20:59:49.446269734 +0100
+@@ -0,0 +1,97 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate secondary header with one of allowed json area
++# size values. Test whether auto-recovery code is able
++# to validate secondary header with non-default json area
++# size.
++#
++# primary header is corrupted on purpose.
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 16 KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-2m.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-2m.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-2m.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-2m.img.sh	2019-03-27 20:59:49.446269734 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 2 MiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_2M
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-2m-secondary.img.sh	2019-03-27 20:59:49.447269724 +0100
+@@ -0,0 +1,96 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 2 MiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_2M
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-256k.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-256k.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-256k.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-256k.img.sh	2019-03-27 20:59:49.447269724 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 256KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_256K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-256k-secondary.img.sh	2019-03-27 20:59:49.448269714 +0100
+@@ -0,0 +1,97 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate secondary header with one of allowed json area
++# size values. Test whether auto-recovery code is able
++# to validate secondary header with non-default json area
++# size.
++#
++# primary header is corrupted on purpose.
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 256 KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_256K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-32k.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-32k.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-32k.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-32k.img.sh	2019-03-27 20:59:49.448269714 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with non-default metadata json_size.
++# There's only limited set of values allowed as json size in
++# config section of LUKS2 metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 32KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-32k-secondary.img.sh	2019-03-27 20:59:49.449269705 +0100
+@@ -0,0 +1,97 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate secondary header with one of allowed json area
++# size values. Test whether auto-recovery code is able
++# to validate secondary header with non-default json area
++# size.
++#
++# primary header is corrupted on purpose.
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 32 KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_32K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-4m.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-4m.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-4m.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-4m.img.sh	2019-03-27 20:59:49.449269705 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 4 MiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_4M
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-4m-secondary.img.sh	2019-03-27 20:59:49.450269695 +0100
+@@ -0,0 +1,96 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 4 MiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_4M
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-512k.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-512k.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-512k.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-512k.img.sh	2019-03-27 20:59:49.450269695 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 512KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_512K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-512k-secondary.img.sh	2019-03-27 20:59:49.451269685 +0100
+@@ -0,0 +1,97 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate secondary header with one of allowed json area
++# size values. Test whether auto-recovery code is able
++# to validate secondary header with non-default json area
++# size.
++#
++# primary header is corrupted on purpose.
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 512 KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_512K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k.img.sh	2019-03-27 20:59:49.451269685 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size. There's only limited
++# set of values allowed as json size in config section of LUKS2
++# metadata
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 64KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k-inv-area-c0.img.sh	2019-03-27 20:59:49.452269675 +0100
+@@ -0,0 +1,94 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with non-default metadata json_size
++# and keyslots area trespassing in json area.
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 64KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024-1))
++	# overlap in json area by exactly one byte
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024-1))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k-inv-area-c1.img.sh	2019-03-27 20:59:49.452269675 +0100
+@@ -0,0 +1,96 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with non-default metadata json_size
++# and keyslot area overflowing out of keyslots area.
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 64KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++			 --arg mda $((2*TEST_MDA_SIZE_BYTES)) \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .keyslots."7".area.offset = ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots."7".area.size | tonumber) + 1) | tostring ) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++# .keyslots.7.area.offset = ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots.7.area.size | tonumber) + 1) | tostring ) |
++	jq -c --arg mda $((2*TEST_MDA_SIZE_BYTES)) --arg jsize $JSON_SIZE \
++		'if (.keyslots."7".area.offset != ( ((.config.keyslots_size | tonumber) + ($mda | tonumber) - (.keyslots."7".area.size | tonumber) + 1) | tostring )) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k-inv-keyslots-size-c0.img.sh	2019-03-27 20:59:49.453269666 +0100
+@@ -0,0 +1,96 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary with predefined json_size where keyslots size
++# overflows in data area (segment offset)
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 64KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++			 --arg mda $((2*TEST_MDA_SIZE_BYTES)) \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .config.keyslots_size = (((($off | tonumber) - ($mda | tonumber) + 4096)) | tostring ) |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area1
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1 $TEST_MDA_SIZE
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE --arg off $DATA_OFFSET --arg mda $((2*TEST_MDA_SIZE_BYTES)) \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize) or
++		    (.config.keyslots_size != (((($off | tonumber) - ($mda | tonumber) + 4096)) | tostring ))
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-metadata-size-64k-secondary.img.sh	2019-03-27 20:59:49.453269666 +0100
+@@ -0,0 +1,97 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate secondary header with one of allowed json area
++# size values. Test whether auto-recovery code is able
++# to validate secondary header with non-default json area
++# size.
++#
++# primary header is corrupted on purpose.
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# 64 KiB metadata
++	TEST_MDA_SIZE=$LUKS2_HDR_SIZE_64K
++
++	TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512))
++	TEST_JSN_SIZE=$((TEST_MDA_SIZE-LUKS2_BIN_HDR_SIZE))
++	KEYSLOTS_OFFSET=$((TEST_MDA_SIZE*1024))
++	JSON_DIFF=$(((TEST_MDA_SIZE-LUKS2_HDR_SIZE)*1024))
++	JSON_SIZE=$((TEST_JSN_SIZE*512))
++	DATA_OFFSET=16777216
++
++	json_str=$(jq -c --arg jdiff $JSON_DIFF --arg jsize $JSON_SIZE --arg off $DATA_OFFSET \
++		   '.keyslots[].area.offset |= ( . | tonumber + ($jdiff | tonumber) | tostring) |
++		    .config.json_size = $jsize |
++		    .segments."0".offset = $off' $TMPDIR/json0)
++	test -n "$json_str" || exit 2
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0 $TEST_JSN_SIZE
++
++	write_bin_hdr_size $TMPDIR/hdr0 $TEST_MDA_SIZE_BYTES
++	write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	write_bin_hdr_offset $TMPDIR/hdr1 $TEST_MDA_SIZE_BYTES
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0 $TEST_JSN_SIZE
++	merge_bin_hdr_with_json $TMPDIR/hdr1 $TMPDIR/json0 $TMPDIR/area1 $TEST_JSN_SIZE
++
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++
++	erase_checksum $TMPDIR/area1
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area1)
++	write_checksum $chks0 $TMPDIR/area1
++
++	kill_bin_hdr $TMPDIR/area0
++
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG $TEST_MDA_SIZE
++	write_luks2_hdr1 $TMPDIR/area1 $TGT_IMG $TEST_MDA_SIZE
++}
++
++function check()
++{
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr_res0 $TEST_MDA_SIZE
++	local str_res0=$(head -c 6 $TMPDIR/hdr_res0)
++	test "$str_res0" = "VACUUM" || exit 2
++	read_luks2_json1 $TGT_IMG $TMPDIR/json_res1 $TEST_JSN_SIZE
++	jq -c --arg koff $KEYSLOTS_OFFSET --arg jsize $JSON_SIZE \
++		'if ([.keyslots[].area.offset] | map(tonumber) | min | tostring != $koff) or
++		    (.config.json_size != $jsize)
++		then error("Unexpected value in result json") else empty end' $TMPDIR/json_res1 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-missing-encryption.img.sh	2019-03-27 20:59:49.454269656 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment encryption field missing
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c 'del(.segments."0".encryption)' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".encryption
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-missing-ivoffset.img.sh	2019-03-27 20:59:49.454269656 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment iv_tweak field missing
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c 'del(.segments."0".iv_tweak)' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".iv_tweak
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-missing-sectorsize.img.sh	2019-03-27 20:59:49.455269646 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment sector_size field missing
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c 'del(.segments."0".sector_size)' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".sector_size
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-encryption.img.sh	2019-03-27 20:59:49.455269646 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment wrong encryption field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".encryption = {}' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".encryption | type != "object"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-ivoffset.img.sh	2019-03-27 20:59:49.456269637 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment iv_tweak field missing
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".iv_tweak = "dynamic"' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".iv_tweak != "dynamic"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-0.img.sh	2019-03-27 20:59:49.456269637 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with wrong segment sector_size field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".sector_size = 1023' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".sector_size != 1023
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-1.img.sh	2019-03-27 20:59:49.457269627 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with wrong segment sector_size field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".sector_size = "4096"' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".sector_size != "4096"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-crypt-wrong-sectorsize-2.img.sh	2019-03-27 20:59:49.457269627 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with wrong segment sector_size field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".sector_size = -1024' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".sector_size != -1024
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-missing-offset.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-missing-offset.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-missing-offset.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-missing-offset.img.sh	2019-03-27 20:59:49.458269617 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment offset field missing
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c 'del(.segments."0".offset)' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".offset
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-missing-size.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-missing-size.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-missing-size.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-missing-size.img.sh	2019-03-27 20:59:49.458269617 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment size field missing
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c 'del(.segments."0".size)' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".size
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-missing-type.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-missing-type.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-missing-type.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-missing-type.img.sh	2019-03-27 20:59:49.459269608 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment type field missing
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c 'del(.segments."0".type)' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".type
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-two.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-two.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-two.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-two.img.sh	2019-03-27 20:59:49.459269608 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with two segments
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".size = "512" | .segments."1" = {type:"some", offset: (.segments."0".offset | tonumber + 512 | tostring), size: "dynamic"}' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."1" | type != "object"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-unknown-type.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-unknown-type.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-unknown-type.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-unknown-type.img.sh	2019-03-27 20:59:49.459269608 +0100
+@@ -0,0 +1,68 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with generic (unknown) segment type.
++# It should pass the validation.
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0" = {type:"some_type", offset: .segments."0".offset, size: .segments."0".size, a_field:0}' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".type != "some_type"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-flags-element.img.sh	2019-03-27 20:59:49.460269598 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment flags containing invalid type
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".flags = [ "hello", 1 ]' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".flags != [ "hello", 1  ]
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-flags.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-flags.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-flags.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-flags.img.sh	2019-03-27 20:59:49.461269588 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with segment flags field of invalid type
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".flags = "hello"' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".flags != "hello"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-offset.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-offset.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-offset.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-offset.img.sh	2019-03-27 20:59:49.461269588 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with wrong segment offset field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".offset = "-42"' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".offset != "-42"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-size-0.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-size-0.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-size-0.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-size-0.img.sh	2019-03-27 20:59:49.462269579 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with wrong segment size field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".size = 4096' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".size != 4096
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-size-1.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-size-1.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-size-1.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-size-1.img.sh	2019-03-27 20:59:49.462269579 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with wrong segment size field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".size = "automatic"' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".size != "automatic"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-size-2.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-size-2.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-size-2.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-size-2.img.sh	2019-03-27 20:59:49.463269569 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with wrong segment size field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".size = "511"' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".size != "511"
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-type.img.sh cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-type.img.sh
+--- cryptsetup-2.0.3.old/tests/generators/generate-luks2-segment-wrong-type.img.sh	1970-01-01 01:00:00.000000000 +0100
++++ cryptsetup-2.0.3/tests/generators/generate-luks2-segment-wrong-type.img.sh	2019-03-27 20:59:49.463269569 +0100
+@@ -0,0 +1,67 @@
++#!/bin/bash
++
++. lib.sh
++
++#
++# *** Description ***
++#
++# generate primary header with wrong segment type field
++#
++# secondary header is corrupted on purpose as well
++#
++
++# $1 full target dir
++# $2 full source luks2 image
++
++function prepare()
++{
++	cp $SRC_IMG $TGT_IMG
++	test -d $TMPDIR || mkdir $TMPDIR
++	read_luks2_json0 $TGT_IMG $TMPDIR/json0
++	read_luks2_bin_hdr0 $TGT_IMG $TMPDIR/hdr0
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr1
++}
++
++function generate()
++{
++	# remove mandatory encryption field
++	json_str=$(jq -c '.segments."0".type = 42' $TMPDIR/json0)
++	test ${#json_str} -lt $((LUKS2_JSON_SIZE*512)) || exit 2
++
++	write_luks2_json "$json_str" $TMPDIR/json0
++
++	merge_bin_hdr_with_json $TMPDIR/hdr0 $TMPDIR/json0 $TMPDIR/area0
++	erase_checksum $TMPDIR/area0
++	chks0=$(calc_sha256_checksum_file $TMPDIR/area0)
++	write_checksum $chks0 $TMPDIR/area0
++	write_luks2_hdr0 $TMPDIR/area0 $TGT_IMG
++	kill_bin_hdr $TMPDIR/hdr1
++	write_luks2_hdr1 $TMPDIR/hdr1 $TGT_IMG
++}
++
++function check()
++{
++	read_luks2_bin_hdr1 $TGT_IMG $TMPDIR/hdr_res1
++	local str_res1=$(head -c 6 $TMPDIR/hdr_res1)
++	test "$str_res1" = "VACUUM" || exit 2
++
++	read_luks2_json0 $TGT_IMG $TMPDIR/json_res0
++	jq -c 'if .segments."0".type != 42
++	       then error("Unexpected value in result json") else empty end' $TMPDIR/json_res0 || exit 5
++}
++
++function cleanup()
++{
++	rm -f $TMPDIR/*
++	rm -fd $TMPDIR
++}
++
++test $# -eq 2 || exit 1
++
++TGT_IMG=$1/$(test_img_name $0)
++SRC_IMG=$2
++
++prepare
++generate
++check
++cleanup
+diff -rupN cryptsetup-2.0.3.old/tests/generators/lib.sh cryptsetup-2.0.3/tests/generators/lib.sh
+--- cryptsetup-2.0.3.old/tests/generators/lib.sh	2019-03-27 20:59:31.664442127 +0100
++++ cryptsetup-2.0.3/tests/generators/lib.sh	2019-03-27 20:59:49.464269559 +0100
+@@ -1,9 +1,17 @@
+ #!/bin/bash
+ 
+-# all in 512 bytes blocks
+-# LUKS2 with 16KiB header
+-LUKS2_HDR_SIZE=32 # 16 KiB
+-LUKS2_BIN_HDR_SIZE=8 # 4096 B
++# all in 512 bytes blocks (including binary hdr (4KiB))
++LUKS2_HDR_SIZE=32		#  16 KiB
++LUKS2_HDR_SIZE_32K=64		#  32 KiB
++LUKS2_HDR_SIZE_64K=128		#  64 KiB
++LUKS2_HDR_SIZE_128K=256		# 128 KiB
++LUKS2_HDR_SIZE_256K=512		# 256 KiB
++LUKS2_HDR_SIZE_512K=1024	# 512 KiB
++LUKS2_HDR_SIZE_1M=2048		#   1 MiB
++LUKS2_HDR_SIZE_2M=4096		#   2 MiB
++LUKS2_HDR_SIZE_4M=8192		#   4 MiB
++
++LUKS2_BIN_HDR_SIZE=8		#   4 KiB
+ LUKS2_JSON_SIZE=$((LUKS2_HDR_SIZE-LUKS2_BIN_HDR_SIZE))
+ 
+ LUKS2_BIN_HDR_CHKS_OFFSET=0x1C0
+@@ -30,57 +38,88 @@ function test_img_name()
+ 	echo $str
+ }
+ 
++# read primary bin hdr
++# 1:from 2:to
+ function read_luks2_bin_hdr0()
+ {
+ 	_dd if=$1 of=$2 bs=512 count=$LUKS2_BIN_HDR_SIZE
+ }
+ 
++# read primary json area
++# 1:from 2:to 3:[json only size (defaults to 12KiB)]
+ function read_luks2_json0()
+ {
+-	_dd if=$1 of=$2 bs=512 skip=$LUKS2_BIN_HDR_SIZE count=$LUKS2_JSON_SIZE
++	local _js=${4:-$LUKS2_JSON_SIZE}
++	local _js=$((_js*512/4096))
++	_dd if=$1 of=$2 bs=4096 skip=1 count=$_js
+ }
+ 
++# read secondary bin hdr
++# 1:from 2:to 3:[metadata size (defaults to 16KiB)]
+ function read_luks2_bin_hdr1()
+ {
+-	_dd if=$1 of=$2 skip=$LUKS2_HDR_SIZE bs=512 count=$LUKS2_BIN_HDR_SIZE
++	_dd if=$1 of=$2 skip=${3:-$LUKS2_HDR_SIZE} bs=512 count=$LUKS2_BIN_HDR_SIZE
+ }
+ 
++# read secondary json area
++# 1:from 2:to 3:[json only size (defaults to 12KiB)]
+ function read_luks2_json1()
+ {
+-	_dd if=$1 of=$2 bs=512 skip=$((LUKS2_BIN_HDR_SIZE+LUKS2_HDR_SIZE)) count=$LUKS2_JSON_SIZE
++	local _js=${3:-$LUKS2_JSON_SIZE}
++	_dd if=$1 of=$2 bs=512 skip=$((2*LUKS2_BIN_HDR_SIZE+_js)) count=$_js
+ }
+ 
++# read primary metadata area (bin + json)
++# 1:from 2:to 3:[metadata size (defaults to 16KiB)]
+ function read_luks2_hdr_area0()
+ {
+-	_dd if=$1 of=$2 bs=512 count=$LUKS2_HDR_SIZE
++	local _as=${3:-$LUKS2_HDR_SIZE}
++	local _as=$((_as*512))
++	_dd if=$1 of=$2 bs=$_as count=1
+ }
+ 
++# read secondary metadata area (bin + json)
++# 1:from 2:to 3:[metadata size (defaults to 16KiB)]
+ function read_luks2_hdr_area1()
+ {
+-	_dd if=$1 of=$2 bs=512 skip=$LUKS2_HDR_SIZE count=$LUKS2_HDR_SIZE
++	local _as=${3:-$LUKS2_HDR_SIZE}
++	local _as=$((_as*512))
++	_dd if=$1 of=$2 bs=$_as skip=1 count=1
+ }
+ 
++# write secondary bin hdr
++# 1:from 2:to 3:[metadata size (defaults to 16KiB)]
+ function write_luks2_bin_hdr1()
+ {
+-	_dd if=$1 of=$2 bs=512 seek=$LUKS2_HDR_SIZE count=$LUKS2_BIN_HDR_SIZE conv=notrunc
++	_dd if=$1 of=$2 bs=512 seek=${3:-$LUKS2_HDR_SIZE} count=$LUKS2_BIN_HDR_SIZE conv=notrunc
+ }
+ 
++# write primary metadata area (bin + json)
++# 1:from 2:to 3:[metadata size (defaults to 16KiB)]
+ function write_luks2_hdr0()
+ {
+-	_dd if=$1 of=$2 bs=512 count=$LUKS2_HDR_SIZE conv=notrunc
++	local _as=${3:-$LUKS2_HDR_SIZE}
++	local _as=$((_as*512))
++	_dd if=$1 of=$2 bs=$_as count=1 conv=notrunc
+ }
+ 
++# write secondary metadata area (bin + json)
++# 1:from 2:to 3:[metadata size (defaults to 16KiB)]
+ function write_luks2_hdr1()
+ {
+-	_dd if=$1 of=$2 bs=512 seek=$LUKS2_HDR_SIZE count=$LUKS2_HDR_SIZE conv=notrunc
++	local _as=${3:-$LUKS2_HDR_SIZE}
++	local _as=$((_as*512))
++	_dd if=$1 of=$2 bs=$_as seek=1 count=1 conv=notrunc
+ }
+ 
+-# 1 - json str
++# write json (includes padding)
++# 1:json_string 2:to 3:[json size (defaults to 12KiB)]
+ function write_luks2_json()
+ {
++	local _js=${3:-$LUKS2_JSON_SIZE}
+ 	local len=${#1}
+-	printf '%s' "$1" | _dd of=$2 bs=1 count=$len conv=notrunc
+-	_dd if=/dev/zero of=$2 bs=1 seek=$len count=$((LUKS2_JSON_SIZE*512-len))
++	echo -n -E "$1" > $2
++	truncate -s $((_js*512)) $2
+ }
+ 
+ function kill_bin_hdr()
+@@ -117,17 +156,25 @@ function calc_sha256_checksum_stdin()
+ 	sha256sum - | cut -d ' ' -f 1
+ }
+ 
+-# 1 - bin
+-# 2 - json
+-# 3 - luks2_hdr_area
++# merge bin hdr with json to form metadata area
++# 1:bin_hdr 2:json 3:to 4:[json size (defaults to 12KiB)]
+ function merge_bin_hdr_with_json()
+ {
+-	_dd if=$1 of=$3 bs=512 count=$LUKS2_BIN_HDR_SIZE
+-	_dd if=$2 of=$3 bs=512 seek=$LUKS2_BIN_HDR_SIZE count=$LUKS2_JSON_SIZE
++	local _js=${4:-$LUKS2_JSON_SIZE}
++	local _js=$((_js*512/4096))
++	_dd if=$1 of=$3 bs=4096 count=1
++	_dd if=$2 of=$3 bs=4096 seek=1 count=$_js
+ }
+ 
+ function _dd()
+ {
+-	dd $@ 2>/dev/null
+-	#dd $@
++	dd $@ status=none
++}
++
++function write_bin_hdr_size() {
++        printf '%016x' $2 | xxd -r -p -l 16 | _dd of=$1 bs=8 count=1 seek=1 conv=notrunc
++}
++
++function write_bin_hdr_offset() {
++        printf '%016x' $2 | xxd -r -p -l 16 | _dd of=$1 bs=8 count=1 seek=32 conv=notrunc
+ }
+diff -rupN cryptsetup-2.0.3.old/tests/luks2-validation-test cryptsetup-2.0.3/tests/luks2-validation-test
+--- cryptsetup-2.0.3.old/tests/luks2-validation-test	2019-03-27 20:59:31.654442224 +0100
++++ cryptsetup-2.0.3/tests/luks2-validation-test	2019-03-27 20:59:49.465269549 +0100
+@@ -3,14 +3,12 @@
+ #turn on debug mode by following env. variable _DEBUG=1
+ 
+ PS4='$LINENO:'
+-CRYPTSETUP=../cryptsetup
++[ -z "$CRYPTSETUP_PATH" ] && CRYPTSETUP_PATH=".."
++CRYPTSETUP=$CRYPTSETUP_PATH/cryptsetup
+ 
+ CRYPTSETUP_VALGRIND=../.libs/cryptsetup
+ CRYPTSETUP_LIB_VALGRIND=../.libs
+ 
+-DM_CRYPT_SECTOR=512
+-LUKS2_HDR_SIZE=2112 # 16 KiB version, stored twice, including luks2 areas with keyslots
+-
+ START_DIR=$(pwd)
+ 
+ IMG=luks2-backend.img
+@@ -19,6 +17,8 @@ TST_IMGS=$START_DIR/luks2-images
+ 
+ GEN_DIR=generators
+ 
++FAILS=0
++
+ [ -z "$srcdir" ] && srcdir="."
+ 
+ function remove_mapping()
+@@ -29,12 +29,18 @@ function remove_mapping()
+ function fail()
+ {
+ 	[ -n "$1" ] && echo "$1"
+-	echo "FAILED"
++	echo "FAILED at line $(caller)"
+ 	cd $START_DIR
+ 	remove_mapping
+ 	exit 2
+ }
+ 
++fail_count()
++{
++	echo "$1"
++	FAILS=$((FAILS+1))
++}
++
+ function skip()
+ {
+ 	[ -n "$1" ] && echo "$1"
+@@ -61,23 +67,24 @@ function test_load()
+ 	case "$1" in
+ 	R)
+ 		if [ -n "$_debug" ]; then
+-			$CRYPTSETUP luksDump $_debug $IMG || fail "$2"
++			$CRYPTSETUP luksDump $_debug $IMG
+ 		else
+-			$CRYPTSETUP luksDump $_debug $IMG > /dev/null || fail "$2"
++			$CRYPTSETUP luksDump $_debug $IMG > /dev/null 2>&1
+ 		fi
++		test $? -eq 0 || return 1
+ 		;;
+ 	F)
+ 		if [ -n "$_debug" ]; then
+-			$CRYPTSETUP luksDump $_debug $IMG && fail "$2"
++			$CRYPTSETUP luksDump $_debug $IMG
+ 		else
+-			$CRYPTSETUP luksDump $_debug $IMG > /dev/null 2>&1 && fail "$2"
++			$CRYPTSETUP luksDump $_debug $IMG > /dev/null 2>&1
+ 		fi
++		test $? -ne 0 || return 1
+ 		;;
+ 	*)
+ 		fail "Internal test error"
+ 		;;
+ 	esac
+-
+ }
+ 
+ function RUN()
+@@ -85,7 +92,11 @@ function RUN()
+ 	echo -n "Test image: $1..."
+ 	cp $TST_IMGS/$1 $IMG || fail "Missing test image"
+ 	test_load $2 "$3"
+-	echo "OK"
++	if [ $? -ne 0 ]; then
++		fail_count "$3"
++	else
++		echo "OK"
++	fi
+ }
+ 
+ function valgrind_setup()
+@@ -158,11 +169,6 @@ RUN luks2-area-in-json-hdr-space-json0.i
+ RUN luks2-missing-keyslot-referenced-in-digest.img	"F" "Failed to detect missing keyslot referenced in digest"
+ RUN luks2-missing-segment-referenced-in-digest.img	"F" "Failed to detect missing segment referenced in digest"
+ RUN luks2-missing-keyslot-referenced-in-token.img	"F" "Failed to detect missing keyslots referenced in token"
+-RUN luks2-invalid-keyslots-size-c0.img			"F" "Failed to detect too large keyslots_size in config section"
+-RUN luks2-invalid-keyslots-size-c1.img			"F" "Failed to detect unaligned keyslots_size in config section"
+-RUN luks2-invalid-keyslots-size-c2.img			"F" "Failed to detect too small keyslots_size config section"
+-RUN luks2-invalid-json-size-c0.img			"F" "Failed to detect invalid json_size config section"
+-RUN luks2-invalid-json-size-c1.img			"F" "Failed to detect invalid json_size config section"
+ RUN luks2-keyslot-missing-digest.img			"F" "Failed to detect missing keyslot digest."
+ RUN luks2-keyslot-too-many-digests.img			"F" "Failed to detect keyslot has too many digests."
+ 
+@@ -171,4 +177,56 @@ RUN luks2-uint64-max-segment-size.img
+ RUN luks2-uint64-overflow-segment-size.img		"F" "Failed to detect uint64_t overflow"
+ RUN luks2-uint64-signed-segment-size.img		"F" "Failed to detect negative value"
+ 
++echo "[5] Test segments validation"
++RUN luks2-segment-missing-type.img			"F" "Failed to detect missing type field"
++RUN luks2-segment-wrong-type.img			"F" "Failed to detect invalid type field"
++RUN luks2-segment-missing-offset.img			"F" "Failed to detect missing offset field"
++RUN luks2-segment-wrong-offset.img			"F" "Failed to detect invalid offset field"
++RUN luks2-segment-missing-size.img			"F" "Failed to detect missing size field"
++RUN luks2-segment-wrong-size-0.img			"F" "Failed to detect invalid size field"
++RUN luks2-segment-wrong-size-1.img			"F" "Failed to detect invalid size field"
++RUN luks2-segment-wrong-size-2.img			"F" "Failed to detect invalid size field"
++RUN luks2-segment-crypt-missing-encryption.img		"F" "Failed to detect missing encryption field"
++RUN luks2-segment-crypt-wrong-encryption.img		"F" "Failed to detect invalid encryption field"
++RUN luks2-segment-crypt-missing-ivoffset.img		"F" "Failed to detect missing iv_tweak field"
++RUN luks2-segment-crypt-wrong-ivoffset.img		"F" "Failed to detect invalid iv_tweak field"
++RUN luks2-segment-crypt-missing-sectorsize.img		"F" "Failed to detect missing sector_size field"
++RUN luks2-segment-crypt-wrong-sectorsize-0.img		"F" "Failed to detect invalid sector_size field"
++RUN luks2-segment-crypt-wrong-sectorsize-1.img		"F" "Failed to detect invalid sector_size field"
++RUN luks2-segment-crypt-wrong-sectorsize-2.img		"F" "Failed to detect invalid sector_size field"
++RUN luks2-segment-unknown-type.img			"R" "Validation rejected segment with all mandatory fields correct"
++RUN luks2-segment-two.img				"R" "Validation rejected two valid segments"
++RUN luks2-segment-wrong-flags.img			"F" "Failed to detect invalid flags field"
++RUN luks2-segment-wrong-flags-element.img		"F" "Failed to detect invalid flags content"
++
++echo "[6] Test metadata size and keyslots size (config section)"
++RUN luks2-invalid-keyslots-size-c0.img			"F" "Failed to detect too large keyslots_size in config section"
++RUN luks2-invalid-keyslots-size-c1.img			"F" "Failed to detect unaligned keyslots_size in config section"
++RUN luks2-invalid-keyslots-size-c2.img			"F" "Failed to detect too small keyslots_size config section"
++RUN luks2-invalid-json-size-c0.img			"F" "Failed to detect invalid json_size config section"
++RUN luks2-invalid-json-size-c1.img			"F" "Failed to detect invalid json_size config section"
++RUN luks2-invalid-json-size-c2.img			"F" "Failed to detect mismatching json size in config and binary hdr"
++RUN luks2-metadata-size-32k.img				"R" "Valid 32KiB metadata size failed to validate"
++RUN luks2-metadata-size-64k.img				"R" "Valid 64KiB metadata size failed to validate"
++RUN luks2-metadata-size-64k-inv-area-c0.img		"F" "Failed to detect keyslot area trespassing in json area"
++RUN luks2-metadata-size-64k-inv-area-c1.img		"F" "Failed to detect keyslot area overflowing keyslots area"
++RUN luks2-metadata-size-64k-inv-keyslots-size-c0.img	"F" "Failed to detect keyslots size overflowing in data area"
++RUN luks2-metadata-size-128k.img			"R" "Valid 128KiB metadata size failed to validate"
++RUN luks2-metadata-size-256k.img			"R" "Valid 256KiB metadata size failed to validate"
++RUN luks2-metadata-size-512k.img			"R" "Valid 512KiB metadata size failed to validate"
++RUN luks2-metadata-size-1m.img				"R" "Valid 1MiB metadata size failed to validate"
++RUN luks2-metadata-size-2m.img				"R" "Valid 2MiB metadata size failed to validate"
++RUN luks2-metadata-size-4m.img				"R" "Valid 4MiB metadata size failed to validate"
++RUN luks2-metadata-size-16k-secondary.img		"R" "Valid 16KiB metadata size in secondary hdr failed to validate"
++RUN luks2-metadata-size-32k-secondary.img		"R" "Valid 32KiB metadata size in secondary hdr failed to validate"
++RUN luks2-metadata-size-64k-secondary.img		"R" "Valid 64KiB metadata size in secondary hdr failed to validate"
++RUN luks2-metadata-size-128k-secondary.img		"R" "Valid 128KiB metadata size in secondary hdr failed to validate"
++RUN luks2-metadata-size-256k-secondary.img		"R" "Valid 256KiB metadata size in secondary hdr failed to validate"
++RUN luks2-metadata-size-512k-secondary.img		"R" "Valid 512KiB metadata size in secondary hdr failed to validate"
++RUN luks2-metadata-size-1m-secondary.img		"R" "Valid 1MiB metadata size in secondary hdr failed to validate"
++RUN luks2-metadata-size-2m-secondary.img		"R" "Valid 2MiB metadata size in secondary hdr failed to validate"
++RUN luks2-metadata-size-4m-secondary.img		"R" "Valid 4MiB metadata size in secondary hdr failed to validate"
++
+ remove_mapping
++
++test $FAILS -eq 0 || fail "($FAILS wrong result(s) in total)"
diff --git a/SPECS/cryptsetup.spec b/SPECS/cryptsetup.spec
index cdd8c23..f3fb720 100644
--- a/SPECS/cryptsetup.spec
+++ b/SPECS/cryptsetup.spec
@@ -30,7 +30,7 @@ Obsoletes: python2-cryptsetup
 Summary: A utility for setting up encrypted disks
 Name: cryptsetup
 Version: 2.0.3
-Release: 3%{?dist}
+Release: 5%{?dist}
 License: GPLv2+ and LGPLv2+
 Group: Applications/System
 URL: https://gitlab.com/cryptsetup/cryptsetup
@@ -57,6 +57,10 @@ Requires: libpwquality >= 1.2.0
 %define upstream_version_old 1.7.4
 Source0: https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-%{upstream_version}.tar.xz
 Source1: https://www.kernel.org/pub/linux/utils/cryptsetup/v1.7/cryptsetup-%{upstream_version_old}.tar.xz
+# contains test images only, original commit id 5a7535c
+Source2: luks2_mda_images.tar.xz
+# contains test images only, original commit id 177cb8b
+Source3: luks2_valid_hdr.tar.xz
 # version 1.7.4 only (all of it, up to next comment)
 Patch0: %{name}-avoid-rh-kernel-bug.patch
 Patch1: %{name}-1.7.5-fix-unaligned-access-to-hidden-truecrypt.patch
@@ -82,6 +86,18 @@ Patch18: %{name}-2.0.4-allow-LUKS2-repair-with-disabled-locks.patch
 Patch19: %{name}-2.0.4-configure.patch
 Patch20: %{name}-2.0.4-update-cryptsetup-man-page-for-type-option-usage.patch
 Patch21: %{name}-2.0.4-rephrase-error-message-for-invalid-type-param-in-con.patch
+Patch22: %{name}-2.0.4-fix-LUKS2-api-test.patch
+Patch23: %{name}-2.0.5-fix-miscalculation-of-device-alignment-offset.patch
+Patch24: %{name}-2.0.5-remove-useless-division-followed-by-multiplication-b.patch
+Patch25: %{name}-2.0.6-LUKS2-metadata-variation-fixes.patch
+Patch26: %{name}-2.0.6-enable-all-supported-metadata-sizes-in-LUKS2-validat.patch
+Patch27: %{name}-2.0.6-check-json-size-matches-value-from-binary-LUKS2-head.patch
+Patch28: %{name}-2.0.6-test-cryptsetup-can-handle-all-LUKS2-metadata-varian.patch
+Patch29: %{name}-2.0.6-do-not-validate-keyslot-areas-so-frantically.patch
+Patch30: %{name}-2.0.6-reshuffle-config-and-keyslots-areas-validation-code.patch
+Patch31: %{name}-2.0.6-fix-keyslot-areas-validation.patch
+# keep validation tests up to date
+Patch32: %{name}-2.1.0-sync-LUKS2-validation-tests.patch
 
 %if 0%{?fedora} >= 19 || 0%{?rhel} >= 7
 %define configure_cipher --enable-gcrypt-pbkdf2
@@ -192,10 +208,24 @@ for setting up disk encryption using dm-crypt kernel module.
 %patch18 -p1
 %patch20 -p1
 %patch21 -p1
+%patch22 -p1
+%patch23 -p1
+%patch24 -p1
+%patch25 -p1
+%patch26 -p1
+%patch27 -p1
+%patch28 -p1
+%patch29 -p1
+%patch30 -p1
+%patch31 -p1
+%patch32 -p1
 # the configure patch (always last)
 %patch19 -p1
 chmod -x python/pycryptsetup-test.py
 chmod -x misc/dracut_90reencrypt/*
+chmod +x tests/generators/generate-*.sh
+%setup -T -a 2 -D -n cryptsetup-%{upstream_version}/tests
+%setup -T -a 3 -D -n cryptsetup-%{upstream_version}/tests
 
 %if %{python3_enable}
 # copy the whole directory for the python3 build
@@ -319,6 +349,17 @@ install -m755 misc/dracut_90reencrypt/reencrypt-verbose.sh %{buildroot}/%{dracut
 %clean
 
 %changelog
+* Wed Apr 03 2019 Ondrej Kozina <okozina@redhat.com> - 2.0.3-5
+- patch: calculate alignment offset correctly for LUKS2 devices.
+- patch: fix memory leak in LUKS2 validation.
+- Resolves: #1613953 #1693592
+
+* Wed Mar 27 2019 Ondrej Kozina <okozina@redhat.com> - 2.0.3-4
+- patch: Fix broken LUKS2 api test.
+- patch: Allow cryptsetup to process all LUKS2 metadata variants
+  according to LUKS2 specifiation.
+- Resolves: #1653388
+
 * Tue Jul 31 2018 Ondrej Kozina <okozina@redhat.com> - 2.0.3-3
 - Add expected permissions explicitly for locking directory.
 - Reinstate sed script removing library rpath from libtool