summaryrefslogtreecommitdiffstats
path: root/providers/fips
diff options
context:
space:
mode:
authorPauli <pauli@openssl.org>2021-05-18 19:03:28 +1000
committerPauli <pauli@openssl.org>2021-05-24 09:43:11 +1000
commitc45df3302d20291ff1125f1aeb82fae1cdceaac8 (patch)
tree171e450ef6f5c881477ee13f1d235a2fe533c551 /providers/fips
parentbca0ffe8b3f229b47a515048505736708e38095b (diff)
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 <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/15324)
Diffstat (limited to 'providers/fips')
-rw-r--r--providers/fips/self_test.c57
1 files 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);