From b8711faf92868dc82b1a64e7673740444199b2ca Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Sun, 25 Jun 2023 23:32:13 +0200 Subject: [PATCH 2/2] Fix activation of LUKS2 with capi format cipher and kernel crypt name. While activation of internal cipher algorithms (like aes-generic) is disallowed, some old LUKS2 images can still use it. Check the cipher in activate call, but allow to load LUKS2 metadata. This can allow to add repair code easily and also allow luksDump. Also fix segfault in reencrypt code for such a header. Fixes: #820 --- lib/luks2/luks2_json_metadata.c | 5 +++++ tests/Makefile.am | 4 +++- tests/compat-test2 | 17 ++++++++++++++++- tests/luks2_invalid_cipher.img.xz | Bin 0 -> 135372 bytes tests/meson.build | 1 + 5 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 tests/luks2_invalid_cipher.img.xz diff --git a/lib/luks2/luks2_json_metadata.c b/lib/luks2/luks2_json_metadata.c index 2fcc8aa6..b1d0c05d 100644 --- a/lib/luks2/luks2_json_metadata.c +++ b/lib/luks2/luks2_json_metadata.c @@ -2605,6 +2605,11 @@ int LUKS2_activate(struct crypt_device *cd, if ((r = LUKS2_unmet_requirements(cd, hdr, 0, 0))) return r; + /* Check that cipher is in compatible format */ + if (!crypt_get_cipher(cd)) { + log_err(cd, _("No known cipher specification pattern detected in LUKS2 header.")); + return -EINVAL; + } r = dm_crypt_target_set(&dmd.segment, 0, dmd.size, crypt_data_device(cd), vk, crypt_get_cipher_spec(cd), crypt_get_iv_offset(cd), crypt_get_data_offset(cd), crypt_get_integrity(cd) ?: "none", diff --git a/tests/Makefile.am b/tests/Makefile.am index c8a46a85..6feaef3b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -68,6 +68,7 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ luks2_valid_hdr.img.xz \ luks2_header_requirements.tar.xz \ luks2_mda_images.tar.xz \ + luks2_invalid_cipher.img.xz \ evil_hdr-payload_overwrite.xz \ evil_hdr-stripes_payload_dmg.xz \ evil_hdr-luks_hdr_damage.xz \ @@ -110,7 +111,8 @@ EXTRA_DIST = compatimage.img.xz compatv10image.img.xz \ CLEANFILES = cryptsetup-tst* valglog* *-fail-*.log test-symbols-list.h fake_token_path.so fake_systemd_tpm_path.so clean-local: - -rm -rf tcrypt-images luks1-images luks2-images bitlk-images fvault2-images conversion_imgs luks2_valid_hdr.img blkid-luks2-pv-img blkid-luks2-pv-img.bcp external-tokens + -rm -rf tcrypt-images luks1-images luks2-images bitlk-images fvault2-images conversion_imgs \ + luks2_valid_hdr.img blkid-luks2-pv-img blkid-luks2-pv-img.bcp external-tokens luks2_invalid_cipher.img differ_SOURCES = differ.c differ_CFLAGS = $(AM_CFLAGS) -Wall -O2 diff --git a/tests/compat-test2 b/tests/compat-test2 index c54dc7ea..8b6bb073 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -16,6 +16,7 @@ IMG10=luks-test-v10 HEADER_IMG=luks-header HEADER_KEYU=luks2_keyslot_unassigned.img HEADER_LUKS2_PV=blkid-luks2-pv.img +HEADER_LUKS2_INV=luks2_invalid_cipher.img KEY1=key1 KEY2=key2 KEY5=key5 @@ -50,7 +51,9 @@ function remove_mapping() [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2 [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $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 $HEADER_LUKS2_PV missing-file $TOKEN_FILE0 $TOKEN_FILE1 test_image_* $KEY_FILE0 $KEY_FILE1 >/dev/null 2>&1 + rm -f $ORIG_IMG $IMG $IMG10 $KEY1 $KEY2 $KEY5 $KEYE $HEADER_IMG $HEADER_KEYU $VK_FILE \ + $HEADER_LUKS2_PV $HEADER_LUKS2_INV missing-file $TOKEN_FILE0 $TOKEN_FILE1 test_image_* \ + $KEY_FILE0 $KEY_FILE1 >/dev/null 2>&1 # unlink whole test keyring [ -n "$TEST_KEYRING" ] && keyctl unlink $TEST_KEYRING "@u" >/dev/null @@ -1200,5 +1203,17 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then $CRYPTSETUP open -q --test-passphrase --token-only --token-id 0 -q $IMG || fail fi +prepare "[44] LUKS2 invalid cipher (kernel cipher driver name)" wipe +xz -dk $HEADER_LUKS2_INV.xz +dd if=$HEADER_LUKS2_INV of=$IMG conv=notrunc >/dev/null 2>&1 +$CRYPTSETUP -q luksDump $LOOPDEV | grep -q "capi:xts(ecb(aes-generic))-plain64" || fail +echo $PWD1 | $CRYPTSETUP open $LOOPDEV --test-passphrase || fail +echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME 2>&1 | grep -q "No known cipher specification pattern" || fail +echo $PWD1 | $CRYPTSETUP reencrypt $LOOPDEV >/dev/null 2>&1 && fail +dmsetup create $DEV_NAME --uuid CRYPT-LUKS2-3d20686f551748cb89911ad32379821b-test --table \ + "0 8 crypt capi:xts(ecb(aes-generic))-plain64 edaa40709797973715e572bf7d86fcbb9cfe2051083c33c28d58fe4e1e7ff642 0 $LOOPDEV 32768" +$CRYPTSETUP status $DEV_NAME | grep -q "n/a" || fail +$CRYPTSETUP close $DEV_NAME ||fail + remove_mapping exit 0 diff --git a/tests/meson.build b/tests/meson.build index 00f629f5..7bb3f406 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -21,6 +21,7 @@ test_files_to_copy = [ 'luks2_keyslot_unassigned.img.xz', 'luks2_mda_images.tar.xz', 'luks2_valid_hdr.img.xz', + 'luks2_invalid_cipher.img.xz', 'tcrypt-images.tar.xz', 'valid_header_file.xz', 'xfs_512_block_size.img.xz', -- 2.40.1