From 997c589e9b4c99de308021ac73beac509978bcd0 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 16 May 2023 06:15:20 +0000 Subject: [PATCH] import cryptsetup-2.3.7-5.el8 --- .cryptsetup.metadata | 1 + .gitignore | 1 + ...t-compiler-optimization-flag-if-wipe.patch | 53 ++++ ...-allocation-if-LUKS2-header-size-is-.patch | 295 ++++++++++++++++++ ...-tests-for-test-passphrase-parameter.patch | 41 +++ ...ssphrase-when-device-in-reencryption.patch | 103 ++++++ ...etup-2.5.0-Fix-typo-in-repair-prompt.patch | 12 + ...KS2-encryption-data-size-restriction.patch | 206 ++++++++++++ SOURCES/cryptsetup-2.6.0-Code-cleanup.patch | 28 ++ ...also-integrity-string-in-legacy-mode.patch | 34 ++ ...er-convert-routines-naming-confusion.patch | 53 ++++ ...ternal-crypt-segment-compare-routine.patch | 130 ++++++++ ...Move-cipher_dm2c-to-crypto-utilities.patch | 250 +++++++++++++++ ...-when-header-and-data-devices-are-sa.patch | 154 +++++++++ .../cryptsetup-add-system-library-paths.patch | 22 ++ ...ryptsetup-disable-verity-compat-test.patch | 13 + SPECS/cryptsetup.spec | 269 ++++++++++++++++ 17 files changed, 1665 insertions(+) create mode 100644 .cryptsetup.metadata create mode 100644 .gitignore create mode 100644 SOURCES/cryptsetup-2.4.2-Do-not-try-to-set-compiler-optimization-flag-if-wipe.patch create mode 100644 SOURCES/cryptsetup-2.4.2-Fix-bogus-memory-allocation-if-LUKS2-header-size-is-.patch create mode 100644 SOURCES/cryptsetup-2.5.0-Add-more-tests-for-test-passphrase-parameter.patch create mode 100644 SOURCES/cryptsetup-2.5.0-Fix-test-passphrase-when-device-in-reencryption.patch create mode 100644 SOURCES/cryptsetup-2.5.0-Fix-typo-in-repair-prompt.patch create mode 100644 SOURCES/cryptsetup-2.5.0-Remove-LUKS2-encryption-data-size-restriction.patch create mode 100644 SOURCES/cryptsetup-2.6.0-Code-cleanup.patch create mode 100644 SOURCES/cryptsetup-2.6.0-Copy-also-integrity-string-in-legacy-mode.patch create mode 100644 SOURCES/cryptsetup-2.6.0-Fix-cipher-convert-routines-naming-confusion.patch create mode 100644 SOURCES/cryptsetup-2.6.0-Fix-internal-crypt-segment-compare-routine.patch create mode 100644 SOURCES/cryptsetup-2.6.0-Move-cipher_dm2c-to-crypto-utilities.patch create mode 100644 SOURCES/cryptsetup-2.6.1-Abort-encryption-when-header-and-data-devices-are-sa.patch create mode 100644 SOURCES/cryptsetup-add-system-library-paths.patch create mode 100644 SOURCES/cryptsetup-disable-verity-compat-test.patch create mode 100644 SPECS/cryptsetup.spec diff --git a/.cryptsetup.metadata b/.cryptsetup.metadata new file mode 100644 index 0000000..899196b --- /dev/null +++ b/.cryptsetup.metadata @@ -0,0 +1 @@ +3ce643e82d52b0c0282c2754c4bfa8c15c1f567e SOURCES/cryptsetup-2.3.7.tar.xz diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..48e6826 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/cryptsetup-2.3.7.tar.xz diff --git a/SOURCES/cryptsetup-2.4.2-Do-not-try-to-set-compiler-optimization-flag-if-wipe.patch b/SOURCES/cryptsetup-2.4.2-Do-not-try-to-set-compiler-optimization-flag-if-wipe.patch new file mode 100644 index 0000000..ea52c96 --- /dev/null +++ b/SOURCES/cryptsetup-2.4.2-Do-not-try-to-set-compiler-optimization-flag-if-wipe.patch @@ -0,0 +1,53 @@ +From a76310b53fbb117e620f2c37350b68dd267f1088 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 20 Sep 2021 17:42:20 +0200 +Subject: [PATCH] Do not try to set compiler optimization flag if wipe is + implemented in libc. + +If zeroing memory is implemented through libc call (like memset_bzero), +compiler should never remove such call. It is not needed to set O0 +optimization flag explicitly. + +Various checkers like annocheck causes problems with these flags, +just remove it where it makes no sense. + +(Moreover, we use the same pattern without compiler magic +in crypt_backend_memzero() already.) +--- + lib/crypto_backend/argon2/core.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/lib/crypto_backend/argon2/core.c b/lib/crypto_backend/argon2/core.c +index b204ba98..db9a7741 100644 +--- a/lib/crypto_backend/argon2/core.c ++++ b/lib/crypto_backend/argon2/core.c +@@ -120,18 +120,24 @@ void free_memory(const argon2_context *context, uint8_t *memory, + } + } + +-void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) { + #if defined(_MSC_VER) && VC_GE_2005(_MSC_VER) ++void secure_wipe_memory(void *v, size_t n) { + SecureZeroMemory(v, n); ++} + #elif defined memset_s ++void secure_wipe_memory(void *v, size_t n) { + memset_s(v, n, 0, n); ++} + #elif defined(HAVE_EXPLICIT_BZERO) ++void secure_wipe_memory(void *v, size_t n) { + explicit_bzero(v, n); ++} + #else ++void NOT_OPTIMIZED secure_wipe_memory(void *v, size_t n) { + static void *(*const volatile memset_sec)(void *, int, size_t) = &memset; + memset_sec(v, 0, n); +-#endif + } ++#endif + + /* Memory clear flag defaults to true. */ + int FLAG_clear_internal_memory = 1; +-- +2.27.0 + diff --git a/SOURCES/cryptsetup-2.4.2-Fix-bogus-memory-allocation-if-LUKS2-header-size-is-.patch b/SOURCES/cryptsetup-2.4.2-Fix-bogus-memory-allocation-if-LUKS2-header-size-is-.patch new file mode 100644 index 0000000..f07fb32 --- /dev/null +++ b/SOURCES/cryptsetup-2.4.2-Fix-bogus-memory-allocation-if-LUKS2-header-size-is-.patch @@ -0,0 +1,295 @@ +From 9576549fee9228cabd9ceee27739a30caab5a7f6 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Tue, 9 Nov 2021 11:54:27 +0100 +Subject: [PATCH] Fix bogus memory allocation if LUKS2 header size is invalid. + +LUKS2 code read the whole header to buffer to verify checksum, +so malloc is called on unvalidated input size parameter. + +This can cause out of memory or unintentional device reads. +(Header validation will fail later anyway - the size is unsupported.) + +Just do not allow too small and too big allocations here and fail quickly. + +Fixes: #683. +--- + lib/luks2/luks2_disk_metadata.c | 20 +++- + ...ks2-metadata-size-invalid-secondary.img.sh | 96 +++++++++++++++++++ + ...enerate-luks2-metadata-size-invalid.img.sh | 94 ++++++++++++++++++ + tests/luks2-validation-test | 2 + + 4 files changed, 208 insertions(+), 4 deletions(-) + create mode 100755 tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh + create mode 100755 tests/generators/generate-luks2-metadata-size-invalid.img.sh + +diff --git a/lib/luks2/luks2_disk_metadata.c b/lib/luks2/luks2_disk_metadata.c +index 502b0226..0500d5c7 100644 +--- a/lib/luks2/luks2_disk_metadata.c ++++ b/lib/luks2/luks2_disk_metadata.c +@@ -195,6 +195,8 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd, + size_t *hdr_json_size, int secondary, + uint64_t offset) + { ++ uint64_t hdr_size; ++ + if (memcmp(hdr->magic, secondary ? LUKS2_MAGIC_2ND : LUKS2_MAGIC_1ST, LUKS2_MAGIC_L)) + return -EINVAL; + +@@ -209,19 +211,26 @@ static int hdr_disk_sanity_check_pre(struct crypt_device *cd, + return -EINVAL; + } + +- if (secondary && (offset != be64_to_cpu(hdr->hdr_size))) { ++ hdr_size = be64_to_cpu(hdr->hdr_size); ++ ++ if (hdr_size < LUKS2_HDR_16K_LEN || hdr_size > LUKS2_HDR_OFFSET_MAX) { ++ log_dbg(cd, "LUKS2 header has bogus size 0x%04x.", (unsigned)hdr_size); ++ return -EINVAL; ++ } ++ ++ if (secondary && (offset != hdr_size)) { + log_dbg(cd, "LUKS2 offset 0x%04x in secondary header does not match size 0x%04x.", +- (unsigned)offset, (unsigned)be64_to_cpu(hdr->hdr_size)); ++ (unsigned)offset, (unsigned)hdr_size); + return -EINVAL; + } + + /* FIXME: sanity check checksum alg. */ + + log_dbg(cd, "LUKS2 header version %u of size %u bytes, checksum %s.", +- (unsigned)be16_to_cpu(hdr->version), (unsigned)be64_to_cpu(hdr->hdr_size), ++ (unsigned)be16_to_cpu(hdr->version), (unsigned)hdr_size, + hdr->checksum_alg); + +- *hdr_json_size = be64_to_cpu(hdr->hdr_size) - LUKS2_HDR_BIN_LEN; ++ *hdr_json_size = hdr_size - LUKS2_HDR_BIN_LEN; + return 0; + } + +@@ -252,6 +261,9 @@ static int hdr_read_disk(struct crypt_device *cd, + return -EIO; + } + ++ /* ++ * hdr_json_size is validated if this call succeeds ++ */ + r = hdr_disk_sanity_check_pre(cd, hdr_disk, &hdr_json_size, secondary, offset); + if (r < 0) { + return r; +diff --git a/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh b/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh +new file mode 100755 +index 00000000..4dd484e9 +--- /dev/null ++++ b/tests/generators/generate-luks2-metadata-size-invalid-secondary.img.sh +@@ -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() ++{ ++ TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M ++ ++ TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512)) ++ TEST_MDA_SIZE_BOGUS_BYTES=$((TEST_MDA_SIZE*512*2*1024)) ++ 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_BOGUS_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 --git a/tests/generators/generate-luks2-metadata-size-invalid.img.sh b/tests/generators/generate-luks2-metadata-size-invalid.img.sh +new file mode 100755 +index 00000000..6b9c0cf7 +--- /dev/null ++++ b/tests/generators/generate-luks2-metadata-size-invalid.img.sh +@@ -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() ++{ ++ TEST_MDA_SIZE=$LUKS2_HDR_SIZE_1M ++ ++ TEST_MDA_SIZE_BYTES=$((TEST_MDA_SIZE*512)) ++ TEST_MDA_SIZE_BOGUS_BYTES=$((TEST_MDA_SIZE*512*2*1024)) ++ 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_BOGUS_BYTES ++ write_bin_hdr_size $TMPDIR/hdr1 $TEST_MDA_SIZE_BOGUS_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 --git a/tests/luks2-validation-test b/tests/luks2-validation-test +index 04183fbc..f771e1f9 100755 +--- a/tests/luks2-validation-test ++++ b/tests/luks2-validation-test +@@ -229,6 +229,8 @@ RUN luks2-metadata-size-512k-secondary.img "R" "Valid 512KiB metadata size in s + 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" ++RUN luks2-metadata-size-invalid.img "F" "Invalid metadata size in secondary hdr not rejected" ++RUN luks2-metadata-size-invalid-secondary.img "F" "Invalid metadata size in secondary hdr not rejected" + + remove_mapping + +-- +2.27.0 + diff --git a/SOURCES/cryptsetup-2.5.0-Add-more-tests-for-test-passphrase-parameter.patch b/SOURCES/cryptsetup-2.5.0-Add-more-tests-for-test-passphrase-parameter.patch new file mode 100644 index 0000000..023666a --- /dev/null +++ b/SOURCES/cryptsetup-2.5.0-Add-more-tests-for-test-passphrase-parameter.patch @@ -0,0 +1,41 @@ +From f671febe64d8f40cdcb1677a08436a8907ccbb7e Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Wed, 23 Feb 2022 12:27:57 +0100 +Subject: [PATCH 2/3] Add more tests for --test-passphrase parameter. + +--- + tests/compat-test-args | 4 ++++ + tests/luks2-reencryption-test | 18 ++++++++++++++++++ + 2 files changed, 22 insertions(+) + +diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test +index 6f156016..73818b5d 100755 +--- a/tests/luks2-reencryption-test ++++ b/tests/luks2-reencryption-test +@@ -1606,5 +1606,23 @@ if [ -n "$DM_SECTOR_SIZE" ]; then + reencrypt_recover_online 4096 journal $HASH1 + fi + ++echo "[27] Verify test passphrase mode works with reencryption metadata" ++echo $PWD1 | $CRYPTSETUP -S5 -q luksFormat --type luks2 $FAST_PBKDF_ARGON $DEV || fail ++echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey --unbound -s80 -S0 $FAST_PBKDF_ARGON $DEV || fail ++echo $PWD1 | $CRYPTSETUP reencrypt --init-only $DEV || fail ++echo $PWD1 | $CRYPTSETUP open --test-passphrase $DEV || fail ++ ++echo $PWD1 | $CRYPTSETUP -q luksFormat -S5 --header $IMG_HDR --type luks2 $FAST_PBKDF_ARGON $DEV || fail ++echo -e "$PWD1\n$PWD1" | $CRYPTSETUP luksAddKey --unbound -s80 -S0 $FAST_PBKDF_ARGON $IMG_HDR || fail ++echo $PWD1 | $CRYPTSETUP reencrypt --decrypt --init-only --header $IMG_HDR $DEV || fail ++echo $PWD1 | $CRYPTSETUP open --test-passphrase $IMG_HDR || fail ++ ++echo $PWD1 | $CRYPTSETUP reencrypt -q --encrypt --init-only --header $IMG_HDR $FAST_PBKDF_ARGON $DEV || fail ++echo $PWD1 | $CRYPTSETUP open --test-passphrase $IMG_HDR || fail ++ ++wipe_dev $DEV ++echo $PWD1 | $CRYPTSETUP reencrypt --encrypt --init-only --reduce-device-size 8M $FAST_PBKDF_ARGON $DEV || fail ++echo $PWD1 | $CRYPTSETUP open --test-passphrase $DEV || fail ++ + remove_mapping + exit 0 +-- +2.27.0 + diff --git a/SOURCES/cryptsetup-2.5.0-Fix-test-passphrase-when-device-in-reencryption.patch b/SOURCES/cryptsetup-2.5.0-Fix-test-passphrase-when-device-in-reencryption.patch new file mode 100644 index 0000000..5566c54 --- /dev/null +++ b/SOURCES/cryptsetup-2.5.0-Fix-test-passphrase-when-device-in-reencryption.patch @@ -0,0 +1,103 @@ +diff -rupN cryptsetup-2.3.7.old/man/cryptsetup.8 cryptsetup-2.3.7/man/cryptsetup.8 +--- cryptsetup-2.3.7.old/man/cryptsetup.8 2022-02-24 15:58:37.968167423 +0100 ++++ cryptsetup-2.3.7/man/cryptsetup.8 2022-02-24 17:06:25.326217548 +0100 +@@ -321,7 +321,7 @@ the command prompts for it interactively + \-\-keyfile\-size, \-\-readonly, \-\-test\-passphrase, + \-\-allow\-discards, \-\-header, \-\-key-slot, \-\-master\-key\-file, \-\-token\-id, + \-\-token\-only, \-\-disable\-keyring, \-\-disable\-locks, \-\-type, \-\-refresh, +-\-\-serialize\-memory\-hard\-pbkdf]. ++\-\-serialize\-memory\-hard\-pbkdf, \-\-unbound]. + .PP + \fIluksSuspend\fR + .IP +@@ -1409,10 +1409,14 @@ aligned to page size and page-cache init + integrity tag. + .TP + .B "\-\-unbound" +- + Creates new or dumps existing LUKS2 unbound keyslot. See \fIluksAddKey\fR or + \fIluksDump\fR actions for more details. + ++When used in \fIluksOpen\fR action (allowed only together with ++\-\-test\-passphrase parameter), it allows to test passphrase for unbound LUKS2 ++keyslot. Otherwise, unbound keyslot passphrase can be tested only when specific ++keyslot is selected via \-\-key\-slot parameter. ++ + .TP + .B "\-\-tcrypt\-hidden" + .B "\-\-tcrypt\-system" +diff -rupN cryptsetup-2.3.7.old/src/cryptsetup.c cryptsetup-2.3.7/src/cryptsetup.c +--- cryptsetup-2.3.7.old/src/cryptsetup.c 2022-02-24 15:58:37.969167429 +0100 ++++ cryptsetup-2.3.7/src/cryptsetup.c 2022-02-24 17:10:30.947561638 +0100 +@@ -230,7 +230,7 @@ static void _set_activation_flags(uint32 + *flags |= CRYPT_ACTIVATE_IGNORE_PERSISTENT; + + /* Only for LUKS2 but ignored elsewhere */ +- if (opt_test_passphrase) ++ if (opt_test_passphrase && (opt_unbound || (opt_key_slot != CRYPT_ANY_SLOT))) + *flags |= CRYPT_ACTIVATE_ALLOW_UNBOUND_KEY; + + if (opt_serialize_memory_hard_pbkdf) +@@ -4021,6 +4021,17 @@ int main(int argc, const char **argv) + _("Option --tcrypt-hidden, --tcrypt-system or --tcrypt-backup is supported only for TCRYPT device."), + poptGetInvocationName(popt_context)); + ++ if (opt_unbound && !strcmp(aname, "open") && device_type && ++ strncmp(device_type, "luks", 4)) ++ usage(popt_context, EXIT_FAILURE, ++ _("Option --unbound is allowed only for open of luks device."), ++ poptGetInvocationName(popt_context)); ++ ++ if (opt_unbound && !opt_test_passphrase && !strcmp(aname, "open")) ++ usage(popt_context, EXIT_FAILURE, ++ _("Option --unbound cannot be used without --test-passphrase."), ++ poptGetInvocationName(popt_context)); ++ + if (opt_tcrypt_hidden && opt_allow_discards) + usage(popt_context, EXIT_FAILURE, + _("Option --tcrypt-hidden cannot be combined with --allow-discards."), +@@ -4103,9 +4114,9 @@ int main(int argc, const char **argv) + _("Keyslot specification is required."), + poptGetInvocationName(popt_context)); + +- if (opt_unbound && strcmp(aname, "luksAddKey") && strcmp(aname, "luksDump")) ++ if (opt_unbound && strcmp(aname, "luksAddKey") && strcmp(aname, "luksDump") && strcmp(aname, "open")) + usage(popt_context, EXIT_FAILURE, +- _("Option --unbound may be used only with luksAddKey and luksDump actions."), ++ _("Option --unbound may be used only with luksAddKey, luksDump and open actions."), + poptGetInvocationName(popt_context)); + + if (opt_refresh && strcmp(aname, "open")) +diff -rupN cryptsetup-2.3.7.old/tests/compat-test2 cryptsetup-2.3.7/tests/compat-test2 +--- cryptsetup-2.3.7.old/tests/compat-test2 2022-02-24 15:58:38.013167680 +0100 ++++ cryptsetup-2.3.7/tests/compat-test2 2022-02-24 17:23:23.035760517 +0100 +@@ -696,7 +696,7 @@ $CRYPTSETUP luksOpen -S 5 -d $KEY1 $LOOP + # otoh it should be allowed to test for proper passphrase + prepare "" new + echo $PWD1 | $CRYPTSETUP open -S1 --test-passphrase $HEADER_KEYU || fail +-echo $PWD1 | $CRYPTSETUP open --test-passphrase $HEADER_KEYU || fail ++echo $PWD1 | $CRYPTSETUP open --unbound --test-passphrase $HEADER_KEYU || fail + echo $PWD1 | $CRYPTSETUP open -S1 $HEADER_KEYU $DEV_NAME 2>/dev/null && fail + [ -b /dev/mapper/$DEV_NAME ] && fail + echo $PWD1 | $CRYPTSETUP open $HEADER_KEYU $DEV_NAME 2>/dev/null && fail +@@ -705,7 +705,7 @@ echo $PWD0 | $CRYPTSETUP open -S1 --test + $CRYPTSETUP luksKillSlot -q $HEADER_KEYU 0 + $CRYPTSETUP luksDump $HEADER_KEYU | grep -q "0: luks2" && fail + echo $PWD1 | $CRYPTSETUP open -S1 --test-passphrase $HEADER_KEYU || fail +-echo $PWD1 | $CRYPTSETUP open --test-passphrase $HEADER_KEYU || fail ++echo $PWD1 | $CRYPTSETUP open --unbound --test-passphrase $HEADER_KEYU || fail + echo $PWD1 | $CRYPTSETUP open -S1 $HEADER_KEYU $DEV_NAME 2>/dev/null && fail + + prepare "[28] Detached LUKS header" wipe +@@ -952,11 +952,9 @@ echo $PWD3 | $CRYPTSETUP -q luksAddKey - + # do not allow to replace keyslot by unbound slot + echo $PWD1 | $CRYPTSETUP -q luksAddKey -S5 --unbound -s 32 $LOOPDEV 2>/dev/null && fail + echo $PWD2 | $CRYPTSETUP -q open $LOOPDEV $DEV_NAME 2> /dev/null && fail +-echo $PWD2 | $CRYPTSETUP -q open $LOOPDEV --test-passphrase || fail + echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV $DEV_NAME 2> /dev/null && fail + echo $PWD2 | $CRYPTSETUP -q open -S2 $LOOPDEV --test-passphrase || fail + echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV $DEV_NAME 2> /dev/null && fail +-echo $PWD1 | $CRYPTSETUP -q open $LOOPDEV --test-passphrase || fail + # check we're able to change passphrase for unbound keyslot + echo -e "$PWD2\n$PWD3" | $CRYPTSETUP luksChangeKey $FAST_PBKDF_OPT -S 2 $LOOPDEV || fail + echo $PWD3 | $CRYPTSETUP open --test-passphrase $FAST_PBKDF_OPT -S 2 $LOOPDEV || fail diff --git a/SOURCES/cryptsetup-2.5.0-Fix-typo-in-repair-prompt.patch b/SOURCES/cryptsetup-2.5.0-Fix-typo-in-repair-prompt.patch new file mode 100644 index 0000000..a34329b --- /dev/null +++ b/SOURCES/cryptsetup-2.5.0-Fix-typo-in-repair-prompt.patch @@ -0,0 +1,12 @@ +diff -rupN cryptsetup-2.3.7.old/src/cryptsetup.c cryptsetup-2.3.7/src/cryptsetup.c +--- cryptsetup-2.3.7.old/src/cryptsetup.c 2022-01-20 14:47:13.198475734 +0100 ++++ cryptsetup-2.3.7/src/cryptsetup.c 2022-01-20 14:47:24.186505625 +0100 +@@ -1137,7 +1137,7 @@ static int reencrypt_metadata_repair(str + _("Operation aborted.\n"))) + return -EINVAL; + +- r = tools_get_key(_("Enter passphrase to protect and uppgrade reencryption metadata: "), ++ r = tools_get_key(_("Enter passphrase to protect and upgrade reencryption metadata: "), + &password, &passwordLen, opt_keyfile_offset, + opt_keyfile_size, opt_key_file, opt_timeout, + _verify_passphrase(0), 0, cd); diff --git a/SOURCES/cryptsetup-2.5.0-Remove-LUKS2-encryption-data-size-restriction.patch b/SOURCES/cryptsetup-2.5.0-Remove-LUKS2-encryption-data-size-restriction.patch new file mode 100644 index 0000000..bf522bf --- /dev/null +++ b/SOURCES/cryptsetup-2.5.0-Remove-LUKS2-encryption-data-size-restriction.patch @@ -0,0 +1,206 @@ +From 6bc1378ddb5bbcc6ba592177c996576b0b3505f9 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Fri, 22 Oct 2021 13:06:48 +0200 +Subject: [PATCH] Remove LUKS2 encryption data size restriction. + +LUKS2 encryption with data shift required remaining +data size (size remaining after substracting --reduce-data-size value) +to be at least --reduce-data-size. This was wrong. Remaining +data size restriction should be correctly at least single sector +(whatever sector size is selected or auto-detected). +--- + lib/luks2/luks2_reencrypt.c | 31 ++++++++++++----------- + tests/api-test-2.c | 6 ++--- + tests/luks2-reencryption-test | 46 +++++++++++++++++++++++++++++------ + 3 files changed, 57 insertions(+), 26 deletions(-) + +diff --git a/lib/luks2/luks2_reencrypt.c b/lib/luks2/luks2_reencrypt.c +index b45327ad..d0e0dc40 100644 +--- a/lib/luks2/luks2_reencrypt.c ++++ b/lib/luks2/luks2_reencrypt.c +@@ -825,7 +825,7 @@ static int reencrypt_offset_backward_moved(struct luks2_hdr *hdr, json_object *j + linear_length += LUKS2_segment_size(hdr, sg, 0); + + /* all active linear segments length */ +- if (linear_length) { ++ if (linear_length && segs > 1) { + if (linear_length < data_shift) + return -EINVAL; + tmp = linear_length - data_shift; +@@ -1745,7 +1745,8 @@ static int reencrypt_set_encrypt_segments(struct crypt_device *cd, struct luks2_ + int r; + uint64_t first_segment_offset, first_segment_length, + second_segment_offset, second_segment_length, +- data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT; ++ data_offset = LUKS2_get_data_offset(hdr) << SECTOR_SHIFT, ++ data_size = dev_size - data_shift; + json_object *jobj_segment_first = NULL, *jobj_segment_second = NULL, *jobj_segments; + + if (dev_size < data_shift) +@@ -1760,9 +1761,14 @@ static int reencrypt_set_encrypt_segments(struct crypt_device *cd, struct luks2_ + * [future LUKS2 header (data shift size)][second data segment][gap (data shift size)][first data segment (data shift size)] + */ + first_segment_offset = dev_size; +- first_segment_length = data_shift; +- second_segment_offset = data_shift; +- second_segment_length = dev_size - 2 * data_shift; ++ if (data_size < data_shift) { ++ first_segment_length = data_size; ++ second_segment_length = second_segment_offset = 0; ++ } else { ++ first_segment_length = data_shift; ++ second_segment_offset = data_shift; ++ second_segment_length = data_size - data_shift; ++ } + } else if (data_shift) { + first_segment_offset = data_offset; + first_segment_length = dev_size; +@@ -2163,17 +2169,10 @@ static int reencrypt_move_data(struct crypt_device *cd, int devfd, uint64_t data + + log_dbg(cd, "Going to move data from head of data device."); + +- buffer_len = data_shift; +- if (!buffer_len) +- return -EINVAL; +- + offset = json_segment_get_offset(LUKS2_get_segment_jobj(hdr, 0), 0); +- +- /* this is nonsense anyway */ +- if (buffer_len != json_segment_get_size(LUKS2_get_segment_jobj(hdr, 0), 0)) { +- log_dbg(cd, "buffer_len %" PRIu64", segment size %" PRIu64, buffer_len, json_segment_get_size(LUKS2_get_segment_jobj(hdr, 0), 0)); ++ buffer_len = json_segment_get_size(LUKS2_get_segment_jobj(hdr, 0), 0); ++ if (!buffer_len || buffer_len > data_shift) + return -EINVAL; +- } + + if (posix_memalign(&buffer, device_alignment(crypt_data_device(cd)), buffer_len)) + return -ENOMEM; +@@ -2447,7 +2446,7 @@ static int reencrypt_init(struct crypt_device *cd, + * encryption initialization (or mount) + */ + if (move_first_segment) { +- if (dev_size < 2 * (params->data_shift << SECTOR_SHIFT)) { ++ if (dev_size < (params->data_shift << SECTOR_SHIFT)) { + log_err(cd, _("Device %s is too small."), device_path(crypt_data_device(cd))); + return -EINVAL; + } +@@ -3484,7 +3483,7 @@ int LUKS2_reencrypt_check_device_size(struct crypt_device *cd, struct luks2_hdr + check_size, check_size >> SECTOR_SHIFT, real_size, real_size >> SECTOR_SHIFT, + real_size - data_offset, (real_size - data_offset) >> SECTOR_SHIFT); + +- if (real_size < data_offset || (check_size && (real_size - data_offset) < check_size)) { ++ if (real_size < data_offset || (check_size && real_size < check_size)) { + log_err(cd, _("Device %s is too small."), device_path(crypt_data_device(cd))); + return -EINVAL; + } +diff --git a/tests/api-test-2.c b/tests/api-test-2.c +index a01a7a72..05ee8f94 100644 +--- a/tests/api-test-2.c ++++ b/tests/api-test-2.c +@@ -4238,7 +4238,7 @@ static void Luks2Reencryption(void) + + _cleanup_dmdevices(); + OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); +- OK_(create_dmdevice_over_loop(L_DEVICE_OK, 12*1024*2+1)); ++ OK_(create_dmdevice_over_loop(L_DEVICE_OK, 8*1024*2+1)); + + /* encryption with datashift and moved segment (data shift + 1 sector) */ + OK_(crypt_init(&cd, DMDIR H_DEVICE)); +@@ -4258,11 +4258,11 @@ static void Luks2Reencryption(void) + + _cleanup_dmdevices(); + OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size)); +- OK_(create_dmdevice_over_loop(L_DEVICE_OK, 12*1024*2)); ++ OK_(create_dmdevice_over_loop(L_DEVICE_OK, 2*8200)); + + OK_(crypt_init(&cd, DMDIR H_DEVICE)); + +- /* encryption with datashift and moved segment (data shift + data offset > device size) */ ++ /* encryption with datashift and moved segment (data shift + data offset <= device size) */ + memset(&rparams, 0, sizeof(rparams)); + params2.sector_size = 512; + params2.data_device = DMDIR L_DEVICE_OK; +diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test +index 8efb2707..bf711c15 100755 +--- a/tests/luks2-reencryption-test ++++ b/tests/luks2-reencryption-test +@@ -152,14 +152,30 @@ function open_crypt() # $1 pwd, $2 hdr + fi + } + ++function wipe_dev_head() # $1 dev, $2 length (in MiBs) ++{ ++ dd if=/dev/zero of=$1 bs=1M count=$2 conv=notrunc >/dev/null 2>&1 ++} ++ + function wipe_dev() # $1 dev + { + if [ -b $1 ] ; then + blkdiscard --zeroout $1 2>/dev/null || dd if=/dev/zero of=$1 bs=1M conv=notrunc >/dev/null 2>&1 ++ if [ $# -gt 2 ]; then ++ dd if=/dev/urandom of=$1 bs=1M seek=$2 conv=notrunc >/dev/null 2>&1 ++ fi + else + local size=$(stat --printf="%s" $1) + truncate -s 0 $1 +- truncate -s $size $1 ++ if [ $# -gt 2 ]; then ++ local diff=$((size-$2*1024*1024)) ++ echo "size: $size, diff: $diff" ++ truncate -s $diff $1 ++ # wipe_dev_head $1 $((diff/(1024*1024))) ++ dd if=/dev/urandom of=$1 bs=1M seek=$2 size=$((diff/(1024*1024))) conv=notrunc >/dev/null 2>&1 ++ else ++ truncate -s $size $1 ++ fi + fi + } + +@@ -214,15 +230,16 @@ function check_hash() # $1 pwd, $2 hash, $3 hdr + $CRYPTSETUP remove $DEV_NAME || fail + } + ++function check_hash_dev_head() # $1 dev, $2 len, $3 hash ++{ ++ local hash=$(dd if=$1 bs=512 count=$2 2>/dev/null | sha256sum | cut -d' ' -f1) ++ [ $hash != "$3" ] && fail "HASH differs (expected: $3) (result $hash)" ++} ++ + function check_hash_head() # $1 pwd, $2 len, $3 hash, $4 hdr + { + open_crypt $1 $4 +- if [ -n "$4" ]; then +- echo $1 | $CRYPTSETUP resize $DEV_NAME --size $2 --header $4 || fail +- else +- echo $1 | $CRYPTSETUP resize $DEV_NAME --size $2 || fail +- fi +- check_hash_dev /dev/mapper/$DEV_NAME $3 ++ check_hash_dev_head /dev/mapper/$DEV_NAME $2 $3 + $CRYPTSETUP remove $DEV_NAME || fail + } + +@@ -865,6 +882,21 @@ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail + $CRYPTSETUP close $DEV_NAME + echo $PWD1 | $CRYPTSETUP open $DEV --test-passphrase || fail + ++# Small device encryption test ++preparebig 65 ++# wipe only 1st MiB (final data size after encryption) ++wipe_dev $DEV 1 ++check_hash_dev_head $DEV 2048 $HASH2 ++echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M -q $FAST_PBKDF_ARGON || fail ++check_hash_head $PWD1 2048 $HASH2 ++ ++wipe_dev_head $DEV 1 ++check_hash_dev_head $DEV 2048 $HASH2 ++echo $PWD1 | $CRYPTSETUP reencrypt $DEV --encrypt --reduce-device-size 64M --init-only -q $FAST_PBKDF_ARGON $DEV_NAME >/dev/null || fail ++check_hash_dev_head /dev/mapper/$DEV_NAME 2048 $HASH2 ++echo $PWD1 | $CRYPTSETUP reencrypt $DEV -q || fail ++check_hash_dev_head /dev/mapper/$DEV_NAME 2048 $HASH2 ++ + echo "[3] Encryption with detached header" + preparebig 256 + wipe_dev $DEV +-- +2.38.1 + diff --git a/SOURCES/cryptsetup-2.6.0-Code-cleanup.patch b/SOURCES/cryptsetup-2.6.0-Code-cleanup.patch new file mode 100644 index 0000000..718abef --- /dev/null +++ b/SOURCES/cryptsetup-2.6.0-Code-cleanup.patch @@ -0,0 +1,28 @@ +From 23903951505cd4ad9f3469e037278494c14a7791 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Wed, 12 Oct 2022 12:05:00 +0200 +Subject: [PATCH 3/5] Code cleanup. + +Type cast is not needed here. +--- + lib/libdevmapper.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c +index 7fcf843f..6a239e14 100644 +--- a/lib/libdevmapper.c ++++ b/lib/libdevmapper.c +@@ -1992,9 +1992,7 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags, + + /* cipher */ + if (get_flags & DM_ACTIVE_CRYPT_CIPHER) { +- r = crypt_capi_to_cipher(CONST_CAST(char**)&cipher, +- CONST_CAST(char**)&integrity, +- rcipher, rintegrity); ++ r = crypt_capi_to_cipher(&cipher, &integrity, rcipher, rintegrity); + if (r < 0) + goto err; + } +-- +2.38.1 + diff --git a/SOURCES/cryptsetup-2.6.0-Copy-also-integrity-string-in-legacy-mode.patch b/SOURCES/cryptsetup-2.6.0-Copy-also-integrity-string-in-legacy-mode.patch new file mode 100644 index 0000000..9a6bdcc --- /dev/null +++ b/SOURCES/cryptsetup-2.6.0-Copy-also-integrity-string-in-legacy-mode.patch @@ -0,0 +1,34 @@ +From 19c15a652f878458493f0ac335110e2779f3cbe3 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Wed, 12 Oct 2022 11:59:09 +0200 +Subject: [PATCH 4/5] Copy also integrity string in legacy mode. + +So that it handles integrity string same as it does +with cipher string. +--- + lib/utils_crypt.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c +index 4f4dbba8..93f846d7 100644 +--- a/lib/utils_crypt.c ++++ b/lib/utils_crypt.c +@@ -284,7 +284,14 @@ int crypt_capi_to_cipher(char **org_c, char **org_i, const char *c_dm, const cha + if (strncmp(c_dm, "capi:", 4)) { + if (!(*org_c = strdup(c_dm))) + return -ENOMEM; +- *org_i = NULL; ++ if (i_dm) { ++ if (!(*org_i = strdup(i_dm))) { ++ free(*org_c); ++ *org_c = NULL; ++ return -ENOMEM; ++ } ++ } else ++ *org_i = NULL; + return 0; + } + +-- +2.38.1 + diff --git a/SOURCES/cryptsetup-2.6.0-Fix-cipher-convert-routines-naming-confusion.patch b/SOURCES/cryptsetup-2.6.0-Fix-cipher-convert-routines-naming-confusion.patch new file mode 100644 index 0000000..27108bc --- /dev/null +++ b/SOURCES/cryptsetup-2.6.0-Fix-cipher-convert-routines-naming-confusion.patch @@ -0,0 +1,53 @@ +From 3616da631f83a004a13a575a54df8123f0d65c29 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Mon, 17 Oct 2022 15:18:42 +0200 +Subject: [PATCH 1/5] Fix cipher convert routines naming confusion. + +The function names were in fact swaped. +--- + lib/libdevmapper.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c +index 6c2eab78..0e45a789 100644 +--- a/lib/libdevmapper.c ++++ b/lib/libdevmapper.c +@@ -481,7 +481,7 @@ static size_t int_log10(uint64_t x) + #define CAPIL 144 /* should be enough to fit whole capi string */ + #define CAPIS "143" /* for sscanf of crypto API string + 16 + \0 */ + +-static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size, ++static int cipher_dm2c(const char *org_c, const char *org_i, unsigned tag_size, + char *c_dm, int c_dm_size, + char *i_dm, int i_dm_size) + { +@@ -543,7 +543,7 @@ static int cipher_c2dm(const char *org_c, const char *org_i, unsigned tag_size, + return 0; + } + +-static int cipher_dm2c(char **org_c, char **org_i, const char *c_dm, const char *i_dm) ++static int cipher_c2dm(char **org_c, char **org_i, const char *c_dm, const char *i_dm) + { + char cipher[CLEN], mode[CLEN], iv[CLEN], auth[CLEN]; + char tmp[CAPIL], dmcrypt_tmp[CAPIL*2], capi[CAPIL+1]; +@@ -629,7 +629,7 @@ static char *get_dm_crypt_params(const struct dm_target *tgt, uint32_t flags) + if (!tgt) + return NULL; + +- r = cipher_c2dm(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size, ++ r = cipher_dm2c(tgt->u.crypt.cipher, tgt->u.crypt.integrity, tgt->u.crypt.tag_size, + cipher_dm, sizeof(cipher_dm), integrity_dm, sizeof(integrity_dm)); + if (r < 0) + return NULL; +@@ -2066,7 +2066,7 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags, + + /* cipher */ + if (get_flags & DM_ACTIVE_CRYPT_CIPHER) { +- r = cipher_dm2c(CONST_CAST(char**)&cipher, ++ r = cipher_c2dm(CONST_CAST(char**)&cipher, + CONST_CAST(char**)&integrity, + rcipher, rintegrity); + if (r < 0) +-- +2.38.1 + diff --git a/SOURCES/cryptsetup-2.6.0-Fix-internal-crypt-segment-compare-routine.patch b/SOURCES/cryptsetup-2.6.0-Fix-internal-crypt-segment-compare-routine.patch new file mode 100644 index 0000000..94b4bdc --- /dev/null +++ b/SOURCES/cryptsetup-2.6.0-Fix-internal-crypt-segment-compare-routine.patch @@ -0,0 +1,130 @@ +From 3e4c69a01709d35322ffa17c5360608907a207d7 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Tue, 11 Oct 2022 11:48:13 +0200 +Subject: [PATCH 5/5] Fix internal crypt segment compare routine. + +The function is supposed to check if manipulated +active dm-crypt device matches the on-disk metadata. +Unfortunately it did not take into account differences +between normal cipher specification (aes-xts-plain64) +and capi format specification (capi:xts(aes)-plain64). +The internal query function always converted capi format +in normal format and therefor failed if capi format was +used in metadata. + +Fixes: #759. +--- + lib/setup.c | 36 ++++++++++++++++++++++++++---------- + tests/api-test-2.c | 14 ++++++++++++-- + 2 files changed, 38 insertions(+), 12 deletions(-) + +diff --git a/lib/setup.c b/lib/setup.c +index 6d7411b5..809049b9 100644 +--- a/lib/setup.c ++++ b/lib/setup.c +@@ -2458,6 +2458,9 @@ static int _compare_crypt_devices(struct crypt_device *cd, + const struct dm_target *src, + const struct dm_target *tgt) + { ++ char *src_cipher = NULL, *src_integrity = NULL; ++ int r = -EINVAL; ++ + /* for crypt devices keys are mandatory */ + if (!src->u.crypt.vk || !tgt->u.crypt.vk) + return -EINVAL; +@@ -2465,21 +2468,30 @@ static int _compare_crypt_devices(struct crypt_device *cd, + /* CIPHER checks */ + if (!src->u.crypt.cipher || !tgt->u.crypt.cipher) + return -EINVAL; +- if (strcmp(src->u.crypt.cipher, tgt->u.crypt.cipher)) { +- log_dbg(cd, "Cipher specs do not match."); ++ ++ /* ++ * dm_query_target converts capi cipher specification to dm-crypt format. ++ * We need to do same for cipher specification requested in source ++ * device. ++ */ ++ if (crypt_capi_to_cipher(&src_cipher, &src_integrity, src->u.crypt.cipher, src->u.crypt.integrity)) + return -EINVAL; ++ ++ if (strcmp(src_cipher, tgt->u.crypt.cipher)) { ++ log_dbg(cd, "Cipher specs do not match."); ++ goto out; + } + + if (tgt->u.crypt.vk->keylength == 0 && crypt_is_cipher_null(tgt->u.crypt.cipher)) + log_dbg(cd, "Existing device uses cipher null. Skipping key comparison."); + else if (_compare_volume_keys(src->u.crypt.vk, 0, tgt->u.crypt.vk, tgt->u.crypt.vk->key_description != NULL)) { + log_dbg(cd, "Keys in context and target device do not match."); +- return -EINVAL; ++ goto out; + } + +- if (crypt_strcmp(src->u.crypt.integrity, tgt->u.crypt.integrity)) { ++ if (crypt_strcmp(src_integrity, tgt->u.crypt.integrity)) { + log_dbg(cd, "Integrity parameters do not match."); +- return -EINVAL; ++ goto out; + } + + if (src->u.crypt.offset != tgt->u.crypt.offset || +@@ -2487,15 +2499,19 @@ static int _compare_crypt_devices(struct crypt_device *cd, + src->u.crypt.iv_offset != tgt->u.crypt.iv_offset || + src->u.crypt.tag_size != tgt->u.crypt.tag_size) { + log_dbg(cd, "Integer parameters do not match."); +- return -EINVAL; ++ goto out; + } + +- if (device_is_identical(src->data_device, tgt->data_device) <= 0) { ++ if (device_is_identical(src->data_device, tgt->data_device) <= 0) + log_dbg(cd, "Data devices do not match."); +- return -EINVAL; +- } ++ else ++ r = 0; + +- return 0; ++out: ++ free(src_cipher); ++ free(src_integrity); ++ ++ return r; + } + + static int _compare_integrity_devices(struct crypt_device *cd, +diff --git a/tests/api-test-2.c b/tests/api-test-2.c +index 0534677a..34002d1a 100644 +--- a/tests/api-test-2.c ++++ b/tests/api-test-2.c +@@ -1585,8 +1585,8 @@ static void ResizeDeviceLuks2(void) + + const char *mk_hex = "bb21158c733229347bd4e681891e213d94c685be6a5b84818afe7a78a6de7a1a"; + size_t key_size = strlen(mk_hex) / 2; +- const char *cipher = "aes"; +- const char *cipher_mode = "cbc-essiv:sha256"; ++ const char *cipher = "aes", *capi_cipher = "capi:cbc(aes)"; ++ const char *cipher_mode = "cbc-essiv:sha256", *capi_cipher_mode = "essiv:sha256"; + uint64_t r_payload_offset, r_header_size, r_size; + + /* Cannot use Argon2 in FIPS */ +@@ -1728,6 +1728,16 @@ static void ResizeDeviceLuks2(void) + OK_(crypt_deactivate(cd, CDEVICE_1)); + CRYPT_FREE(cd); + ++ OK_(crypt_init(&cd, DMDIR L_DEVICE_OK)); ++ OK_(crypt_set_pbkdf_type(cd, &pbkdf)); ++ OK_(crypt_format(cd, CRYPT_LUKS2, capi_cipher, capi_cipher_mode, NULL, key, key_size, NULL)); ++ OK_(crypt_activate_by_volume_key(cd, CDEVICE_1, key, key_size, 0)); ++ OK_(crypt_resize(cd, CDEVICE_1, 8)); ++ if (!t_device_size(DMDIR CDEVICE_1, &r_size)) ++ EQ_(8, r_size >> SECTOR_SHIFT); ++ OK_(crypt_deactivate(cd, CDEVICE_1)); ++ CRYPT_FREE(cd); ++ + _cleanup_dmdevices(); + } + +-- +2.38.1 + diff --git a/SOURCES/cryptsetup-2.6.0-Move-cipher_dm2c-to-crypto-utilities.patch b/SOURCES/cryptsetup-2.6.0-Move-cipher_dm2c-to-crypto-utilities.patch new file mode 100644 index 0000000..35909ee --- /dev/null +++ b/SOURCES/cryptsetup-2.6.0-Move-cipher_dm2c-to-crypto-utilities.patch @@ -0,0 +1,250 @@ +From 9a9ddc7d22e14e14c9a6e97860cffada406adac3 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Tue, 11 Oct 2022 10:50:17 +0200 +Subject: [PATCH 2/5] Move cipher_dm2c to crypto utilities. + +(Gets renamed to crypt_capi_to_cipher) +--- + lib/libdevmapper.c | 84 +++------------------------------------------- + lib/utils_crypt.c | 72 +++++++++++++++++++++++++++++++++++++++ + lib/utils_crypt.h | 11 ++++-- + 3 files changed, 85 insertions(+), 82 deletions(-) + +diff --git a/lib/libdevmapper.c b/lib/libdevmapper.c +index 0e45a789..7fcf843f 100644 +--- a/lib/libdevmapper.c ++++ b/lib/libdevmapper.c +@@ -476,27 +476,22 @@ static size_t int_log10(uint64_t x) + return r; + } + +-#define CLEN 64 /* 2*MAX_CIPHER_LEN */ +-#define CLENS "63" /* for sscanf length + '\0' */ +-#define CAPIL 144 /* should be enough to fit whole capi string */ +-#define CAPIS "143" /* for sscanf of crypto API string + 16 + \0 */ +- + static int cipher_dm2c(const char *org_c, const char *org_i, unsigned tag_size, + char *c_dm, int c_dm_size, + char *i_dm, int i_dm_size) + { + int c_size = 0, i_size = 0, i; +- char cipher[CLEN], mode[CLEN], iv[CLEN+1], tmp[CLEN]; +- char capi[CAPIL]; ++ char cipher[MAX_CAPI_ONE_LEN], mode[MAX_CAPI_ONE_LEN], iv[MAX_CAPI_ONE_LEN+1], ++ tmp[MAX_CAPI_ONE_LEN], capi[MAX_CAPI_LEN]; + + if (!c_dm || !c_dm_size || !i_dm || !i_dm_size) + return -EINVAL; + +- i = sscanf(org_c, "%" CLENS "[^-]-%" CLENS "s", cipher, tmp); ++ i = sscanf(org_c, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", cipher, tmp); + if (i != 2) + return -EINVAL; + +- i = sscanf(tmp, "%" CLENS "[^-]-%" CLENS "s", mode, iv); ++ i = sscanf(tmp, "%" MAX_CAPI_ONE_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", mode, iv); + if (i == 1) { + memset(iv, 0, sizeof(iv)); + strncpy(iv, mode, sizeof(iv)-1); +@@ -543,75 +538,6 @@ static int cipher_dm2c(const char *org_c, const char *org_i, unsigned tag_size, + return 0; + } + +-static int cipher_c2dm(char **org_c, char **org_i, const char *c_dm, const char *i_dm) +-{ +- char cipher[CLEN], mode[CLEN], iv[CLEN], auth[CLEN]; +- char tmp[CAPIL], dmcrypt_tmp[CAPIL*2], capi[CAPIL+1]; +- size_t len; +- int i; +- +- if (!c_dm) +- return -EINVAL; +- +- /* legacy mode */ +- if (strncmp(c_dm, "capi:", 4)) { +- if (!(*org_c = strdup(c_dm))) +- return -ENOMEM; +- *org_i = NULL; +- return 0; +- } +- +- /* modes with capi: prefix */ +- i = sscanf(c_dm, "capi:%" CAPIS "[^-]-%" CLENS "s", tmp, iv); +- if (i != 2) +- return -EINVAL; +- +- len = strlen(tmp); +- if (len < 2) +- return -EINVAL; +- +- if (tmp[len-1] == ')') +- tmp[len-1] = '\0'; +- +- if (sscanf(tmp, "rfc4309(%" CAPIS "s", capi) == 1) { +- if (!(*org_i = strdup("aead"))) +- return -ENOMEM; +- } else if (sscanf(tmp, "rfc7539(%" CAPIS "[^,],%" CLENS "s", capi, auth) == 2) { +- if (!(*org_i = strdup(auth))) +- return -ENOMEM; +- } else if (sscanf(tmp, "authenc(%" CLENS "[^,],%" CAPIS "s", auth, capi) == 2) { +- if (!(*org_i = strdup(auth))) +- return -ENOMEM; +- } else { +- if (i_dm) { +- if (!(*org_i = strdup(i_dm))) +- return -ENOMEM; +- } else +- *org_i = NULL; +- memset(capi, 0, sizeof(capi)); +- strncpy(capi, tmp, sizeof(capi)-1); +- } +- +- i = sscanf(capi, "%" CLENS "[^(](%" CLENS "[^)])", mode, cipher); +- if (i == 2) +- i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv); +- else +- i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv); +- if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) { +- free(*org_i); +- *org_i = NULL; +- return -EINVAL; +- } +- +- if (!(*org_c = strdup(dmcrypt_tmp))) { +- free(*org_i); +- *org_i = NULL; +- return -ENOMEM; +- } +- +- return 0; +-} +- + static char *_uf(char *buf, size_t buf_size, const char *s, unsigned u) + { + size_t r = snprintf(buf, buf_size, " %s:%u", s, u); +@@ -2066,7 +1992,7 @@ static int _dm_target_query_crypt(struct crypt_device *cd, uint32_t get_flags, + + /* cipher */ + if (get_flags & DM_ACTIVE_CRYPT_CIPHER) { +- r = cipher_c2dm(CONST_CAST(char**)&cipher, ++ r = crypt_capi_to_cipher(CONST_CAST(char**)&cipher, + CONST_CAST(char**)&integrity, + rcipher, rintegrity); + if (r < 0) +diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c +index 83d0a2c5..4f4dbba8 100644 +--- a/lib/utils_crypt.c ++++ b/lib/utils_crypt.c +@@ -31,6 +31,8 @@ + #include "libcryptsetup.h" + #include "utils_crypt.h" + ++#define MAX_CAPI_LEN_STR "143" /* for sscanf of crypto API string + 16 + \0 */ ++ + int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums, + char *cipher_mode) + { +@@ -266,3 +268,73 @@ bool crypt_is_cipher_null(const char *cipher_spec) + return false; + return (strstr(cipher_spec, "cipher_null") || !strcmp(cipher_spec, "null")); + } ++ ++int crypt_capi_to_cipher(char **org_c, char **org_i, const char *c_dm, const char *i_dm) ++{ ++ char cipher[MAX_CAPI_ONE_LEN], mode[MAX_CAPI_ONE_LEN], iv[MAX_CAPI_ONE_LEN], ++ auth[MAX_CAPI_ONE_LEN], tmp[MAX_CAPI_LEN], dmcrypt_tmp[MAX_CAPI_LEN*2], ++ capi[MAX_CAPI_LEN+1]; ++ size_t len; ++ int i; ++ ++ if (!c_dm) ++ return -EINVAL; ++ ++ /* legacy mode */ ++ if (strncmp(c_dm, "capi:", 4)) { ++ if (!(*org_c = strdup(c_dm))) ++ return -ENOMEM; ++ *org_i = NULL; ++ return 0; ++ } ++ ++ /* modes with capi: prefix */ ++ i = sscanf(c_dm, "capi:%" MAX_CAPI_LEN_STR "[^-]-%" MAX_CAPI_ONE_LEN_STR "s", tmp, iv); ++ if (i != 2) ++ return -EINVAL; ++ ++ len = strlen(tmp); ++ if (len < 2) ++ return -EINVAL; ++ ++ if (tmp[len-1] == ')') ++ tmp[len-1] = '\0'; ++ ++ if (sscanf(tmp, "rfc4309(%" MAX_CAPI_LEN_STR "s", capi) == 1) { ++ if (!(*org_i = strdup("aead"))) ++ return -ENOMEM; ++ } else if (sscanf(tmp, "rfc7539(%" MAX_CAPI_LEN_STR "[^,],%" MAX_CAPI_ONE_LEN_STR "s", capi, auth) == 2) { ++ if (!(*org_i = strdup(auth))) ++ return -ENOMEM; ++ } else if (sscanf(tmp, "authenc(%" MAX_CAPI_ONE_LEN_STR "[^,],%" MAX_CAPI_LEN_STR "s", auth, capi) == 2) { ++ if (!(*org_i = strdup(auth))) ++ return -ENOMEM; ++ } else { ++ if (i_dm) { ++ if (!(*org_i = strdup(i_dm))) ++ return -ENOMEM; ++ } else ++ *org_i = NULL; ++ memset(capi, 0, sizeof(capi)); ++ strncpy(capi, tmp, sizeof(capi)-1); ++ } ++ ++ i = sscanf(capi, "%" MAX_CAPI_ONE_LEN_STR "[^(](%" MAX_CAPI_ONE_LEN_STR "[^)])", mode, cipher); ++ if (i == 2) ++ i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s-%s", cipher, mode, iv); ++ else ++ i = snprintf(dmcrypt_tmp, sizeof(dmcrypt_tmp), "%s-%s", capi, iv); ++ if (i < 0 || (size_t)i >= sizeof(dmcrypt_tmp)) { ++ free(*org_i); ++ *org_i = NULL; ++ return -EINVAL; ++ } ++ ++ if (!(*org_c = strdup(dmcrypt_tmp))) { ++ free(*org_i); ++ *org_i = NULL; ++ return -ENOMEM; ++ } ++ ++ return 0; ++} +diff --git a/lib/utils_crypt.h b/lib/utils_crypt.h +index 5922350a..a4a9b6ca 100644 +--- a/lib/utils_crypt.h ++++ b/lib/utils_crypt.h +@@ -27,9 +27,12 @@ + #include + #include + +-#define MAX_CIPHER_LEN 32 +-#define MAX_CIPHER_LEN_STR "31" +-#define MAX_KEYFILES 32 ++#define MAX_CIPHER_LEN 32 ++#define MAX_CIPHER_LEN_STR "31" ++#define MAX_KEYFILES 32 ++#define MAX_CAPI_ONE_LEN 2 * MAX_CIPHER_LEN ++#define MAX_CAPI_ONE_LEN_STR "63" /* for sscanf length + '\0' */ ++#define MAX_CAPI_LEN 144 /* should be enough to fit whole capi string */ + + int crypt_parse_name_and_mode(const char *s, char *cipher, + int *key_nums, char *cipher_mode); +@@ -46,4 +49,6 @@ void crypt_log_hex(struct crypt_device *cd, + + bool crypt_is_cipher_null(const char *cipher_spec); + ++int crypt_capi_to_cipher(char **org_c, char **org_i, const char *c_dm, const char *i_dm); ++ + #endif /* _UTILS_CRYPT_H */ +-- +2.38.1 + diff --git a/SOURCES/cryptsetup-2.6.1-Abort-encryption-when-header-and-data-devices-are-sa.patch b/SOURCES/cryptsetup-2.6.1-Abort-encryption-when-header-and-data-devices-are-sa.patch new file mode 100644 index 0000000..b8c056d --- /dev/null +++ b/SOURCES/cryptsetup-2.6.1-Abort-encryption-when-header-and-data-devices-are-sa.patch @@ -0,0 +1,154 @@ +From c18dcfaa0b91eb48006232fbfadce9e6a9b4a790 Mon Sep 17 00:00:00 2001 +From: Ondrej Kozina +Date: Fri, 2 Dec 2022 15:39:36 +0100 +Subject: [PATCH 2/2] Abort encryption when header and data devices are same. + +If data device reduction is not requsted this led +to data corruption since LUKS metadata was written +over the data device. +--- + src/utils_reencrypt.c | 42 ++++++++++++++++++++++++++++++---- + tests/luks2-reencryption-test | 16 +++++++++++++ + tests/reencryption-compat-test | 20 +++++++++++++--- + 3 files changed, 70 insertions(+), 8 deletions(-) + +diff --git a/src/utils_tools.c b/src/utils_tools.c +--- a/src/utils_tools.c ++++ b/src/utils_tools.c +@@ -624,3 +624,23 @@ int tools_reencrypt_progress(uint64_t si + + return r; + } ++ ++int reencrypt_is_header_detached(const char *header_device, const char *data_device) ++{ ++ int r; ++ struct stat st; ++ struct crypt_device *cd; ++ ++ if (!header_device) ++ return 0; ++ ++ if (header_device && stat(header_device, &st) < 0 && errno == ENOENT) ++ return 1; ++ ++ if ((r = crypt_init_data_device(&cd, header_device, data_device))) ++ return r; ++ ++ r = crypt_get_metadata_device_name(cd) && crypt_get_device_name(cd) && strcmp(crypt_get_metadata_device_name(cd), crypt_get_device_name(cd)); ++ crypt_free(cd); ++ return r; ++} +diff --git a/src/cryptsetup.h b/src/cryptsetup.h +--- a/src/cryptsetup.h ++++ b/src/cryptsetup.h +@@ -103,6 +103,7 @@ void tools_clear_line(void); + + int tools_wipe_progress(uint64_t size, uint64_t offset, void *usrptr); + int tools_reencrypt_progress(uint64_t size, uint64_t offset, void *usrptr); ++int reencrypt_is_header_detached(const char *header_device, const char *data_device); + + int tools_read_mk(const char *file, char **key, int keysize); + int tools_write_mk(const char *file, const char *key, int keysize); +diff --git a/src/cryptsetup.c b/src/cryptsetup.c +--- a/src/cryptsetup.c ++++ b/src/cryptsetup.c +@@ -2892,6 +2892,16 @@ static int action_encrypt_luks2(struct c + return -ENOTSUP; + } + ++ if (!opt_data_shift) { ++ r = reencrypt_is_header_detached(opt_header_device, action_argv[0]); ++ if (r < 0) ++ return r; ++ if (!r) { ++ log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size).")); ++ return -ENOTSUP; ++ } ++ } ++ + if (!opt_header_device && opt_offset && opt_data_shift && (opt_offset > (imaxabs(opt_data_shift) / (2 * SECTOR_SIZE)))) { + log_err(_("Requested data offset must be less than or equal to half of --reduce-device-size parameter.")); + return -EINVAL; +diff --git a/src/cryptsetup_reencrypt.c b/src/cryptsetup_reencrypt.c +--- a/src/cryptsetup_reencrypt.c ++++ b/src/cryptsetup_reencrypt.c +@@ -1553,6 +1553,17 @@ static int run_reencrypt(const char *dev + goto out; + } + ++ if (rc.reencrypt_mode == ENCRYPT) { ++ r = reencrypt_is_header_detached(opt_header_device, action_argv[0]); ++ if (r < 0) ++ goto out; ++ if (!r && !opt_reduce_size) { ++ log_err(_("Encryption without detached header (--header) is not possible without data device size reduction (--reduce-device-size).")); ++ r = -ENOTSUP; ++ goto out; ++ } ++ } ++ + log_dbg("Running reencryption."); + + if (!rc.in_progress) { +diff --git a/tests/luks2-reencryption-test b/tests/luks2-reencryption-test +index bab54353..a647a8c2 100755 +--- a/tests/luks2-reencryption-test ++++ b/tests/luks2-reencryption-test +@@ -1080,6 +1080,15 @@ $CRYPTSETUP status $DEV_NAME >/dev/null 2>&1 || fail + $CRYPTSETUP close $DEV_NAME + echo $PWD1 | $CRYPTSETUP open --header $IMG_HDR $DEV --test-passphrase || fail + ++# Encrypt without size reduction must not allow header device same as data device ++wipe_dev_head $DEV 1 ++echo $PWD1 | $CRYPTSETUP reencrypt $DEV --type luks2 --encrypt --header $DEV -q $FAST_PBKDF_ARGON 2>/dev/null && fail ++$CRYPTSETUP isLUKS $DEV 2>/dev/null && fail ++ ++dd if=/dev/zero of=$IMG bs=4k count=1 >/dev/null 2>&1 ++echo $PWD1 | $CRYPTSETUP reencrypt $IMG --type luks2 --encrypt --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail ++$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail ++ + echo "[4] Reencryption with detached header" + wipe $PWD1 $IMG_HDR + echo $PWD1 | $CRYPTSETUP reencrypt -c aes-cbc-essiv:sha256 -s 128 --header $IMG_HDR -q $FAST_PBKDF_ARGON $DEV || fail +diff --git a/tests/reencryption-compat-test b/tests/reencryption-compat-test +index f6a84137..453831d1 100755 +--- a/tests/reencryption-compat-test ++++ b/tests/reencryption-compat-test +@@ -11,5 +11,6 @@ IMG=reenc-data + IMG_HDR=$IMG.hdr + ORIG_IMG=reenc-data-orig ++DEV_LINK="reenc-test-link" + KEY1=key1 + PWD1="93R4P4pIqAH8" + PWD2="1cND4319812f" +@@ -40,7 +41,7 @@ function remove_mapping() + [ -b /dev/mapper/$DEV_NAME2 ] && dmsetup remove --retry $DEV_NAME2 + [ -b /dev/mapper/$DEV_NAME ] && dmsetup remove --retry $DEV_NAME + [ ! -z "$LOOPDEV1" ] && losetup -d $LOOPDEV1 >/dev/null 2>&1 +- rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 >/dev/null 2>&1 ++ rm -f $IMG $IMG_HDR $ORIG_IMG $KEY1 $DEV_LINK >/dev/null 2>&1 + umount $MNT_DIR > /dev/null 2>&1 + rmdir $MNT_DIR > /dev/null 2>&1 + LOOPDEV1="" +@@ -265,10 +265,16 @@ $REENC $LOOPDEV1 -d $KEY1 $FAST_PBKDF -q + # FIXME echo $PWD1 | $REENC ... + + echo "[4] Encryption of not yet encrypted device" ++# Encrypt without size reduction must not allow header device same as data device ++wipe_dev $LOOPDEV1 ++echo $PWD1 | $REENC $LOOPDEV1 --type luks1 --new --header $LOOPDEV1 -q $FAST_PBKDF_ARGON 2>/dev/null && fail ++$CRYPTSETUP isLUKS $LOOPDEV1 2>/dev/null && fail ++echo $PWD1 | $REENC $IMG --type luks1 --new --header $IMG -q $FAST_PBKDF_ARGON 2>/dev/null && fail ++$CRYPTSETUP isLUKS $IMG 2>/dev/null && fail ++ + # well, movin' zeroes :-) + OFFSET=2048 + SIZE=$(blockdev --getsz $LOOPDEV1) +-wipe_dev $LOOPDEV1 + dmsetup create $DEV_NAME2 --table "0 $(($SIZE - $OFFSET)) linear $LOOPDEV1 0" || fail + check_hash_dev /dev/mapper/$DEV_NAME2 $HASH3 + dmsetup remove --retry $DEV_NAME2 || fail +-- +2.38.1 + diff --git a/SOURCES/cryptsetup-add-system-library-paths.patch b/SOURCES/cryptsetup-add-system-library-paths.patch new file mode 100644 index 0000000..cc22adf --- /dev/null +++ b/SOURCES/cryptsetup-add-system-library-paths.patch @@ -0,0 +1,22 @@ +diff -rupN cryptsetup-2.0.4.old/configure cryptsetup-2.0.4/configure +--- cryptsetup-2.0.4.old/configure 2018-08-03 12:31:52.000000000 +0200 ++++ cryptsetup-2.0.4/configure 2018-08-03 13:42:50.605275535 +0200 +@@ -12300,6 +12300,9 @@ fi + # before this can be enabled. + hardcode_into_libs=yes + ++ # Add ABI-specific directories to the system library path. ++ sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" ++ + # Ideally, we could use ldconfig to report *all* directores which are + # searched for libraries, however this is still not possible. Aside from not + # being certain /sbin/ldconfig is available, command +@@ -12308,7 +12311,7 @@ fi + # appending ld.so.conf contents (and includes) to the search path. + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` +- sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" ++ sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on diff --git a/SOURCES/cryptsetup-disable-verity-compat-test.patch b/SOURCES/cryptsetup-disable-verity-compat-test.patch new file mode 100644 index 0000000..efc3363 --- /dev/null +++ b/SOURCES/cryptsetup-disable-verity-compat-test.patch @@ -0,0 +1,13 @@ +diff --git a/tests/Makefile.localtest b/tests/Makefile.localtest +index 29a62f3..da2183e 100644 +--- a/tests/Makefile.localtest ++++ b/tests/Makefile.localtest +@@ -5,7 +5,7 @@ + CPPFLAGS=-I../lib/ -I../lib/luks1 -DHAVE_DECL_DM_TASK_RETRY_REMOVE -DKERNEL_KEYRING -DHAVE_SYS_SYSMACROS_H -DNO_CRYPTSETUP_PATH + CFLAGS=-O2 -g -Wall + LDLIBS=-lcryptsetup -ldevmapper +-TESTS=$(wildcard *-test *-test2) api-test api-test-2 ++TESTS=$(filter-out verity-compat-test, $(wildcard *-test *-test2)) api-test api-test-2 + + differ: differ.o + $(CC) -o $@ $^ diff --git a/SPECS/cryptsetup.spec b/SPECS/cryptsetup.spec new file mode 100644 index 0000000..1f790e7 --- /dev/null +++ b/SPECS/cryptsetup.spec @@ -0,0 +1,269 @@ +Obsoletes: python2-cryptsetup +Obsoletes: cryptsetup-python +Obsoletes: cryptsetup-python3 + +Summary: A utility for setting up encrypted disks +Name: cryptsetup +Version: 2.3.7 +Release: 5%{?dist} +License: GPLv2+ and LGPLv2+ +Group: Applications/System +URL: https://gitlab.com/cryptsetup/cryptsetup +BuildRequires: openssl-devel, popt-devel, device-mapper-devel +BuildRequires: libuuid-devel, gcc, libblkid-devel +BuildRequires: libpwquality-devel, json-c-devel +Provides: cryptsetup-luks = %{version}-%{release} +Obsoletes: cryptsetup-luks < 1.4.0 +Requires: cryptsetup-libs = %{version}-%{release} +Requires: libpwquality >= 1.2.0 + +%global upstream_version %{version} +Source0: https://www.kernel.org/pub/linux/utils/cryptsetup/v2.0/cryptsetup-%{upstream_version}.tar.xz +# Following patch has to applied last +Patch0: %{name}-add-system-library-paths.patch +# Remove the patch when (if ever) osci infrastructure gets stable enough +Patch1: %{name}-disable-verity-compat-test.patch +Patch2: %{name}-2.4.2-Do-not-try-to-set-compiler-optimization-flag-if-wipe.patch +Patch3: %{name}-2.4.2-Fix-bogus-memory-allocation-if-LUKS2-header-size-is-.patch +Patch4: %{name}-2.5.0-Fix-typo-in-repair-prompt.patch +Patch5: %{name}-2.5.0-Fix-test-passphrase-when-device-in-reencryption.patch +Patch6: %{name}-2.5.0-Add-more-tests-for-test-passphrase-parameter.patch +Patch7: %{name}-2.5.0-Remove-LUKS2-encryption-data-size-restriction.patch +Patch8: %{name}-2.6.0-Fix-cipher-convert-routines-naming-confusion.patch +Patch9: %{name}-2.6.0-Move-cipher_dm2c-to-crypto-utilities.patch +Patch10: %{name}-2.6.0-Code-cleanup.patch +Patch11: %{name}-2.6.0-Copy-also-integrity-string-in-legacy-mode.patch +Patch12: %{name}-2.6.0-Fix-internal-crypt-segment-compare-routine.patch +Patch13: %{name}-2.6.1-Abort-encryption-when-header-and-data-devices-are-sa.patch + +%description +The cryptsetup package contains a utility for setting up +disk encryption using dm-crypt kernel module. + +%package devel +Group: Development/Libraries +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +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 + +%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 -n integritysetup +Group: Applications/System +Summary: A utility for setting up dm-integrity volumes +Requires: cryptsetup-libs = %{version}-%{release} + +%description -n integritysetup +The integritysetup package contains a utility for setting up +disk integrity protection using dm-integrity kernel module. + +%package reencrypt +Group: Applications/System +Summary: A utility for offline reencryption of LUKS encrypted disks. +Requires: cryptsetup-libs = %{version}-%{release} + +%description reencrypt +This package contains cryptsetup-reencrypt utility which +can be used for offline reencryption of disk in situ. + +%prep +%setup -q -n cryptsetup-%{upstream_version} +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch0 -p1 +chmod -x misc/dracut_90reencrypt/* + +%build +%configure --enable-fips --enable-pwquality --enable-internal-sse-argon2 --with-crypto_backend=openssl --with-default-luks-format=LUKS2 +make %{?_smp_mflags} + +%install +make install DESTDIR=%{buildroot} +rm -rf %{buildroot}/%{_libdir}/*.la + +%find_lang cryptsetup + +%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 + +%files -n integritysetup +%{!?_licensedir:%global license %%doc} +%license COPYING +%{_mandir}/man8/integritysetup.8.gz +%{_sbindir}/integritysetup + +%files reencrypt +%{!?_licensedir:%global license %%doc} +%license COPYING +%doc misc/dracut_90reencrypt +%{_mandir}/man8/cryptsetup-reencrypt.8.gz +%{_sbindir}/cryptsetup-reencrypt + +%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 + +%clean + +%changelog +* Tue Jan 10 2023 Daniel Zatovic - 2.3.7-5 +- change cryptsetup-devel dependency from cryptsetup to cryptsetup-libs +- Resolves: #2150254 + +* Wed Dec 21 2022 Daniel Zatovic - 2.3.7-4 +- patch: Remove LUKS2 encryption data size restriction. +- patch: Abort encryption when header and data devices are same. +- Resolves: #2150254 + +* Fri Nov 4 2022 Daniel Zatovic - 2.3.7-3 +- patch: Fix internal crypt segment compare routine +- Resolves: #2110810 + +* Thu Feb 24 2022 Ondrej Kozina - 2.3.7-2 +- patch: Fix cryptsetup --test-passphrase when device in + reencryption +- Resolves: #2058009 + +* Thu Jan 20 2022 Ondrej Kozina - 2.3.7-1 +- update to cryptsetup 2.3.7 +- fixes CVE-2021-4122 +- patch: Fix suboptimal optimization in bundled argon2. +- patch: Fix bogus memory allocation/device read with + invalid LUKS2 headers +- patch: Fix typo in luksRepair prompt. +- Resolves: #2021815 #2022301 #2031859 + +* Wed Feb 17 2021 Ondrej Kozina - 2.3.3-4 +- patch: Fix reencryption for custom devices with data segments + set to use cipher_null. +- Resolves: #1927409 + +* Wed Feb 03 2021 Ondrej Kozina - 2.3.3-3 +- patch: Fix crypto backend to properly handle ECB mode. +- Resolves: #1859091 + +* Thu Aug 27 2020 Ondrej Kozina - 2.3.3-2 +- patch: Fix possible memory corruption in LUKS2 validation + code in 32bit library. +- Resolves: #1872294 + +* Thu May 28 2020 Ondrej Kozina - 2.3.3-1 +- Update to cryptsetup 2.3.3 +- Resolves: #1796826 #1743891 #1785748 + +* Fri Apr 03 2020 Ondrej Kozina - 2.3.1-1 +- Update to cryptsetup 2.3.1 +- Resolves: #1796826 #1743891 #1785748 + +* Mon Nov 18 2019 Ondrej Kozina - 2.2.2-1 +- Update to cryptsetup 2.2.2 +- LUKS2 reencryption honors activation flags (one time and persistent). +- LUKS2 reencryption works also without volume keys put in kernel + keyring service. +- Resolves: #1757783 #1750680 #1753597 #1743399 + +* Fri Aug 30 2019 Ondrej Kozina - 2.2.0-2 +- patch: Fix mapped segments overflow on 32bit architectures. +- patch: Take optimal io size in account with LUKS2 reencryption. +- Resolves: #1742815 #1746532 + +* Thu Aug 15 2019 Ondrej Kozina - 2.2.0-1 +- Update to cryptsetup 2.2.0 (final) +- Resolves: #1738263 #1740342 #1733391 #1729600 #1733390 + +* Fri Jun 14 2019 Ondrej Kozina - 2.2.0-0.2 +- Updates to reencryption feature. +- Resolves: #1676622 + +* Fri May 03 2019 Ondrej Kozina - 2.2.0-0.1 +- Update to cryptsetup 2.2.0 +- remove python bits from spec file. +- Resolves: #1676622 + +* Thu Mar 21 2019 Milan Broz - 2.0.6-2 +- Add gating tests. +- Resolves: #1682539 + +* Mon Dec 03 2018 Ondrej Kozina - 2.0.6-1 +- Update to cryptsetup 2.0.6 +- Enables all supported metadata sizes in LUKS2 validation code. +- Resolves: #1653383 + +* Fri Aug 10 2018 Ondrej Kozina - 2.0.4-2 +- patch: fix device alignment bug when processing hinted + value by device topology info. +- Resolves: #1614219 + +* Wed Aug 08 2018 Ondrej Kozina - 2.0.4-1 +- Update to cryptsetup 2.0.4. +- patch: Add RHEL system library paths in configure. +- patch: Increase default LUKS2 header size to 8 MiBs. +- patch: update tests to be compatible with larger headers. +- Set default format to LUKS2. +- Cleanup changelog. +- Resolves: #1564540 #1595257 #1595266 #1595881 #1600164 + +* Fri May 04 2018 Ondrej Kozina - 2.0.3-1 +- Update to cryptsetup 2.0.3. + +* Tue Mar 27 2018 Björn Esser - 2.0.2-2 +- Rebuilt for libjson-c.so.4 (json-c v0.13.1) on fc28 + +* Wed Mar 07 2018 Milan Broz - 2.0.2-1 +- Update to cryptsetup 2.0.2.