From 13dcfa5ac7b6a3bd91f2fe5f0d56bc37c9829cdd Mon Sep 17 00:00:00 2001 From: wangzhiqiang Date: Thu, 16 Feb 2023 21:30:59 +0800 Subject: [PATCH] Fix OpenSSL < 2 crypto backend PBKDF2 possible iteration count overflow. --- ...ypto-backend-PBKDF2-possible-iterati.patch | 129 ++++++++++++++++++ cryptsetup.spec | 6 +- 2 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 0003-Fix-OpenSSL-2-crypto-backend-PBKDF2-possible-iterati.patch diff --git a/0003-Fix-OpenSSL-2-crypto-backend-PBKDF2-possible-iterati.patch b/0003-Fix-OpenSSL-2-crypto-backend-PBKDF2-possible-iterati.patch new file mode 100644 index 0000000..7765c1e --- /dev/null +++ b/0003-Fix-OpenSSL-2-crypto-backend-PBKDF2-possible-iterati.patch @@ -0,0 +1,129 @@ +From ace015a3e5d0940ae00c309ed53097f5a695dee5 Mon Sep 17 00:00:00 2001 +From: Milan Broz +Date: Tue, 31 Jan 2023 20:15:58 +0100 +Subject: [PATCH] Fix OpenSSL < 2 crypto backend PBKDF2 possible iteration + count overflow. + +For OpenSSL2, we use PKCS5_PBKDF2_HMAC() function. +Unfortunately, the iteration count is defined as signed integer +(unlike unsigned in OpenSSL3 PARAMS KDF API). + +This can lead to overflow and decreasing of actual iterations count. +In reality this can happen only if pbkdf-force-iterations is used. + +This patch add check to INT_MAX if linked to older OpenSSL and +disallows such setting. + +Note, this is misconception in OpenSSL2 API, cryptsetup internally +use uint32_t for iterations count. + +Reported by wangzhiqiang in cryptsetup list. + +Conflict: context adaptation +--- + lib/crypto_backend/crypto_backend.h | 3 ++- + lib/crypto_backend/crypto_openssl.c | 9 +++++++++ + lib/luks1/keymanage.c | 7 ++++++- + lib/luks2/luks2_keyslot_luks2.c | 4 ++++ + 4 files changed, 21 insertions(+), 2 deletions(-) + +diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h +index 88cc2d5..47e5186 100644 +--- a/lib/crypto_backend/crypto_backend.h ++++ b/lib/crypto_backend/crypto_backend.h +@@ -34,7 +34,8 @@ struct crypt_storage; + int crypt_backend_init(bool fips); + void crypt_backend_destroy(void); + +-#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */ ++#define CRYPT_BACKEND_KERNEL (1 << 0) /* Crypto uses kernel part, for benchmark */ ++#define CRYPT_BACKEND_PBKDF2_INT (1 << 1) /* Iteration in PBKDF2 is signed int and can overflow */ + + uint32_t crypt_backend_flags(void); + const char *crypt_backend_version(void); +diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c +index 0dbcb75..fc11efa 100644 +--- a/lib/crypto_backend/crypto_openssl.c ++++ b/lib/crypto_backend/crypto_openssl.c +@@ -35,6 +35,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -228,7 +229,11 @@ void crypt_backend_destroy(void) + + uint32_t crypt_backend_flags(void) + { ++#if OPENSSL_VERSION_MAJOR >= 3 + return 0; ++#else ++ return CRYPT_BACKEND_PBKDF2_INT; ++#endif + } + + const char *crypt_backend_version(void) +@@ -527,6 +532,10 @@ static int pbkdf2(const char *password, size_t password_length, + if (!hash_id) + return 0; + ++ /* OpenSSL2 has iteration as signed int, avoid overflow */ ++ if (iterations > INT_MAX) ++ return 0; ++ + return PKCS5_PBKDF2_HMAC(password, (int)password_length, (const unsigned char *)salt, + (int)salt_length, iterations, hash_id, + (int)key_length, key); +diff --git a/lib/luks1/keymanage.c b/lib/luks1/keymanage.c +index 244b0d5..792088c 100644 +--- a/lib/luks1/keymanage.c ++++ b/lib/luks1/keymanage.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #include "luks.h" + #include "af.h" +@@ -922,8 +923,12 @@ int LUKS_set_key(unsigned int keyIndex, + hdr->keyblock[keyIndex].passwordSalt, LUKS_SALTSIZE, + derived_key->key, hdr->keyBytes, + hdr->keyblock[keyIndex].passwordIterations, 0, 0); +- if (r < 0) ++ if (r < 0) { ++ if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) && ++ hdr->keyblock[keyIndex].passwordIterations > INT_MAX) ++ log_err(ctx, _("PBKDF2 iteration value overflow.")); + goto out; ++ } + + /* + * AF splitting, the masterkey stored in vk->key is split to AfKey +diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c +index ea58112..74f1152 100644 +--- a/lib/luks2/luks2_keyslot_luks2.c ++++ b/lib/luks2/luks2_keyslot_luks2.c +@@ -19,6 +19,7 @@ + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + ++#include + #include "luks2_internal.h" + + /* FIXME: move keyslot encryption to crypto backend */ +@@ -254,6 +255,9 @@ static int luks2_keyslot_set_key(struct crypt_device *cd, + pbkdf.iterations, pbkdf.max_memory_kb, + pbkdf.parallel_threads); + if (r < 0) { ++ if ((crypt_backend_flags() & CRYPT_BACKEND_PBKDF2_INT) && ++ pbkdf.iterations > INT_MAX) ++ log_err(cd, _("PBKDF2 iteration value overflow.")); + crypt_free_volume_key(derived_key); + return r; + } +-- +2.33.0 + diff --git a/cryptsetup.spec b/cryptsetup.spec index 7cfd84a..31e949a 100644 --- a/cryptsetup.spec +++ b/cryptsetup.spec @@ -1,6 +1,6 @@ Name: cryptsetup Version: 2.4.1 -Release: 2 +Release: 3 Summary: Utility used to conveniently set up disk encryption License: GPLv2+ and CC0-1.0 and LGPLv2+ URL: https://gitlab.com/cryptsetup/cryptsetup @@ -8,6 +8,7 @@ Source0: https://www.kernel.org/pub/linux/utils/cryptsetup/v2.4/cryptsetup-%{ve Patch1: 0001-cryptsetup-add-system-library-paths.patch Patch2: 0002-fix-compat-test.patch +Patch3: 0003-Fix-OpenSSL-2-crypto-backend-PBKDF2-possible-iterati.patch BuildRequires: openssl-devel, popt-devel, device-mapper-devel, gcc, libssh-devel BuildRequires: libuuid-devel, json-c-devel, libargon2-devel, libpwquality-devel, libblkid-devel @@ -113,6 +114,9 @@ make check %{_mandir}/man8/* %changelog +* Thu Feb 16 2023 wangzhiqiang - 2.4.1-3 +- fix pbkdf-force-iterations in openssl + * Mon Oct 17 2022 wuguanghao - 2.4.1-2 - add CC0-1.0 license -- Gitee