]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
fips: default to running self tests when starting the fips provider
authorPauli <pauli@openssl.org>
Tue, 18 May 2021 09:03:28 +0000 (19:03 +1000)
committerPauli <pauli@openssl.org>
Sun, 23 May 2021 23:43:11 +0000 (09:43 +1000)
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)

providers/fips/self_test.c

index dbd744ff7ca8d065b41828cdf2834ab44a2f22bd..34dbf6cb85b4602ed742e52ba3da75b9b4d97a8f 100644 (file)
@@ -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);