From 83ccf81b1dd8886d54c570354ef8c532af4c514f Mon Sep 17 00:00:00 2001 From: Pauli Date: Fri, 17 Mar 2023 12:42:21 +1100 Subject: fips: rework the option handling code Add option for restricting digests available to DRBGs. Reviewed-by: Tomas Mraz Reviewed-by: Shane Lontis (Merged from https://github.com/openssl/openssl/pull/20521) --- providers/fips/fipsprov.c | 123 ++++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 49 deletions(-) (limited to 'providers') diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index a16c379fba..d583bb9f2a 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -46,8 +46,6 @@ static OSSL_FUNC_provider_query_operation_fn fips_query; #define UNAPPROVED_ALG(NAMES, FUNC) UNAPPROVED_ALGC(NAMES, FUNC, NULL) extern OSSL_FUNC_core_thread_start_fn *c_thread_start; -int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx); -int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx); /* * Should these function pointers be stored in the provider side provctx? Could @@ -79,27 +77,34 @@ static OSSL_FUNC_BIO_vsnprintf_fn *c_BIO_vsnprintf; static OSSL_FUNC_self_test_cb_fn *c_stcbfn = NULL; static OSSL_FUNC_core_get_libctx_fn *c_get_libctx = NULL; +typedef struct { + const char *option; + unsigned char enabled; +} FIPS_OPTION; + typedef struct fips_global_st { const OSSL_CORE_HANDLE *handle; SELF_TEST_POST_PARAMS selftest_params; - int fips_security_checks; - int fips_tls1_prf_ems_check; - const char *fips_security_check_option; - const char *fips_tls1_prf_ems_check_option; + FIPS_OPTION fips_security_checks; + FIPS_OPTION fips_tls1_prf_ems_check; + FIPS_OPTION fips_restricted_drgb_digests; } FIPS_GLOBAL; +static void init_fips_option(FIPS_OPTION *opt, int enabled) +{ + opt->enabled = enabled; + opt->option = enabled ? "1" : "0"; +} + void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *libctx) { FIPS_GLOBAL *fgbl = OPENSSL_zalloc(sizeof(*fgbl)); if (fgbl == NULL) return NULL; - fgbl->fips_security_checks = 1; - fgbl->fips_security_check_option = "1"; - - fgbl->fips_tls1_prf_ems_check = 0; /* Disabled by default */ - fgbl->fips_tls1_prf_ems_check_option = "0"; - + init_fips_option(&fgbl->fips_security_checks, 1); + init_fips_option(&fgbl->fips_tls1_prf_ems_check, 0); /* Disabled by default */ + init_fips_option(&fgbl->fips_restricted_drgb_digests, 0); return fgbl; } @@ -116,6 +121,7 @@ static const OSSL_PARAM fips_param_types[] = { OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SECURITY_CHECKS, OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_DEFN(OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK, OSSL_PARAM_INTEGER, NULL, 0), + OSSL_PARAM_DEFN(OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST, OSSL_PARAM_INTEGER, NULL, 0), OSSL_PARAM_END }; @@ -129,7 +135,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[9], *p = core_params; + OSSL_PARAM core_params[10], *p = core_params; *p++ = OSSL_PARAM_construct_utf8_ptr( OSSL_PROV_PARAM_CORE_MODULE_FILENAME, @@ -155,14 +161,21 @@ static int fips_get_params_from_core(FIPS_GLOBAL *fgbl) OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS, (char **)&fgbl->selftest_params.conditional_error_check, sizeof(fgbl->selftest_params.conditional_error_check)); - *p++ = OSSL_PARAM_construct_utf8_ptr( - OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS, - (char **)&fgbl->fips_security_check_option, - sizeof(fgbl->fips_security_check_option)); - *p++ = OSSL_PARAM_construct_utf8_ptr( - OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK, - (char **)&fgbl->fips_tls1_prf_ems_check_option, - sizeof(fgbl->fips_tls1_prf_ems_check_option)); + +/* FIPS features can be enabled or disabled independently */ +#define FIPS_FEATURE_OPTION(fgbl, pname, field) \ + *p++ = OSSL_PARAM_construct_utf8_ptr( \ + pname, (char **)&fgbl->field.option, \ + sizeof(fgbl->field.option)) + + FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS, + fips_security_checks); + FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK, + fips_tls1_prf_ems_check); + FIPS_FEATURE_OPTION(fgbl, OSSL_PROV_FIPS_PARAM_DRBG_TRUNC_DIGEST, + fips_restricted_drgb_digests); +#undef FIPS_FEATURE_OPTION + *p = OSSL_PARAM_construct_end(); if (!c_get_params(fgbl->handle, core_params)) { @@ -196,12 +209,19 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS); if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running())) return 0; - p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_SECURITY_CHECKS); - if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->fips_security_checks)) - return 0; - p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK); - if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->fips_tls1_prf_ems_check)) - return 0; + +#define FIPS_FEATURE_GET(fgbl, pname, field) \ + p = OSSL_PARAM_locate(params, pname); \ + if (p != NULL && !OSSL_PARAM_set_int(p, fgbl->field.enabled)) \ + return 0 + + FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_SECURITY_CHECKS, + fips_security_checks); + FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK, + fips_tls1_prf_ems_check); + FIPS_FEATURE_GET(fgbl, OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST, + fips_restricted_drgb_digests); +#undef FIPS_FEATURE_GET return 1; } @@ -708,15 +728,21 @@ int OSSL_provider_init_int(const OSSL_CORE_HANDLE *handle, && strcmp(fgbl->selftest_params.conditional_error_check, "0") == 0) SELF_TEST_disable_conditional_error_state(); - /* Disable the security check if it's disabled in the fips config file. */ - if (fgbl->fips_security_check_option != NULL - && strcmp(fgbl->fips_security_check_option, "0") == 0) - fgbl->fips_security_checks = 0; + /* Enable or disable FIPS provider options */ +#define FIPS_SET_OPTION(fgbl, field) \ + if (fgbl->field.option != NULL) { \ + if (strcmp(fgbl->field.option, "1") == 0) \ + fgbl->field.enabled = 1; \ + else if (strcmp(fgbl->field.option, "0") == 0) \ + fgbl->field.enabled = 0; \ + else \ + goto err; \ + } - /* Enable the ems check if it's enabled in the fips config file. */ - if (fgbl->fips_tls1_prf_ems_check_option != NULL - && strcmp(fgbl->fips_tls1_prf_ems_check_option, "1") == 0) - fgbl->fips_tls1_prf_ems_check = 1; + FIPS_SET_OPTION(fgbl, fips_security_checks); + FIPS_SET_OPTION(fgbl, fips_tls1_prf_ems_check); + FIPS_SET_OPTION(fgbl, fips_restricted_drgb_digests); +#undef FIPS_SET_OPTION ossl_prov_cache_exported_algorithms(fips_ciphers, exported_fips_ciphers); @@ -905,21 +931,20 @@ int BIO_snprintf(char *buf, size_t n, const char *format, ...) return ret; } -int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx) -{ - FIPS_GLOBAL *fgbl = ossl_lib_ctx_get_data(libctx, - OSSL_LIB_CTX_FIPS_PROV_INDEX); - - return fgbl->fips_security_checks; -} - -int FIPS_tls_prf_ems_check(OSSL_LIB_CTX *libctx) -{ - FIPS_GLOBAL *fgbl = ossl_lib_ctx_get_data(libctx, - OSSL_LIB_CTX_FIPS_PROV_INDEX); +#define FIPS_FEATURE_CHECK(fname, field) \ + int fname(OSSL_LIB_CTX *libctx); \ + int fname(OSSL_LIB_CTX *libctx) \ + { \ + FIPS_GLOBAL *fgbl = \ + ossl_lib_ctx_get_data(libctx, OSSL_LIB_CTX_FIPS_PROV_INDEX); \ + return fgbl->field.enabled; \ + } - return fgbl->fips_tls1_prf_ems_check; -} +FIPS_FEATURE_CHECK(FIPS_security_check_enabled, fips_security_checks) +FIPS_FEATURE_CHECK(FIPS_tls_prf_ems_check, fips_tls1_prf_ems_check) +FIPS_FEATURE_CHECK(FIPS_restricted_drbg_digests_enabled, + fips_restricted_drgb_digests) +#undef FIPS_FEATURE_CHECK void OSSL_SELF_TEST_get_callback(OSSL_LIB_CTX *libctx, OSSL_CALLBACK **cb, void **cbarg) -- cgit v1.2.1