openssl/0034-FIPS-PBKDF2-Set-minimum-password-length.patch
Dmitry Belyavskiy 296ae60f11 Rebasing OpenSSL to 3.5
Resolves: RHEL-80811
Resolves: RHEL-57022
Resolves: RHEL-24098
Resolves: RHEL-24097
Resolves: RHEL-86865
2025-04-16 10:23:19 +02:00

122 lines
5.4 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 07db6d2bc68c37db2c8b00225c42e3c2e3c8b6cc Mon Sep 17 00:00:00 2001
From: rpm-build <rpm-build>
Date: Wed, 6 Mar 2024 19:17:17 +0100
Subject: [PATCH 34/50] FIPS: PBKDF2: Set minimum password length
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The Implementation Guidance for FIPS 140-3 says in section D.N
"Password-Based Key Derivation for Storage Applications" that "the
vendor shall document in the modules Security Policy the length of
a password/passphrase used in key derivation and establish an upper
bound for the probability of having this parameter guessed at random.
This probability shall take into account not only the length of the
password/passphrase, but also the difficulty of guessing it. The
decision on the minimum length of a password used for key derivation is
the vendors, but the vendor shall at a minimum informally justify the
decision."
We are choosing a minimum password length of 8 bytes, because NIST's
ACVP testing uses passwords as short as 8 bytes, and requiring longer
passwords combined with an implicit indicator (i.e., returning an error)
would cause the module to fail ACVP testing.
Signed-off-by: Clemens Lang <cllang@redhat.com>
From-dist-git-commit: 4334bc837fbc64d14890fdc51679a80770d498ce
---
providers/implementations/kdfs/pbkdf2.c | 39 +++++++++++++++++++++----
1 file changed, 33 insertions(+), 6 deletions(-)
diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c
index b383314064..68f9355b7d 100644
--- a/providers/implementations/kdfs/pbkdf2.c
+++ b/providers/implementations/kdfs/pbkdf2.c
@@ -36,6 +36,21 @@
#define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF
#define KDF_PBKDF2_MIN_ITERATIONS 1000
#define KDF_PBKDF2_MIN_SALT_LEN (128 / 8)
+/* The Implementation Guidance for FIPS 140-3 says in section D.N
+ * "Password-Based Key Derivation for Storage Applications" that "the vendor
+ * shall document in the modules Security Policy the length of
+ * a password/passphrase used in key derivation and establish an upper bound
+ * for the probability of having this parameter guessed at random. This
+ * probability shall take into account not only the length of the
+ * password/passphrase, but also the difficulty of guessing it. The decision on
+ * the minimum length of a password used for key derivation is the vendors,
+ * but the vendor shall at a minimum informally justify the decision."
+ *
+ * We are choosing a minimum password length of 8 bytes, because NIST's ACVP
+ * testing uses passwords as short as 8 bytes, and requiring longer passwords
+ * combined with an implicit indicator (i.e., returning an error) would cause
+ * the module to fail ACVP testing. */
+#define KDF_PBKDF2_MIN_PASSWORD_LEN (8)
static OSSL_FUNC_kdf_newctx_fn kdf_pbkdf2_new;
static OSSL_FUNC_kdf_dupctx_fn kdf_pbkdf2_dup;
@@ -179,8 +194,8 @@ static int pbkdf2_set_membuf(unsigned char **buffer, size_t *buflen,
}
static int pbkdf2_lower_bound_check_passed(int saltlen, uint64_t iter,
- size_t keylen, int *error,
- const char **desc)
+ size_t keylen, size_t passlen,
+ int *error, const char **desc)
{
if ((keylen * 8) < KDF_PBKDF2_MIN_KEY_LEN_BITS) {
*error = PROV_R_KEY_SIZE_TOO_SMALL;
@@ -200,7 +215,12 @@ static int pbkdf2_lower_bound_check_passed(int saltlen, uint64_t iter,
*desc = "Iteration count";
return 0;
}
-
+ if (passlen < KDF_PBKDF2_MIN_PASSWORD_LEN) {
+ *error = PROV_R_INVALID_INPUT_LENGTH;
+ if (desc != NULL)
+ *desc = "Password length";
+ return 0;
+ }
return 1;
}
@@ -211,7 +231,8 @@ static int fips_lower_bound_check_passed(KDF_PBKDF2 *ctx, size_t keylen)
int error = 0;
const char *desc = NULL;
int approved = pbkdf2_lower_bound_check_passed(ctx->salt_len, ctx->iter,
- keylen, &error, &desc);
+ keylen, ctx->pass_len,
+ &error, &desc);
if (!approved) {
if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, libctx,
@@ -283,9 +304,15 @@ static int kdf_pbkdf2_set_ctx_params(void *vctx, const OSSL_PARAM params[])
#endif
}
- if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
+ if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL) {
+ if (ctx->lower_bound_checks != 0
+ && p->data_size < KDF_PBKDF2_MIN_PASSWORD_LEN) {
+ ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+ return 0;
+ }
if (!pbkdf2_set_membuf(&ctx->pass, &ctx->pass_len, p))
return 0;
+ }
if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
if (ctx->lower_bound_checks != 0
@@ -406,7 +433,7 @@ static int pbkdf2_derive(KDF_PBKDF2 *ctx, const char *pass, size_t passlen,
if (lower_bound_checks) {
int error = 0;
int passed = pbkdf2_lower_bound_check_passed(saltlen, iter, keylen,
- &error, NULL);
+ passlen, &error, NULL);
if (!passed) {
ERR_raise(ERR_LIB_PROV, error);
--
2.49.0