From c45df3302d20291ff1125f1aeb82fae1cdceaac8 Mon Sep 17 00:00:00 2001 From: Pauli Date: Tue, 18 May 2021 19:03:28 +1000 Subject: fips: default to running self tests when starting the fips provider Also add a C++ constructor as per note 7 of IG 9.10 if no DEP is available and C++ is being used. Fixes #15322 Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/15324) --- providers/fips/self_test.c | 57 ++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c index dbd744ff7c..34dbf6cb85 100644 --- a/providers/fips/self_test.c +++ b/providers/fips/self_test.c @@ -46,7 +46,6 @@ #define DIGEST_NAME "SHA256" static int FIPS_conditional_error_check = 1; -static int FIPS_state = FIPS_STATE_INIT; static CRYPTO_RWLOCK *self_test_lock = NULL; static CRYPTO_RWLOCK *fips_state_lock = NULL; static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS }; @@ -64,19 +63,22 @@ DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init) return self_test_lock != NULL; } -#define DEP_DECLARE() \ -void init(void); \ -void cleanup(void); +/* + * Declarations for the DEP entry/exit points. + * Ones not required or incorrect need to be undefined or redefined respectively. + */ +#define DEP_INITIAL_STATE FIPS_STATE_INIT +#define DEP_INIT_ATTRIBUTE static +#define DEP_FINI_ATTRIBUTE static + +#if !defined(__GNUC__) +static void init(void); +static void cleanup(void); +#endif /* - * This is the Default Entry Point (DEP) code. Every platform must have a DEP. + * This is the Default Entry Point (DEP) code. * See FIPS 140-2 IG 9.10 - * - * If we're run on a platform where we don't know how to define the DEP then - * the self-tests will never get triggered (FIPS_state never moves to - * FIPS_STATE_SELFTEST). This will be detected as an error when SELF_TEST_post() - * is called from OSSL_provider_init(), and so the fips module will be unusable - * on those platforms. */ #if defined(_WIN32) || defined(__CYGWIN__) # ifdef __CYGWIN__ @@ -88,9 +90,6 @@ void cleanup(void); */ # endif -DEP_DECLARE() -# define DEP_INIT_ATTRIBUTE -# define DEP_FINI_ATTRIBUTE BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved); BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { @@ -107,30 +106,20 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) return TRUE; } #elif defined(__sun) || defined(_AIX) - -DEP_DECLARE() /* must be declared before pragma */ -# define DEP_INIT_ATTRIBUTE -# define DEP_FINI_ATTRIBUTE # pragma init(init) # pragma fini(cleanup) #elif defined(__hpux) - -DEP_DECLARE() -# define DEP_INIT_ATTRIBUTE -# define DEP_FINI_ATTRIBUTE # pragma init "init" # pragma fini "cleanup" #elif defined(__GNUC__) +# undef DEP_INIT_ATTRIBUTE +# undef DEP_FINI_ATTRIBUTE # define DEP_INIT_ATTRIBUTE static __attribute__((constructor)) # define DEP_FINI_ATTRIBUTE static __attribute__((destructor)) #elif defined(__TANDEM) -DEP_DECLARE() /* must be declared before calling init() or cleanup() */ -# define DEP_INIT_ATTRIBUTE -# define DEP_FINI_ATTRIBUTE - /* Method automatically called by the NonStop OS when the DLL loads */ void __INIT__init(void) { init(); @@ -141,14 +130,28 @@ void __TERM__cleanup(void) { cleanup(); } +#else +/* + * This build does not support any kind of DEP. + * We force the self-tests to run as part of the FIPS provider initialisation + * rather than being triggered by the DEP. + */ +# undef DEP_INIT_ATTRIBUTE +# undef DEP_FINI_ATTRIBUTE +# undef DEP_INITIAL_STATE +# define DEP_INITIAL_STATE FIPS_STATE_SELFTEST #endif -#if defined(DEP_INIT_ATTRIBUTE) && defined(DEP_FINI_ATTRIBUTE) +static int FIPS_state = DEP_INITIAL_STATE; + +#if defined(DEP_INIT_ATTRIBUTE) DEP_INIT_ATTRIBUTE void init(void) { FIPS_state = FIPS_STATE_SELFTEST; } +#endif +#if defined(DEP_FINI_ATTRIBUTE) DEP_FINI_ATTRIBUTE void cleanup(void) { CRYPTO_THREAD_lock_free(self_test_lock); -- cgit v1.2.3