]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
fips: add kbkdf key length check as per SP 800-131a revision 2
authorPauli <ppzgs1@gmail.com>
Mon, 5 Aug 2024 06:07:43 +0000 (16:07 +1000)
committerPauli <ppzgs1@gmail.com>
Wed, 7 Aug 2024 22:44:38 +0000 (08:44 +1000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/25095)

providers/fips/fipsprov.c
providers/implementations/kdfs/kbkdf.c

index 3ef42796aaf378b4e47144aca6625d7e13725dc0..796ff106498018f7a484bd894723fe6f71abaa5b 100644 (file)
@@ -101,6 +101,7 @@ typedef struct fips_global_st {
     FIPS_OPTION fips_rsa_pkcs15_padding_disabled;
     FIPS_OPTION fips_rsa_sign_x931_disallowed;
     FIPS_OPTION fips_hkdf_key_check;
+    FIPS_OPTION fips_kbkdf_key_check;
     FIPS_OPTION fips_tls13_kdf_key_check;
     FIPS_OPTION fips_tls1_prf_key_check;
     FIPS_OPTION fips_sshkdf_key_check;
@@ -137,6 +138,7 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx)
     init_fips_option(&fgbl->fips_rsa_pkcs15_padding_disabled, 0);
     init_fips_option(&fgbl->fips_rsa_sign_x931_disallowed, 0);
     init_fips_option(&fgbl->fips_hkdf_key_check, 0);
+    init_fips_option(&fgbl->fips_kbkdf_key_check, 0);
     init_fips_option(&fgbl->fips_tls13_kdf_key_check, 0);
     init_fips_option(&fgbl->fips_tls1_prf_key_check, 0);
     init_fips_option(&fgbl->fips_sshkdf_key_check, 0);
@@ -206,7 +208,7 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
     * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS and
     * OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK are not self test parameters.
     */
-    OSSL_PARAM core_params[29], *p = core_params;
+    OSSL_PARAM core_params[30], *p = core_params;
 
     *p++ = OSSL_PARAM_construct_utf8_ptr(
             OSSL_PROV_PARAM_CORE_MODULE_FILENAME,
@@ -271,6 +273,8 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl)
                         fips_rsa_sign_x931_disallowed);
     FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_HKDF_KEY_CHECK,
                         fips_hkdf_key_check);
+    FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_KBKDF_KEY_CHECK,
+                        fips_kbkdf_key_check);
     FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS13_KDF_KEY_CHECK,
                         fips_tls13_kdf_key_check);
     FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS1_PRF_KEY_CHECK,
@@ -356,6 +360,8 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
                      fips_rsa_sign_x931_disallowed);
     FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_HKDF_KEY_CHECK,
                      fips_hkdf_key_check);
+    FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_KBKDF_KEY_CHECK,
+                     fips_kbkdf_key_check);
     FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS13_KDF_KEY_CHECK,
                      fips_tls13_kdf_key_check);
     FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS1_PRF_KEY_CHECK,
@@ -915,6 +921,7 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle,
     FIPS_SET_OPTION(fgbl, fips_rsa_pkcs15_padding_disabled);
     FIPS_SET_OPTION(fgbl, fips_rsa_sign_x931_disallowed);
     FIPS_SET_OPTION(fgbl, fips_hkdf_key_check);
+    FIPS_SET_OPTION(fgbl, fips_kbkdf_key_check);
     FIPS_SET_OPTION(fgbl, fips_tls13_kdf_key_check);
     FIPS_SET_OPTION(fgbl, fips_tls1_prf_key_check);
     FIPS_SET_OPTION(fgbl, fips_sshkdf_key_check);
@@ -1137,6 +1144,7 @@ FIPS_FEATURE_CHECK(FIPS_rsa_pkcs15_padding_disabled,
 FIPS_FEATURE_CHECK(FIPS_rsa_sign_x931_disallowed,
                    fips_rsa_sign_x931_disallowed)
 FIPS_FEATURE_CHECK(FIPS_hkdf_key_check, fips_hkdf_key_check)
+FIPS_FEATURE_CHECK(FIPS_kbkdf_key_check, fips_kbkdf_key_check)
 FIPS_FEATURE_CHECK(FIPS_tls13_kdf_key_check, fips_tls13_kdf_key_check)
 FIPS_FEATURE_CHECK(FIPS_tls1_prf_key_check, fips_tls1_prf_key_check)
 FIPS_FEATURE_CHECK(FIPS_sshkdf_key_check, fips_sshkdf_key_check)
index cee68d063d54ddab516f50127c5dde32fbccba6a..4dd8fe6f8731d65c711547c172339588062c170a 100644 (file)
@@ -43,6 +43,9 @@
 #include "prov/provider_ctx.h"
 #include "prov/provider_util.h"
 #include "prov/providercommon.h"
+#include "prov/securitycheck.h"
+#include "prov/fipscommon.h"
+#include "prov/fipsindicator.h"
 
 #include "internal/e_os.h"
 #include "internal/params.h"
@@ -73,6 +76,7 @@ typedef struct {
     int use_l;
     int is_kmac;
     int use_separator;
+    OSSL_FIPS_IND_DECLARE
 } KBKDF;
 
 /* Definitions needed for typechecking. */
@@ -122,6 +126,7 @@ static void *kbkdf_new(void *provctx)
         return NULL;
 
     ctx->provctx = provctx;
+    OSSL_FIPS_IND_INIT(ctx)
     init(ctx);
     return ctx;
 }
@@ -174,6 +179,7 @@ static void *kbkdf_dup(void *vctx)
         dest->use_l = src->use_l;
         dest->use_separator = src->use_separator;
         dest->is_kmac = src->is_kmac;
+        OSSL_FIPS_IND_COPY(dest, src)
     }
     return dest;
 
@@ -182,6 +188,24 @@ static void *kbkdf_dup(void *vctx)
     return NULL;
 }
 
+#ifdef FIPS_MODULE
+static int fips_kbkdf_key_check_passed(KBKDF *ctx)
+{
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    int key_approved = ossl_kdf_check_key_size(ctx->ki_len);
+
+    if (!key_approved) {
+        if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0,
+                                         libctx, "KBKDF", "Key size",
+                                         FIPS_kbkdf_key_check)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+    }
+    return 1;
+}
+#endif
+
 /* SP800-108 section 5.1 or section 5.2 depending on mode. */
 static int derive(EVP_MAC_CTX *ctx_init, kbkdf_mode mode, unsigned char *iv,
                   size_t iv_len, unsigned char *label, size_t label_len,
@@ -351,6 +375,10 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
     if (params == NULL)
         return 1;
 
+    if (!OSSL_FIPS_IND_SET_CTX_PARAM(ctx, OSSL_FIPS_IND_SETTABLE0, params,
+                                     OSSL_KDF_PARAM_FIPS_KEY_CHECK))
+        return 0;
+
     if (!ossl_prov_macctx_load_from_params(&ctx->ctx_init, params, NULL,
                                            NULL, NULL, libctx))
         return 0;
@@ -382,9 +410,16 @@ static int kbkdf_set_ctx_params(void *vctx, const OSSL_PARAM params[])
         return 0;
     }
 
-    if (ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_KEY,
-                                     &ctx->ki, &ctx->ki_len) == 0)
+    p = OSSL_PARAM_locate_const(params, OSSL_KDF_PARAM_KEY);
+    if (p != NULL) {
+        if (ossl_param_get1_octet_string(p, OSSL_KDF_PARAM_KEY,
+                                         &ctx->ki, &ctx->ki_len) == 0)
+            return 0;
+#ifdef FIPS_MODULE
+        if (!fips_kbkdf_key_check_passed(ctx))
             return 0;
+#endif
+    }
 
     if (ossl_param_get1_octet_string(params, OSSL_KDF_PARAM_SALT,
                                      &ctx->label, &ctx->label_len) == 0)
@@ -443,6 +478,7 @@ static const OSSL_PARAM *kbkdf_settable_ctx_params(ossl_unused void *ctx,
         OSSL_PARAM_int(OSSL_KDF_PARAM_KBKDF_USE_L, NULL),
         OSSL_PARAM_int(OSSL_KDF_PARAM_KBKDF_USE_SEPARATOR, NULL),
         OSSL_PARAM_int(OSSL_KDF_PARAM_KBKDF_R, NULL),
+        OSSL_FIPS_IND_SETTABLE_CTX_PARAM(OSSL_KDF_PARAM_FIPS_KEY_CHECK)
         OSSL_PARAM_END,
     };
     return known_settable_ctx_params;
@@ -450,21 +486,28 @@ static const OSSL_PARAM *kbkdf_settable_ctx_params(ossl_unused void *ctx,
 
 static int kbkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
 {
+#ifdef FIPS_MODULE
+    KBKDF *ctx = (KBKDF *)vctx;
+#endif
     OSSL_PARAM *p;
 
+    /* KBKDF can produce results as large as you like. */
     p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_SIZE);
-    if (p == NULL)
-        return -2;
+    if (p != NULL && !OSSL_PARAM_set_size_t(p, SIZE_MAX))
+        return 0;
 
-    /* KBKDF can produce results as large as you like. */
-    return OSSL_PARAM_set_size_t(p, SIZE_MAX);
+    if (!OSSL_FIPS_IND_GET_CTX_PARAM(ctx, params))
+        return 0;
+    return 1;
 }
 
 static const OSSL_PARAM *kbkdf_gettable_ctx_params(ossl_unused void *ctx,
                                                    ossl_unused void *provctx)
 {
     static const OSSL_PARAM known_gettable_ctx_params[] = {
-        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL), OSSL_PARAM_END
+        OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
+        OSSL_FIPS_IND_GETTABLE_CTX_PARAM()
+        OSSL_PARAM_END
     };
     return known_gettable_ctx_params;
 }