Skip to content

Commit

Permalink
fips: rework the option handling code
Browse files Browse the repository at this point in the history
Add option for restricting digests available to DRBGs.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from #20521)

(cherry picked from commit 83ccf81)
  • Loading branch information
paulidale committed Mar 28, 2023
1 parent fc814a3 commit 965a469
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 50 deletions.
1 change: 1 addition & 0 deletions include/openssl/core_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ extern "C" {
#define OSSL_PROV_PARAM_STATUS "status" /* uint */
#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks" /* uint */
#define OSSL_PROV_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check" /* uint */
#define OSSL_PROV_PARAM_DRBG_TRUNC_DIGEST "drbg-no-trunc-md" /* uint */

/* Self test callback parameters */
#define OSSL_PROV_PARAM_SELF_TEST_PHASE "st-phase" /* utf8_string */
Expand Down
11 changes: 10 additions & 1 deletion include/openssl/fips_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,18 +49,27 @@ extern "C" {

/*
* A boolean that determines if the runtime FIPS security checks are performed.
* This is enabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS "security-checks"

/*
* A boolean that determines if the runtime FIPS check for TLS1_PRF EMS is performed.
* This is disabled by default.
*
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_TLS1_PRF_EMS_CHECK "tls1-prf-ems-check"

/*
* A boolean that determines if truncated digests can be used with Hash and HMAC
* DRBGs. FIPS 140-3 IG D.R disallows such use for efficiency rather than
* security reasons.
* This is disabled by default.
* Type: OSSL_PARAM_UTF8_STRING
*/
# define OSSL_PROV_FIPS_PARAM_DRBG_TRUNC_DIGEST "drbg-no-trunc-md"

# ifdef __cplusplus
}
# endif
Expand Down
123 changes: 74 additions & 49 deletions providers/fips/fipsprov.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
}

Expand All @@ -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
};

Expand All @@ -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,
Expand All @@ -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)) {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 965a469

Please sign in to comment.