From 6c3c5093eef2d98a1765d11c14748bfe124bf066 Mon Sep 17 00:00:00 2001 From: Daniel Zatovic Date: Thu, 22 Jun 2023 15:51:09 +0200 Subject: [PATCH] Disallow use of internal kernel crypto driver names in "capi" specification. --- ...tive-devices-with-internal-kernel-na.patch | 79 +++++++++++++++++++ ...internal-kenrel-crypto-driver-names-.patch | 68 ++++++++++++++++ ...-to-allow-unknown-cipher-format-in-d.patch | 52 ++++++++++++ cryptsetup.spec | 13 +++ 4 files changed, 212 insertions(+) create mode 100644 cryptsetup-2.7.0-Also-disallow-active-devices-with-internal-kernel-na.patch create mode 100644 cryptsetup-2.7.0-Disallow-use-of-internal-kenrel-crypto-driver-names-.patch create mode 100644 cryptsetup-2.7.0-Fix-init_by_name-to-allow-unknown-cipher-format-in-d.patch diff --git a/cryptsetup-2.7.0-Also-disallow-active-devices-with-internal-kernel-na.patch b/cryptsetup-2.7.0-Also-disallow-active-devices-with-internal-kernel-na.patch new file mode 100644 index 0000000..31dc60c --- /dev/null +++ b/cryptsetup-2.7.0-Also-disallow-active-devices-with-internal-kernel-na.patch @@ -0,0 +1,79 @@ +From dff9ee8c8cb68432e96261b87aabb7aaa51215e7 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Tue, 2 May 2023 15:42:21 +0200 +Subject: [PATCH] Also disallow active devices with internal kernel names. + +The same problem fixed in commit 438cf1d1b3ef6d7405cfbcbe5f631d3d7467a605 +is present in libdevmapper wrapper when parsing active device table. + +The whole point of conversion was that non-authenticated modes +can be always represented in the old cipher-mode-iv format. +As the internal names contains dash, these are unsupported. + +That said, the libdevmapper backend now correctly returns +full cipher specification including capi prefix for this case. + +Init_by_name call now fails with incomplatible cipher definition error. +--- + lib/setup.c | 2 +- + lib/utils_crypt.c | 9 +++++++++ + tests/mode-test | 5 +++++ + 3 files changed, 15 insertions(+), 1 deletion(-) + +Index: cryptsetup-2.3.7/lib/setup.c +=================================================================== +--- cryptsetup-2.3.7.orig/lib/setup.c ++++ cryptsetup-2.3.7/lib/setup.c +@@ -1188,7 +1188,7 @@ static int _init_by_name_crypt(struct cr + r = crypt_parse_name_and_mode(tgt->type == DM_LINEAR ? "null" : tgt->u.crypt.cipher, cipher, + &key_nums, cipher_mode); + if (r < 0) { +- log_dbg(cd, "Cannot parse cipher and mode from active device."); ++ log_err(cd, _("No known cipher specification pattern detected for active device %s."), name); + goto out; + } + +Index: cryptsetup-2.3.7/lib/utils_crypt.c +=================================================================== +--- cryptsetup-2.3.7.orig/lib/utils_crypt.c ++++ cryptsetup-2.3.7/lib/utils_crypt.c +@@ -224,6 +224,15 @@ int crypt_capi_to_cipher(char **org_c, c + if (i != 2) + return -EINVAL; + ++ /* non-cryptsetup compatible mode (generic driver with dash?) */ ++ if (strrchr(iv, ')')) { ++ if (i_dm) ++ return -EINVAL; ++ if (!(*org_c = strdup(c_dm))) ++ return -ENOMEM; ++ return 0; ++ } ++ + len = strlen(tmp); + if (len < 2) + return -EINVAL; +Index: cryptsetup-2.3.7/tests/mode-test +=================================================================== +--- cryptsetup-2.3.7.orig/tests/mode-test ++++ cryptsetup-2.3.7/tests/mode-test +@@ -8,6 +8,8 @@ DEV_NAME=dmc_test + HEADER_IMG=mode-test.img + PASSWORD=3xrododenron + PASSWORD1=$PASSWORD ++KEY="7c0dc5dfd0c9191381d92e6ebb3b29e7f0dba53b0de132ae23f5726727173540" ++FAST_PBKDF2="--pbkdf pbkdf2 --pbkdf-force-iterations 1000" + + # cipher-chainmode-ivopts:ivmode + CIPHERS="aes twofish serpent" +@@ -172,6 +174,10 @@ echo -n "CAPI format:" + echo $PASSWORD | $CRYPTSETUP create -h sha256 -c 'capi:xts(aes)-plain64' -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME || fail + $CRYPTSETUP close "$DEV_NAME"_tstdev || fail + echo $PASSWORD | $CRYPTSETUP create -h sha256 -c 'capi:xts(ecb(aes-generic))-plain64' -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME 2>/dev/null && fail ++dmsetup create "$DEV_NAME"_tstdev --table "0 8 crypt capi:xts(ecb(aes-generic))-plain64 $KEY 0 /dev/mapper/$DEV_NAME 0" || fail ++$CRYPTSETUP status "$DEV_NAME"_tstdev >/dev/null 2>&1 && fail ++$CRYPTSETUP close "$DEV_NAME"_tstdev 2>/dev/null && fail ++dmsetup remove "$DEV_NAME"_tstdev || fail + echo [OK] + + cleanup diff --git a/cryptsetup-2.7.0-Disallow-use-of-internal-kenrel-crypto-driver-names-.patch b/cryptsetup-2.7.0-Disallow-use-of-internal-kenrel-crypto-driver-names-.patch new file mode 100644 index 0000000..d689213 --- /dev/null +++ b/cryptsetup-2.7.0-Disallow-use-of-internal-kenrel-crypto-driver-names-.patch @@ -0,0 +1,68 @@ +From 438cf1d1b3ef6d7405cfbcbe5f631d3d7467a605 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 24 Apr 2023 21:19:03 +0200 +Subject: [PATCH] Disallow use of internal kenrel crypto driver names in "capi" + specification. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The common way to specify cipher mode in cryptsetup +is to use cipher-mode-iv notation (like aes-xts-plain64). +With introduction of authenticated ciphers we also allow "capi:" +notation that is directly used by dm-crypt (e.g. capi:xts(aes)-plain64). + +CAPI specification was never intended to be used with internal +kernel crypto api names (with dash in algorithm name), actually the +whole parsing routine wrongly parses mode here now. + +The code not checks if parsing wrongly separated the full cipher +string and effectively allowing only proper cipher names +(example of no longer supported string is capi:xts(ecb(aes-generic))-plain64). + +Thanks to Jan Wichelmann, Luca Wilke and Thomas Eisenbarth from +University of Lübeck for noticing the problems with this code. + +Fixes: #809 +--- + lib/utils_crypt.c | 8 +++++++- + tests/mode-test | 6 ++++++ + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c +index 0b7dc378..c1bde000 100644 +--- a/lib/utils_crypt.c ++++ b/lib/utils_crypt.c +@@ -43,7 +43,13 @@ int crypt_parse_name_and_mode(const char *s, char *cipher, int *key_nums, + cipher, cipher_mode) == 2) { + if (!strcmp(cipher_mode, "plain")) + strcpy(cipher_mode, "cbc-plain"); +- if (key_nums) { ++ if (!strncmp(cipher, "capi:", 5)) { ++ /* CAPI must not use internal cipher driver names with dash */ ++ if (strchr(cipher_mode, ')')) ++ return -EINVAL; ++ if (key_nums) ++ *key_nums = 1; ++ } else if (key_nums) { + char *tmp = strchr(cipher, ':'); + *key_nums = tmp ? atoi(++tmp) : 1; + if (!*key_nums) +diff --git a/tests/mode-test b/tests/mode-test +index 82171fbd..fe61880a 100755 +--- a/tests/mode-test ++++ b/tests/mode-test +@@ -184,4 +184,10 @@ done + dmcrypt xchacha12,aes-adiantum-plain64 + dmcrypt xchacha20,aes-adiantum-plain64 + ++echo -n "CAPI format:" ++echo $PASSWORD | $CRYPTSETUP create -h sha256 -c 'capi:xts(aes)-plain64' -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME || fail ++$CRYPTSETUP close "$DEV_NAME"_tstdev || fail ++echo $PASSWORD | $CRYPTSETUP create -h sha256 -c 'capi:xts(ecb(aes-generic))-plain64' -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME 2>/dev/null && fail ++echo [OK] ++ + cleanup +-- +2.40.1 + diff --git a/cryptsetup-2.7.0-Fix-init_by_name-to-allow-unknown-cipher-format-in-d.patch b/cryptsetup-2.7.0-Fix-init_by_name-to-allow-unknown-cipher-format-in-d.patch new file mode 100644 index 0000000..fdbc060 --- /dev/null +++ b/cryptsetup-2.7.0-Fix-init_by_name-to-allow-unknown-cipher-format-in-d.patch @@ -0,0 +1,52 @@ +From 53aa5f6c4f7439db1b25846597fb5603870ba55e Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Mon, 5 Jun 2023 16:02:06 +0200 +Subject: [PATCH] Fix init_by_name to allow unknown cipher format in dm-crypt + as null context. + +Deactivation code should deactivate dm-crypt device even if it is unknown +for libcryptsetup. Previous fix for cipher specification was too strict. + +Let's allow initialization as null context, that allow status and +deactivate to be usable again. +--- + lib/setup.c | 6 ++++++ + tests/mode-test | 5 ++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + +diff --git a/lib/setup.c b/lib/setup.c +index fd17be8c..786aa900 100644 +--- a/lib/setup.c ++++ b/lib/setup.c +@@ -1276,6 +1276,12 @@ static int _init_by_name_crypt(struct crypt_device *cd, const char *name) + r = crypt_parse_name_and_mode(tgt->type == DM_LINEAR ? "null" : tgt->u.crypt.cipher, cipher, + &key_nums, cipher_mode); + if (r < 0) { ++ /* Allow crypt null context with unknown cipher string */ ++ if (tgt->type == DM_CRYPT && !tgt->u.crypt.integrity) { ++ crypt_set_null_type(cd); ++ r = 0; ++ goto out; ++ } + log_err(cd, _("No known cipher specification pattern detected for active device %s."), name); + goto out; + } +diff --git a/tests/mode-test b/tests/mode-test +index 4775751e..7f7f20a1 100755 +--- a/tests/mode-test ++++ b/tests/mode-test +@@ -190,9 +190,8 @@ echo $PASSWORD | $CRYPTSETUP create -h sha256 -c 'capi:xts(aes)-plain64' -s 256 + $CRYPTSETUP close "$DEV_NAME"_tstdev || fail + echo $PASSWORD | $CRYPTSETUP create -h sha256 -c 'capi:xts(ecb(aes-generic))-plain64' -s 256 "$DEV_NAME"_tstdev /dev/mapper/$DEV_NAME 2>/dev/null && fail + dmsetup create "$DEV_NAME"_tstdev --table "0 8 crypt capi:xts(ecb(aes-generic))-plain64 $KEY 0 /dev/mapper/$DEV_NAME 0" || fail +-$CRYPTSETUP status "$DEV_NAME"_tstdev >/dev/null 2>&1 && fail +-$CRYPTSETUP close "$DEV_NAME"_tstdev 2>/dev/null && fail +-dmsetup remove "$DEV_NAME"_tstdev || fail ++$CRYPTSETUP status "$DEV_NAME"_tstdev 2>/dev/null | grep "type:" | grep -q "n/a" || fail ++$CRYPTSETUP close "$DEV_NAME"_tstdev 2>/dev/null || fail + echo [OK] + + cleanup +-- +2.40.1 + diff --git a/cryptsetup.spec b/cryptsetup.spec index 3d7dda7..8f13ad5 100644 --- a/cryptsetup.spec +++ b/cryptsetup.spec @@ -36,6 +36,9 @@ 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.0-Delegate-FIPS-mode-detection-to-configured-crypto-ba.patch Patch14: %{name}-2.6.1-Abort-encryption-when-header-and-data-devices-are-sa.patch +Patch15: %{name}-2.7.0-Disallow-use-of-internal-kenrel-crypto-driver-names-.patch +Patch16: %{name}-2.7.0-Also-disallow-active-devices-with-internal-kernel-na.patch +Patch17: %{name}-2.7.0-Fix-init_by_name-to-allow-unknown-cipher-format-in-d.patch %description The cryptsetup package contains a utility for setting up @@ -105,6 +108,9 @@ can be used for offline reencryption of disk in situ. %patch12 -p1 %patch13 -p1 %patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 %patch0 -p1 chmod -x misc/dracut_90reencrypt/* @@ -164,6 +170,13 @@ rm -rf %{buildroot}/%{_libdir}/*.la %clean %changelog +* Thu Jun 22 2023 Daniel Zatovic - 2.3.7-6 +- patch: Delegate FIPS mode detection to configured crypto backend +- patch: Disallow use of internal kenrel crypto driver names in "capi" +- patch: Also disallow active devices with internal kernel names +- patch: Fix init_by_name to allow unknown cipher format in dm-crypt +- Resolves: #2212772 #2193342 + * Tue Jan 10 2023 Daniel Zatovic - 2.3.7-5 - change cryptsetup-devel dependency from cryptsetup to cryptsetup-libs - Resolves: #2150254