mirror of
https://gitlab.com/cryptsetup/cryptsetup.git
synced 2025-12-12 03:10:08 +01:00
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.
This commit is contained in:
@@ -41,7 +41,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);
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/hmac.h>
|
||||
@@ -231,7 +232,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)
|
||||
@@ -574,6 +579,10 @@ static int openssl_pbkdf2(const char *password, size_t password_length,
|
||||
if (!hash_id)
|
||||
return -EINVAL;
|
||||
|
||||
/* OpenSSL2 has iteration as signed int, avoid overflow */
|
||||
if (iterations > INT_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
r = PKCS5_PBKDF2_HMAC(password, (int)password_length, (const unsigned char *)salt,
|
||||
(int)salt_length, iterations, hash_id, (int)key_length, (unsigned char*) key);
|
||||
#endif
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <uuid/uuid.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "luks.h"
|
||||
#include "af.h"
|
||||
@@ -924,8 +925,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 volume key stored in vk->key is split to AfKey
|
||||
|
||||
@@ -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 */
|
||||
@@ -264,6 +265,9 @@ static int luks2_keyslot_set_key(struct crypt_device *cd,
|
||||
pbkdf.parallel_threads);
|
||||
free(salt);
|
||||
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user