-Fix-OpenSSL-2-crypto-backend-PBKDF2-possible-iterati

(cherry picked from commit d450a9c21f0ad9f59394e7432180aeaab65f48aa)
This commit is contained in:
volcanodragon 2023-02-25 10:15:59 +08:00 committed by openeuler-sync-bot
parent 15ecf7d4ad
commit 6dad584d3d
3 changed files with 136 additions and 60 deletions

View File

@ -0,0 +1,131 @@
From ace015a3e5d0940ae00c309ed53097f5a695dee5 Mon Sep 17 00:00:00 2001
From: Milan Broz <gmazyland@gmail.com>
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 <wangzhiqiang95@huawei.com> in cryptsetup list.
Conflict: context adaptation
---
lib/crypto_backend/crypto_backend.h | 3 ++-
lib/crypto_backend/crypto_openssl.c | 10 ++++++++++
lib/luks1/keymanage.c | 7 ++++++-
lib/luks2/luks2_keyslot_luks2.c | 4 ++++
4 files changed, 22 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..3a58dcd 100644
--- a/lib/crypto_backend/crypto_openssl.c
+++ b/lib/crypto_backend/crypto_openssl.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <errno.h>
+#include <limits.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
@@ -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,11 @@ 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 <ctype.h>
#include <assert.h>
#include <uuid/uuid.h>
+#include <limits.h>
#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..098f6c6 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 <limits.h>
#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

View File

@ -1,58 +0,0 @@
From 3592f3da11ba6d830d700c2c987165ddc86345d8 Mon Sep 17 00:00:00 2001
From: wangzhiqiang <wangzhiqiang95@huawei.com>
Date: Mon, 30 Jan 2023 16:36:29 +0800
Subject: [PATCH] check whether the forced iteration count is out of range
struct crypt_pbkdf_type has a uint32_t variable iterations, but
PKCS5_PBKDF2_HMAC interface of openssl accept int variable, so
return fail when it greater than INT_MAX.
Signed-off-by: wangzhiqiang <wangzhiqiang95@huawei.com>
---
lib/crypto_backend/crypto_openssl.c | 2 +-
lib/luks2/luks2_keyslot_luks2.c | 1 +
man/cryptsetup.8 | 3 ++-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c
index 0dbcb75..db400e4 100644
--- a/lib/crypto_backend/crypto_openssl.c
+++ b/lib/crypto_backend/crypto_openssl.c
@@ -541,7 +541,7 @@ int crypt_pbkdf(const char *kdf, const char *hash,
uint32_t iterations, uint32_t memory, uint32_t parallel)
{
- if (!kdf)
+ if (!kdf || iterations > INT_MAX)
return -EINVAL;
if (!strcmp(kdf, "pbkdf2")) {
diff --git a/lib/luks2/luks2_keyslot_luks2.c b/lib/luks2/luks2_keyslot_luks2.c
index ea58112..509a391 100644
--- a/lib/luks2/luks2_keyslot_luks2.c
+++ b/lib/luks2/luks2_keyslot_luks2.c
@@ -254,6 +254,7 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
pbkdf.iterations, pbkdf.max_memory_kb,
pbkdf.parallel_threads);
if (r < 0) {
+ log_err(cd, "Invalid parameter.");
crypt_free_volume_key(derived_key);
return r;
}
diff --git a/man/cryptsetup.8 b/man/cryptsetup.8
index c54480a..70d1f23 100644
--- a/man/cryptsetup.8
+++ b/man/cryptsetup.8
@@ -1132,7 +1132,8 @@ be used on some small embedded system.
\fBMINIMAL AND MAXIMAL PBKDF COSTS:\fR
For \fBPBKDF2\fR, the minimum iteration count is 1000 and
-maximum is 4294967295 (maximum for 32bit unsigned integer).
+maximum is 4294967295 (maximum for 32bit unsigned integer),
+except openssl, which supports only 2147483647 (maximum for 32bit integer).
Memory and parallel costs are unused for PBKDF2.
For \fBArgon2i\fR and \fBArgon2id\fR, minimum iteration count (CPU cost) is 4 and
maximum is 4294967295 (maximum for 32bit unsigned integer).
--
2.33.0

View File

@ -1,6 +1,6 @@
Name: cryptsetup
Version: 2.4.1
Release: 3
Release: 4
Summary: Utility used to conveniently set up disk encryption
License: GPLv2+ and CC0-1.0 and LGPLv2+
URL: https://gitlab.com/cryptsetup/cryptsetup
@ -10,7 +10,7 @@ Patch1: 0001-cryptsetup-add-system-library-paths.patch
Patch2: 0002-fix-compat-test.patch
Patch3: 0003-add-test-case-for-sm4.patch
Patch4: 0004-Fix-CVE-2021-4122-LUKS2-reencryption-crash-recovery-.patch
Patch5: 0005-check-whether-the-forced-iteration-count-is-out-of-r.patch
Patch5: 0005-Fix-OpenSSL-2-crypto-backend-PBKDF2-possible-iterati.patch
BuildRequires: openssl-devel, popt-devel, device-mapper-devel, gcc, libssh-devel, gettext-devel libtool
BuildRequires: libuuid-devel, json-c-devel, libargon2-devel, libpwquality-devel, libblkid-devel
@ -117,6 +117,9 @@ make check
%{_mandir}/man8/*
%changelog
* Sat Feb 25 2023 volcanodragon <linfeilong@huawei.com> - 2.4.1-4
- fix pbkdf-force-iterations in openssl
* Thu Feb 23 2023 volcanodragon <linfeilong@huawei.com> - 2.4.1-3
- add testcase for sm4-xts-plain64, fix CVE-2021-4122, add out of range check