isaacpittman-hitachi / rpms / openssl

Forked from rpms/openssl 2 years ago
Clone

Blame SOURCES/0084-pbkdf2-Set-minimum-password-length-of-8-bytes.patch

3da501
From 754862899058cfb5f2341c81f9e04dd2f7b37056 Mon Sep 17 00:00:00 2001
3da501
From: Clemens Lang <cllang@redhat.com>
3da501
Date: Thu, 17 Nov 2022 18:37:17 +0100
3da501
Subject: [PATCH] pbkdf2: Set minimum password length of 8 bytes
3da501
MIME-Version: 1.0
3da501
Content-Type: text/plain; charset=UTF-8
3da501
Content-Transfer-Encoding: 8bit
3da501
3da501
The Implementation Guidance for FIPS 140-3 says in section D.N
3da501
"Password-Based Key Derivation for Storage Applications" that "the
3da501
vendor shall document in the module’s Security Policy the length of
3da501
a password/passphrase used in key derivation and establish an upper
3da501
bound for the probability of having this parameter guessed at random.
3da501
This probability shall take into account not only the length of the
3da501
password/passphrase, but also the difficulty of guessing it. The
3da501
decision on the minimum length of a password used for key derivation is
3da501
the vendor’s, but the vendor shall at a minimum informally justify the
3da501
decision."
3da501
3da501
We are choosing a minimum password length of 8 bytes, because NIST's
3da501
ACVP testing uses passwords as short as 8 bytes, and requiring longer
3da501
passwords combined with an implicit indicator (i.e., returning an error)
3da501
would cause the module to fail ACVP testing.
3da501
3da501
Signed-off-by: Clemens Lang <cllang@redhat.com>
3da501
---
3da501
 providers/implementations/kdfs/pbkdf2.c | 27 ++++++++++++++++++++++++-
3da501
 1 file changed, 26 insertions(+), 1 deletion(-)
3da501
3da501
diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c
3da501
index 2a0ae63acc..aa0adce5e6 100644
3da501
--- a/providers/implementations/kdfs/pbkdf2.c
3da501
+++ b/providers/implementations/kdfs/pbkdf2.c
3da501
@@ -35,6 +35,21 @@
3da501
 #define KDF_PBKDF2_MAX_KEY_LEN_DIGEST_RATIO 0xFFFFFFFF
3da501
 #define KDF_PBKDF2_MIN_ITERATIONS 1000
3da501
 #define KDF_PBKDF2_MIN_SALT_LEN   (128 / 8)
3da501
+/* The Implementation Guidance for FIPS 140-3 says in section D.N
3da501
+ * "Password-Based Key Derivation for Storage Applications" that "the vendor
3da501
+ * shall document in the module’s Security Policy the length of
3da501
+ * a password/passphrase used in key derivation and establish an upper bound
3da501
+ * for the probability of having this parameter guessed at random. This
3da501
+ * probability shall take into account not only the length of the
3da501
+ * password/passphrase, but also the difficulty of guessing it. The decision on
3da501
+ * the minimum length of a password used for key derivation is the vendor’s,
3da501
+ * but the vendor shall at a minimum informally justify the decision."
3da501
+ *
3da501
+ * We are choosing a minimum password length of 8 bytes, because NIST's ACVP
3da501
+ * testing uses passwords as short as 8 bytes, and requiring longer passwords
3da501
+ * combined with an implicit indicator (i.e., returning an error) would cause
3da501
+ * the module to fail ACVP testing. */
3da501
+#define KDF_PBKDF2_MIN_PASSWORD_LEN (8)
3da501
 
3da501
 static OSSL_FUNC_kdf_newctx_fn kdf_pbkdf2_new;
3da501
 static OSSL_FUNC_kdf_freectx_fn kdf_pbkdf2_free;
3da501
@@ -186,9 +201,15 @@ static int kdf_pbkdf2_set_ctx_params(void *vctx, const OSSL_PARAM params[])
3da501
         ctx->lower_bound_checks = pkcs5 == 0;
3da501
     }
3da501
 
3da501
-    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL)
3da501
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_PASSWORD)) != NULL) {
3da501
+        if (ctx->lower_bound_checks != 0
3da501
+            && p->data_size < KDF_PBKDF2_MIN_PASSWORD_LEN) {
3da501
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
3da501
+            return 0;
3da501
+        }
3da501
         if (!pbkdf2_set_membuf(&ctx->pass, &ctx->pass_len, p))
3da501
             return 0;
3da501
+    }
3da501
 
3da501
     if ((p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_SALT)) != NULL) {
3da501
         if (ctx->lower_bound_checks != 0
3da501
@@ -297,6 +318,10 @@ static int pbkdf2_derive(const char *pass, size_t passlen,
3da501
     }
3da501
 
3da501
     if (lower_bound_checks) {
3da501
+        if (passlen < KDF_PBKDF2_MIN_PASSWORD_LEN) {
3da501
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
3da501
+            return 0;
3da501
+        }
3da501
         if ((keylen * 8) < KDF_PBKDF2_MIN_KEY_LEN_BITS) {
3da501
             ERR_raise(ERR_LIB_PROV, PROV_R_KEY_SIZE_TOO_SMALL);
3da501
             return 0;
3da501
-- 
3da501
2.38.1
3da501