diff --git a/lib/luks2/luks2_json_format.c b/lib/luks2/luks2_json_format.c index 313e9f51..0950a12d 100644 --- a/lib/luks2/luks2_json_format.c +++ b/lib/luks2/luks2_json_format.c @@ -154,19 +154,48 @@ int LUKS2_generate_hdr( metadata_size = LUKS2_HDR_16K_LEN; hdr->hdr_size = metadata_size; + if (data_offset && data_offset < get_min_offset(hdr)) { + log_err(cd, _("Requested data offset is too small.")); + return -EINVAL; + } + + /* Increase keyslot size according to data offset */ + if (!keyslots_size && data_offset) + keyslots_size = data_offset - get_min_offset(hdr); + + /* keyslots size has to be 4 KiB aligned */ + keyslots_size -= (keyslots_size % 4096); + + if (keyslots_size > LUKS2_MAX_KEYSLOTS_SIZE) + keyslots_size = LUKS2_MAX_KEYSLOTS_SIZE; + if (!keyslots_size) keyslots_size = LUKS2_DEFAULT_KEYSLOTS_SIZE; /* Decrease keyslots_size if we have smaller data_offset */ - if (data_offset && (keyslots_size + get_min_offset(hdr)) > data_offset) + if (data_offset && (keyslots_size + get_min_offset(hdr)) > data_offset) { keyslots_size = data_offset - get_min_offset(hdr); + log_dbg(cd, "Decreasing keyslot area size to %" PRIu64 + " bytes due to the requested data offset %" + PRIu64 " bytes.", keyslots_size, data_offset); + } /* Data offset has priority */ if (!data_offset && required_alignment) { - data_offset = size_round_up(get_min_offset(hdr) + keyslots_size, (size_t)required_alignment); + data_offset = size_round_up(get_min_offset(hdr) + keyslots_size, + (size_t)required_alignment); data_offset += align_offset; } + log_dbg(cd, "Formatting LUKS2 with JSON metadata area %" PRIu64 + " bytes and keyslots area %" PRIu64 " bytes.", + metadata_size - LUKS2_HDR_BIN_LEN, keyslots_size); + + if (keyslots_size < LUKS2_DEFAULT_KEYSLOTS_SIZE) + log_std(cd, _("WARNING: keyslots area (%" PRIu64 " bytes) is very small," + " available LUKS2 keyslot count is very limited.\n"), + keyslots_size); + hdr->seqid = 1; hdr->version = 2; memset(hdr->label, 0, LUKS2_LABEL_L); diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index d945554c..f1df4e77 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -1053,6 +1053,11 @@ data is by default aligned to a 1MiB boundary (i.e. 2048 512-byte sectors). For a detached LUKS header, this option specifies the offset on the data device. See also the \-\-header option. + +\fBWARNING:\fR This option is DEPRECATED and has often unexpected impact +to the data offset and keyslot area size (for LUKS2) due to the complex rounding. +For fixed data device offset use \fI\-\-offset\fR option instead. + .TP .B "\-\-uuid=\fIUUID\fR" Use the provided \fIUUID\fR for the \fIluksFormat\fR command diff --git a/tests/compat-test2 b/tests/compat-test2 index 94a1c2f7..a49c5253 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -633,7 +633,7 @@ prepare "[28] Detached LUKS header" wipe echo $PWD1 | $CRYPTSETUP luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG || 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 +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 4096 >/dev/null || fail $CRYPTSETUP luksDump $HEADER_IMG | grep -e "0: crypt" -A1 | grep -qe $((4096*512)) || fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --header $HEADER_IMG --align-payload 0 || fail echo $PWD1 | $CRYPTSETUP luksOpen $LOOPDEV --header $HEADER_IMG $DEV_NAME || fail @@ -887,15 +887,22 @@ echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks1 $LOOPDEV --l echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=128k --luks2-keyslots-size=127k 2> /dev/null && fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=127k --luks2-keyslots-size=128k 2> /dev/null && fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=128k --luks2-keyslots-size=128M >/dev/null 2>&1 && fail -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=128k --luks2-keyslots-size=128k || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-metadata-size=128k --luks2-keyslots-size=128k >/dev/null || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --luks2-metadata-size=128k || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Metadata area:" | grep -q "131072 \[bytes\]" || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Keyslots area:" | grep -q "4161536 \[bytes\]" || fail -echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-keyslots-size=128k || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --luks2-keyslots-size=128k >/dev/null || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Metadata area:" | grep -q "16384 \[bytes\]" || fail $CRYPTSETUP luksDump $LOOPDEV | grep "Keyslots area:" | grep -q "131072 \[bytes\]" || fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --offset 16384 || fail +$CRYPTSETUP luksDump $LOOPDEV | grep "Metadata area:" | grep -q "16384 \[bytes\]" || fail +$CRYPTSETUP luksDump $LOOPDEV | grep "Keyslots area:" | grep -q "8355840 \[bytes\]" || fail +# data offset vs area size +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --offset 64 --luks2-keyslots-size=8192 >/dev/null 2>&1 && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --offset $((256+56)) >/dev/null 2>&1 && fail +echo $PWD1 | $CRYPTSETUP -q luksFormat $FAST_PBKDF_OPT --type luks2 $LOOPDEV --key-size 256 --offset $((256+64)) >/dev/null || fail prepare "[41] Per-keyslot encryption parameters" wipe KEYSLOT_CIPHER="aes-cbc-plain64"