Fix user defined moved segment size in LUKS2 decryption.

--hotzone-size argument was ignored in cases where actual data size
was less than original LUKS2 data offset.
This commit is contained in:
Ondrej Kozina
2022-07-29 14:31:14 +02:00
committed by Milan Broz
parent a009614191
commit 093adfc5f9
2 changed files with 24 additions and 16 deletions

View File

@@ -1912,7 +1912,6 @@ static int reencrypt_set_encrypt_segments(struct crypt_device *cd, struct luks2_
static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd,
struct luks2_hdr *hdr,
uint64_t dev_size,
uint64_t data_shift,
uint64_t moved_segment_length,
crypt_reencrypt_direction_info di)
{
@@ -1922,7 +1921,7 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd,
data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT;
json_object *jobj_segment_first = NULL, *jobj_segment_second = NULL, *jobj_segments;
if (!data_shift || di == CRYPT_REENCRYPT_BACKWARD)
if (di == CRYPT_REENCRYPT_BACKWARD)
return -ENOTSUP;
/*
@@ -1930,12 +1929,11 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd,
* [encrypted first segment (max data shift size)][gap (data shift size)][second encrypted data segment]
*/
first_segment_offset = 0;
if (dev_size > data_shift) {
first_segment_length = moved_segment_length;
first_segment_length = moved_segment_length;
if (dev_size > moved_segment_length) {
second_segment_offset = data_offset + first_segment_length;
second_segment_length = 0;
} else
first_segment_length = dev_size;
}
jobj_segments = json_object_new_object();
if (!jobj_segments)
@@ -1951,7 +1949,7 @@ static int reencrypt_set_decrypt_shift_segments(struct crypt_device *cd,
return r;
}
if (dev_size > data_shift) {
if (dev_size > moved_segment_length) {
jobj_segment_second = json_segment_create_crypt(second_segment_offset,
crypt_get_iv_offset(cd) + (first_segment_length >> SECTOR_SHIFT),
second_segment_length ? &second_segment_length : NULL,
@@ -2769,10 +2767,12 @@ static int reencrypt_decrypt_with_datashift_init(struct crypt_device *cd,
moved_segment_length = data_shift < LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH ?
data_shift : LUKS2_DEFAULT_NONE_REENCRYPTION_LENGTH;
r = reencrypt_set_decrypt_shift_segments(cd, hdr,
data_size, data_shift,
moved_segment_length,
params->direction);
if (moved_segment_length > data_size)
moved_segment_length = data_size;
r = reencrypt_set_decrypt_shift_segments(cd, hdr, data_size,
moved_segment_length,
params->direction);
if (r)
goto out;

View File

@@ -1827,15 +1827,12 @@ test -f $IMG_HDR && fail
echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience none 2> /dev/null && fail
test -f $IMG_HDR && fail
$CRYPTSETUP luksDump $DEV | grep -q "online-reencrypt" && fail
# FIXME: There's a bug in --hotzone-size parameter when initializing decryption with datashift
#echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience checksum --hotzone-size 4m || fail
echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience checksum || fail
echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --init-only $FAST_PBKDF_ARGON --resilience checksum --hotzone-size 4m || fail
$CRYPTSETUP isLuks $DEV -q && fail
# $CRYPTSETUP luksDump $IMG_HDR
echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience datashift 2> /dev/null && fail
echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience none 2> /dev/null && fail
# FIXME: (see above)
#echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience journal || fail
echo $PWD1 | $CRYPTSETUP reencrypt --decrypt $DEV --header $IMG_HDR -q --resilience journal || fail
rm -f $IMG_HDR
check_blkid
@@ -1989,6 +1986,17 @@ check_hash_dev_head $DEV 32768 $HASH10
# FIXME: Should not reencryption remove it automatically?
rm -f $IMG_HDR
# 1MiB data size
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV --offset 63488 || fail
echo $PWD1 | $CRYPTSETUP open $DEV $DEV_NAME || fail
wipe_dev /dev/mapper/$DEV_NAME
# --hotzone-size larger than data expected to get auto corrected by library
echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --init-only --hotzone-size 4M || fail
check_hash_dev /dev/mapper/$DEV_NAME $HASH2
echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q --decrypt --header $IMG_HDR --debug || fail
check_hash_dev_head $DEV 2048 $HASH2
rm -f $IMG_HDR
# small device (less than header size)
prepare dev_size_mb=5
echo $PWD1 | $CRYPTSETUP -q luksFormat --type luks2 -S5 $FAST_PBKDF_ARGON $DEV --offset 8192 || fail