From aa3830c3fc0f087d65a05fd0ea4fc03e26add002 Mon Sep 17 00:00:00 2001 From: pohsingwu Date: Fri, 26 Jul 2024 15:28:51 +0800 Subject: [PATCH] Add new configurable item `pbkdf2-lower-bound-check` Since FIPS provider performs lower bound check by default from v3.0, the default value for new configurable item will be one. Reviewed-by: Shane Lontis Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/24120) --- apps/fipsinstall.c | 14 ++++++++++++++ doc/man1/openssl-fipsinstall.pod.in | 6 ++++++ include/openssl/fips_names.h | 8 ++++++++ providers/common/include/prov/fipscommon.h | 1 + providers/fips/fipsprov.c | 12 +++++++++++- providers/implementations/kdfs/pbkdf2.c | 8 ++------ test/recipes/03-test_fipsinstall.t | 3 ++- util/mk-fipsmodule-cnf.pl | 2 ++ util/perl/OpenSSL/paramnames.pm | 1 + 9 files changed, 47 insertions(+), 8 deletions(-) diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c index caa0f39b8d850..6807810f503d5 100644 --- a/apps/fipsinstall.c +++ b/apps/fipsinstall.c @@ -55,6 +55,7 @@ typedef enum OPTION_choice { OPT_SSHKDF_KEY_CHECK, OPT_SSKDF_KEY_CHECK, OPT_X963KDF_KEY_CHECK, + OPT_NO_PBKDF2_LOWER_BOUND_CHECK, OPT_SELF_TEST_ONLOAD, OPT_SELF_TEST_ONINSTALL } OPTION_CHOICE; @@ -112,6 +113,8 @@ const OPTIONS fipsinstall_options[] = { "Enable key check for SSKDF"}, {"x963kdf_key_check", OPT_X963KDF_KEY_CHECK, '-', "Enable key check for X963KDF"}, + {"no_pbkdf2_lower_bound_check", OPT_NO_PBKDF2_LOWER_BOUND_CHECK, '-', + "Disable lower bound check for PBKDF2"}, OPT_SECTION("Input"), {"in", OPT_IN, '<', "Input config file, used when verifying"}, @@ -150,6 +153,7 @@ typedef struct { unsigned int sshkdf_key_check : 1; unsigned int sskdf_key_check : 1; unsigned int x963kdf_key_check : 1; + unsigned int pbkdf2_lower_bound_check : 1; } FIPS_OPTS; /* Pedantic FIPS compliance */ @@ -175,6 +179,7 @@ static const FIPS_OPTS pedantic_opts = { 1, /* sshkdf_key_check */ 1, /* sskdf_key_check */ 1, /* x963kdf_key_check */ + 1, /* pbkdf2_lower_bound_check */ }; /* Default FIPS settings for backward compatibility */ @@ -200,6 +205,7 @@ static FIPS_OPTS fips_opts = { 0, /* sshkdf_key_check */ 0, /* sskdf_key_check */ 0, /* x963kdf_key_check */ + 1, /* pbkdf2_lower_bound_check */ }; static int check_non_pedantic_fips(int pedantic, const char *name) @@ -361,6 +367,9 @@ static int write_config_fips_section(BIO *out, const char *section, opts->sskdf_key_check ? "1": "0") <= 0 || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_X963KDF_KEY_CHECK, opts->x963kdf_key_check ? "1": "0") <= 0 + || BIO_printf(out, "%s = %s\n", + OSSL_PROV_FIPS_PARAM_PBKDF2_LOWER_BOUND_CHECK, + opts->pbkdf2_lower_bound_check ? "1" : "0") <= 0 || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac, module_mac_len)) goto end; @@ -595,6 +604,11 @@ int fipsinstall_main(int argc, char **argv) case OPT_X963KDF_KEY_CHECK: fips_opts.x963kdf_key_check = 1; break; + case OPT_NO_PBKDF2_LOWER_BOUND_CHECK: + if (!check_non_pedantic_fips(pedantic, "no_pbkdf2_lower_bound_check")) + goto end; + fips_opts.pbkdf2_lower_bound_check = 0; + break; case OPT_QUIET: quiet = 1; /* FALLTHROUGH */ diff --git a/doc/man1/openssl-fipsinstall.pod.in b/doc/man1/openssl-fipsinstall.pod.in index f5b36e58ecfb4..88e4a8a20c70f 100644 --- a/doc/man1/openssl-fipsinstall.pod.in +++ b/doc/man1/openssl-fipsinstall.pod.in @@ -31,6 +31,7 @@ B [B<-sskdf_digest_check>] [B<-x963kdf_digest_check>] [B<-dsa_sign_disabled>] +[B<-no_pbkdf2_lower_bound_check>] [B<-no_short_mac>] [B<-tdes_encrypt_disabled>] [B<-rsa_sign_x931_disabled>] @@ -299,6 +300,11 @@ Configure the module to enable a run-time short key-derivation key check when deriving a key by X963KDF. See NIST SP 800-131Ar2 for details. +=item B<-no_pbkdf2_lower_bound_check> + +Configure the module to not perform run-time lower bound check for PBKDF2. +See NIST SP 800-132 for details. + =item B<-self_test_onload> Do not write the two fields related to the "test status indicator" and diff --git a/include/openssl/fips_names.h b/include/openssl/fips_names.h index 730082014b1c9..9b80247e87d40 100644 --- a/include/openssl/fips_names.h +++ b/include/openssl/fips_names.h @@ -198,6 +198,14 @@ extern "C" { */ # define OSSL_PROV_FIPS_PARAM_X963KDF_KEY_CHECK "x963kdf-key-check" +/* + * A boolean that determines if the runtime lower bound check for PBKDF2 is + * performed. + * This is enabled by default. + * Type: OSSL_PARAM_UTF8_STRING + */ +# define OSSL_PROV_FIPS_PARAM_PBKDF2_LOWER_BOUND_CHECK "pbkdf2-lower-bound-check" + # ifdef __cplusplus } # endif diff --git a/providers/common/include/prov/fipscommon.h b/providers/common/include/prov/fipscommon.h index 7b99bce5d6af4..c9d0106cb7727 100644 --- a/providers/common/include/prov/fipscommon.h +++ b/providers/common/include/prov/fipscommon.h @@ -29,5 +29,6 @@ int FIPS_tls1_prf_key_check(OSSL_LIB_CTX *libctx); int FIPS_sshkdf_key_check(OSSL_LIB_CTX *libctx); int FIPS_sskdf_key_check(OSSL_LIB_CTX *libctx); int FIPS_x963kdf_key_check(OSSL_LIB_CTX *libctx); +int FIPS_pbkdf2_lower_bound_check(OSSL_LIB_CTX *libctx); #endif diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index f27527607d00b..c1f55d5fca3dc 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -104,6 +104,7 @@ typedef struct fips_global_st { FIPS_OPTION fips_sshkdf_key_check; FIPS_OPTION fips_sskdf_key_check; FIPS_OPTION fips_x963kdf_key_check; + FIPS_OPTION fips_pbkdf2_lower_bound_check; } FIPS_GLOBAL; static void init_fips_option(FIPS_OPTION *opt, int enabled) @@ -137,6 +138,7 @@ void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx) init_fips_option(&fgbl->fips_sshkdf_key_check, 0); init_fips_option(&fgbl->fips_sskdf_key_check, 0); init_fips_option(&fgbl->fips_x963kdf_key_check, 0); + init_fips_option(&fgbl->fips_pbkdf2_lower_bound_check, 1); return fgbl; } @@ -185,6 +187,8 @@ static const OSSL_PARAM fips_param_types[] = { 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_X963KDF_KEY_CHECK, OSSL_PARAM_INTEGER, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_PBKDF2_LOWER_BOUND_CHECK, + OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_END }; @@ -198,7 +202,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[26], *p = core_params; + OSSL_PARAM core_params[27], *p = core_params; *p++ = OSSL_PARAM_construct_utf8_ptr( OSSL_PROV_PARAM_CORE_MODULE_FILENAME, @@ -269,6 +273,8 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl) fips_sskdf_key_check); FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_X963KDF_KEY_CHECK, fips_x963kdf_key_check); + FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_PBKDF2_LOWER_BOUND_CHECK, + fips_pbkdf2_lower_bound_check); #undef FIPS_FEATURE_OPTION *p = OSSL_PARAM_construct_end(); @@ -348,6 +354,8 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[]) fips_sskdf_key_check); FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_X963KDF_KEY_CHECK, fips_x963kdf_key_check); + FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_PBKDF2_LOWER_BOUND_CHECK, + fips_pbkdf2_lower_bound_check); #undef FIPS_FEATURE_GET return 1; } @@ -898,6 +906,7 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, FIPS_SET_OPTION(fgbl, fips_sshkdf_key_check); FIPS_SET_OPTION(fgbl, fips_sskdf_key_check); FIPS_SET_OPTION(fgbl, fips_x963kdf_key_check); + FIPS_SET_OPTION(fgbl, fips_pbkdf2_lower_bound_check); #undef FIPS_SET_OPTION ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers); @@ -1116,6 +1125,7 @@ FIPS_FEATURE_CHECK(FIPS_tls1_prf_key_check, fips_tls1_prf_key_check) FIPS_FEATURE_CHECK(FIPS_sshkdf_key_check, fips_sshkdf_key_check) FIPS_FEATURE_CHECK(FIPS_sskdf_key_check, fips_sskdf_key_check) FIPS_FEATURE_CHECK(FIPS_x963kdf_key_check, fips_x963kdf_key_check) +FIPS_FEATURE_CHECK(FIPS_pbkdf2_lower_bound_check, fips_pbkdf2_lower_bound_check) #undef FIPS_FEATURE_CHECK diff --git a/providers/implementations/kdfs/pbkdf2.c b/providers/implementations/kdfs/pbkdf2.c index cf95517f7a6b9..2ee637ec4337d 100644 --- a/providers/implementations/kdfs/pbkdf2.c +++ b/providers/implementations/kdfs/pbkdf2.c @@ -28,6 +28,7 @@ #include "prov/providercommon.h" #include "prov/implementations.h" #include "prov/provider_util.h" +#include "prov/fipscommon.h" #include "prov/fipsindicator.h" #include "pbkdf2.h" @@ -205,11 +206,6 @@ static int pbkdf2_lower_bound_check_passed(int saltlen, uint64_t iter, } #ifdef FIPS_MODULE -static int fips_lower_bound_check_enabled(OSSL_LIB_CTX *libctx) -{ - return ossl_kdf_pbkdf2_default_checks; /* Always is 1 */ -} - static int fips_lower_bound_check_passed(KDF_PBKDF2 *ctx, size_t keylen) { OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx); @@ -221,7 +217,7 @@ static int fips_lower_bound_check_passed(KDF_PBKDF2 *ctx, size_t keylen) if (!approved) { if (!OSSL_FIPS_IND_ON_UNAPPROVED(ctx, OSSL_FIPS_IND_SETTABLE0, libctx, "PBKDF2", desc, - fips_lower_bound_check_enabled)) { + FIPS_pbkdf2_lower_bound_check)) { ERR_raise(ERR_LIB_PROV, error); return 0; } diff --git a/test/recipes/03-test_fipsinstall.t b/test/recipes/03-test_fipsinstall.t index b8b136d110bb7..9c82bd7f0f4b0 100644 --- a/test/recipes/03-test_fipsinstall.t +++ b/test/recipes/03-test_fipsinstall.t @@ -30,7 +30,8 @@ my @pedantic_okay = # Incompatible options for pedantic FIPS compliance my @pedantic_fail = - ( 'no_conditional_errors', 'no_security_checks', 'self_test_oninstall' ); + ( 'no_conditional_errors', 'no_security_checks', 'self_test_oninstall', + 'no_pbkdf2_lower_bound_check' ); plan tests => 35 + (scalar @pedantic_okay) + (scalar @pedantic_fail); diff --git a/util/mk-fipsmodule-cnf.pl b/util/mk-fipsmodule-cnf.pl index 6c23153dcf636..c1574b6948285 100644 --- a/util/mk-fipsmodule-cnf.pl +++ b/util/mk-fipsmodule-cnf.pl @@ -20,6 +20,7 @@ my $tdes_encrypt_disabled = 1; my $rsa_sign_x931_pad_disabled = 1; my $kdf_key_check = 1; +my $pbkdf2_lower_bound_check = 1; my $activate = 1; my $version = 1; @@ -72,4 +73,5 @@ sshkdf-key-check = $kdf_key_check sskdf-key-check = $kdf_key_check x963kdf-key-check = $kdf_key_check +pbkdf2-lower-bound-check = $pbkdf2_lower_bound_check _____ diff --git a/util/perl/OpenSSL/paramnames.pm b/util/perl/OpenSSL/paramnames.pm index 223181652da5a..713dff3c262de 100644 --- a/util/perl/OpenSSL/paramnames.pm +++ b/util/perl/OpenSSL/paramnames.pm @@ -49,6 +49,7 @@ my %params = ( 'PROV_PARAM_SSHKDF_KEY_CHECK' => "sshkdf-key-check", # uint 'PROV_PARAM_SSKDF_KEY_CHECK' => "sskdf-key-check", # uint 'PROV_PARAM_X963KDF_KEY_CHECK' => "x963kdf-key-check", # uint + 'PROV_PARAM_PBKDF2_LOWER_BOUND_CHECK' => "pbkdf2-lower-bound-check", # uint # Self test callback parameters 'PROV_PARAM_SELF_TEST_PHASE' => "st-phase",# utf8_string