From 3593266d1c924ea595a1074e78381890f964392c Mon Sep 17 00:00:00 2001 From: Matt Caswell Date: Wed, 10 Apr 2019 15:01:40 +0100 Subject: [PATCH] Make core code available within the FIPS module Reviewed-by: Richard Levitte (Merged from https://github.com/openssl/openssl/pull/8728) --- crypto/build.info | 6 +++- crypto/context.c | 2 +- crypto/provider_core.c | 18 ++++++++++++ crypto/provider_predefined.c | 5 ++++ crypto/stack/build.info | 1 + crypto/threads_pthread.c | 12 +++++--- include/openssl/core_numbers.h | 7 +++++ providers/fips/fipsprov.c | 52 ++++++++++++++++++++++++++++++++++ 8 files changed, 97 insertions(+), 6 deletions(-) diff --git a/crypto/build.info b/crypto/build.info index 63913f40e8..546865bdc9 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -12,6 +12,9 @@ LIBS=../libcrypto SOURCE[../libcrypto]=provider_core.c provider_predefined.c provider_conf.c \ core_fetch.c core_namemap.c +SOURCE[../providers/fips]=provider_core.c provider_predefined.c \ + core_fetch.c core_namemap.c + # Central utilities SOURCE[../libcrypto]=\ cryptlib.c mem.c mem_dbg.c cversion.c info.c ex_data.c cpt_err.c \ @@ -23,7 +26,8 @@ SOURCE[../libcrypto]=\ # FIPS module SOURCE[../providers/fips]=\ - cryptlib.c mem.c mem_clr.c params.c bsearch.c + cryptlib.c mem.c mem_clr.c params.c bsearch.c ex_data.c o_str.c \ + threads_pthread.c threads_win.c threads_none.c context.c DEPEND[cversion.o]=buildinf.h diff --git a/crypto/context.c b/crypto/context.c index be2d348fec..7a976c0270 100644 --- a/crypto/context.c +++ b/crypto/context.c @@ -36,10 +36,10 @@ struct openssl_ctx_st { #ifndef FIPS_MODE static OPENSSL_CTX default_context_int; -#endif /* Always points at default_context_int if it has been initialised */ static OPENSSL_CTX *default_context = NULL; +#endif static int context_init(OPENSSL_CTX *ctx) { diff --git a/crypto/provider_core.c b/crypto/provider_core.c index 36af52717f..36692b6ce4 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -275,7 +275,9 @@ void ossl_provider_free(OSSL_PROVIDER *prov) * the store. All we have to do here is clean it out. */ if (ref == 0) { +#ifndef FIPS_MODE DSO_free(prov->module); +#endif OPENSSL_free(prov->name); OPENSSL_free(prov->path); sk_INFOPAIR_pop_free(prov->parameters, free_infopair); @@ -352,6 +354,9 @@ static int provider_activate(OSSL_PROVIDER *prov) * a loadable module. */ if (prov->init_function == NULL) { +#ifdef FIPS_MODE + return 0; +#else if (prov->module == NULL) { char *allocated_path = NULL; const char *module_path = NULL; @@ -389,6 +394,7 @@ static int provider_activate(OSSL_PROVIDER *prov) if (prov->module != NULL) prov->init_function = (OSSL_provider_init_fn *) DSO_bind_func(prov->module, "OSSL_provider_init"); +#endif } if (prov->init_function == NULL @@ -396,8 +402,10 @@ static int provider_activate(OSSL_PROVIDER *prov) &prov->provctx)) { CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL); ERR_add_error_data(2, "name=", prov->name); +#ifndef FIPS_MODE DSO_free(prov->module); prov->module = NULL; +#endif return 0; } @@ -557,13 +565,21 @@ const DSO *ossl_provider_dso(OSSL_PROVIDER *prov) const char *ossl_provider_module_name(OSSL_PROVIDER *prov) { +#ifdef FIPS_MODE + return NULL; +#else return DSO_get_filename(prov->module); +#endif } const char *ossl_provider_module_path(OSSL_PROVIDER *prov) { +#ifdef FIPS_MODE + return NULL; +#else /* FIXME: Ensure it's a full path */ return DSO_get_filename(prov->module); +#endif } /* Wrappers around calls to the provider */ @@ -643,6 +659,8 @@ static int core_get_params(const OSSL_PROVIDER *prov, const OSSL_PARAM params[]) static const OSSL_DISPATCH core_dispatch_[] = { { OSSL_FUNC_CORE_GET_PARAM_TYPES, (void (*)(void))core_get_param_types }, { OSSL_FUNC_CORE_GET_PARAMS, (void (*)(void))core_get_params }, + { OSSL_FUNC_CORE_PUT_ERROR, (void (*)(void))ERR_put_error }, + { OSSL_FUNC_CORE_ADD_ERROR_VDATA, (void (*)(void))ERR_add_error_vdata }, { 0, NULL } }; static const OSSL_DISPATCH *core_dispatch = core_dispatch_; diff --git a/crypto/provider_predefined.c b/crypto/provider_predefined.c index d14cd5b96e..d1423b1c6c 100644 --- a/crypto/provider_predefined.c +++ b/crypto/provider_predefined.c @@ -11,8 +11,13 @@ #include "provider_local.h" OSSL_provider_init_fn ossl_default_provider_init; +OSSL_provider_init_fn fips_intern_provider_init; const struct predefined_providers_st predefined_providers[] = { +#ifdef FIPS_MODE + { "fips", fips_intern_provider_init, 1 }, +#else { "default", ossl_default_provider_init, 1 }, +#endif { NULL, NULL, 0 } }; diff --git a/crypto/stack/build.info b/crypto/stack/build.info index e5870210ac..e4183e089c 100644 --- a/crypto/stack/build.info +++ b/crypto/stack/build.info @@ -1,2 +1,3 @@ LIBS=../../libcrypto SOURCE[../../libcrypto]=stack.c +SOURCE[../../providers/fips]=stack.c diff --git a/crypto/threads_pthread.c b/crypto/threads_pthread.c index 0a6c903b8b..0d351ca6fa 100644 --- a/crypto/threads_pthread.c +++ b/crypto/threads_pthread.c @@ -175,7 +175,10 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) return 1; } -# ifdef OPENSSL_SYS_UNIX +# ifndef FIPS_MODE +/* TODO(3.0): No fork protection in FIPS module yet! */ + +# ifdef OPENSSL_SYS_UNIX static pthread_once_t fork_once_control = PTHREAD_ONCE_INIT; static void fork_once_func(void) @@ -183,14 +186,15 @@ static void fork_once_func(void) pthread_atfork(OPENSSL_fork_prepare, OPENSSL_fork_parent, OPENSSL_fork_child); } -# endif +# endif int openssl_init_fork_handlers(void) { -# ifdef OPENSSL_SYS_UNIX +# ifdef OPENSSL_SYS_UNIX if (pthread_once(&fork_once_control, fork_once_func) == 0) return 1; -# endif +# endif return 0; } +# endif /* FIPS_MODE */ #endif diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h index 8ce00c3e6f..8d026f4a17 100644 --- a/include/openssl/core_numbers.h +++ b/include/openssl/core_numbers.h @@ -10,6 +10,7 @@ #ifndef OSSL_CORE_NUMBERS_H # define OSSL_CORE_NUMBERS_H +# include # include # ifdef __cplusplus @@ -57,6 +58,12 @@ OSSL_CORE_MAKE_FUNC(const OSSL_ITEM *, # define OSSL_FUNC_CORE_GET_PARAMS 2 OSSL_CORE_MAKE_FUNC(int,core_get_params,(const OSSL_PROVIDER *prov, const OSSL_PARAM params[])) +# define OSSL_FUNC_CORE_PUT_ERROR 3 +OSSL_CORE_MAKE_FUNC(void,core_put_error,(int lib, int func, int reason, + const char *file, int line)) +# define OSSL_FUNC_CORE_ADD_ERROR_VDATA 4 +OSSL_CORE_MAKE_FUNC(void,core_add_error_vdata,(int num, va_list args)) + /* Functions provided by the provider to the Core, reserved numbers 1024-1535 */ # define OSSL_FUNC_PROVIDER_TEARDOWN 1024 diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index 1b8316388b..026dd2f9a9 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -13,10 +13,14 @@ #include #include #include +#include +#include "internal/cryptlib.h" /* Functions provided by the core */ static OSSL_core_get_param_types_fn *c_get_param_types = NULL; static OSSL_core_get_params_fn *c_get_params = NULL; +static OSSL_core_put_error_fn *c_put_error = NULL; +static OSSL_core_add_error_vdata_fn *c_add_error_vdata = NULL; /* Parameters we provide to the core */ static const OSSL_ITEM fips_param_types[] = { @@ -26,6 +30,11 @@ static const OSSL_ITEM fips_param_types[] = { { 0, NULL } }; +static void fips_teardown(void) +{ + do_default_context_deinit(); +} + static const OSSL_ITEM *fips_get_param_types(const OSSL_PROVIDER *prov) { return fips_param_types; @@ -70,6 +79,7 @@ static const OSSL_ALGORITHM *fips_query(OSSL_PROVIDER *prov, /* Functions we provide to the core */ static const OSSL_DISPATCH fips_dispatch_table[] = { + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))fips_teardown }, { OSSL_FUNC_PROVIDER_GET_PARAM_TYPES, (void (*)(void))fips_get_param_types }, { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))fips_get_params }, { OSSL_FUNC_PROVIDER_QUERY_OPERATION, (void (*)(void))fips_query }, @@ -89,6 +99,12 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider, case OSSL_FUNC_CORE_GET_PARAMS: c_get_params = OSSL_get_core_get_params(in); break; + case OSSL_FUNC_CORE_PUT_ERROR: + c_put_error = OSSL_get_core_put_error(in); + break; + case OSSL_FUNC_CORE_ADD_ERROR_VDATA: + c_add_error_vdata = OSSL_get_core_add_error_vdata(in); + break; /* Just ignore anything we don't understand */ default: break; @@ -98,3 +114,39 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider, *out = fips_dispatch_table; return 1; } + +OSSL_provider_init_fn fips_intern_provider_init; +int fips_intern_provider_init(const OSSL_PROVIDER *provider, + const OSSL_DISPATCH *in, + const OSSL_DISPATCH **out) +{ + /* + * The internal init function used when the FIPS module uses EVP to call + * another algorithm also in the FIPS module. + */ + return 1; +} + +void ERR_put_error(int lib, int func, int reason, const char *file, int line) +{ + /* + * TODO(3.0): This works for the FIPS module because we're going to be + * using lib/func/reason codes that libcrypto already knows about. This + * won't work for third party providers that have their own error mechanisms, + * so we'll need to come up with something else for them. + */ + c_put_error(lib, func, reason, file, line); +} + +void ERR_add_error_data(int num, ...) +{ + va_list args; + va_start(args, num); + ERR_add_error_vdata(num, args); + va_end(args); +} + +void ERR_add_error_vdata(int num, va_list args) +{ + c_add_error_vdata(num, args); +} -- 2.25.1