diff --git a/.cryptsetup.metadata b/.cryptsetup.metadata
new file mode 100644
index 0000000..ff5999b
--- /dev/null
+++ b/.cryptsetup.metadata
@@ -0,0 +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
new file mode 100644
index 0000000..7c79481
--- /dev/null
+++ b/.gitignore
@@ -0,0 +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-1.7.5-fix-luksformat-in-fips-mode.patch b/SOURCES/cryptsetup-1.7.5-fix-luksformat-in-fips-mode.patch
new file mode 100644
index 0000000..c321d4a
--- /dev/null
+++ b/SOURCES/cryptsetup-1.7.5-fix-luksformat-in-fips-mode.patch
@@ -0,0 +1,35 @@
+From 3c2135b36bbc52d052e4ced7c94dc4981eb07a53 Mon Sep 17 00:00:00 2001
+From: Milan Broz <gmazyland@gmail.com>
+Date: Fri, 21 Apr 2017 08:16:14 +0200
+Subject: [PATCH] Fix luksFormat if running in FIPS mode on recent kernel.
+
+Recently introduced check for weak keys for XTS mode makes
+zeroed key for algorithm check unusable.
+
+Use random key for the test instead.
+---
+ lib/luks1/keymanage.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c
+index b700bab..5b1421b 100644
+--- a/lib/luks1/keymanage.c
++++ b/lib/luks1/keymanage.c
+@@ -631,9 +631,11 @@ static int LUKS_check_cipher(struct luks_phdr *hdr, struct crypt_device *ctx)
+ 	if (!empty_key)
+ 		return -ENOMEM;
+ 
+-	r = LUKS_decrypt_from_storage(buf, sizeof(buf),
+-				      hdr->cipherName, hdr->cipherMode,
+-				      empty_key, 0, ctx);
++	/* No need to get KEY quality random but it must avoid known weak keys. */
++	r = crypt_random_get(ctx, empty_key->key, empty_key->keylength, CRYPT_RND_NORMAL);
++	if (!r)
++		r = LUKS_decrypt_from_storage(buf, sizeof(buf), hdr->cipherName,
++					      hdr->cipherMode, empty_key, 0, ctx);
+ 
+ 	crypt_free_volume_key(empty_key);
+ 	crypt_memzero(buf, sizeof(buf));
+-- 
+2.7.4
+
diff --git a/SOURCES/cryptsetup-1.7.5-fix-unaligned-access-to-hidden-truecrypt.patch b/SOURCES/cryptsetup-1.7.5-fix-unaligned-access-to-hidden-truecrypt.patch
new file mode 100644
index 0000000..874a851
--- /dev/null
+++ b/SOURCES/cryptsetup-1.7.5-fix-unaligned-access-to-hidden-truecrypt.patch
@@ -0,0 +1,376 @@
+From a117f431179a2747f2b1d5293f43d9e198f1bac9 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Mon, 30 Nov 2015 16:44:15 +0100
+Subject: [PATCH] Fix access to unaligned hidden TrueCrypt header.
+
+backport all changes needed to fix unaligned access
+to hidden TrueCrypt hedaer.
+---
+ lib/internal.h        |   7 ++-
+ lib/luks1/keymanage.c |   6 +-
+ lib/tcrypt/tcrypt.c   |  24 ++++----
+ lib/utils.c           | 155 +++++++++++++++++++++++++++++++++++++++++++-------
+ 4 files changed, 152 insertions(+), 40 deletions(-)
+
+diff --git a/lib/internal.h b/lib/internal.h
+index 382a600..f1525f2 100644
+--- a/lib/internal.h
++++ b/lib/internal.h
+@@ -101,9 +101,12 @@ char *crypt_get_partition_device(const char *dev_path, uint64_t offset, uint64_t
+ char *crypt_get_base_device(const char *dev_path);
+ uint64_t crypt_dev_partition_offset(const char *dev_path);
+ 
++ssize_t write_buffer(int fd, const void *buf, size_t count);
++ssize_t read_buffer(int fd, void *buf, size_t count);
+ ssize_t write_blockwise(int fd, int bsize, void *buf, size_t count);
+-ssize_t read_blockwise(int fd, int bsize, void *_buf, size_t count);
+-ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t offset);
++ssize_t read_blockwise(int fd, int bsize, void *buf, size_t count);
++ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset);
++ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset);
+ 
+ unsigned crypt_getpagesize(void);
+ int init_crypto(struct crypt_device *ctx);
+diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c
+index 23e3fe2..b193ee9 100644
+--- a/lib/luks1/keymanage.c
++++ b/lib/luks1/keymanage.c
+@@ -201,7 +201,7 @@ int LUKS_hdr_backup(const char *backup_file, struct crypt_device *ctx)
+ 		r = -EINVAL;
+ 		goto out;
+ 	}
+-	if (write(devfd, buffer, buffer_size) < buffer_size) {
++	if (write_buffer(devfd, buffer, buffer_size) < buffer_size) {
+ 		log_err(ctx, _("Cannot write header backup file %s.\n"), backup_file);
+ 		r = -EIO;
+ 		goto out;
+@@ -253,7 +253,7 @@ int LUKS_hdr_restore(
+ 		goto out;
+ 	}
+ 
+-	if (read(devfd, buffer, buffer_size) < buffer_size) {
++	if (read_buffer(devfd, buffer, buffer_size) < buffer_size) {
+ 		log_err(ctx, _("Cannot read header backup file %s.\n"), backup_file);
+ 		r = -EIO;
+ 		goto out;
+@@ -498,7 +498,7 @@ int LUKS_read_phdr_backup(const char *backup_file,
+ 		return -ENOENT;
+ 	}
+ 
+-	if (read(devfd, hdr, hdr_size) < hdr_size)
++	if (read_buffer(devfd, hdr, hdr_size) < hdr_size)
+ 		r = -EIO;
+ 	else {
+ 		LUKS_fix_header_compatible(hdr);
+diff --git a/lib/tcrypt/tcrypt.c b/lib/tcrypt/tcrypt.c
+index 45154ed..9ff7157 100644
+--- a/lib/tcrypt/tcrypt.c
++++ b/lib/tcrypt/tcrypt.c
+@@ -469,8 +469,7 @@ static int TCRYPT_pool_keyfile(struct crypt_device *cd,
+ 		return -EIO;
+ 	}
+ 
+-	/* FIXME: add while */
+-	data_size = read(fd, data, TCRYPT_KEYFILE_LEN);
++	data_size = read_buffer(fd, data, TCRYPT_KEYFILE_LEN);
+ 	close(fd);
+ 	if (data_size < 0) {
+ 		log_err(cd, _("Error reading keyfile %s.\n"), keyfile);
+@@ -628,27 +627,26 @@ int TCRYPT_read_phdr(struct crypt_device *cd,
+ 
+ 	r = -EIO;
+ 	if (params->flags & CRYPT_TCRYPT_SYSTEM_HEADER) {
+-		if (lseek(devfd, TCRYPT_HDR_SYSTEM_OFFSET, SEEK_SET) >= 0 &&
+-		    read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size) {
++		if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
++			TCRYPT_HDR_SYSTEM_OFFSET) == hdr_size) {
+ 			r = TCRYPT_init_hdr(cd, hdr, params);
+ 		}
+ 	} else if (params->flags & CRYPT_TCRYPT_HIDDEN_HEADER) {
+ 		if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
+-			if (lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET_BCK, SEEK_END) >= 0 &&
+-			    read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size)
++			if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
++				TCRYPT_HDR_HIDDEN_OFFSET_BCK) == hdr_size)
+ 				r = TCRYPT_init_hdr(cd, hdr, params);
+ 		} else {
+-			if (lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET, SEEK_SET) >= 0 &&
+-			    read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size)
++			if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
++				TCRYPT_HDR_HIDDEN_OFFSET) == hdr_size)
+ 				r = TCRYPT_init_hdr(cd, hdr, params);
+-			if (r &&
+-			    lseek(devfd, TCRYPT_HDR_HIDDEN_OFFSET_OLD, SEEK_END) >= 0 &&
+-			    read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size)
++			if (r && read_lseek_blockwise(devfd, bs, hdr, hdr_size,
++				TCRYPT_HDR_HIDDEN_OFFSET_OLD) == hdr_size)
+ 				r = TCRYPT_init_hdr(cd, hdr, params);
+ 		}
+ 	} else if (params->flags & CRYPT_TCRYPT_BACKUP_HEADER) {
+-		if (lseek(devfd, TCRYPT_HDR_OFFSET_BCK, SEEK_END) >= 0 &&
+-			    read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size)
++		if (read_lseek_blockwise(devfd, bs, hdr, hdr_size,
++			TCRYPT_HDR_OFFSET_BCK) == hdr_size)
+ 			r = TCRYPT_init_hdr(cd, hdr, params);
+ 	} else if (read_blockwise(devfd, bs, hdr, hdr_size) == hdr_size)
+ 		r = TCRYPT_init_hdr(cd, hdr, params);
+diff --git a/lib/utils.c b/lib/utils.c
+index 2dcf753..802ba55 100644
+--- a/lib/utils.c
++++ b/lib/utils.c
+@@ -56,22 +56,70 @@ static void *aligned_malloc(void **base, int size, int alignment)
+ /* Credits go to Michal's padlock patches for this alignment code */
+ 	char *ptr;
+ 
+-	ptr  = malloc(size + alignment);
+-	if(ptr == NULL) return NULL;
++	ptr = malloc(size + alignment);
++	if (!ptr)
++		return NULL;
+ 
+ 	*base = ptr;
+-	if(alignment > 1 && ((long)ptr & (alignment - 1))) {
++	if (alignment > 1 && ((long)ptr & (alignment - 1)))
+ 		ptr += alignment - ((long)(ptr) & (alignment - 1));
+-	}
++
+ 	return ptr;
+ #endif
+ }
+ 
++ssize_t read_buffer(int fd, void *buf, size_t count)
++{
++	size_t read_size = 0;
++	ssize_t r;
++
++	if (fd < 0 || !buf)
++		return -EINVAL;
++
++	do {
++		r = read(fd, buf, count - read_size);
++		if (r == -1 && errno != EINTR)
++			return r;
++		if (r == 0)
++			return (ssize_t)read_size;
++		if (r > 0) {
++			read_size += (size_t)r;
++			buf = (uint8_t*)buf + r;
++		}
++	} while (read_size != count);
++
++	return (ssize_t)count;
++}
++
++ssize_t write_buffer(int fd, const void *buf, size_t count)
++{
++	size_t write_size = 0;
++	ssize_t w;
++
++	if (fd < 0 || !buf || !count)
++		return -EINVAL;
++
++	do {
++		w = write(fd, buf, count - write_size);
++		if (w < 0 && errno != EINTR)
++			return w;
++		if (w == 0)
++			return (ssize_t)write_size;
++		if (w > 0) {
++			write_size += (size_t) w;
++			buf = (const uint8_t*)buf + w;
++		}
++	} while (write_size != count);
++
++	return (ssize_t)write_size;
++}
++
+ ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count)
+ {
+ 	void *hangover_buf, *hangover_buf_base = NULL;
+ 	void *buf, *buf_base = NULL;
+-	int r, hangover, solid, alignment;
++	int r, alignment;
++	size_t hangover, solid;
+ 	ssize_t ret = -1;
+ 
+ 	if (fd == -1 || !orig_buf || bsize <= 0)
+@@ -89,17 +137,19 @@ ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count)
+ 	} else
+ 		buf = orig_buf;
+ 
+-	r = write(fd, buf, solid);
+-	if (r < 0 || r != solid)
+-		goto out;
++	if (solid) {
++		r = write_buffer(fd, buf, solid);
++		if (r < 0 || r != (ssize_t)solid)
++			goto out;
++	}
+ 
+ 	if (hangover) {
+ 		hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
+ 		if (!hangover_buf)
+ 			goto out;
+ 
+-		r = read(fd, hangover_buf, bsize);
+-		if (r < 0 || r < hangover)
++		r = read_buffer(fd, hangover_buf, bsize);
++		if (r < 0 || r < (ssize_t)hangover)
+ 			goto out;
+ 
+ 		if (r < bsize)
+@@ -110,8 +160,8 @@ ssize_t write_blockwise(int fd, int bsize, void *orig_buf, size_t count)
+ 
+ 		memcpy(hangover_buf, (char*)buf + solid, hangover);
+ 
+-		r = write(fd, hangover_buf, bsize);
+-		if (r < 0 || r < hangover)
++		r = write_buffer(fd, hangover_buf, bsize);
++		if (r < 0 || r < (ssize_t)hangover)
+ 			goto out;
+ 	}
+ 	ret = count;
+@@ -122,10 +172,12 @@ out:
+ 	return ret;
+ }
+ 
+-ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count) {
++ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count)
++{
+ 	void *hangover_buf, *hangover_buf_base = NULL;
+ 	void *buf, *buf_base = NULL;
+-	int r, hangover, solid, alignment;
++	int r, alignment;
++	size_t hangover, solid;
+ 	ssize_t ret = -1;
+ 
+ 	if (fd == -1 || !orig_buf || bsize <= 0)
+@@ -142,16 +194,16 @@ ssize_t read_blockwise(int fd, int bsize, void *orig_buf, size_t count) {
+ 	} else
+ 		buf = orig_buf;
+ 
+-	r = read(fd, buf, solid);
+-	if(r < 0 || r != solid)
++	r = read_buffer(fd, buf, solid);
++	if (r < 0 || r != (ssize_t)solid)
+ 		goto out;
+ 
+ 	if (hangover) {
+ 		hangover_buf = aligned_malloc(&hangover_buf_base, bsize, alignment);
+ 		if (!hangover_buf)
+ 			goto out;
+-		r = read(fd, hangover_buf, bsize);
+-		if (r <  0 || r < hangover)
++		r = read_buffer(fd, hangover_buf, bsize);
++		if (r <  0 || r < (ssize_t)hangover)
+ 			goto out;
+ 
+ 		memcpy((char *)buf + solid, hangover_buf, hangover);
+@@ -172,7 +224,8 @@ out:
+  * is implicitly included in the read/write offset, which can not be set to non-aligned
+  * boundaries. Hence, we combine llseek with write.
+  */
+-ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t offset) {
++ssize_t write_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset)
++{
+ 	char *frontPadBuf;
+ 	void *frontPadBuf_base = NULL;
+ 	int r, frontHang;
+@@ -182,6 +235,12 @@ ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t
+ 	if (fd == -1 || !buf || bsize <= 0)
+ 		return -1;
+ 
++	if (offset < 0)
++		offset = lseek(fd, offset, SEEK_END);
++
++	if (offset < 0)
++		return -1;
++
+ 	frontHang = offset % bsize;
+ 
+ 	if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
+@@ -193,7 +252,7 @@ ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t
+ 		if (!frontPadBuf)
+ 			goto out;
+ 
+-		r = read(fd, frontPadBuf, bsize);
++		r = read_buffer(fd, frontPadBuf, bsize);
+ 		if (r < 0 || r != bsize)
+ 			goto out;
+ 
+@@ -206,11 +265,11 @@ ssize_t write_lseek_blockwise(int fd, int bsize, char *buf, size_t count, off_t
+ 		if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
+ 			goto out;
+ 
+-		r = write(fd, frontPadBuf, bsize);
++		r = write_buffer(fd, frontPadBuf, bsize);
+ 		if (r < 0 || r != bsize)
+ 			goto out;
+ 
+-		buf += innerCount;
++		buf = (char*)buf + innerCount;
+ 		count -= innerCount;
+ 	}
+ 
+@@ -223,6 +282,58 @@ out:
+ 	return ret;
+ }
+ 
++ssize_t read_lseek_blockwise(int fd, int bsize, void *buf, size_t count, off_t offset)
++{
++	char *frontPadBuf;
++	void *frontPadBuf_base = NULL;
++	int r, frontHang;
++	size_t innerCount = 0;
++	ssize_t ret = -1;
++
++	if (fd == -1 || !buf || bsize <= 0)
++		return -1;
++
++	if (offset < 0)
++		offset = lseek(fd, offset, SEEK_END);
++
++	if (offset < 0)
++		return -1;
++
++	frontHang = offset % bsize;
++
++	if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
++		return ret;
++
++	if (frontHang) {
++		frontPadBuf = aligned_malloc(&frontPadBuf_base,
++					     bsize, get_alignment(fd));
++
++		if (!frontPadBuf)
++			return ret;
++
++		r = read_buffer(fd, frontPadBuf, bsize);
++		if (r < 0 || r != bsize)
++			goto out;
++
++		innerCount = bsize - frontHang;
++		if (innerCount > count)
++			innerCount = count;
++
++		memcpy(buf, frontPadBuf + frontHang, innerCount);
++
++		buf = (char*)buf + innerCount;
++		count -= innerCount;
++	}
++
++	ret = read_blockwise(fd, bsize, buf, count);
++	if (ret >= 0)
++		ret += innerCount;
++out:
++	free(frontPadBuf_base);
++
++	return ret;
++}
++
+ /* MEMLOCK */
+ #define DEFAULT_PROCESS_PRIORITY -18
+ 
+-- 
+2.7.4
+
diff --git a/SOURCES/cryptsetup-1.7.6-crypt_deactivate-fail-earlier-when-holders-detected.patch b/SOURCES/cryptsetup-1.7.6-crypt_deactivate-fail-earlier-when-holders-detected.patch
new file mode 100644
index 0000000..df91689
--- /dev/null
+++ b/SOURCES/cryptsetup-1.7.6-crypt_deactivate-fail-earlier-when-holders-detected.patch
@@ -0,0 +1,150 @@
+From 2e4aaa1adad2d0838593b13efbf5efe79f58255c Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Mon, 16 Oct 2017 16:41:43 +0200
+Subject: [PATCH] crypt_deactivate: fail earlier when holders detected
+
+crypt_deactivate fails earlier without noisy dm retries
+when other device holders detected. The early detection
+works if:
+
+a) other device-mapper device has a hold reference on the
+   device
+
+- or -
+
+b) mounted fs is detected on the device
+
+diff -rupN cryptsetup-1.7.4.old/config.h.in cryptsetup-1.7.4/config.h.in
+--- cryptsetup-1.7.4.old/config.h.in	2017-03-15 10:43:26.000000000 +0100
++++ cryptsetup-1.7.4/config.h.in	2017-10-19 09:37:17.000000000 +0200
+@@ -97,6 +97,14 @@
+    */
+ #undef HAVE_DCGETTEXT
+ 
++/* Define to 1 if you have the declaration of `dm_device_has_holders', and to
++   0 if you don't. */
++#undef HAVE_DECL_DM_DEVICE_HAS_HOLDERS
++
++/* Define to 1 if you have the declaration of `dm_device_has_mounted_fs', and
++   to 0 if you don't. */
++#undef HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS
++
+ /* Define to 1 if you have the declaration of `dm_task_retry_remove', and to 0
+    if you don't. */
+ #undef HAVE_DECL_DM_TASK_RETRY_REMOVE
+diff -rupN cryptsetup-1.7.4.old/configure cryptsetup-1.7.4/configure
+--- cryptsetup-1.7.4.old/configure	2017-03-15 10:43:13.000000000 +0100
++++ cryptsetup-1.7.4/configure	2017-10-19 09:37:18.590530138 +0200
+@@ -16735,6 +16735,30 @@ cat >>confdefs.h <<_ACEOF
+ #define HAVE_DECL_DM_TASK_RETRY_REMOVE $ac_have_decl
+ _ACEOF
+ 
++ac_fn_c_check_decl "$LINENO" "dm_device_has_mounted_fs" "ac_cv_have_decl_dm_device_has_mounted_fs" "#include <libdevmapper.h>
++"
++if test "x$ac_cv_have_decl_dm_device_has_mounted_fs" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS $ac_have_decl
++_ACEOF
++
++ac_fn_c_check_decl "$LINENO" "dm_device_has_holders" "ac_cv_have_decl_dm_device_has_holders" "#include <libdevmapper.h>
++"
++if test "x$ac_cv_have_decl_dm_device_has_holders" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_DM_DEVICE_HAS_HOLDERS $ac_have_decl
++_ACEOF
++
+ ac_fn_c_check_decl "$LINENO" "DM_UDEV_DISABLE_DISK_RULES_FLAG" "ac_cv_have_decl_DM_UDEV_DISABLE_DISK_RULES_FLAG" "#include <libdevmapper.h>
+ "
+ if test "x$ac_cv_have_decl_DM_UDEV_DISABLE_DISK_RULES_FLAG" = xyes; then :
+diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c
+index a0d6872..d6017b1 100644
+--- a/lib/libdevmapper.c
++++ b/lib/libdevmapper.c
+@@ -1181,6 +1181,13 @@ int dm_query_device(struct crypt_device *cd, const char *name,
+ 			dmd->uuid = strdup(tmp_uuid + DM_UUID_PREFIX_LEN);
+ 	}
+ 
++	dmd->holders = 0;
++#if (HAVE_DECL_DM_DEVICE_HAS_HOLDERS && HAVE_DECL_DM_DEVICE_HAS_MOUNTED_FS)
++	if (get_flags & DM_ACTIVE_HOLDERS)
++		dmd->holders = (dm_device_has_mounted_fs(dmi.major, dmi.minor) ||
++				dm_device_has_holders(dmi.major, dmi.minor));
++#endif
++
+ 	r = (dmi.open_count > 0);
+ out:
+ 	if (dmt)
+diff --git a/lib/setup.c b/lib/setup.c
+index b2e4396..93e8079 100644
+--- a/lib/setup.c
++++ b/lib/setup.c
+@@ -2249,6 +2249,7 @@ int crypt_activate_by_volume_key(struct crypt_device *cd,
+ int crypt_deactivate(struct crypt_device *cd, const char *name)
+ {
+ 	struct crypt_device *fake_cd = NULL;
++	struct crypt_dm_active_device dmd = {};
+ 	int r;
+ 
+ 	if (!name)
+@@ -2266,6 +2267,13 @@ int crypt_deactivate(struct crypt_device *cd, const char *name)
+ 	switch (crypt_status(cd, name)) {
+ 		case CRYPT_ACTIVE:
+ 		case CRYPT_BUSY:
++			r = dm_query_device(cd, name, DM_ACTIVE_HOLDERS, &dmd);
++			if (r >= 0 && dmd.holders) {
++				log_err(cd, _("Device %s is still in use.\n"), name);
++				r = -EBUSY;
++				break;
++			}
++
+ 			if (isTCRYPT(cd->type))
+ 				r = TCRYPT_deactivate(cd, name);
+ 			else
+diff --git a/lib/utils_dm.h b/lib/utils_dm.h
+index c87e9aa..cf22e12 100644
+--- a/lib/utils_dm.h
++++ b/lib/utils_dm.h
+@@ -48,14 +48,16 @@ uint32_t dm_flags(void);
+ 
+ #define DM_ACTIVE_DEVICE	(1 << 0)
+ #define DM_ACTIVE_UUID		(1 << 1)
++#define DM_ACTIVE_HOLDERS	(1 << 2)
+ 
+-#define DM_ACTIVE_CRYPT_CIPHER	(1 << 2)
+-#define DM_ACTIVE_CRYPT_KEYSIZE	(1 << 3)
+-#define DM_ACTIVE_CRYPT_KEY	(1 << 4)
++#define DM_ACTIVE_CRYPT_CIPHER	(1 << 3)
++#define DM_ACTIVE_CRYPT_KEYSIZE	(1 << 4)
++#define DM_ACTIVE_CRYPT_KEY	(1 << 5)
++
++#define DM_ACTIVE_VERITY_ROOT_HASH	(1 << 6)
++#define DM_ACTIVE_VERITY_HASH_DEVICE	(1 << 7)
++#define DM_ACTIVE_VERITY_PARAMS		(1 << 8)
+ 
+-#define DM_ACTIVE_VERITY_ROOT_HASH	(1 << 5)
+-#define DM_ACTIVE_VERITY_HASH_DEVICE	(1 << 6)
+-#define DM_ACTIVE_VERITY_PARAMS		(1 << 7)
+ 
+ struct crypt_dm_active_device {
+ 	enum { DM_CRYPT = 0, DM_VERITY } target;
+@@ -63,6 +65,7 @@ struct crypt_dm_active_device {
+ 	uint32_t flags;		/* activation flags */
+ 	const char *uuid;
+ 	struct device *data_device;
++	unsigned holders:1;
+ 	union {
+ 	struct {
+ 		const char *cipher;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-1.7.6-fix-blockwise-access-functions-for-64k-page-size.patch b/SOURCES/cryptsetup-1.7.6-fix-blockwise-access-functions-for-64k-page-size.patch
new file mode 100644
index 0000000..2c82dff
--- /dev/null
+++ b/SOURCES/cryptsetup-1.7.6-fix-blockwise-access-functions-for-64k-page-size.patch
@@ -0,0 +1,50 @@
+diff -rupN cryptsetup-1.7.4.bcp/lib/utils.c cryptsetup-1.7.4/lib/utils.c
+--- cryptsetup-1.7.4.bcp/lib/utils.c	2017-10-18 11:39:01.694902755 +0200
++++ cryptsetup-1.7.4/lib/utils.c	2017-10-18 11:48:16.584868357 +0200
+@@ -252,21 +252,21 @@ ssize_t write_lseek_blockwise(int fd, in
+ 		if (!frontPadBuf)
+ 			goto out;
+ 
+-		r = read_buffer(fd, frontPadBuf, bsize);
+-		if (r < 0 || r != bsize)
+-			goto out;
+-
+ 		innerCount = bsize - frontHang;
+ 		if (innerCount > count)
+ 			innerCount = count;
+ 
++		r = read_buffer(fd, frontPadBuf, bsize);
++		if (r < (frontHang + innerCount))
++			goto out;
++
+ 		memcpy(frontPadBuf + frontHang, buf, innerCount);
+ 
+ 		if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
+ 			goto out;
+ 
+-		r = write_buffer(fd, frontPadBuf, bsize);
+-		if (r < 0 || r != bsize)
++		r = write_buffer(fd, frontPadBuf, frontHang + innerCount);
++		if (r != (frontHang + innerCount))
+ 			goto out;
+ 
+ 		buf = (char*)buf + innerCount;
+@@ -311,14 +311,14 @@ ssize_t read_lseek_blockwise(int fd, int
+ 		if (!frontPadBuf)
+ 			return ret;
+ 
+-		r = read_buffer(fd, frontPadBuf, bsize);
+-		if (r < 0 || r != bsize)
+-			goto out;
+-
+ 		innerCount = bsize - frontHang;
+ 		if (innerCount > count)
+ 			innerCount = count;
+ 
++		r = read_buffer(fd, frontPadBuf, bsize);
++		if (r < (frontHang + innerCount))
++			goto out;
++
+ 		memcpy(buf, frontPadBuf + frontHang, innerCount);
+ 
+ 		buf = (char*)buf + innerCount;
diff --git a/SOURCES/cryptsetup-2.0.4-add-blkid-utilities-for-fast-detection-of-device-sig.patch b/SOURCES/cryptsetup-2.0.4-add-blkid-utilities-for-fast-detection-of-device-sig.patch
new file mode 100644
index 0000000..16a3ed6
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-add-blkid-utilities-for-fast-detection-of-device-sig.patch
@@ -0,0 +1,306 @@
+From 12d00da84239c3dcc4560dc60a0c36d534908cc0 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Wed, 4 Jul 2018 15:39:11 +0200
+Subject: [PATCH 1/6] Add blkid utilities for fast detection of device
+ signatures.
+
+---
+ configure.ac      |  21 ++++++++
+ lib/Makemodule.am |   5 +-
+ lib/utils_blkid.c | 158 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ lib/utils_blkid.h |  48 +++++++++++++++++
+ 4 files changed, 231 insertions(+), 1 deletion(-)
+ create mode 100644 lib/utils_blkid.c
+ create mode 100644 lib/utils_blkid.h
+
+diff --git a/configure.ac b/configure.ac
+index 05da6d6..31508d0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -415,6 +415,26 @@ if test x$enable_internal_argon2 = xyes ; then
+ fi
+ AM_CONDITIONAL(CRYPTO_INTERNAL_ARGON2, test x$enable_internal_argon2 = xyes)
+ 
++dnl Link with blkid to check for other device types
++AC_ARG_ENABLE(blkid, AS_HELP_STRING([--disable-blkid],
++	[disable use of blkid for device signature detection and wiping.]), [], [enable_blkid=yes])
++
++if test x$enable_blkid = xyes ; then
++	PKG_CHECK_MODULES([BLKID], [blkid],[AC_DEFINE([HAVE_BLKID], 1, [Define to 1 to use blkid for detection of disk signatures.])],[LIBBLKID_LIBS="-lblkid"])
++
++	AC_CHECK_HEADERS(blkid/blkid.h,,[AC_MSG_ERROR([You need blkid development library installed.])])
++	AC_CHECK_DECLS([ blkid_reset_probe,
++			 blkid_probe_set_device,
++			 blkid_probe_filter_superblocks_type,
++			 blkid_do_safeprobe,
++			 blkid_do_probe,
++			 blkid_probe_lookup_value
++		       ],,
++		       [AC_MSG_ERROR([Can not compile with blkid support, disable it by --disable-blkid.])],
++		       [#include <blkid/blkid.h>])
++fi
++AM_CONDITIONAL(HAVE_BLKID, test x$enable_blkid = xyes)
++
+ dnl Magic for cryptsetup.static build.
+ if test x$enable_static_cryptsetup = xyes; then
+ 	saved_PKG_CONFIG=$PKG_CONFIG
+@@ -465,6 +485,7 @@ AC_SUBST([CRYPTO_STATIC_LIBS])
+ 
+ AC_SUBST([JSON_C_LIBS])
+ AC_SUBST([LIBARGON2_LIBS])
++AC_SUBST([BLKID_LIBS])
+ 
+ AC_SUBST([LIBCRYPTSETUP_VERSION])
+ AC_SUBST([LIBCRYPTSETUP_VERSION_INFO])
+diff --git a/lib/Makemodule.am b/lib/Makemodule.am
+index 5e20039..26178b8 100644
+--- a/lib/Makemodule.am
++++ b/lib/Makemodule.am
+@@ -30,6 +30,7 @@ libcryptsetup_la_LIBADD = \
+ 	@CRYPTO_LIBS@		\
+ 	@LIBARGON2_LIBS@	\
+ 	@JSON_C_LIBS@		\
++	@BLKID_LIBS@		\
+ 	libcrypto_backend.la
+ 
+ libcryptsetup_la_SOURCES = \
+@@ -92,4 +93,6 @@ libcryptsetup_la_SOURCES = \
+ 	lib/luks2/luks2_token_keyring.c	\
+ 	lib/luks2/luks2_token.c		\
+ 	lib/luks2/luks2_internal.h	\
+-	lib/luks2/luks2.h
++	lib/luks2/luks2.h		\
++	lib/utils_blkid.c		\
++	lib/utils_blkid.h
+diff --git a/lib/utils_blkid.c b/lib/utils_blkid.c
+new file mode 100644
+index 0000000..7425bc5
+--- /dev/null
++++ b/lib/utils_blkid.c
+@@ -0,0 +1,158 @@
++/*
++ * blkid probe utilities
++ *
++ * Copyright (C) 2018, Red Hat, Inc. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "utils_blkid.h"
++
++#ifdef HAVE_BLKID
++#include <blkid/blkid.h>
++struct blkid_handle {
++	int fd;
++	blkid_probe pr;
++};
++#endif
++
++void blk_set_chains_for_fast_detection(struct blkid_handle *h)
++{
++#ifdef HAVE_BLKID
++	blkid_probe_enable_partitions(h->pr, 1);
++	blkid_probe_set_partitions_flags(h->pr, 0);
++
++	blkid_probe_enable_superblocks(h->pr, 1);
++	blkid_probe_set_superblocks_flags(h->pr, BLKID_SUBLKS_TYPE);
++#endif
++}
++
++int blk_init_by_path(struct blkid_handle **h, const char *path)
++{
++	int r = -ENOTSUP;
++#ifdef HAVE_BLKID
++	struct blkid_handle *tmp = malloc(sizeof(*tmp));
++	if (!tmp)
++		return -ENOMEM;
++
++	tmp->fd = -1;
++
++	tmp->pr = blkid_new_probe_from_filename(path);
++	if (!tmp->pr) {
++		free(tmp);
++		return -EINVAL;
++	}
++
++	*h = tmp;
++
++	r = 0;
++#endif
++	return r;
++}
++
++int blk_superblocks_filter_luks(struct blkid_handle *h)
++{
++	int r = -ENOTSUP;
++#ifdef HAVE_BLKID
++	char *luks_filter[] = {
++		"crypto_LUKS",
++		NULL
++	};
++	r = blkid_probe_filter_superblocks_type(h->pr, BLKID_FLTR_NOTIN, luks_filter);
++#endif
++	return r;
++}
++
++blk_probe_status blk_safeprobe(struct blkid_handle *h)
++{
++	int r = -1;
++#ifdef HAVE_BLKID
++	r = blkid_do_safeprobe(h->pr);
++#endif
++	switch (r) {
++	case -2:
++		return PRB_AMBIGUOUS;
++	case 1:
++		return PRB_EMPTY;
++	case 0:
++		return PRB_OK;
++	default:
++		return PRB_FAIL;
++	}
++}
++
++int blk_is_partition(struct blkid_handle *h)
++{
++	int r = 0;
++#ifdef HAVE_BLKID
++	r = blkid_probe_has_value(h->pr, "PTTYPE");
++#endif
++	return r;
++}
++
++int blk_is_superblock(struct blkid_handle *h)
++{
++	int r = 0;
++#ifdef HAVE_BLKID
++	r = blkid_probe_has_value(h->pr, "TYPE");
++#endif
++	return r;
++}
++
++const char *blk_get_partition_type(struct blkid_handle *h)
++{
++	const char *value = NULL;
++#ifdef HAVE_BLKID
++	(void) blkid_probe_lookup_value(h->pr, "PTTYPE", &value, NULL);
++#endif
++	return value;
++}
++
++const char *blk_get_superblock_type(struct blkid_handle *h)
++{
++	const char *value = NULL;
++#ifdef HAVE_BLKID
++	(void) blkid_probe_lookup_value(h->pr, "TYPE", &value, NULL);
++#endif
++	return value;
++}
++
++void blk_free(struct blkid_handle *h)
++{
++#ifdef HAVE_BLKID
++	if (!h)
++		return;
++
++	if (h->pr)
++		blkid_free_probe(h->pr);
++
++	free(h);
++#endif
++}
++
++int blk_supported(void)
++{
++	int r = 0;
++#ifdef HAVE_BLKID
++	r = 1;
++#endif
++	return r;
++}
+diff --git a/lib/utils_blkid.h b/lib/utils_blkid.h
+new file mode 100644
+index 0000000..d18b0a0
+--- /dev/null
++++ b/lib/utils_blkid.h
+@@ -0,0 +1,48 @@
++/*
++ * blkid probe utilities
++ *
++ * Copyright (C) 2018, Red Hat, Inc. All rights reserved.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version 2
++ * of the License, or (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#ifndef _UTILS_BLKID_H
++#define _UTILS_BLKID_H
++
++struct blkid_handle;
++
++typedef enum { PRB_OK = 0, PRB_EMPTY, PRB_AMBIGUOUS, PRB_FAIL } blk_probe_status;
++
++int blk_init_by_path(struct blkid_handle **h, const char *path);
++
++void blk_free(struct blkid_handle *h);
++
++void blk_set_chains_for_fast_detection(struct blkid_handle *h);
++
++int blk_superblocks_filter_luks(struct blkid_handle *h);
++
++blk_probe_status blk_safeprobe(struct blkid_handle *h);
++
++int blk_is_partition(struct blkid_handle *h);
++
++int blk_is_superblock(struct blkid_handle *h);
++
++const char *blk_get_partition_type(struct blkid_handle *h);
++
++const char *blk_get_superblock_type(struct blkid_handle *h);
++
++int blk_supported(void);
++
++#endif
+-- 
+1.8.3.1
+
+--- cryptsetup-2.0.3.old/aclocal.m4	2018-05-03 21:36:53.000000000 +0200
++++ cryptsetup-2.0.3/aclocal.m4	2018-07-16 15:37:34.935817650 +0200
+@@ -31,7 +31,7 @@ To do so, use the procedure documented b
+ # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
+ # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ #
+-# Last-changed: 2014-10-02
++# Last-changed: 2018-07-16
+ 
+ 
+ dnl AM_PATH_LIBGCRYPT([MINIMUM-VERSION,
diff --git a/SOURCES/cryptsetup-2.0.4-allow-LUKS2-repair-to-override-blkid-checks.patch b/SOURCES/cryptsetup-2.0.4-allow-LUKS2-repair-to-override-blkid-checks.patch
new file mode 100644
index 0000000..31737aa
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-allow-LUKS2-repair-to-override-blkid-checks.patch
@@ -0,0 +1,131 @@
+From b82eaf14f7a01cfd542cb95fe97b8d3a22d5ba8f Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Thu, 28 Jun 2018 15:48:13 +0200
+Subject: [PATCH 3/6] Allow LUKS2 repair to override blkid checks.
+
+Allow user to run cryptsetup repair command and explicitly do
+repair on corrupted LUKS2 headers where blkid decides it's no longer
+a LUKS2 device.
+---
+ lib/luks2/luks2.h               |  2 +-
+ lib/luks2/luks2_json_metadata.c | 13 +++++++------
+ lib/setup.c                     | 10 +++++-----
+ 3 files changed, 13 insertions(+), 12 deletions(-)
+
+diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h
+index ee57b41..c431e8f 100644
+--- a/lib/luks2/luks2.h
++++ b/lib/luks2/luks2.h
+@@ -131,7 +131,7 @@ struct luks2_keyslot_params {
+ int LUKS2_hdr_version_unlocked(struct crypt_device *cd,
+ 	const char *backup_file);
+ 
+-int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr);
++int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair);
+ int LUKS2_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr);
+ int LUKS2_hdr_dump(struct crypt_device *cd, struct luks2_hdr *hdr);
+ 
+diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c
+index 125cad9..0fd6340 100644
+--- a/lib/luks2/luks2_json_metadata.c
++++ b/lib/luks2/luks2_json_metadata.c
+@@ -842,7 +842,8 @@ int LUKS2_hdr_validate(json_object *hdr_jobj)
+ 	return 0;
+ }
+ 
+-int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
++/* FIXME: should we expose do_recovery parameter explicitly? */
++int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr, int repair)
+ {
+ 	int r;
+ 
+@@ -853,7 +854,7 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
+ 		return r;
+ 	}
+ 
+-	r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, 1);
++	r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, !repair);
+ 	if (r == -EAGAIN) {
+ 		/* unlikely: auto-recovery is required and failed due to read lock being held */
+ 		device_read_unlock(crypt_metadata_device(cd));
+@@ -865,7 +866,7 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
+ 			return r;
+ 		}
+ 
+-		r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, 1);
++		r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, !repair);
+ 
+ 		device_write_unlock(crypt_metadata_device(cd));
+ 	} else
+@@ -1050,7 +1051,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
+ 		return r;
+ 	}
+ 
+-	r = LUKS2_disk_hdr_read(cd, &hdr_file, backup_device, 0);
++	r = LUKS2_disk_hdr_read(cd, &hdr_file, backup_device, 0, 0);
+ 	device_read_unlock(backup_device);
+ 	device_free(backup_device);
+ 
+@@ -1089,7 +1090,7 @@ int LUKS2_hdr_restore(struct crypt_device *cd, struct luks2_hdr *hdr,
+ 	close(devfd);
+ 	devfd = -1;
+ 
+-	r = LUKS2_hdr_read(cd, &tmp_hdr);
++	r = LUKS2_hdr_read(cd, &tmp_hdr, 0);
+ 	if (r == 0) {
+ 		log_dbg("Device %s already contains LUKS2 header, checking UUID and requirements.", device_path(device));
+ 		r = LUKS2_config_get_requirements(cd, &tmp_hdr, &reqs);
+@@ -1176,7 +1177,7 @@ out:
+ 
+ 	if (!r) {
+ 		LUKS2_hdr_free(hdr);
+-		r = LUKS2_hdr_read(cd, hdr);
++		r = LUKS2_hdr_read(cd, hdr, 1);
+ 	}
+ 
+ 	return r;
+diff --git a/lib/setup.c b/lib/setup.c
+index fddbe7e..a9b2eba 100644
+--- a/lib/setup.c
++++ b/lib/setup.c
+@@ -644,16 +644,16 @@ struct crypt_pbkdf_type *crypt_get_pbkdf(struct crypt_device *cd)
+ /*
+  * crypt_load() helpers
+  */
+-static int _crypt_load_luks2(struct crypt_device *cd, int reload)
++static int _crypt_load_luks2(struct crypt_device *cd, int reload, int repair)
+ {
+ 	int r;
+ 	char tmp_cipher[MAX_CIPHER_LEN], tmp_cipher_mode[MAX_CIPHER_LEN],
+ 	     *cipher = NULL, *cipher_mode = NULL, *type = NULL;
+ 	struct luks2_hdr hdr2 = {};
+ 
+-	log_dbg("%soading LUKS2 header.", reload ? "Rel" : "L");
++	log_dbg("%soading LUKS2 header (repair %sabled).", reload ? "Rel" : "L", repair ? "en" : "dis");
+ 
+-	r = LUKS2_hdr_read(cd, &hdr2);
++	r = LUKS2_hdr_read(cd, &hdr2, repair);
+ 	if (r)
+ 		return r;
+ 
+@@ -713,7 +713,7 @@ static void _luks2_reload(struct crypt_device *cd)
+ 	if (!cd || !isLUKS2(cd->type))
+ 		return;
+ 
+-	(void) _crypt_load_luks2(cd, 1);
++	(void) _crypt_load_luks2(cd, 1, 0);
+ }
+ 
+ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
+@@ -768,7 +768,7 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
+ 			return -EINVAL;
+ 		}
+ 
+-		r =  _crypt_load_luks2(cd, cd->type != NULL);
++		r =  _crypt_load_luks2(cd, cd->type != NULL, repair);
+ 	} else
+ 		r = -EINVAL;
+ out:
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-allow-LUKS2-repair-with-disabled-locks.patch b/SOURCES/cryptsetup-2.0.4-allow-LUKS2-repair-with-disabled-locks.patch
new file mode 100644
index 0000000..a5d5258
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-allow-LUKS2-repair-with-disabled-locks.patch
@@ -0,0 +1,26 @@
+From c6dc8dd86c797b982d47ebb918367b4575d59dad Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Mon, 9 Jul 2018 18:43:02 +0200
+Subject: [PATCH 6/6] Allow LUKS2 repair with disabled locks.
+
+---
+ lib/luks2/luks2_disk_metadata.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/lib/luks2/luks2_disk_metadata.c b/lib/luks2/luks2_disk_metadata.c
+index 6ca9d5e..bd5223f 100644
+--- a/lib/luks2/luks2_disk_metadata.c
++++ b/lib/luks2/luks2_disk_metadata.c
+@@ -592,7 +592,8 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
+ 	int i, r;
+ 	uint64_t hdr_size;
+ 
+-	if (do_recovery && !crypt_metadata_locking_enabled()) {
++	/* Skip auto-recovery if locks are disabled and we're not doing LUKS2 explicit repair */
++	if (do_recovery && do_blkprobe && !crypt_metadata_locking_enabled()) {
+ 		do_recovery = 0;
+ 		log_dbg("Disabling header auto-recovery due to locking being disabled.");
+ 	}
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-allow-explicit-LUKS2-repair.patch b/SOURCES/cryptsetup-2.0.4-allow-explicit-LUKS2-repair.patch
new file mode 100644
index 0000000..5dc1782
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-allow-explicit-LUKS2-repair.patch
@@ -0,0 +1,44 @@
+From 4b3b6b07ad42ebab346f0fe343aab2a14cd5a9da Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Mon, 9 Jul 2018 17:18:17 +0200
+Subject: [PATCH 4/6] Allow explicit LUKS2 repair.
+
+Also moves FIXME comment lower to LUKS2 code with note that currently it's
+safe to do crypt_repair on LUKS2 format without paying attention to LUKS2
+requirements.
+---
+ lib/setup.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+diff --git a/lib/setup.c b/lib/setup.c
+index a9b2eba..952fa0e 100644
+--- a/lib/setup.c
++++ b/lib/setup.c
+@@ -768,6 +768,14 @@ static int _crypt_load_luks(struct crypt_device *cd, const char *requested_type,
+ 			return -EINVAL;
+ 		}
+ 
++		/*
++		 * Current LUKS2 repair just overrides blkid probes
++		 * and perform auto-recovery if possible. This is safe
++		 * unless future LUKS2 repair code do something more
++		 * sophisticated. In such case we would need to check
++		 * for LUKS2 requirements and decide if it's safe to
++		 * perform repair.
++		 */
+ 		r =  _crypt_load_luks2(cd, cd->type != NULL, repair);
+ 	} else
+ 		r = -EINVAL;
+@@ -2023,8 +2031,7 @@ int crypt_repair(struct crypt_device *cd,
+ 	if (!crypt_metadata_device(cd))
+ 		return -EINVAL;
+ 
+-	/* FIXME LUKS2 (if so it also must respect LUKS2 requirements) */
+-	if (requested_type && !isLUKS1(requested_type))
++	if (requested_type && !isLUKS(requested_type))
+ 		return -EINVAL;
+ 
+ 	/* Load with repair */
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-dracut-reencrypt.patch b/SOURCES/cryptsetup-2.0.4-dracut-reencrypt.patch
new file mode 100644
index 0000000..abca3a3
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-dracut-reencrypt.patch
@@ -0,0 +1,106 @@
+From 1b9148f12f85f326cb8127665ecfc2136c9822d5 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Wed, 18 Oct 2017 09:57:03 +0200
+Subject: [PATCH] dracut-reencrypt: add --progress-frequency parameter
+
+---
+ misc/dracut_90reencrypt/reencrypt.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/misc/dracut_90reencrypt/reencrypt.sh b/misc/dracut_90reencrypt/reencrypt.sh
+index e6f87e0..b4960d7 100755
+--- a/misc/dracut_90reencrypt/reencrypt.sh
++++ b/misc/dracut_90reencrypt/reencrypt.sh
+@@ -18,7 +18,7 @@ else
+     device="$1"
+ fi
+ 
+-PARAMS="$device -T 1 --use-fsync -B 32"
++PARAMS="$device -T 1 --use-fsync --progress-frequency 5 -B 32"
+ if [ "$3" != "any" ]; then
+     PARAMS="$PARAMS -S $3"
+ fi
+-- 
+1.8.3.1
+
+From cda0a8ac7f30f120cdf5fadf16484715e8f9a040 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Thu, 19 Jul 2018 17:33:58 +0200
+Subject: [PATCH 2/2] Indicate running in initrd phase.
+
+---
+ misc/dracut_90reencrypt/reencrypt.sh | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/misc/dracut_90reencrypt/reencrypt.sh b/misc/dracut_90reencrypt/reencrypt.sh
+index e6f87e0..24c7716 100755
+--- a/misc/dracut_90reencrypt/reencrypt.sh
++++ b/misc/dracut_90reencrypt/reencrypt.sh
+@@ -11,6 +11,8 @@
+ 
+ . /lib/dracut-lib.sh
+ 
++export CRYPT_REENCRYPT_IN_INITRD=1
++
+ # if device name is /dev/dm-X, convert to /dev/mapper/name
+ if [ "${1##/dev/dm-}" != "$1" ]; then
+     device="/dev/mapper/$(dmsetup info -c --noheadings -o name "$1")"
+-- 
+1.8.3.1
+
+From 5da5e7f095e09c9501179864f6a20293dd9cada5 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Mon, 16 Jul 2018 17:17:45 +0200
+Subject: [PATCH] Redirect stdout to stderr during reencryption in initrd.
+
+Stdout is not printed in initrd unless user invokes debug mode.
+It's inconvenient to have users waiting for reencryption to
+finish with no input at all.
+---
+ misc/dracut_90reencrypt/module-setup.sh      | 1 +
+ misc/dracut_90reencrypt/reencrypt-verbose.sh | 5 +++++
+ misc/dracut_90reencrypt/reencrypt.sh         | 4 ++--
+ 3 files changed, 8 insertions(+), 2 deletions(-)
+ create mode 100755 misc/dracut_90reencrypt/reencrypt-verbose.sh
+
+diff --git a/misc/dracut_90reencrypt/module-setup.sh b/misc/dracut_90reencrypt/module-setup.sh
+index 2ec9953..fcd7c92 100755
+--- a/misc/dracut_90reencrypt/module-setup.sh
++++ b/misc/dracut_90reencrypt/module-setup.sh
+@@ -28,4 +28,5 @@ install() {
+     # shellcheck disable=SC2154
+     inst_hook cmdline 30 "$moddir/parse-reencrypt.sh"
+     inst_simple "$moddir"/reencrypt.sh /sbin/reencrypt
++    inst_simple "$moddir"/reencrypt-verbose.sh /sbin/cryptsetup-reencrypt-verbose
+ }
+diff --git a/misc/dracut_90reencrypt/reencrypt-verbose.sh b/misc/dracut_90reencrypt/reencrypt-verbose.sh
+new file mode 100755
+index 0000000..5db75d5
+--- /dev/null
++++ b/misc/dracut_90reencrypt/reencrypt-verbose.sh
+@@ -0,0 +1,5 @@
++#!/bin/sh
++
++# Route stdout to stderr in initrd. Otherwise output is invisible
++# unless we run in debug mode.
++/sbin/cryptsetup-reencrypt $@ 1>&2
+diff --git a/misc/dracut_90reencrypt/reencrypt.sh b/misc/dracut_90reencrypt/reencrypt.sh
+index b4960d7..4243773 100755
+--- a/misc/dracut_90reencrypt/reencrypt.sh
++++ b/misc/dracut_90reencrypt/reencrypt.sh
+@@ -50,10 +50,10 @@ reenc_run() {
+ 	fi
+         /bin/plymouth ask-for-password \
+         --prompt "$_prompt" \
+-        --command="/sbin/cryptsetup-reencrypt $PARAMS"
++        --command="/sbin/cryptsetup-reencrypt-verbose $PARAMS"
+     else
+         info "REENCRYPT using key $1"
+-        reenc_readkey "$1" | /sbin/cryptsetup-reencrypt -d - $PARAMS
++        reenc_readkey "$1" | /sbin/cryptsetup-reencrypt-verbose -d - $PARAMS
+     fi
+     _ret=$?
+     cd $cwd
+-- 
+1.8.3.1
+
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.4-fix-write_blockwise-on-short-files.patch b/SOURCES/cryptsetup-2.0.4-fix-write_blockwise-on-short-files.patch
new file mode 100644
index 0000000..8821a14
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-fix-write_blockwise-on-short-files.patch
@@ -0,0 +1,40 @@
+From 63d66e7a3356da4bca77f521fd93df7cdf09b41a Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Tue, 19 Jun 2018 15:10:33 +0200
+Subject: [PATCH 3/4] Fix write_blockwise on short files.
+
+see unit test write_blockwise(length=2097153, bsize=4096), on x86
+with original test file size=2097152.
+
+The test is trying to write_blockwise 1 more byte than actual file
+size.
+---
+ lib/utils_io.c | 8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+diff --git a/lib/utils_io.c b/lib/utils_io.c
+index 8336b18..e0c2381 100644
+--- a/lib/utils_io.c
++++ b/lib/utils_io.c
+@@ -105,15 +105,13 @@ ssize_t write_blockwise(int fd, size_t bsize, size_t alignment,
+ 	if (hangover) {
+ 		if (posix_memalign(&hangover_buf, alignment, bsize))
+ 			goto out;
++		memset(hangover_buf, 0, bsize);
+ 
+ 		r = read_buffer(fd, hangover_buf, bsize);
+-		if (r < 0 || r < (ssize_t)hangover)
++		if (r < 0)
+ 			goto out;
+ 
+-		if (r < (ssize_t)bsize)
+-			bsize = r;
+-
+-		if (lseek(fd, -(off_t)bsize, SEEK_CUR) < 0)
++		if (lseek(fd, -(off_t)r, SEEK_CUR) < 0)
+ 			goto out;
+ 
+ 		memcpy(hangover_buf, (char*)buf + solid, hangover);
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-fix-write_lseek_blockwise-for-in-the-middle-of-secto.patch b/SOURCES/cryptsetup-2.0.4-fix-write_lseek_blockwise-for-in-the-middle-of-secto.patch
new file mode 100644
index 0000000..92f889b
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-fix-write_lseek_blockwise-for-in-the-middle-of-secto.patch
@@ -0,0 +1,32 @@
+From 6392be68c4d481148e20dbc2a8380cc246f27ad1 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Tue, 19 Jun 2018 14:45:45 +0200
+Subject: [PATCH 2/4] Fix write_lseek_blockwise for in the middle of sector
+ case.
+
+See unit test write_lseek_blockwise(bsize=512, offset=1, length=1).
+
+The test tries to modify single byte at offset 1 of device with
+bsize=512.
+---
+ lib/utils_io.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/utils_io.c b/lib/utils_io.c
+index 94c4ef6..8336b18 100644
+--- a/lib/utils_io.c
++++ b/lib/utils_io.c
+@@ -216,8 +216,8 @@ ssize_t write_lseek_blockwise(int fd, size_t bsize, size_t alignment,
+ 		if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
+ 			goto out;
+ 
+-		r = write_buffer(fd, frontPadBuf, frontHang + innerCount);
+-		if (r < 0 || r != (ssize_t)(frontHang + innerCount))
++		r = write_buffer(fd, frontPadBuf, bsize);
++		if (r < 0 || r != (ssize_t)bsize)
+ 			goto out;
+ 
+ 		buf = (char*)buf + innerCount;
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-make-LUKS2-auto-recovery-aware-of-device-signatures.patch b/SOURCES/cryptsetup-2.0.4-make-LUKS2-auto-recovery-aware-of-device-signatures.patch
new file mode 100644
index 0000000..c472424
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-make-LUKS2-auto-recovery-aware-of-device-signatures.patch
@@ -0,0 +1,164 @@
+From 078ed81d14904f48a6237646050ba5eb74d702b7 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Wed, 4 Jul 2018 15:58:09 +0200
+Subject: [PATCH 2/6] Make LUKS2 auto-recovery aware of device signatures.
+
+auto-recovery triggers any time when only single correct LUKS2
+header instance was found. That may be dangerous.
+
+We should suppress auto-recovery in case blkid decided the
+device is no longer LUKS device. For example if secondary (intact)
+LUKS2 header was left behind and blkid declares the device is LVM2
+member.
+
+Moreover if at least one header instance is corrupted and blkid
+declares device non-empty and non-LUKS in the same time, header load
+operation will be aborted with error.
+---
+ lib/internal.h                  |  1 +
+ lib/luks2/luks2_disk_metadata.c | 61 ++++++++++++++++++++++++++++++++++++++++-
+ lib/luks2/luks2_internal.h      |  2 +-
+ lib/luks2/luks2_json_metadata.c |  4 +--
+ 4 files changed, 64 insertions(+), 4 deletions(-)
+
+diff --git a/lib/internal.h b/lib/internal.h
+index 07a1a08..e6d2323 100644
+--- a/lib/internal.h
++++ b/lib/internal.h
+@@ -32,6 +32,7 @@
+ 
+ #include "nls.h"
+ #include "bitops.h"
++#include "utils_blkid.h"
+ #include "utils_crypt.h"
+ #include "utils_loop.h"
+ #include "utils_dm.h"
+diff --git a/lib/luks2/luks2_disk_metadata.c b/lib/luks2/luks2_disk_metadata.c
+index 4d9bce2..6ca9d5e 100644
+--- a/lib/luks2/luks2_disk_metadata.c
++++ b/lib/luks2/luks2_disk_metadata.c
+@@ -531,12 +531,59 @@ static json_object *parse_and_validate_json(const char *json_area, int length)
+ 	return jobj;
+ }
+ 
++static int detect_device_signatures(const char *path)
++{
++	blk_probe_status prb_state;
++	int r;
++	struct blkid_handle *h;
++
++	if (!blk_supported()) {
++		log_dbg("Blkid probing of device signatures disabled.");
++		return 0;
++	}
++
++	if ((r = blk_init_by_path(&h, path))) {
++		log_dbg("Failed to initialize blkid_handle by path.");
++		return -EINVAL;
++	}
++
++	/* We don't care about details. Be fast. */
++	blk_set_chains_for_fast_detection(h);
++
++	/* Filter out crypto_LUKS. we don't care now */
++	blk_superblocks_filter_luks(h);
++
++	prb_state = blk_safeprobe(h);
++
++	switch (prb_state) {
++	case PRB_AMBIGUOUS:
++		log_dbg("Blkid probe couldn't decide device type unambiguously.");
++		/* fall through */
++	case PRB_FAIL:
++		log_dbg("Blkid probe failed.");
++		r = -EINVAL;
++		break;
++	case PRB_OK: /* crypto_LUKS type is filtered out */
++		r = -EINVAL;
++
++		if (blk_is_partition(h))
++			log_dbg("Blkid probe detected partition type '%s'", blk_get_partition_type(h));
++		else if (blk_is_superblock(h))
++			log_dbg("blkid probe detected superblock type '%s'", blk_get_superblock_type(h));
++		break;
++	case PRB_EMPTY:
++		log_dbg("Blkid probe detected no foreign device signature.");
++	}
++	blk_free(h);
++	return r;
++}
++
+ /*
+  * Read and convert on-disk LUKS2 header to in-memory representation..
+  * Try to do recovery if on-disk state is not consistent.
+  */
+ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
+-			struct device *device, int do_recovery)
++			struct device *device, int do_recovery, int do_blkprobe)
+ {
+ 	enum { HDR_OK, HDR_OBSOLETE, HDR_FAIL, HDR_FAIL_IO } state_hdr1, state_hdr2;
+ 	struct luks2_hdr_disk hdr_disk1, hdr_disk2;
+@@ -616,6 +663,12 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
+ 	if (state_hdr1 == HDR_OK && state_hdr2 != HDR_OK) {
+ 		log_dbg("Secondary LUKS2 header requires recovery.");
+ 
++		if (do_blkprobe && (r = detect_device_signatures(device_path(device)))) {
++			log_err(cd, _("Device contains ambiguous signatures, cannot auto-recover LUKS2.\n"
++				      "Please run \"cryptsetup repair\" for recovery."));
++			goto err;
++		}
++
+ 		if (do_recovery) {
+ 			memcpy(&hdr_disk2, &hdr_disk1, LUKS2_HDR_BIN_LEN);
+ 			r = crypt_random_get(NULL, (char*)hdr_disk2.salt, sizeof(hdr_disk2.salt), CRYPT_RND_SALT);
+@@ -631,6 +684,12 @@ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
+ 	} else if (state_hdr1 != HDR_OK && state_hdr2 == HDR_OK) {
+ 		log_dbg("Primary LUKS2 header requires recovery.");
+ 
++		if (do_blkprobe && (r = detect_device_signatures(device_path(device)))) {
++			log_err(cd, _("Device contains ambiguous signatures, cannot auto-recover LUKS2.\n"
++				      "Please run \"cryptsetup repair\" for recovery."));
++			goto err;
++		}
++
+ 		if (do_recovery) {
+ 			memcpy(&hdr_disk1, &hdr_disk2, LUKS2_HDR_BIN_LEN);
+ 			r = crypt_random_get(NULL, (char*)hdr_disk1.salt, sizeof(hdr_disk1.salt), CRYPT_RND_SALT);
+diff --git a/lib/luks2/luks2_internal.h b/lib/luks2/luks2_internal.h
+index e9beab8..dcabed7 100644
+--- a/lib/luks2/luks2_internal.h
++++ b/lib/luks2/luks2_internal.h
+@@ -42,7 +42,7 @@
+  * On-disk access function prototypes
+  */
+ int LUKS2_disk_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr,
+-			struct device *device, int do_recovery);
++			struct device *device, int do_recovery, int do_blkprobe);
+ int LUKS2_disk_hdr_write(struct crypt_device *cd, struct luks2_hdr *hdr,
+ 			 struct device *device);
+ 
+diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c
+index 362388e..125cad9 100644
+--- a/lib/luks2/luks2_json_metadata.c
++++ b/lib/luks2/luks2_json_metadata.c
+@@ -853,7 +853,7 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
+ 		return r;
+ 	}
+ 
+-	r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1);
++	r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, 1);
+ 	if (r == -EAGAIN) {
+ 		/* unlikely: auto-recovery is required and failed due to read lock being held */
+ 		device_read_unlock(crypt_metadata_device(cd));
+@@ -865,7 +865,7 @@ int LUKS2_hdr_read(struct crypt_device *cd, struct luks2_hdr *hdr)
+ 			return r;
+ 		}
+ 
+-		r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1);
++		r = LUKS2_disk_hdr_read(cd, hdr, crypt_metadata_device(cd), 1, 1);
+ 
+ 		device_write_unlock(crypt_metadata_device(cd));
+ 	} else
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-rephrase-error-message-for-invalid-type-param-in-con.patch b/SOURCES/cryptsetup-2.0.4-rephrase-error-message-for-invalid-type-param-in-con.patch
new file mode 100644
index 0000000..6c34ab8
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-rephrase-error-message-for-invalid-type-param-in-con.patch
@@ -0,0 +1,25 @@
+From b60e856087db77abbc5aa62a7f980e62b8b75029 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Tue, 17 Jul 2018 10:53:13 +0200
+Subject: [PATCH] Rephrase error message for invalid --type param in convert.
+
+---
+ src/cryptsetup.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/cryptsetup.c b/src/cryptsetup.c
+index fc3481d..5f8df37 100644
+--- a/src/cryptsetup.c
++++ b/src/cryptsetup.c
+@@ -1851,7 +1851,7 @@ static int action_luksConvert(void)
+ 	} else if (!strcmp(opt_type, "luks1")) {
+ 		to_type = CRYPT_LUKS1;
+ 	} else {
+-		log_err(_("Missing LUKS target type, option --type is required."));
++		log_err(_("Invalid LUKS type, only luks1 and luks2 are supported."));
+ 		return -EINVAL;
+ 	}
+ 
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-update-crypt_repair-API-documentation-for-LUKS2.patch b/SOURCES/cryptsetup-2.0.4-update-crypt_repair-API-documentation-for-LUKS2.patch
new file mode 100644
index 0000000..a2f9d2e
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-update-crypt_repair-API-documentation-for-LUKS2.patch
@@ -0,0 +1,40 @@
+From 167da99eaa9708289492e8fca2ebe4964cf5baa7 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Mon, 9 Jul 2018 17:27:55 +0200
+Subject: [PATCH 5/6] Update crypt_repair API documentation for LUKS2.
+
+---
+ lib/libcryptsetup.h | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h
+index 0a7ebdb..2d959fa 100644
+--- a/lib/libcryptsetup.h
++++ b/lib/libcryptsetup.h
+@@ -624,7 +624,7 @@ int crypt_load(struct crypt_device *cd,
+ 	void *params);
+ 
+ /**
+- * Try to repair crypt device LUKS1 on-disk header if invalid.
++ * Try to repair crypt device LUKS on-disk header if invalid.
+  *
+  * @param cd crypt device handle
+  * @param requested_type @link crypt-type @endlink or @e NULL for all known
+@@ -632,9 +632,11 @@ int crypt_load(struct crypt_device *cd,
+  *
+  * @returns 0 on success or negative errno value otherwise.
+  *
+- * @note Does not support LUKS2 devices explicitly. LUKS2 header is auto-repaired
+- *	 (if exactly one header checksum does not match) automatically on
+- *	 crypt_load().
++ * @note For LUKS2 device crypt_repair bypass blkid checks and
++ * 	 perform auto-recovery even though there're third party device
++ * 	 signatures found by blkid probes. Currently the crypt_repair on LUKS2
++ * 	 works only if exactly one header checksum does not match or exactly
++ * 	 one header is missing.
+  */
+ int crypt_repair(struct crypt_device *cd,
+ 	const char *requested_type,
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-update-cryptsetup-man-page-for-type-option-usage.patch b/SOURCES/cryptsetup-2.0.4-update-cryptsetup-man-page-for-type-option-usage.patch
new file mode 100644
index 0000000..d21d220
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-update-cryptsetup-man-page-for-type-option-usage.patch
@@ -0,0 +1,110 @@
+From 3f0f7acbc0dd72f1d98feb7af214cf12eb9bc47e Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Tue, 10 Jul 2018 14:36:45 +0200
+Subject: [PATCH] Update cryptsetup man page for --type option usage.
+
+Fixes #394.
+---
+ man/cryptsetup.8 | 23 +++++++++++++----------
+ 1 file changed, 13 insertions(+), 10 deletions(-)
+
+diff --git a/man/cryptsetup.8 b/man/cryptsetup.8
+index b2ef8cd..96d4fef 100644
+--- a/man/cryptsetup.8
++++ b/man/cryptsetup.8
+@@ -70,8 +70,8 @@ The following are valid actions for all supported device types.
+ .IP
+ Opens (creates a mapping with) <name> backed by device <device>.
+ 
+-Device type can be \fIplain\fR, \fIluks\fR (default), \fIloopaes\fR
+-or \fItcrypt\fR.
++Device type can be \fIplain\fR, \fIluks\fR (default), \fIluks1\fR, \fIluks2\fR,
++\fIloopaes\fR or \fItcrypt\fR.
+ 
+ For backward compatibility there are \fBopen\fR command aliases:
+ 
+@@ -243,7 +243,7 @@ the command prompts for it interactively.
+ \fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
+ \-\-keyfile\-size, \-\-readonly, \-\-test\-passphrase,
+ \-\-allow\-discards, \-\-header, \-\-key-slot, \-\-master\-key\-file, \-\-token\-id,
+-\-\-token\-only, \-\-disable\-keyring, \-\-disable\-locks].
++\-\-token\-only, \-\-disable\-keyring, \-\-disable\-locks, \-\-type].
+ .PP
+ \fIluksSuspend\fR <name>
+ .IP
+@@ -266,7 +266,7 @@ Resumes a suspended device and reinstates the encryption key.
+ Prompts interactively for a passphrase if \-\-key-file is not given.
+ 
+ \fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-size, \-\-header,
+-\-\-disable\-keyring,\-\-disable\-locks]
++\-\-disable\-keyring, \-\-disable\-locks, \-\-type]
+ .PP
+ \fIluksAddKey\fR <device> [<key file with new key>]
+ .IP
+@@ -285,7 +285,7 @@ is not required.
+ \-\-keyfile\-size, \-\-new\-keyfile\-offset,
+ \-\-new\-keyfile\-size, \-\-key\-slot, \-\-master\-key\-file,
+ \-\-iter\-time, \-\-force\-password, \-\-header, \-\-disable\-locks,
+-\-\-unbound].
++\-\-unbound, \-\-type].
+ .PP
+ \fIluksRemoveKey\fR <device> [<key file with passphrase to be removed>]
+ .IP
+@@ -294,7 +294,7 @@ passphrase to be removed can be specified interactively,
+ as the positional argument or via \-\-key-file.
+ 
+ \fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
+-\-\-keyfile\-size, \-\-header, \-\-disable\-locks]
++\-\-keyfile\-size, \-\-header, \-\-disable\-locks, \-\-type]
+ 
+ \fBWARNING:\fR If you read the passphrase from stdin
+ (without further argument or with '-' as an argument
+@@ -328,7 +328,7 @@ inaccessible.
+ \fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
+ \-\-keyfile\-size, \-\-new\-keyfile\-offset,
+ \-\-new\-keyfile\-size, \-\-key\-slot, \-\-force\-password, \-\-header,
+-\-\-disable\-locks].
++\-\-disable\-locks, \-\-type].
+ .PP
+ .PP
+ \fIluksConvertKey\fR <device>
+@@ -364,7 +364,7 @@ an interactive confirmation when doing so. Removing the last
+ passphrase makes a LUKS container permanently inaccessible.
+ 
+ \fB<options>\fR can be [\-\-key\-file, \-\-keyfile\-offset,
+-\-\-keyfile\-size, \-\-header, \-\-disable\-locks].
++\-\-keyfile\-size, \-\-header, \-\-disable\-locks, \-\-type].
+ 
+ \fBWARNING:\fR If you read the passphrase from stdin
+ (without further argument or with '-' as an argument
+@@ -399,6 +399,8 @@ Set new UUID if \fI\-\-uuid\fR option is specified.
+ Returns true, if <device> is a LUKS device, false otherwise.
+ Use option \-v to get human-readable feedback. 'Command successful.'
+ means the device is a LUKS device.
++
++By specifying \-\-type you may query for specific LUKS version.
+ .PP
+ \fIluksDump\fR <device>
+ .IP
+@@ -417,7 +419,7 @@ either interactively or via \-\-key\-file.
+ 
+ \fB<options>\fR can be [\-\-dump\-master\-key, \-\-key\-file,
+ \-\-keyfile\-offset, \-\-keyfile\-size, \-\-header, \-\-disable\-locks,
+-\-\-master\-key\-file].
++\-\-master\-key\-file, \-\-type].
+ 
+ \fBWARNING:\fR If \-\-dump\-master\-key is used with \-\-key\-file
+ and the argument to \-\-key\-file is '-', no validation question
+@@ -663,7 +665,8 @@ for LUKS device type.
+ This command is useful to fix some known benign LUKS metadata
+ header corruptions. Only basic corruptions of unused keyslot
+ are fixable. This command will only change the LUKS header, not
+-any key-slot data.
++any key-slot data. You may enforce LUKS version by adding \-\-type
++option.
+ 
+ \fBWARNING:\fR Always create a binary backup of the original
+ header before calling this command.
+-- 
+1.8.3.1
+
diff --git a/SOURCES/cryptsetup-2.0.4-zero-length-lseek-blockwise-i-o-should-return-zero.patch b/SOURCES/cryptsetup-2.0.4-zero-length-lseek-blockwise-i-o-should-return-zero.patch
new file mode 100644
index 0000000..6d4d7e3
--- /dev/null
+++ b/SOURCES/cryptsetup-2.0.4-zero-length-lseek-blockwise-i-o-should-return-zero.patch
@@ -0,0 +1,39 @@
+From 685bcc56351b3e46b69d46118d23268b69052097 Mon Sep 17 00:00:00 2001
+From: Ondrej Kozina <okozina@redhat.com>
+Date: Tue, 19 Jun 2018 14:07:20 +0200
+Subject: [PATCH 1/4] Zero length lseek blockwise i/o should return zero.
+
+Note that both functions perform seek operations aligned to sector
+boundary if possible before returning.
+
+Unaligned input offset gets aligned on first preceding sector
+boundary.
+---
+ lib/utils_io.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/lib/utils_io.c b/lib/utils_io.c
+index 0f671d6..94c4ef6 100644
+--- a/lib/utils_io.c
++++ b/lib/utils_io.c
+@@ -199,7 +199,7 @@ ssize_t write_lseek_blockwise(int fd, size_t bsize, size_t alignment,
+ 	if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
+ 		return -1;
+ 
+-	if (frontHang) {
++	if (frontHang && length) {
+ 		if (posix_memalign(&frontPadBuf, alignment, bsize))
+ 			return -1;
+ 
+@@ -253,7 +253,7 @@ ssize_t read_lseek_blockwise(int fd, size_t bsize, size_t alignment,
+ 	if (lseek(fd, offset - frontHang, SEEK_SET) < 0)
+ 		return -1;
+ 
+-	if (frontHang) {
++	if (frontHang && length) {
+ 		if (posix_memalign(&frontPadBuf, alignment, bsize))
+ 			return -1;
+ 
+-- 
+1.8.3.1
+
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/SOURCES/cryptsetup-2.2.1-reinstate-missing-backing-file-hint-for-loop-device.patch b/SOURCES/cryptsetup-2.2.1-reinstate-missing-backing-file-hint-for-loop-device.patch
new file mode 100644
index 0000000..7aa6b76
--- /dev/null
+++ b/SOURCES/cryptsetup-2.2.1-reinstate-missing-backing-file-hint-for-loop-device.patch
@@ -0,0 +1,149 @@
+diff -rupN cryptsetup-2.0.3.old/src/Makemodule.am cryptsetup-2.0.3.new/src/Makemodule.am
+--- cryptsetup-2.0.3.old/src/Makemodule.am	2019-08-27 17:37:25.043999695 +0200
++++ cryptsetup-2.0.3.new/src/Makemodule.am	2019-08-27 17:39:40.303336254 +0200
+@@ -6,6 +6,7 @@ cryptsetup_SOURCES =		\
+ 	lib/utils_loop.c	\
+ 	lib/utils_io.c		\
+ 	src/utils_tools.c	\
++	lib/utils_loop.c	\
+ 	src/utils_password.c	\
+ 	src/cryptsetup.c	\
+ 	src/cryptsetup.h
+diff -rupN cryptsetup-2.0.3.old/src/utils_password.c cryptsetup-2.0.3.new/src/utils_password.c
+--- cryptsetup-2.0.3.old/src/utils_password.c	2019-08-27 17:37:25.043999695 +0200
++++ cryptsetup-2.0.3.new/src/utils_password.c	2019-08-27 17:38:35.354214280 +0200
+@@ -256,7 +256,7 @@ int tools_get_key(const char *prompt,
+ 		  int timeout, int verify, int pwquality,
+ 		  struct crypt_device *cd)
+ {
+-	char tmp[1024];
++	char tmp[1024], *backing_file;
+ 	int r = -EINVAL, block;
+ 
+ 	block = tools_signals_blocked();
+@@ -270,9 +270,11 @@ int tools_get_key(const char *prompt,
+ 			} else {
+ 				if (!prompt && !crypt_get_device_name(cd))
+ 					snprintf(tmp, sizeof(tmp), _("Enter passphrase: "));
+-				else if (!prompt)
+-					snprintf(tmp, sizeof(tmp), _("Enter passphrase for %s: "),
+-						crypt_get_device_name(cd));
++				else if (!prompt) {
++					backing_file = crypt_loop_backing_file(crypt_get_device_name(cd));
++					snprintf(tmp, sizeof(tmp), _("Enter passphrase for %s: "), backing_file ?: crypt_get_device_name(cd));
++					free(backing_file);
++				}
+ 				r = crypt_get_key_tty(prompt ?: tmp, key, key_size, timeout, verify, cd);
+ 			}
+ 		} else {
+diff -rupN cryptsetup-2.0.3.old/tests/compat-test cryptsetup-2.0.3.new/tests/compat-test
+--- cryptsetup-2.0.3.old/tests/compat-test	2019-08-27 17:37:24.942997950 +0200
++++ cryptsetup-2.0.3.new/tests/compat-test	2019-08-27 17:41:15.868988979 +0200
+@@ -735,15 +735,20 @@ fi
+ which expect >/dev/null 2>&1 || skip "WARNING: expect tool missing, interactive test will be skipped." 0
+ 
+ prepare "[32] Interactive password retry from terminal." new
++if [ "$(pwd)" = "/" ]; then
++	EXPECT_DEV=/$IMG
++else
++	EXPECT_DEV=$(pwd)/$IMG
++fi
+ expect - >/dev/null <<EOF
+ proc abort {} { send_error "Timeout. "; exit 2 }
+ set timeout 10
+ eval spawn $CRYPTSETUP luksOpen -v -T 2 $LOOPDEV $DEV_NAME
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0 x\n"
+ expect timeout abort "No key available with this passphrase."
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0\n"
+ expect timeout abort "Key slot 0 unlocked."
+@@ -760,11 +765,11 @@ expect - >/dev/null <<EOF
+ proc abort {} { send_error "Timeout. "; exit 2 }
+ set timeout 10
+ eval spawn $CRYPTSETUP luksOpen -v -T 2 $LOOPDEV $DEV_NAME
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0 x\n"
+ expect timeout abort "No key available with this passphrase."
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0 y\n"
+ expect timeout abort "No key available with this passphrase."
+@@ -799,7 +804,7 @@ set timeout 10
+ eval spawn $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT -v $LOOPDEV
+ expect timeout abort "Are you sure? (Type uppercase yes):"
+ send "YES\n"
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0\n"
+ expect timeout abort "Verify passphrase:"
+@@ -808,7 +813,7 @@ send "$PWD0\n"
+ expect timeout abort "Command successful."
+ expect timeout abort eof
+ eval spawn $CRYPTSETUP luksOpen -v $LOOPDEV --test-passphrase
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0\n"
+ expect timeout abort "Command successful."
+@@ -829,7 +834,7 @@ expect timeout abort eof
+ eval spawn $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT -v $LOOPDEV
+ expect timeout abort "Are you sure? (Type uppercase yes):"
+ send "YES\n"
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0\n"
+ expect timeout abort "Verify passphrase:"
+@@ -838,7 +843,7 @@ send "$PWD0 x\n"
+ expect timeout abort "Passphrases do not match."
+ expect timeout abort eof
+ eval spawn $CRYPTSETUP luksOpen -v $LOOPDEV -T 1 --test-passphrase
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0\n"
+ expect timeout abort "No key available with this passphrase."
+@@ -890,7 +895,7 @@ send "$PWD1\n"
+ expect timeout abort "Command successful."
+ expect timeout abort eof
+ eval spawn $CRYPTSETUP luksOpen -v $LOOPDEV --test-passphrase
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD1\n"
+ expect timeout abort "Command successful."
+@@ -908,21 +913,21 @@ eval spawn $CRYPTSETUP luksSuspend -v $D
+ expect timeout abort "Command successful."
+ expect timeout abort eof
+ eval spawn $CRYPTSETUP luksResume -v -T 3  $DEV_NAME
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0 x\n"
+ expect timeout abort "No key available with this passphrase."
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD1\n"
+ expect timeout abort "No key available with this passphrase."
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0 y\n"
+ expect timeout abort "No key available with this passphrase."
+ expect timeout abort eof
+ eval spawn $CRYPTSETUP luksResume -v $DEV_NAME
+-expect timeout abort "Enter passphrase for $LOOPDEV:"
++expect timeout abort "Enter passphrase for $EXPECT_DEV:"
+ sleep 0.1
+ send "$PWD0\n"
+ expect timeout abort "Command successful."
diff --git a/SOURCES/cryptsetup-argon2-fips.patch b/SOURCES/cryptsetup-argon2-fips.patch
new file mode 100644
index 0000000..5261c8d
--- /dev/null
+++ b/SOURCES/cryptsetup-argon2-fips.patch
@@ -0,0 +1,33 @@
+diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c
+index 3716c26..540915b 100644
+--- a/lib/luks2/luks2_keyslot_luks2.c
++++ b/lib/luks2/luks2_keyslot_luks2.c
+@@ -350,6 +350,13 @@ static int luks2_keyslot_get_key(struct crypt_device *cd,
+ 		crypt_free_volume_key(derived_key);
+ 		return -ENOMEM;
+ 	}
++
++	if (crypt_fips_mode() &&
++	    (!strcmp(pbkdf.type, CRYPT_KDF_ARGON2I) ||
++	     !strcmp(pbkdf.type, CRYPT_KDF_ARGON2ID)))
++		log_verbose(cd, _("%s key derivation function is not currently FIPS-compliant."),
++			    pbkdf.type);
++
+ 	/*
+ 	 * Calculate derived key, decrypt keyslot content and merge it.
+ 	 */
+@@ -406,6 +413,14 @@ static int luks2_keyslot_update_json(struct crypt_device *cd,
+ 	if (!pbkdf)
+ 		return -EINVAL;
+ 
++	if (crypt_fips_mode() &&
++	    (!strcmp(pbkdf->type, CRYPT_KDF_ARGON2I) ||
++	     !strcmp(pbkdf->type, CRYPT_KDF_ARGON2ID))) {
++		log_err(cd, _("%s key derivation function is not allowed in FIPS mode."),
++			pbkdf->type);
++		return -EINVAL;
++	}
++
+ 	r = crypt_benchmark_pbkdf_internal(cd, CONST_CAST(struct crypt_pbkdf_type *)pbkdf, keyslot_key_len);
+ 	if (r < 0)
+ 		return r;
diff --git a/SOURCES/cryptsetup-avoid-rh-kernel-bug.patch b/SOURCES/cryptsetup-avoid-rh-kernel-bug.patch
new file mode 100644
index 0000000..c0ca3b2
--- /dev/null
+++ b/SOURCES/cryptsetup-avoid-rh-kernel-bug.patch
@@ -0,0 +1,56 @@
+--- a/lib/crypto_backend/crypto_cipher_kernel.c
++++ b/lib/crypto_backend/crypto_cipher_kernel.c
+@@ -31,6 +31,7 @@
+ #ifdef ENABLE_AF_ALG
+ 
+ #include <linux/if_alg.h>
++#include <sys/utsname.h>
+ 
+ #ifndef AF_ALG
+ #define AF_ALG 38
+@@ -88,6 +89,35 @@ int crypt_cipher_blocksize(const char *n
+ 	return ca ? ca->blocksize : -EINVAL;
+ }
+ 
++static size_t pagesize(size_t defsize)
++{
++	long r = sysconf(_SC_PAGESIZE);
++	return r < 0 ? defsize : (size_t)r;
++}
++
++static int check_rh_kernel_version(void)
++{
++	unsigned maj, mid, min, rel;
++	static struct utsname uts = {{ 0 }};
++	size_t ps = pagesize(32768);
++
++	if (ps < 32768)
++		return 0;
++
++	if (!*uts.release && uname(&uts) < 0)
++		return -ENOTSUP;
++	/*
++	 * RH kernels 3.10.0-185 and lower are affected by a crypto API kernel
++	 * socket bug. The bug only manifests on archs with page size >= 32 KiB.
++	 *
++	 * For reference, see rhbz#1136075
++	 */
++	if (sscanf(uts.release, "%u.%u.%u-%u", &maj, &mid, &min, &rel) == 4)
++		return (maj == 3 && mid == 10 && min == 0 && rel < 186) ? -ENOTSUP : 0;
++
++	return -ENOTSUP;
++}
++
+ /*
+  * ciphers
+  *
+@@ -104,6 +134,9 @@ int crypt_cipher_init(struct crypt_ciphe
+ 		.salg_type = "skcipher",
+ 	};
+ 
++	if (check_rh_kernel_version())
++		return -ENOTSUP;
++
+ 	h = malloc(sizeof(*h));
+ 	if (!h)
+ 		return -ENOMEM;
diff --git a/SOURCES/cryptsetup-configure.patch b/SOURCES/cryptsetup-configure.patch
new file mode 100644
index 0000000..044988e
--- /dev/null
+++ b/SOURCES/cryptsetup-configure.patch
@@ -0,0 +1,417 @@
+diff -rupN cryptsetup-2.0.3.old/config.h.in cryptsetup-2.0.3.new/config.h.in
+--- cryptsetup-2.0.3.old/config.h.in	2019-08-27 18:30:14.342521239 +0200
++++ cryptsetup-2.0.3.new/config.h.in	2019-08-27 18:30:48.212105267 +0200
+@@ -106,6 +106,12 @@
+ /* Define to 1 if you have the <argon2.h> header file. */
+ #undef HAVE_ARGON2_H
+ 
++/* Define to 1 to use blkid for detection of disk signatures. */
++#undef HAVE_BLKID
++
++/* Define to 1 if you have the <blkid/blkid.h> header file. */
++#undef HAVE_BLKID_BLKID_H
++
+ /* Define to 1 if you have the <byteswap.h> header file. */
+ #undef HAVE_BYTESWAP_H
+ 
+@@ -127,6 +133,30 @@
+    */
+ #undef HAVE_DCGETTEXT
+ 
++/* Define to 1 if you have the declaration of `blkid_do_probe', and to 0 if
++   you don't. */
++#undef HAVE_DECL_BLKID_DO_PROBE
++
++/* Define to 1 if you have the declaration of `blkid_do_safeprobe', and to 0
++   if you don't. */
++#undef HAVE_DECL_BLKID_DO_SAFEPROBE
++
++/* Define to 1 if you have the declaration of
++   `blkid_probe_filter_superblocks_type', and to 0 if you don't. */
++#undef HAVE_DECL_BLKID_PROBE_FILTER_SUPERBLOCKS_TYPE
++
++/* Define to 1 if you have the declaration of `blkid_probe_lookup_value ', and
++   to 0 if you don't. */
++#undef HAVE_DECL_BLKID_PROBE_LOOKUP_VALUE__________
++
++/* Define to 1 if you have the declaration of `blkid_probe_set_device', and to
++   0 if you don't. */
++#undef HAVE_DECL_BLKID_PROBE_SET_DEVICE
++
++/* Define to 1 if you have the declaration of `blkid_reset_probe', and to 0 if
++   you don't. */
++#undef HAVE_DECL_BLKID_RESET_PROBE
++
+ /* Define to 1 if you have the declaration of `dm_device_has_holders', and to
+    0 if you don't. */
+ #undef HAVE_DECL_DM_DEVICE_HAS_HOLDERS
+diff -rupN cryptsetup-2.0.3.old/configure cryptsetup-2.0.3.new/configure
+--- cryptsetup-2.0.3.old/configure	2019-08-27 18:30:14.342521239 +0200
++++ cryptsetup-2.0.3.new/configure	2019-08-27 18:30:48.212105267 +0200
+@@ -664,6 +664,10 @@ PWQUALITY_STATIC_LIBS
+ systemd_tmpfilesdir
+ DEVMAPPER_STATIC_LIBS
+ DEVMAPPER_STATIC_CFLAGS
++HAVE_BLKID_FALSE
++HAVE_BLKID_TRUE
++BLKID_LIBS
++BLKID_CFLAGS
+ CRYPTO_INTERNAL_ARGON2_FALSE
+ CRYPTO_INTERNAL_ARGON2_TRUE
+ LIBARGON2_LIBS
+@@ -878,6 +882,7 @@ enable_gcrypt_pbkdf2
+ with_libgcrypt_prefix
+ enable_internal_argon2
+ enable_libargon2
++enable_blkid
+ enable_dev_random
+ enable_python
+ with_python_version
+@@ -935,6 +940,8 @@ NSS_CFLAGS
+ NSS_LIBS
+ LIBARGON2_CFLAGS
+ LIBARGON2_LIBS
++BLKID_CFLAGS
++BLKID_LIBS
+ DEVMAPPER_STATIC_CFLAGS
+ DEVMAPPER_STATIC_LIBS
+ systemd_tmpfilesdir
+@@ -1607,6 +1614,8 @@ Optional Features:
+                           disable internal implementation of Argon2 PBKDF
+   --enable-libargon2      enable external libargon2 (PHC) library (disables
+                           internal bundled version)
++  --disable-blkid         disable use of blkid for device signature detection
++                          and wiping.
+   --enable-dev-random     use blocking /dev/random by default for key
+                           generator (otherwise use /dev/urandom)
+   --enable-python         enable Python bindings
+@@ -1719,6 +1728,9 @@ Some influential environment variables:
+               C compiler flags for LIBARGON2, overriding pkg-config
+   LIBARGON2_LIBS
+               linker flags for LIBARGON2, overriding pkg-config
++  BLKID_CFLAGS
++              C compiler flags for BLKID, overriding pkg-config
++  BLKID_LIBS  linker flags for BLKID, overriding pkg-config
+   DEVMAPPER_STATIC_CFLAGS
+               C compiler flags for DEVMAPPER_STATIC, overriding pkg-config
+   DEVMAPPER_STATIC_LIBS
+@@ -18580,6 +18592,211 @@ else
+ fi
+ 
+ 
++# Check whether --enable-blkid was given.
++if test "${enable_blkid+set}" = set; then :
++  enableval=$enable_blkid;
++else
++  enable_blkid=yes
++fi
++
++
++if test x$enable_blkid = xyes ; then
++
++pkg_failed=no
++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BLKID" >&5
++$as_echo_n "checking for BLKID... " >&6; }
++
++if test -n "$BLKID_CFLAGS"; then
++    pkg_cv_BLKID_CFLAGS="$BLKID_CFLAGS"
++ elif test -n "$PKG_CONFIG"; then
++    if test -n "$PKG_CONFIG" && \
++    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid\""; } >&5
++  ($PKG_CONFIG --exists --print-errors "blkid") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; then
++  pkg_cv_BLKID_CFLAGS=`$PKG_CONFIG --cflags "blkid" 2>/dev/null`
++		      test "x$?" != "x0" && pkg_failed=yes
++else
++  pkg_failed=yes
++fi
++ else
++    pkg_failed=untried
++fi
++if test -n "$BLKID_LIBS"; then
++    pkg_cv_BLKID_LIBS="$BLKID_LIBS"
++ elif test -n "$PKG_CONFIG"; then
++    if test -n "$PKG_CONFIG" && \
++    { { $as_echo "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"blkid\""; } >&5
++  ($PKG_CONFIG --exists --print-errors "blkid") 2>&5
++  ac_status=$?
++  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
++  test $ac_status = 0; }; then
++  pkg_cv_BLKID_LIBS=`$PKG_CONFIG --libs "blkid" 2>/dev/null`
++		      test "x$?" != "x0" && pkg_failed=yes
++else
++  pkg_failed=yes
++fi
++ else
++    pkg_failed=untried
++fi
++
++
++
++if test $pkg_failed = yes; then
++   	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++
++if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
++        _pkg_short_errors_supported=yes
++else
++        _pkg_short_errors_supported=no
++fi
++        if test $_pkg_short_errors_supported = yes; then
++	        BLKID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "blkid" 2>&1`
++        else
++	        BLKID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "blkid" 2>&1`
++        fi
++	# Put the nasty error message in config.log where it belongs
++	echo "$BLKID_PKG_ERRORS" >&5
++
++	LIBBLKID_LIBS="-lblkid"
++elif test $pkg_failed = untried; then
++     	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
++$as_echo "no" >&6; }
++	LIBBLKID_LIBS="-lblkid"
++else
++	BLKID_CFLAGS=$pkg_cv_BLKID_CFLAGS
++	BLKID_LIBS=$pkg_cv_BLKID_LIBS
++        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
++$as_echo "yes" >&6; }
++
++$as_echo "#define HAVE_BLKID 1" >>confdefs.h
++
++fi
++
++	for ac_header in blkid/blkid.h
++do :
++  ac_fn_c_check_header_mongrel "$LINENO" "blkid/blkid.h" "ac_cv_header_blkid_blkid_h" "$ac_includes_default"
++if test "x$ac_cv_header_blkid_blkid_h" = xyes; then :
++  cat >>confdefs.h <<_ACEOF
++#define HAVE_BLKID_BLKID_H 1
++_ACEOF
++
++else
++  as_fn_error $? "You need blkid development library installed." "$LINENO" 5
++fi
++
++done
++
++	ac_fn_c_check_decl "$LINENO" "blkid_reset_probe" "ac_cv_have_decl_blkid_reset_probe" "#include <blkid/blkid.h>
++"
++if test "x$ac_cv_have_decl_blkid_reset_probe" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_BLKID_RESET_PROBE $ac_have_decl
++_ACEOF
++if test $ac_have_decl = 1; then :
++
++else
++  as_fn_error $? "Can not compile with blkid support, disable it by --disable-blkid." "$LINENO" 5
++fi
++ac_fn_c_check_decl "$LINENO" "blkid_probe_set_device" "ac_cv_have_decl_blkid_probe_set_device" "#include <blkid/blkid.h>
++"
++if test "x$ac_cv_have_decl_blkid_probe_set_device" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_BLKID_PROBE_SET_DEVICE $ac_have_decl
++_ACEOF
++if test $ac_have_decl = 1; then :
++
++else
++  as_fn_error $? "Can not compile with blkid support, disable it by --disable-blkid." "$LINENO" 5
++fi
++ac_fn_c_check_decl "$LINENO" "blkid_probe_filter_superblocks_type" "ac_cv_have_decl_blkid_probe_filter_superblocks_type" "#include <blkid/blkid.h>
++"
++if test "x$ac_cv_have_decl_blkid_probe_filter_superblocks_type" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_BLKID_PROBE_FILTER_SUPERBLOCKS_TYPE $ac_have_decl
++_ACEOF
++if test $ac_have_decl = 1; then :
++
++else
++  as_fn_error $? "Can not compile with blkid support, disable it by --disable-blkid." "$LINENO" 5
++fi
++ac_fn_c_check_decl "$LINENO" "blkid_do_safeprobe" "ac_cv_have_decl_blkid_do_safeprobe" "#include <blkid/blkid.h>
++"
++if test "x$ac_cv_have_decl_blkid_do_safeprobe" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_BLKID_DO_SAFEPROBE $ac_have_decl
++_ACEOF
++if test $ac_have_decl = 1; then :
++
++else
++  as_fn_error $? "Can not compile with blkid support, disable it by --disable-blkid." "$LINENO" 5
++fi
++ac_fn_c_check_decl "$LINENO" "blkid_do_probe" "ac_cv_have_decl_blkid_do_probe" "#include <blkid/blkid.h>
++"
++if test "x$ac_cv_have_decl_blkid_do_probe" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_BLKID_DO_PROBE $ac_have_decl
++_ACEOF
++if test $ac_have_decl = 1; then :
++
++else
++  as_fn_error $? "Can not compile with blkid support, disable it by --disable-blkid." "$LINENO" 5
++fi
++ac_fn_c_check_decl "$LINENO" "blkid_probe_lookup_value
++		       " "ac_cv_have_decl_blkid_probe_lookup_value__________" "#include <blkid/blkid.h>
++"
++if test "x$ac_cv_have_decl_blkid_probe_lookup_value__________" = xyes; then :
++  ac_have_decl=1
++else
++  ac_have_decl=0
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define HAVE_DECL_BLKID_PROBE_LOOKUP_VALUE__________ $ac_have_decl
++_ACEOF
++if test $ac_have_decl = 1; then :
++
++else
++  as_fn_error $? "Can not compile with blkid support, disable it by --disable-blkid." "$LINENO" 5
++fi
++
++fi
++ if test x$enable_blkid = xyes; then
++  HAVE_BLKID_TRUE=
++  HAVE_BLKID_FALSE='#'
++else
++  HAVE_BLKID_TRUE='#'
++  HAVE_BLKID_FALSE=
++fi
++
++
+ if test x$enable_static_cryptsetup = xyes; then
+ 	saved_PKG_CONFIG=$PKG_CONFIG
+ 	PKG_CONFIG="$PKG_CONFIG --static"
+@@ -19043,6 +19260,7 @@ $as_echo "$systemd_tmpfilesdir" >&6; }
+ 
+ 
+ 
++
+ # Check whether --enable-dev-random was given.
+ if test "${enable_dev_random+set}" = set; then :
+   enableval=$enable_dev_random; default_rng=/dev/random
+@@ -20146,6 +20364,10 @@ if test -z "${CRYPTO_INTERNAL_ARGON2_TRU
+   as_fn_error $? "conditional \"CRYPTO_INTERNAL_ARGON2\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+ fi
++if test -z "${HAVE_BLKID_TRUE}" && test -z "${HAVE_BLKID_FALSE}"; then
++  as_fn_error $? "conditional \"HAVE_BLKID\" was never defined.
++Usually this means the macro was only invoked conditionally." "$LINENO" 5
++fi
+ if test -z "${PYTHON_CRYPTSETUP_TRUE}" && test -z "${PYTHON_CRYPTSETUP_FALSE}"; then
+   as_fn_error $? "conditional \"PYTHON_CRYPTSETUP\" was never defined.
+ Usually this means the macro was only invoked conditionally." "$LINENO" 5
+diff -rupN cryptsetup-2.0.3.old/Makefile.in cryptsetup-2.0.3.new/Makefile.in
+--- cryptsetup-2.0.3.old/Makefile.in	2019-08-27 18:30:14.223519187 +0200
++++ cryptsetup-2.0.3.new/Makefile.in	2019-08-27 18:34:03.679475168 +0200
+@@ -270,7 +270,8 @@ am_libcryptsetup_la_OBJECTS = lib/libcry
+ 	lib/luks2/libcryptsetup_la-luks2_keyslot.lo \
+ 	lib/luks2/libcryptsetup_la-luks2_keyslot_luks2.lo \
+ 	lib/luks2/libcryptsetup_la-luks2_token_keyring.lo \
+-	lib/luks2/libcryptsetup_la-luks2_token.lo
++	lib/luks2/libcryptsetup_la-luks2_token.lo \
++	lib/libcryptsetup_la-utils_blkid.lo
+ libcryptsetup_la_OBJECTS = $(am_libcryptsetup_la_OBJECTS)
+ libcryptsetup_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+ 	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+@@ -308,12 +309,14 @@ am__cryptsetup_SOURCES_DIST = lib/utils_
+ cryptsetup_OBJECTS = $(am_cryptsetup_OBJECTS)
+ @CRYPTSETUP_TRUE@cryptsetup_DEPENDENCIES = libcryptsetup.la
+ am__cryptsetup_reencrypt_SOURCES_DIST = lib/utils_crypt.c \
+-	lib/utils_io.c src/utils_tools.c src/utils_password.c \
+-	src/cryptsetup_reencrypt.c src/cryptsetup.h
++	lib/utils_io.c src/utils_tools.c lib/utils_loop.c \
++	src/utils_password.c src/cryptsetup_reencrypt.c \
++	src/cryptsetup.h
+ @REENCRYPT_TRUE@am_cryptsetup_reencrypt_OBJECTS =  \
+ @REENCRYPT_TRUE@	lib/utils_crypt.$(OBJEXT) \
+ @REENCRYPT_TRUE@	lib/utils_io.$(OBJEXT) \
+ @REENCRYPT_TRUE@	src/utils_tools.$(OBJEXT) \
++@REENCRYPT_TRUE@	lib/utils_loop.$(OBJEXT) \
+ @REENCRYPT_TRUE@	src/utils_password.$(OBJEXT) \
+ @REENCRYPT_TRUE@	src/cryptsetup_reencrypt.$(OBJEXT)
+ cryptsetup_reencrypt_OBJECTS = $(am_cryptsetup_reencrypt_OBJECTS)
+@@ -591,6 +594,8 @@ AUTOCONF = @AUTOCONF@
+ AUTOHEADER = @AUTOHEADER@
+ AUTOMAKE = @AUTOMAKE@
+ AWK = @AWK@
++BLKID_CFLAGS = @BLKID_CFLAGS@
++BLKID_LIBS = @BLKID_LIBS@
+ CC = @CC@
+ CCDEPMODE = @CCDEPMODE@
+ CFLAGS = @CFLAGS@
+@@ -846,6 +851,7 @@ libcryptsetup_la_LIBADD = \
+ 	@CRYPTO_LIBS@		\
+ 	@LIBARGON2_LIBS@	\
+ 	@JSON_C_LIBS@		\
++	@BLKID_LIBS@		\
+ 	libcrypto_backend.la
+ 
+ libcryptsetup_la_SOURCES = \
+@@ -908,7 +914,9 @@ libcryptsetup_la_SOURCES = \
+ 	lib/luks2/luks2_token_keyring.c	\
+ 	lib/luks2/luks2_token.c		\
+ 	lib/luks2/luks2_internal.h	\
+-	lib/luks2/luks2.h
++	lib/luks2/luks2.h		\
++	lib/utils_blkid.c		\
++	lib/utils_blkid.h
+ 
+ 
+ # cryptsetup
+@@ -1351,6 +1359,8 @@ lib/luks2/libcryptsetup_la-luks2_token_k
+ 	lib/luks2/$(am__dirstamp) lib/luks2/$(DEPDIR)/$(am__dirstamp)
+ lib/luks2/libcryptsetup_la-luks2_token.lo: lib/luks2/$(am__dirstamp) \
+ 	lib/luks2/$(DEPDIR)/$(am__dirstamp)
++lib/libcryptsetup_la-utils_blkid.lo: lib/$(am__dirstamp) \
++	lib/$(DEPDIR)/$(am__dirstamp)
+ 
+ libcryptsetup.la: $(libcryptsetup_la_OBJECTS) $(libcryptsetup_la_DEPENDENCIES) $(EXTRA_libcryptsetup_la_DEPENDENCIES) 
+ 	$(AM_V_CCLD)$(libcryptsetup_la_LINK) -rpath $(libdir) $(libcryptsetup_la_OBJECTS) $(libcryptsetup_la_LIBADD) $(LIBS)
+@@ -1507,6 +1517,7 @@ distclean-compile:
+ @AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libcryptsetup_la-setup.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libcryptsetup_la-utils.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libcryptsetup_la-utils_benchmark.Plo@am__quote@
++@AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libcryptsetup_la-utils_blkid.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libcryptsetup_la-utils_crypt.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libcryptsetup_la-utils_device.Plo@am__quote@
+ @AMDEP_TRUE@@am__include@ @am__quote@lib/$(DEPDIR)/libcryptsetup_la-utils_device_locking.Plo@am__quote@
+@@ -1991,6 +2002,13 @@ lib/luks2/libcryptsetup_la-luks2_token.l
+ @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcryptsetup_la_CPPFLAGS) $(CPPFLAGS) $(libcryptsetup_la_CFLAGS) $(CFLAGS) -c -o lib/luks2/libcryptsetup_la-luks2_token.lo `test -f 'lib/luks2/luks2_token.c' || echo '$(srcdir)/'`lib/luks2/luks2_token.c
+ 
++lib/libcryptsetup_la-utils_blkid.lo: lib/utils_blkid.c
++@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcryptsetup_la_CPPFLAGS) $(CPPFLAGS) $(libcryptsetup_la_CFLAGS) $(CFLAGS) -MT lib/libcryptsetup_la-utils_blkid.lo -MD -MP -MF lib/$(DEPDIR)/libcryptsetup_la-utils_blkid.Tpo -c -o lib/libcryptsetup_la-utils_blkid.lo `test -f 'lib/utils_blkid.c' || echo '$(srcdir)/'`lib/utils_blkid.c
++@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) lib/$(DEPDIR)/libcryptsetup_la-utils_blkid.Tpo lib/$(DEPDIR)/libcryptsetup_la-utils_blkid.Plo
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='lib/utils_blkid.c' object='lib/libcryptsetup_la-utils_blkid.lo' libtool=yes @AMDEPBACKSLASH@
++@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
++@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcryptsetup_la_CPPFLAGS) $(CPPFLAGS) $(libcryptsetup_la_CFLAGS) $(CFLAGS) -c -o lib/libcryptsetup_la-utils_blkid.lo `test -f 'lib/utils_blkid.c' || echo '$(srcdir)/'`lib/utils_blkid.c
++
+ python/pycryptsetup_la-pycryptsetup.lo: python/pycryptsetup.c
+ @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(pycryptsetup_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT python/pycryptsetup_la-pycryptsetup.lo -MD -MP -MF python/$(DEPDIR)/pycryptsetup_la-pycryptsetup.Tpo -c -o python/pycryptsetup_la-pycryptsetup.lo `test -f 'python/pycryptsetup.c' || echo '$(srcdir)/'`python/pycryptsetup.c
+ @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) python/$(DEPDIR)/pycryptsetup_la-pycryptsetup.Tpo python/$(DEPDIR)/pycryptsetup_la-pycryptsetup.Plo
diff --git a/SOURCES/cryptsetup-new-avoid-rh-kernel-bug.patch b/SOURCES/cryptsetup-new-avoid-rh-kernel-bug.patch
new file mode 100644
index 0000000..2e9a27f
--- /dev/null
+++ b/SOURCES/cryptsetup-new-avoid-rh-kernel-bug.patch
@@ -0,0 +1,59 @@
+diff -rupN cryptsetup-2.0.3.old/lib/crypto_backend/crypto_cipher_kernel.c cryptsetup-2.0.3/lib/crypto_backend/crypto_cipher_kernel.c
+--- cryptsetup-2.0.3.old/lib/crypto_backend/crypto_cipher_kernel.c	2018-04-17 09:20:35.000000000 +0200
++++ cryptsetup-2.0.3/lib/crypto_backend/crypto_cipher_kernel.c	2018-05-07 14:13:45.176124062 +0200
+@@ -31,6 +31,7 @@
+ #ifdef ENABLE_AF_ALG
+ 
+ #include <linux/if_alg.h>
++#include <sys/utsname.h>
+ 
+ #ifndef AF_ALG
+ #define AF_ALG 38
+@@ -44,6 +45,36 @@ struct crypt_cipher {
+ 	int opfd;
+ };
+ 
++ 
++static size_t pagesize(size_t defsize)
++{
++	long r = sysconf(_SC_PAGESIZE);
++	return r < 0 ? defsize : (size_t)r;
++}
++
++static int check_rh_kernel_version(void)
++{
++	unsigned maj, mid, min, rel;
++	static struct utsname uts = {{ 0 }};
++	size_t ps = pagesize(32768);
++
++	if (ps < 32768)
++		return 0;
++
++	if (!*uts.release && uname(&uts) < 0)
++		return -ENOTSUP;
++	/*
++	 * RH kernels 3.10.0-185 and lower are affected by a crypto API kernel
++	 * socket bug. The bug only manifests on archs with page size >= 32 KiB.
++	 *
++	 * For reference, see rhbz#1136075
++	 */
++	if (sscanf(uts.release, "%u.%u.%u-%u", &maj, &mid, &min, &rel) == 4)
++		return (maj == 3 && mid == 10 && min == 0 && rel < 186) ? -ENOTSUP : 0;
++
++	return -ENOTSUP;
++}
++
+ /*
+  * ciphers
+  *
+@@ -60,6 +91,9 @@ int crypt_cipher_init(struct crypt_ciphe
+ 		.salg_type = "skcipher",
+ 	};
+ 
++	if (check_rh_kernel_version())
++		return -ENOTSUP;
++
+ 	h = malloc(sizeof(*h));
+ 	if (!h)
+ 		return -ENOMEM;
+Binary files cryptsetup-2.0.3.old/lib/crypto_backend/.crypto_cipher_kernel.c.rej.swp and cryptsetup-2.0.3/lib/crypto_backend/.crypto_cipher_kernel.c.rej.swp differ
diff --git a/SOURCES/cryptsetup-sector-size-detection.patch b/SOURCES/cryptsetup-sector-size-detection.patch
new file mode 100644
index 0000000..a10bff0
--- /dev/null
+++ b/SOURCES/cryptsetup-sector-size-detection.patch
@@ -0,0 +1,13 @@
+--- cryptsetup-2.0.3.old/lib/libdevmapper.c	2018-05-03 18:30:59.000000000 +0200
++++ cryptsetup-2.0.3/lib/libdevmapper.c	2018-06-19 20:01:10.263369754 +0200
+@@ -164,6 +164,10 @@ static void _dm_set_crypt_compat(unsigne
+ 		_dm_flags |= DM_CAPI_STRING_SUPPORTED;
+ 	}
+ 
++	if (!_dm_satisfies_version(1, 15, 0, crypt_maj, crypt_min, crypt_patch) &&
++	     _dm_satisfies_version(1, 14, 5, crypt_maj, crypt_min, crypt_patch))
++		_dm_flags |= DM_SECTOR_SIZE_SUPPORTED;
++
+ 	_dm_crypt_checked = true;
+ }
+ 
diff --git a/SOURCES/cryptsetup-tests-device-test.patch b/SOURCES/cryptsetup-tests-device-test.patch
new file mode 100644
index 0000000..ebc7186
--- /dev/null
+++ b/SOURCES/cryptsetup-tests-device-test.patch
@@ -0,0 +1,17 @@
+diff -rupN cryptsetup-2.0.3.old/tests/device-test cryptsetup-2.0.3/tests/device-test
+--- cryptsetup-2.0.3.old/tests/device-test	2018-06-06 11:00:28.716305843 -0400
++++ cryptsetup-2.0.3/tests/device-test	2018-06-06 11:00:37.036343168 -0400
+@@ -39,11 +39,12 @@ function dm_crypt_features()
+ 
+ 	VER_MAJ=$(echo $VER_STR | cut -f 1 -d.)
+ 	VER_MIN=$(echo $VER_STR | cut -f 2 -d.)
++	VER_PAT=$(echo $VER_STR | cut -f 3 -d.)
+ 
+ 	[ $VER_MAJ -lt 1 ] && return
+ 	[ $VER_MAJ -eq 1 -a $VER_MIN -lt 14 ] && return
+ 	DM_PERF_CPU=1
+-	[ $VER_MAJ -eq 1 -a $VER_MIN -lt 17 ] && return
++	[ $VER_MAJ -eq 1 -a $VER_MIN -lt 15 -a $VER_PAT -lt 5 ] && return
+ 	DM_SECTOR_SIZE=1
+ }
+ 
diff --git a/SPECS/cryptsetup.spec b/SPECS/cryptsetup.spec
new file mode 100644
index 0000000..db7bfdf
--- /dev/null
+++ b/SPECS/cryptsetup.spec
@@ -0,0 +1,757 @@
+%{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(1)")}
+
+%if 0%{?fedora}
+%if 0%{?fedora} >= 29
+Obsoletes: python2-cryptsetup
+Obsoletes: cryptsetup-python3
+%global python2_enable 0
+%global python3_enable 0
+%else
+%global python2_enable 1
+%global python3_enable 1
+%endif
+%else
+Obsoletes: cryptsetup-python3
+%global python3_enable 0
+%if 0%{?rhel} == 7
+%global python2_enable 1
+# Change to 1 when argon2 lands
+%global libargon2_enable 0
+# Change to 1 when dm-integrity gets backported
+%global integritysetup_enable 0
+%else
+Obsoletes: cryptsetup-python
+Obsoletes: python2-cryptsetup
+%global python2_enable 0
+%endif
+%endif
+
+
+Summary: A utility for setting up encrypted disks
+Name: cryptsetup
+Version: 2.0.3
+Release: 6%{?dist}
+License: GPLv2+ and LGPLv2+
+Group: Applications/System
+URL: https://gitlab.com/cryptsetup/cryptsetup
+BuildRequires: libgcrypt-devel, popt-devel, device-mapper-devel
+BuildRequires: libgpg-error-devel, libuuid-devel, libsepol-devel
+BuildRequires: libselinux-devel, gcc, libblkid-devel
+%if %{python2_enable}
+BuildRequires: python-devel
+%endif
+%if %{python3_enable}
+BuildRequires: python3-devel
+%endif
+BuildRequires: libpwquality-devel, json-c-devel
+%if 0%{?libargon2_enable}
+BuildRequires: libargon2-devel
+%endif
+Provides: cryptsetup-luks = %{version}-%{release}
+Obsoletes: cryptsetup-luks < 1.4.0
+Requires: cryptsetup-libs%{?_isa} = %{version}-%{release}
+Requires: libpwquality >= 1.2.0
+
+%define dracutmodulesdir %{_prefix}/lib/dracut/modules.d
+%define upstream_version %{version}
+%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
+Patch2: %{name}-1.7.5-fix-luksformat-in-fips-mode.patch
+Patch3: %{name}-1.7.6-fix-blockwise-access-functions-for-64k-page-size.patch
+Patch4: %{name}-1.7.6-crypt_deactivate-fail-earlier-when-holders-detected.patch
+# 2.0.x only
+Patch5: %{name}-2.0.4-dracut-reencrypt.patch
+Patch6: %{name}-new-avoid-rh-kernel-bug.patch
+Patch7: %{name}-sector-size-detection.patch
+Patch8: %{name}-tests-device-test.patch
+Patch9: %{name}-argon2-fips.patch
+Patch10: %{name}-2.0.4-zero-length-lseek-blockwise-i-o-should-return-zero.patch
+Patch11: %{name}-2.0.4-fix-write_lseek_blockwise-for-in-the-middle-of-secto.patch
+Patch12: %{name}-2.0.4-fix-write_blockwise-on-short-files.patch
+Patch13: %{name}-2.0.4-add-blkid-utilities-for-fast-detection-of-device-sig.patch
+Patch14: %{name}-2.0.4-make-LUKS2-auto-recovery-aware-of-device-signatures.patch
+Patch15: %{name}-2.0.4-allow-LUKS2-repair-to-override-blkid-checks.patch
+Patch16: %{name}-2.0.4-allow-explicit-LUKS2-repair.patch
+Patch17: %{name}-2.0.4-update-crypt_repair-API-documentation-for-LUKS2.patch
+Patch18: %{name}-2.0.4-allow-LUKS2-repair-with-disabled-locks.patch
+# the configure patch must be applied last
+Patch19: %{name}-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
+Patch33: %{name}-2.2.1-reinstate-missing-backing-file-hint-for-loop-device.patch
+
+%if 0%{?fedora} >= 19 || 0%{?rhel} >= 7
+%define configure_cipher --enable-gcrypt-pbkdf2
+%else
+%define configure_cipher --with-luks1-cipher=aes --with-luks1-mode=cbc-essiv:sha256 --with-luks1-keybits=256
+%endif
+
+%if 0%{?libargon2_enable}
+%define configure_libargon2 --enable-libargon2
+%endif
+%if 0%{?integritysetup_enable}
+%define configure_integritysetup --enable-integritysetup
+%else
+%define configure_integritysetup --disable-integritysetup
+%endif
+
+%description
+The cryptsetup package contains a utility for setting up
+disk encryption using dm-crypt kernel module.
+
+%package devel
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+Requires: libgcrypt-devel > 1.1.42, device-mapper-devel, libuuid-devel
+Requires: pkgconfig
+Summary: Headers and libraries for using encrypted file systems
+Provides: cryptsetup-luks-devel = %{version}-%{release}
+Obsoletes: cryptsetup-luks-devel < 1.4.0
+
+%description devel
+The cryptsetup-devel package contains libraries and header files
+used for writing code that makes use of disk encryption.
+
+%package libs
+Group: System Environment/Libraries
+Summary: Cryptsetup shared library
+Provides: cryptsetup-luks-libs = %{version}-%{release}
+Obsoletes: cryptsetup-luks-libs < 1.4.0
+Obsoletes: cryptsetup-reencrypt-libs < 1.6.5
+# Need support for empty password in gcrypt PBKDF2
+%if 0%{?fedora} >= 19 || 0%{?rhel} >= 7
+Requires: libgcrypt >= 1.5.3-3
+%endif
+
+%description libs
+This package contains the cryptsetup shared library, libcryptsetup.
+
+%package -n veritysetup
+Group: Applications/System
+Summary: A utility for setting up dm-verity volumes
+Requires: cryptsetup-libs = %{version}-%{release}
+
+%description -n veritysetup
+The veritysetup package contains a utility for setting up
+disk verification using dm-verity kernel module.
+
+%package reencrypt
+Group: Applications/System
+Summary: A utility for offline reencryption of LUKS encrypted disks.
+Provides: cryptsetup-reencrypt = %{version}-%{release}
+Obsoletes: cryptsetup-reencrypt < 1.6.5
+Requires: cryptsetup-libs = %{version}-%{release}
+
+%description reencrypt
+This package contains cryptsetup-reencrypt utility which
+can be used for offline reencryption of disk in situ.
+Also includes dracut module required to perform reencryption
+of device containing a root filesystem.
+
+%package python
+Group: System Environment/Libraries
+Summary: Python bindings for libcryptsetup
+Requires: %{name}-libs = %{version}-%{release}
+Provides: python-cryptsetup = %{version}-%{release}
+Obsoletes: python-cryptsetup < 1.4.0
+
+%description python
+This package provides Python bindings for libcryptsetup, a library
+for setting up disk encryption using dm-crypt kernel module.
+
+%if %{python3_enable}
+%package python3
+Group: System Environment/Libraries
+Summary: Python3 bindings for libcryptsetup
+Requires: %{name}-libs = %{version}-%{release}
+Provides: python3-cryptsetup = %{version}-%{release}
+
+%description python3
+This package provides Python bindings for libcryptsetup, a library
+for setting up disk encryption using dm-crypt kernel module.
+%endif
+
+%prep
+%setup -q -n cryptsetup-%{upstream_version}
+%patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%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
+%patch33 -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
+cp -a . %{py3dir}
+%endif
+
+%setup -T -a 1 -D -n cryptsetup-%{upstream_version}
+pushd cryptsetup-1.7.4
+%patch0 -p1
+%patch1 -p1
+%patch2 -p1
+%patch3 -p1
+%patch4 -p1
+
+%build
+%configure --enable-fips --enable-pwquality --with-default-luks-format=LUKS1 %{?configure_cipher} %{?configure_libargon2} %{?configure_integritysetup}
+pushd cryptsetup-1.7.4
+%configure --enable-python --enable-fips --enable-pwquality --disable-cryptsetup-reencrypt --disable-veritysetup %{?configure_cipher}
+# remove rpath
+sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
+sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
+make %{?_smp_mflags}
+popd
+# remove rpath
+sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
+sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
+make %{?_smp_mflags}
+
+%if %{python3_enable}
+pushd %{py3dir}
+%configure --enable-python --with-python_version=3
+make %{?_smp_mflags}
+popd
+%endif
+
+%install
+pushd cryptsetup-1.7.4
+make install DESTDIR=%{buildroot}
+popd
+make install DESTDIR=%{buildroot}
+rm -rf %{buildroot}/%{_libdir}/*.la
+
+%if %{python3_enable}
+pushd %{py3dir}
+make install DESTDIR=%{buildroot}
+rm -rf %{buildroot}/%{_libdir}/*.la
+popd
+%endif
+
+%find_lang cryptsetup
+
+install -d -m755 %{buildroot}/%{dracutmodulesdir}/90reencrypt
+install -m755 misc/dracut_90reencrypt/module-setup.sh %{buildroot}/%{dracutmodulesdir}/90reencrypt
+install -m755 misc/dracut_90reencrypt/parse-reencrypt.sh %{buildroot}/%{dracutmodulesdir}/90reencrypt
+install -m755 misc/dracut_90reencrypt/reencrypt.sh %{buildroot}/%{dracutmodulesdir}/90reencrypt
+install -m755 misc/dracut_90reencrypt/reencrypt-verbose.sh %{buildroot}/%{dracutmodulesdir}/90reencrypt
+
+%post -n cryptsetup-libs -p /sbin/ldconfig
+
+%postun -n cryptsetup-libs -p /sbin/ldconfig
+
+%files
+%{!?_licensedir:%global license %%doc}
+%license COPYING
+%doc AUTHORS FAQ docs/*ReleaseNotes
+%{_mandir}/man8/cryptsetup.8.gz
+%{_sbindir}/cryptsetup
+
+%files -n veritysetup
+%{!?_licensedir:%global license %%doc}
+%license COPYING
+%{_mandir}/man8/veritysetup.8.gz
+%{_sbindir}/veritysetup
+
+%if %{integritysetup_enable}
+%files -n integritysetup
+%{!?_licensedir:%global license %%doc}
+%license COPYING
+%{_mandir}/man8/integritysetup.8.gz
+%{_sbindir}/integritysetup
+%endif
+
+%files reencrypt
+%{!?_licensedir:%global license %%doc}
+%license COPYING
+%doc misc/dracut_90reencrypt/README
+%{_mandir}/man8/cryptsetup-reencrypt.8.gz
+%{_sbindir}/cryptsetup-reencrypt
+%{dracutmodulesdir}/90reencrypt
+%{dracutmodulesdir}/90reencrypt/*
+
+%files devel
+%doc docs/examples/*
+%{_includedir}/libcryptsetup.h
+%{_libdir}/libcryptsetup.so
+%{_libdir}/pkgconfig/libcryptsetup.pc
+
+%files libs -f cryptsetup.lang
+%{!?_licensedir:%global license %%doc}
+%license COPYING COPYING.LGPL
+%{_libdir}/libcryptsetup.so.*
+%{_tmpfilesdir}/cryptsetup.conf
+%ghost %attr(700, -, -) %dir /run/cryptsetup
+
+%files python
+%{!?_licensedir:%global license %%doc}
+%license COPYING.LGPL
+%doc python/pycryptsetup-test.py
+%exclude %{python_sitearch}/pycryptsetup.la
+%{python_sitearch}/pycryptsetup.so
+
+%if %{python3_enable}
+%files python3
+%{!?_licensedir:%global license %%doc}
+%license COPYING.LGPL
+%doc python/pycryptsetup-test.py
+%exclude %{python3_sitearch}/pycryptsetup.la
+%{python3_sitearch}/pycryptsetup.so
+%endif
+
+%clean
+
+%changelog
+* Tue Aug 27 2019 Ondrej Kozina <okozina@redhat.com> - 2.0.3-6
+- patch: Reinstate missing backing file hint for loop device
+  during unlock.
+- Resolves: #1726287
+
+* 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
+  script due to bug in upstream sources distribution.
+- Resolves: #1609847 #1610379
+
+* Mon Jul 16 2018 Ondrej Kozina <okozina@redhat.com> - 2.0.3-2
+- patch: stop LUKS2 auto-recovery if device is no longer LUKS
+  type
+- patch: update cryptsetup man page for --type option
+- patch: rephrase error message for invalid --type option in
+  convert action
+- Resolves: #1599281 #1601477 #1601481
+
+* Wed Jun 20 2018 Ondrej Kozina <okozina@redhat.com> - 2.0.3-1
+- Update to cryptsetup 2.0.3.
+- Resolves: #1475904 #1380347 #1416174 #1536105 #1574239
+
+* Thu Oct 19 2017 Ondrej Kozina <okozina@redhat.com> - 1.7.4-4
+- patch: fix regression in blockwise functions
+- patch: avoid repeating error messages when device holders
+  detected.
+- patch: add option to cryptsetup-reencrypt to print progress
+  log sequentaly
+- patch: use --progress-frequency in reencryption dracut module
+- Resolves: #1480006 #1447632 #1479857
+
+* Tue Apr 25 2017 Ondrej Kozina <okozina@redhat.com> - 1.7.4-3
+- patch: fix luksFormat failure while running in FIPS mode.
+- Resolves: #1444137
+
+* Tue Apr 04 2017 Ondrej Kozina <okozina@redhat.com> - 1.7.4-2
+- patch: fix access to unaligned hidden TrueCrypt header.
+- Resolves: #1435543
+
+* Wed Mar 15 2017 Ondrej Kozina <okozina@redhat.com> - 1.7.4-1
+- Update to cryptsetup 1.7.4.
+- Resolves: #1381273
+
+* Tue Jun  7 2016 Ondrej Kozina <okozina@redhat.com> - 1.7.2-1
+- Update to cryptsetup 1.7.2.
+- Resolves: #1302022 #1070825
+
+* Thu Jun 18 2015 Ondrej Kozina <okozina@redhat.com> - 1.6.7-1
+- Update to cryptsetup 1.6.7.
+- patch: avoid use of kernel crypto API socket which is known
+  to be broken in RHEL7.0 kernel (7.1+ is fine).
+- Resolves: #1206170
+
+* Thu Dec 18 2014 Ondrej Kozina <okozina@redhat.com> - 1.6.6-3
+- drop FIPS power on self test and library checksum
+- Resolves: #1158897
+
+* Mon Sep 29 2014 Ondrej Kozina <okozina@redhat.com> - 1.6.6-2
+- patch: fix failures related to reencrypt log files
+- Resolves: #1140199
+
+* Mon Sep  8 2014 Ondrej Kozina <okozina@redhat.com> - 1.6.6-1
+- Update to cryptsetup 1.6.6.
+- Resolves: #1117372 #1038097
+
+* Fri Jan 24 2014 Daniel Mach <dmach@redhat.com> - 1.6.3-2
+- Mass rebuild 2014-01-24
+
+* Mon Jan 6 2014 Ondrej Kozina <okozina@redhat.com> - 1.6.3-1
+- Update to cryptsetup 1.6.3.
+- various fixes related to block devices with 4KiB sectors
+- enable reencryption using specific keyslot (dracut module)
+- fix failure in reading last keyslot from external LUKS header
+- update FIPS POST to be complaint with actual requirements
+- fix hash limiting if parameter is not numeric
+- Resolves: #1028362 #1029032 #1029406 #1030288 #1034388 #1038097
+
+* Fri Dec 27 2013 Daniel Mach <dmach@redhat.com> - 1.6.2-3
+- Mass rebuild 2013-12-27
+
+* Tue Nov 5 2013 Ondrej Kozina <okozina@redhat.com> - 1.6.2-2
+- 90reencrypt: Move conflict with 90crypt to install() section.
+- 90reencrypt: Drop to emergency_shell after successful reencryption.
+- Resolves: #1021593
+
+* Mon Oct 14 2013 Ondrej Kozina <okozina@redhat.com> - 1.6.2-1
+- Update to cryptsetup 1.6.2.
+- Add dracut module for cryptsetup-reencrypt (90reencrypt).
+- 90reencrypt: Rename dracut parameteres to be compliant with actual naming guidance.
+- 90reencrypt: Install and load loop kernel module.
+- 90reencrypt: Fix lock file name.
+- 90reencrypt: Add conflict with 90crypt dracut module (more info in #1010287)
+- Resolves: #1010278 #1010287
+
+* Sun Mar 31 2013 Milan Broz <gmazyland@gmail.com> - 1.6.1-1
+- Update to cryptsetup 1.6.1.
+- Install ReleaseNotes files instead of empty Changelog file.
+
+* Wed Feb 13 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.6.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
+
+* Mon Jan 14 2013 Milan Broz <mbroz@redhat.com> - 1.6.0-1
+- Update to cryptsetup 1.6.0.
+- Change default LUKS encryption mode to aes-xts-plain64 (AES128).
+- Force use of gcrypt PBKDF2 instead of internal implementation.
+
+* Sat Dec 29 2012 Milan Broz <mbroz@redhat.com> - 1.6.0-0.1
+- Update to cryptsetup 1.6.0-rc1.
+- Relax license to GPLv2+ according to new release.
+- Compile cryptsetup with libpwquality support.
+
+* Tue Oct 16 2012 Milan Broz <mbroz@redhat.com> - 1.5.1-1
+- Update to cryptsetup 1.5.1.
+
+* Wed Jul 18 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.5.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jul 10 2012 Milan Broz <mbroz@redhat.com> - 1.5.0-1
+- Update to cryptsetup 1.5.0.
+
+* Wed Jun 20 2012 Milan Broz <mbroz@redhat.com> - 1.5.0-0.2
+- Update to cryptsetup 1.5.0-rc2.
+- Add cryptsetup-reencrypt subpackage.
+
+* Mon Jun 11 2012 Milan Broz <mbroz@redhat.com> - 1.5.0-0.1
+- Update to cryptsetup 1.5.0-rc1.
+- Add veritysetup subpackage.
+- Move localization files to libs subpackage.
+
+* Thu May 31 2012 Milan Broz <mbroz@redhat.com> - 1.4.3-2
+- Build with fipscheck (verification in fips mode).
+- Clean up spec file, use install to /usr.
+
+* Thu May 31 2012 Milan Broz <mbroz@redhat.com> - 1.4.3-1
+- Update to cryptsetup 1.4.3.
+
+* Thu Apr 12 2012 Milan Broz <mbroz@redhat.com> - 1.4.2-1
+- Update to cryptsetup 1.4.2.
+
+* Fri Jan 13 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.4.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Wed Nov 09 2011 Milan Broz <mbroz@redhat.com> - 1.4.1-1
+- Update to cryptsetup 1.4.1.
+- Add Python cryptsetup bindings.
+- Obsolete separate python-cryptsetup package.
+
+* Wed Oct 26 2011 Milan Broz <mbroz@redhat.com> - 1.4.0-1
+- Update to cryptsetup 1.4.0.
+
+* Mon Oct 10 2011 Milan Broz <mbroz@redhat.com> - 1.4.0-0.1
+- Update to cryptsetup 1.4.0-rc1.
+- Rename package back from cryptsetup-luks to cryptsetup.
+
+* Wed Jun 22 2011 Milan Broz <mbroz@redhat.com> - 1.3.1-2
+- Fix return code for status command when device doesn't exist.
+
+* Tue May 24 2011 Milan Broz <mbroz@redhat.com> - 1.3.1-1
+- Update to cryptsetup 1.3.1.
+
+* Tue Apr 05 2011 Milan Broz <mbroz@redhat.com> - 1.3.0-1
+- Update to cryptsetup 1.3.0.
+
+* Tue Mar 22 2011 Milan Broz <mbroz@redhat.com> - 1.3.0-0.2
+- Update to cryptsetup 1.3.0-rc2
+
+* Mon Mar 14 2011 Milan Broz <mbroz@redhat.com> - 1.3.0-0.1
+- Update to cryptsetup 1.3.0-rc1
+
+* Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.2.0-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Mon Dec 20 2010 Milan Broz <mbroz@redhat.com> - 1.2.0-1
+- Update to cryptsetup 1.2.0
+
+* Thu Nov 25 2010 Milan Broz <mbroz@redhat.com> - 1.2.0-0.2
+- Fix crypt_activate_by_keyfile() to work with PLAIN devices.
+
+* Tue Nov 16 2010 Milan Broz <mbroz@redhat.com> - 1.2.0-0.1
+- Add FAQ to documentation.
+- Update to cryptsetup 1.2.0-rc1
+
+* Sat Jul 03 2010 Milan Broz <mbroz@redhat.com> - 1.1.3-1
+- Update to cryptsetup 1.1.3
+
+* Mon Jun 07 2010 Milan Broz <mbroz@redhat.com> - 1.1.2-2
+- Fix alignment ioctl use.
+- Fix API activation calls to handle NULL device name.
+
+* Sun May 30 2010 Milan Broz <mbroz@redhat.com> - 1.1.2-1
+- Update to cryptsetup 1.1.2
+- Fix luksOpen handling of new line char on stdin.
+
+* Sun May 23 2010 Milan Broz <mbroz@redhat.com> - 1.1.1-1
+- Update to cryptsetup 1.1.1
+- Fix luksClose for stacked LUKS/LVM devices.
+
+* Mon May 03 2010 Milan Broz <mbroz@redhat.com> - 1.1.1-0.2
+- Update to cryptsetup 1.1.1-rc2.
+
+* Sat May 01 2010 Milan Broz <mbroz@redhat.com> - 1.1.1-0.1
+- Update to cryptsetup 1.1.1-rc1.
+
+* Sun Jan 17 2010 Milan Broz <mbroz@redhat.com> - 1.1.0-1
+- Update to cryptsetup 1.1.0.
+
+* Fri Jan 15 2010 Milan Broz <mbroz@redhat.com> - 1.1.0-0.6
+- Fix gcrypt initialisation.
+- Fix backward compatibility for hash algorithm (uppercase).
+
+* Wed Dec 30 2009 Milan Broz <mbroz@redhat.com> - 1.1.0-0.5
+- Update to cryptsetup 1.1.0-rc4
+
+* Mon Nov 16 2009 Milan Broz <mbroz@redhat.com> - 1.1.0-0.4
+- Update to cryptsetup 1.1.0-rc3
+
+* Thu Oct 01 2009 Milan Broz <mbroz@redhat.com> - 1.1.0-0.3
+- Update to cryptsetup 1.1.0-rc2
+- Fix libcryptsetup to properly export only versioned symbols.
+
+* Tue Sep 29 2009 Milan Broz <mbroz@redhat.com> - 1.1.0-0.2
+- Update to cryptsetup 1.1.0-rc1
+- Add luksHeaderBackup and luksHeaderRestore commands.
+
+* Fri Sep 11 2009 Milan Broz <mbroz@redhat.com> - 1.1.0-0.1
+- Update to new upstream testing version with new API interface.
+- Add luksSuspend and luksResume commands.
+- Introduce pkgconfig.
+
+* Fri Jul 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.0.7-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Wed Jul 22 2009 Milan Broz <mbroz@redhat.com> - 1.0.7-1
+- Update to upstream final release.
+- Split libs subpackage.
+- Remove rpath setting from cryptsetup binary.
+
+* Wed Jul 15 2009 Till Maas <opensource@till.name> - 1.0.7-0.2
+- update BR because of libuuid splitout from e2fsprogs
+
+* Mon Jun 22 2009 Milan Broz <mbroz@redhat.com> - 1.0.7-0.1
+- Update to new upstream 1.0.7-rc1.
+
+- Wipe old fs headers to not confuse blkid (#468062)
+* Tue Feb 24 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 1.0.6-7
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Thu Oct 30 2008 Milan Broz <mbroz@redhat.com> - 1.0.6-6
+- Wipe old fs headers to not confuse blkid (#468062)
+
+* Tue Sep 23 2008 Milan Broz <mbroz@redhat.com> - 1.0.6-5
+- Change new project home page.
+- Print more descriptive messages for initialization errors.
+- Refresh patches to versions commited upstream.
+
+* Sat Sep 06 2008 Milan Broz <mbroz@redhat.com> - 1.0.6-4
+- Fix close of zero decriptor.
+- Fix udevsettle delays - use temporary crypt device remapping.
+
+* Wed May 28 2008 Till Maas <opensource till name> - 1.0.6-3
+- remove a duplicate sentence from the manpage (RH #448705)
+- add patch metadata about upstream status
+
+* Tue Apr 15 2008 Bill Nottinghm <notting@redhat.com> - 1.0.6-2
+- Add the device to the luksOpen prompt (#433406)
+- Use iconv, not recode (#442574)
+
+* Thu Mar 13 2008 Till Maas <opensource till name> - 1.0.6-1
+- Update to latest version
+- remove patches that have been merged upstream
+
+* Mon Mar 03 2008 Till Maas <opensource till name> - 1.0.6-0.1.pre2
+- Update to new version with several bugfixes
+- remove patches that have been merged upstream
+- add patch from cryptsetup newsgroup
+- fix typo / missing luksRemoveKey in manpage (patch)
+
+* Tue Feb 19 2008 Fedora Release Engineering <rel-eng@fedoraproject.org> - 1.0.5-9
+- Autorebuild for GCC 4.3
+
+* Sat Jan 19 2008 Peter Jones <pjones@redhat.com> - 1.0.5-8
+- Rebuild for broken deps.
+
+* Thu Aug 30 2007 Till Maas <opensource till name> - 1.0.5-7
+- update URL
+- update license tag
+- recode ChangeLog from latin1 to uf8
+- add smp_mflags to make
+
+* Fri Aug 24 2007 Till Maas <opensource till name> - 1.0.5-6
+- cleanup BuildRequires:
+- removed versions, packages in Fedora are new enough
+- changed popt to popt-devel
+
+* Thu Aug 23 2007 Till Maas <opensource till name> - 1.0.5-5
+- fix devel subpackage requires
+- remove empty NEWS README
+- remove uneeded INSTALL
+- remove uneeded ldconfig requires
+- add readonly detection patch
+
+* Wed Aug 08 2007 Till Maas <opensource till name> - 1.0.5-4
+- disable patch2, libsepol is now detected by configure
+- move libcryptsetup.so to %%{_libdir} instead of /%%{_lib}
+
+* Fri Jul 27 2007 Till Maas <opensource till name> - 1.0.5-3
+- Use /%%{_lib} instead of /lib to use /lib64 on 64bit archs
+
+* Thu Jul 26 2007 Till Maas <opensource till name> - 1.0.5-2
+- Use /lib as libdir (#243228)
+- sync header and library (#215349)
+- do not use %%makeinstall (recommended by PackageGuidelines)
+- select sbindir with %%configure instead with make
+- add TODO
+
+* Wed Jun 13 2007 Jeremy Katz <katzj@redhat.com> - 1.0.5-1
+- update to 1.0.5
+
+* Mon Jun 04 2007 Peter Jones <pjones@redhat.com> - 1.0.3-5
+- Don't build static any more.
+
+* Mon Feb 05 2007 Alasdair Kergon <agk@redhat.com> - 1.0.3-4
+- Add build dependency on new device-mapper-devel package.
+- Add preun and post ldconfig requirements.
+- Update BuildRoot.
+
+* Wed Nov  1 2006 Peter Jones <pjones@redhat.com> - 1.0.3-3
+- Require newer libselinux (#213414)
+
+* Wed Jul 12 2006 Jesse Keating <jkeating@redhat.com> - 1.0.3-2.1
+- rebuild
+
+* Wed Jun  7 2006 Jeremy Katz <katzj@redhat.com> - 1.0.3-2
+- put shared libs in the right subpackages
+
+* Fri Apr  7 2006 Bill Nottingham <notting@redhat.com> 1.0.3-1
+- update to final 1.0.3
+
+* Mon Feb 27 2006 Bill Nottingham <notting@redhat.com> 1.0.3-0.rc2
+- update to 1.0.3rc2, fixes bug with HAL & encrypted devices (#182658)
+
+* Wed Feb 22 2006 Bill Nottingham <notting@redhat.com> 1.0.3-0.rc1
+- update to 1.0.3rc1, reverts changes to default encryption type
+
+* Tue Feb 21 2006 Bill Nottingham <notting@redhat.com> 1.0.2-1
+- update to 1.0.2, fix incompatiblity with old cryptsetup (#176726)
+
+* Mon Feb 20 2006 Karsten Hopp <karsten@redhat.de> 1.0.1-5
+- BuildRequires: libselinux-devel
+
+* Fri Feb 10 2006 Jesse Keating <jkeating@redhat.com> - 1.0.1-4.2.1
+- bump again for double-long bug on ppc(64)
+
+* Tue Feb 07 2006 Jesse Keating <jkeating@redhat.com> - 1.0.1-4.2
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Fri Dec 09 2005 Jesse Keating <jkeating@redhat.com>
+- rebuilt
+
+* Mon Dec  5 2005 Bill Nottingham <notting@redhat.com> 1.0.1-4
+- rebuild against new libdevmapper
+
+* Thu Oct 13 2005 Florian La Roche <laroche@redhat.com>
+- add -lsepol to rebuild on current fc5
+
+* Mon Aug 22 2005 Karel Zak <kzak@redhat.com> 1.0.1-2
+- fix cryptsetup help for isLuks action
+
+* Fri Jul  1 2005 Bill Nottingham <notting@redhat.com> 1.0.1-1
+- update to 1.0.1 - fixes incompatiblity with previous cryptsetup for
+  piped passwords
+
+* Thu Jun 16 2005 Bill Nottingham <notting@redhat.com> 1.0-2
+- add patch for 32/64 bit compatibility (#160445, <redhat@paukstadt.de>)
+
+* Tue Mar 29 2005 Bill Nottingham <notting@redhat.com> 1.0-1
+- update to 1.0
+
+* Thu Mar 10 2005 Bill Nottingham <notting@redhat.com> 0.993-1
+- switch to cryptsetup-luks, for LUKS support
+
+* Tue Oct 12 2004 Bill Nottingham <notting@redhat.com> 0.1-4
+- oops, make that *everything* static (#129926)
+
+* Tue Aug 31 2004 Bill Nottingham <notting@redhat.com> 0.1-3
+- link some things static, move to /sbin (#129926)
+
+* Tue Jun 15 2004 Elliot Lee <sopwith@redhat.com>
+- rebuilt
+
+* Fri Apr 16 2004 Bill Nottingham <notting@redhat.com> 0.1-1
+- initial packaging