diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index e4752cd0..e65d65fd 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -148,8 +148,29 @@ void crypt_set_confirm_callback(struct crypt_device *cd, * @param cd crypt device handle * @param device path to device * + * @returns 0 on success or negative errno value otherwise. */ int crypt_set_data_device(struct crypt_device *cd, const char *device); + +/** + * Set data device offset in 512-byte sectors. + * Used for LUKS. + * This function is replacement for data alignment fields in LUKS param struct. + * If set to 0 (default), old behaviour is preserved. + * This value is reset on @link crypt_load @endlink. + * + * @param cd crypt device handle + * @param data_offset data offset in bytes + * + * @returns 0 on success or negative errno value otherwise. + * + * @note Data offset must be aligned to multiple of 8 (alignment to 4096-byte sectors) + * and must be big enough to accomodate the whole LUKS header with all keyslots. + * @note Data offset is enforced by this function, device topology + * information is no longer used after calling this function. + */ +int crypt_set_data_offset(struct crypt_device *cd, uint64_t data_offset); + /** @} */ /** diff --git a/lib/libcryptsetup.sym b/lib/libcryptsetup.sym index 3740bde7..492cb524 100644 --- a/lib/libcryptsetup.sym +++ b/lib/libcryptsetup.sym @@ -69,6 +69,7 @@ CRYPTSETUP_2.0 { crypt_get_cipher_mode; crypt_get_integrity_info; crypt_get_uuid; + crypt_set_data_offset; crypt_get_data_offset; crypt_get_iv_offset; crypt_get_volume_key_size; diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c index 0e69dd34..b9028225 100644 --- a/lib/luks1/keymanage.c +++ b/lib/luks1/keymanage.c @@ -417,8 +417,7 @@ static int _keyslot_repair(struct luks_phdr *phdr, struct crypt_device *ctx) /* payloadOffset - cannot check */ r = LUKS_generate_phdr(&temp_phdr, vk, phdr->cipherName, phdr->cipherMode, phdr->hashSpec,phdr->uuid, LUKS_STRIPES, - phdr->payloadOffset, 0, - 1, ctx); + phdr->payloadOffset * SECTOR_SIZE, 0, true, ctx); if (r < 0) goto out; @@ -725,12 +724,12 @@ int LUKS_generate_phdr(struct luks_phdr *header, const struct volume_key *vk, const char *cipherName, const char *cipherMode, const char *hashSpec, const char *uuid, unsigned int stripes, - unsigned int alignPayload, - unsigned int alignOffset, - int detached_metadata_device, + uint64_t data_offset, + uint64_t align_offset, + bool fixed_data_offset, struct crypt_device *ctx) { - unsigned int i = 0, hdr_sectors = LUKS_calculate_device_sectors(vk->keylength); + unsigned int i = 0, alignPayload, alignOffset, hdr_sectors = LUKS_calculate_device_sectors(vk->keylength); size_t blocksPerStripeSet, currentSector; int r; uuid_t partitionUuid; @@ -738,14 +737,14 @@ int LUKS_generate_phdr(struct luks_phdr *header, double PBKDF2_temp; char luksMagic[] = LUKS_MAGIC; - /* For separate metadata device allow zero alignment */ - if (alignPayload == 0 && !detached_metadata_device) - alignPayload = DEFAULT_DISK_ALIGNMENT / SECTOR_SIZE; + if (data_offset % SECTOR_SIZE || align_offset % SECTOR_SIZE) + return -EINVAL; + alignPayload = data_offset / SECTOR_SIZE; + alignOffset = align_offset / SECTOR_SIZE; - if (alignPayload && detached_metadata_device && alignPayload < hdr_sectors) { + if (alignPayload && fixed_data_offset && alignPayload < hdr_sectors) { log_err(ctx, _("Data offset for detached LUKS header must be " - "either 0 or higher than header size (%d sectors)."), - hdr_sectors); + "either 0 or higher than header size.")); return -EINVAL; } @@ -816,7 +815,7 @@ int LUKS_generate_phdr(struct luks_phdr *header, LUKS_ALIGN_KEYSLOTS / SECTOR_SIZE); } - if (detached_metadata_device) { + if (fixed_data_offset) { /* for separate metadata device use alignPayload directly */ header->payloadOffset = alignPayload; } else { diff --git a/lib/luks1/luks.h b/lib/luks1/luks.h index 18d8545f..0b05d115 100644 --- a/lib/luks1/luks.h +++ b/lib/luks1/luks.h @@ -26,6 +26,7 @@ * LUKS partition header */ +#include #include "libcryptsetup.h" #define LUKS_CIPHERNAME_L 32 @@ -115,9 +116,9 @@ int LUKS_generate_phdr( const char *hashSpec, const char *uuid, unsigned int stripes, - unsigned int alignPayload, - unsigned int alignOffset, - int detached_metadata_device, + uint64_t data_offset, + uint64_t align_offset, + bool fixed_data_offset, struct crypt_device *ctx); int LUKS_read_phdr( diff --git a/lib/luks2/luks2.h b/lib/luks2/luks2.h index 4290831f..2b1e1b7e 100644 --- a/lib/luks2/luks2.h +++ b/lib/luks2/luks2.h @@ -22,6 +22,7 @@ #ifndef _CRYPTSETUP_LUKS2_ONDISK_H #define _CRYPTSETUP_LUKS2_ONDISK_H +#include #include "libcryptsetup.h" #define LUKS2_MAGIC_1ST "LUKS\xba\xbe" @@ -323,9 +324,9 @@ int LUKS2_generate_hdr( const char *integrity, const char *uuid, unsigned int sector_size, - unsigned int alignPayload, - unsigned int alignOffset, - int detached_metadata_device); + uint64_t data_offset, + uint64_t align_offset, + bool fixed_data_offset); int LUKS2_check_metadata_area_size(uint64_t metadata_size); int LUKS2_check_keyslots_area_size(uint64_t keyslots_size); diff --git a/lib/luks2/luks2_json_format.c b/lib/luks2/luks2_json_format.c index 5e3d6303..678d113c 100644 --- a/lib/luks2/luks2_json_format.c +++ b/lib/luks2/luks2_json_format.c @@ -139,9 +139,9 @@ int LUKS2_generate_hdr( const char *integrity, const char *uuid, unsigned int sector_size, /* in bytes */ - unsigned int alignPayload, /* in bytes */ - unsigned int alignOffset, /* in bytes */ - int detached_metadata_device) + uint64_t data_offset, /* in bytes */ + uint64_t align_offset, /* in bytes */ + bool fixed_data_offset) { struct json_object *jobj_segment, *jobj_integrity, *jobj_keyslots, *jobj_segments, *jobj_config; char num[24], cipher[128]; @@ -197,13 +197,13 @@ 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; + if (fixed_data_offset) + offset = data_offset; 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); - offset += alignOffset; + offset = size_round_up(LUKS2_HDR_DEFAULT_LEN, (size_t)data_offset); + offset += align_offset; } json_object_object_add(jobj_segment, "offset", json_object_new_uint64(offset)); @@ -228,7 +228,7 @@ int LUKS2_generate_hdr( /* for detached metadata device compute reasonable keyslot areas size */ // FIXME: this is coupled with FIXME above - if (detached_metadata_device && !offset) + if (fixed_data_offset && !offset) keyslots_size = LUKS2_HDR_DEFAULT_LEN - get_min_offset(hdr); else keyslots_size = offset - get_min_offset(hdr); diff --git a/lib/setup.c b/lib/setup.c index f3aa87b7..0094ca97 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -54,6 +54,8 @@ struct crypt_device { /* global context scope settings */ unsigned key_in_keyring:1; + uint64_t data_offset; + // FIXME: private binary headers and access it properly // through sub-library (LUKS1, TCRYPT) @@ -359,6 +361,7 @@ static void crypt_set_null_type(struct crypt_device *cd) free(cd->type); cd->type = NULL; cd->u.none.active_name = NULL; + cd->data_offset = 0; } static void crypt_reset_null_type(struct crypt_device *cd) @@ -945,6 +948,7 @@ int crypt_load(struct crypt_device *cd, return -EINVAL; crypt_reset_null_type(cd); + cd->data_offset = 0; if (!requested_type || isLUKS1(requested_type) || isLUKS2(requested_type)) { if (cd->type && !isLUKS1(cd->type) && !isLUKS2(cd->type)) { @@ -1439,6 +1443,12 @@ static int _crypt_format_luks1(struct crypt_device *cd, return -EINVAL; } + if (params && cd->data_offset && params->data_alignment && + (cd->data_offset % params->data_alignment)) { + log_err(cd, _("Requested data alignment is not compatible with data offset.")); + return -EINVAL; + } + if (!(cd->type = strdup(CRYPT_LUKS1))) return -ENOMEM; @@ -1474,9 +1484,14 @@ static int _crypt_format_luks1(struct crypt_device *cd, return -ENOMEM; } - if (params && (params->data_alignment || cd->metadata_device)) + if (params && cd->metadata_device) { + /* For detached header the alignment is used directly as data offset */ + if (!cd->data_offset) + cd->data_offset = params->data_alignment; required_alignment = params->data_alignment * SECTOR_SIZE; - else + } else if (params && params->data_alignment) { + required_alignment = params->data_alignment * SECTOR_SIZE; + } else device_topology_alignment(cd, cd->device, &required_alignment, &alignment_offset, DEFAULT_DISK_ALIGNMENT); @@ -1485,11 +1500,18 @@ static int _crypt_format_luks1(struct crypt_device *cd, if (r < 0) return r; + /* New data_offset has priority */ + if (cd->data_offset) { + required_alignment = cd->data_offset * SECTOR_SIZE; + /* Check overflow */ + if (required_alignment != (cd->data_offset * (uint64_t)SECTOR_SIZE)) + return -EINVAL; + } + r = LUKS_generate_phdr(&cd->u.luks1.hdr, cd->volume_key, cipher, cipher_mode, cd->pbkdf.hash, uuid, LUKS_STRIPES, - required_alignment / SECTOR_SIZE, - alignment_offset / SECTOR_SIZE, - cd->metadata_device ? 1 : 0, cd); + required_alignment, alignment_offset, + (cd->data_offset || cd->metadata_device), cd); if (r < 0) return r; @@ -1534,6 +1556,12 @@ static int _crypt_format_luks2(struct crypt_device *cd, return -EINVAL; } + if (params && cd->data_offset && params->data_alignment && + (cd->data_offset % params->data_alignment)) { + log_err(cd, _("Requested data alignment is not compatible with data offset.")); + return -EINVAL; + } + if (sector_size < SECTOR_SIZE || sector_size > MAX_SECTOR_SIZE || NOTPOW2(sector_size)) { log_err(cd, _("Unsupported encryption sector size.")); @@ -1598,9 +1626,14 @@ static int _crypt_format_luks2(struct crypt_device *cd, return -ENOMEM; } - if (params && (params->data_alignment || cd->metadata_device)) + if (params && cd->metadata_device) { + /* For detached header the alignment is used directly as data offset */ + if (!cd->data_offset) + cd->data_offset = params->data_alignment; required_alignment = params->data_alignment * SECTOR_SIZE; - else + } else if (params && params->data_alignment) { + required_alignment = params->data_alignment * SECTOR_SIZE; + } else device_topology_alignment(cd, cd->device, &required_alignment, &alignment_offset, DEFAULT_DISK_ALIGNMENT); @@ -1623,13 +1656,23 @@ static int _crypt_format_luks2(struct crypt_device *cd, goto out; } + /* New data_offset has priority */ + if (cd->data_offset) { + required_alignment = cd->data_offset * SECTOR_SIZE; + /* Check overflow */ + if (required_alignment != (cd->data_offset * (uint64_t)SECTOR_SIZE)) { + r = -EINVAL; + goto out; + } + } + r = LUKS2_generate_hdr(cd, &cd->u.luks2.hdr, cd->volume_key, cipher, cipher_mode, integrity, uuid, sector_size, required_alignment, alignment_offset, - cd->metadata_device ? 1 : 0); + (cd->data_offset || cd->metadata_device)); if (r < 0) goto out; @@ -3904,6 +3947,21 @@ int crypt_keyslot_get_key_size(struct crypt_device *cd, int keyslot) return -EINVAL; } +int crypt_set_data_offset(struct crypt_device *cd, uint64_t data_offset) +{ + if (!cd) + return -EINVAL; + if (data_offset % (MAX_SECTOR_SIZE >> SECTOR_SHIFT)) { + log_err(cd, "Data offset is not multiple of %u bytes.", MAX_SECTOR_SIZE); + return -EINVAL; + } + + cd->data_offset = data_offset; + log_dbg(cd, "Data offset set to %" PRIu64 " (512-byte) sectors.", data_offset); + + return 0; +} + uint64_t crypt_get_data_offset(struct crypt_device *cd) { if (!cd) @@ -3924,7 +3982,7 @@ uint64_t crypt_get_data_offset(struct crypt_device *cd) if (isTCRYPT(cd->type)) return TCRYPT_get_data_offset(cd, &cd->u.tcrypt.hdr, &cd->u.tcrypt.params); - return 0; + return cd->data_offset; } uint64_t crypt_get_iv_offset(struct crypt_device *cd) diff --git a/tests/api-test-2.c b/tests/api-test-2.c index 6fdebab4..f78d9c7e 100644 --- a/tests/api-test-2.c +++ b/tests/api-test-2.c @@ -556,6 +556,7 @@ static void SuspendDevice(void) static void AddDeviceLuks2(void) { + enum { OFFSET_1M = 2048 , OFFSET_2M = 4096, OFFSET_4M = 8192, OFFSET_8M = 16384 }; struct crypt_device *cd; struct crypt_pbkdf_type pbkdf = { .type = CRYPT_KDF_ARGON2I, @@ -608,10 +609,35 @@ static void AddDeviceLuks2(void) OK_(!(crypt_get_data_offset(cd) > 0)); crypt_free(cd); + // set_data_offset has priority, alignment must be 0 or must be compatible + params.data_alignment = 0; + OK_(crypt_init(&cd, DEVICE_2)); + OK_(crypt_set_data_offset(cd, OFFSET_8M)); + OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + EQ_(crypt_get_data_offset(cd), OFFSET_8M); + crypt_free(cd); + + // Load gets the value from metadata + OK_(crypt_init(&cd, DEVICE_2)); + OK_(crypt_set_data_offset(cd, OFFSET_2M)); + OK_(crypt_load(cd, CRYPT_LUKS2, DEVICE_2)); + EQ_(crypt_get_data_offset(cd), OFFSET_8M); + crypt_free(cd); + + params.data_alignment = OFFSET_4M; + OK_(crypt_init(&cd, DEVICE_2)); + FAIL_(crypt_set_data_offset(cd, OFFSET_2M + 1), "Not aligned to 4096"); // must be aligned to 4k + OK_(crypt_set_data_offset(cd, OFFSET_2M)); + FAIL_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms), "Alignment not compatible"); + OK_(crypt_set_data_offset(cd, OFFSET_4M)); + OK_(crypt_format(cd, CRYPT_LUKS2, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + EQ_(crypt_get_data_offset(cd), OFFSET_4M); + crypt_free(cd); + /* * test limit values for backing device size */ - params.data_alignment = 8192; + params.data_alignment = OFFSET_4M; OK_(get_luks2_offsets(0, params.data_alignment, 0, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_0S, r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1)); @@ -673,7 +699,7 @@ static void AddDeviceLuks2(void) OK_(crypt_deactivate(cd, CDEVICE_1)); crypt_free(cd); - params.data_alignment = 2048; + params.data_alignment = OFFSET_1M; params.data_device = NULL; // test uuid mismatch and _init_by_name_and_header diff --git a/tests/api-test.c b/tests/api-test.c index 08a96ee1..2b3ed97a 100644 --- a/tests/api-test.c +++ b/tests/api-test.c @@ -734,10 +734,11 @@ static void SuspendDevice(void) static void AddDeviceLuks(void) { + enum { OFFSET_1M = 2048 , OFFSET_2M = 4096, OFFSET_4M = 8192, OFFSET_8M = 16384 }; struct crypt_device *cd; struct crypt_params_luks1 params = { .hash = "sha512", - .data_alignment = 2048, // 4M, data offset will be 4096 + .data_alignment = OFFSET_1M, // 4M, data offset will be 4096 .data_device = DEVICE_2 }; char key[128], key2[128], key3[128]; @@ -779,10 +780,35 @@ static void AddDeviceLuks(void) OK_(!(crypt_get_data_offset(cd) > 0)); crypt_free(cd); + // set_data_offset has priority, alignment must be 0 or must be compatible + params.data_alignment = 0; + OK_(crypt_init(&cd, DEVICE_2)); + OK_(crypt_set_data_offset(cd, OFFSET_8M)); + OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + EQ_(crypt_get_data_offset(cd), OFFSET_8M); + crypt_free(cd); + + // Load gets the value from metadata + OK_(crypt_init(&cd, DEVICE_2)); + OK_(crypt_set_data_offset(cd, OFFSET_2M)); + OK_(crypt_load(cd, CRYPT_LUKS1, DEVICE_2)); + EQ_(crypt_get_data_offset(cd), OFFSET_8M); + crypt_free(cd); + + params.data_alignment = OFFSET_4M; + OK_(crypt_init(&cd, DEVICE_2)); + FAIL_(crypt_set_data_offset(cd, OFFSET_2M + 1), "Not aligned to 4096"); // must be aligned to 4k + OK_(crypt_set_data_offset(cd, OFFSET_2M)); + FAIL_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms), "Alignment not compatible"); + OK_(crypt_set_data_offset(cd, OFFSET_4M)); + OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, ¶ms)); + EQ_(crypt_get_data_offset(cd), OFFSET_4M); + crypt_free(cd); + /* * test limit values for backing device size */ - params.data_alignment = 4096; + params.data_alignment = OFFSET_2M; OK_(get_luks_offsets(0, key_size, params.data_alignment, 0, NULL, &r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_0S, r_payload_offset)); OK_(create_dmdevice_over_loop(L_DEVICE_1S, r_payload_offset + 1)); @@ -844,7 +870,7 @@ static void AddDeviceLuks(void) OK_(crypt_deactivate(cd, CDEVICE_1)); crypt_free(cd); - params.data_alignment = 2048; + params.data_alignment = OFFSET_1M; params.data_device = NULL; // test uuid mismatch and _init_by_name_and_header @@ -936,7 +962,7 @@ static void AddDeviceLuks(void) OK_(strcmp(cipher, crypt_get_cipher(cd))); OK_(strcmp(cipher_mode, crypt_get_cipher_mode(cd))); EQ_((int)key_size, crypt_get_volume_key_size(cd)); - EQ_(4096, crypt_get_data_offset(cd)); + EQ_(OFFSET_2M, crypt_get_data_offset(cd)); OK_(strcmp(DEVICE_2, crypt_get_device_name(cd))); reset_log(); diff --git a/tests/compat-test b/tests/compat-test index 6123ee48..55801137 100755 --- a/tests/compat-test +++ b/tests/compat-test @@ -369,7 +369,7 @@ echo "$PWD1" | $CRYPTSETUP -q luksOpen $LOOPDEV $DEV_NAME || fail $CRYPTSETUP -q luksClose $DEV_NAME || fail prepare "[15] UUID - use and report provided UUID" wipe -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --uuid blah $LOOPDEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --uuid blah $LOOPDEV 2>/dev/null && fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT --uuid $TEST_UUID $LOOPDEV || fail tst=$($CRYPTSETUP -q luksUUID $LOOPDEV) [ "$tst"x = "$TEST_UUID"x ] || fail @@ -519,9 +519,9 @@ prepare "[20] Disallow open/create if already mapped." wipe $CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 || fail $CRYPTSETUP create $DEV_NAME $LOOPDEV -d $KEY1 2>/dev/null && fail $CRYPTSETUP create $DEV_NAME2 $LOOPDEV -d $KEY1 2>/dev/null && fail -echo $PWD1 | $CRYPTSETUP -q luksFormat $LOOPDEV 2>/dev/null && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $LOOPDEV 2>/dev/null && fail $CRYPTSETUP remove $DEV_NAME || fail -echo $PWD1 | $CRYPTSETUP -q luksFormat $LOOPDEV || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $LOOPDEV || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV $DEV_NAME2 2>/dev/null && fail $CRYPTSETUP luksClose $DEV_NAME || fail @@ -675,7 +675,7 @@ $CRYPTSETUP luksOpen -S 5 -d $KEY1 $LOOPDEV $DEV_NAME 2>/dev/null && fail prepare "[28] Detached LUKS header" wipe echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG || fail -echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 1 >/dev/null 2>&1 && fail +echo $PWD1 | $CRYPTSETUP luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 1 >/dev/null 2>&1 && fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 8192 || fail echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks1 $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 0 || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail diff --git a/tests/compat-test2 b/tests/compat-test2 index 79151f5d..58d7620c 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -619,8 +619,7 @@ echo $PWD1 | $CRYPTSETUP open -S1 $HEADER_KEYU $DEV_NAME && fail prepare "[28] Detached LUKS header" wipe echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG || fail -#FIXME -#echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT $LOOPDEV --header $HEADER_IMG --align-payload 1 >/dev/null 2>&1 && fail +echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 1 >/dev/null 2>&1 && fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 8192 || fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 4096 || fail $CRYPTSETUP luksDump $HEADER_IMG | grep -e "0: crypt" -A1 | grep -qe $((4096*512)) || fail