Commit 3cd2e2ccc for strongswan.org

commit 3cd2e2ccc63cba904f41a1024aaa977facbf978e
Author: Tobias Brunner <tobias@strongswan.org>
Date:   Mon Nov 22 10:34:08 2021 +0100

    openssl: Make fips_mode option work with OpenSSL 3

diff --git a/conf/plugins/openssl.opt b/conf/plugins/openssl.opt
index 4ae8399deb..e8a60c8a94 100644
--- a/conf/plugins/openssl.opt
+++ b/conf/plugins/openssl.opt
@@ -4,7 +4,15 @@ charon.plugins.openssl.engine_id = pkcs11
 charon.plugins.openssl.fips_mode = 0
 	Set OpenSSL FIPS mode: disabled(0), enabled(1), Suite B enabled(2).

+	Set OpenSSL FIPS mode.  With OpenSSL before 3.0, the supported values are
+	disabled(0), enabled(1) and Suite B enabled(2).  With OpenSSL 3+, any value
+	other than 0 will explicitly load the fips and base providers (_load_legacy_
+	will be ignored). The latter still requires the config in fipsmodule.cnf
+	(e.g. for the module's MAC), but allows explicitly loading the provider if
+	it's not activated in that config.
+
 charon.plugins.openssl.load_legacy = yes
 	Load the legacy provider in OpenSSL 3+ for algorithms like MD4, DES, or
 	Blowfish (the first two are required for EAP-MSCHAPv2). If disabled, the
-	default provider is loaded, or those configured in the OpenSSL config.
+	default provider is loaded, or those configured in the OpenSSL config (e.g.
+	the fips provider).
diff --git a/src/libstrongswan/plugins/openssl/openssl_plugin.c b/src/libstrongswan/plugins/openssl/openssl_plugin.c
index 35bc6d93f8..e7e3dc456b 100644
--- a/src/libstrongswan/plugins/openssl/openssl_plugin.c
+++ b/src/libstrongswan/plugins/openssl/openssl_plugin.c
@@ -931,15 +931,16 @@ plugin_t *openssl_plugin_create()
 	{
 		if (FIPS_mode() != fips_mode && !FIPS_mode_set(fips_mode))
 		{
-			DBG1(DBG_LIB, "unable to set openssl FIPS mode(%d) from (%d)",
+			DBG1(DBG_LIB, "unable to set OpenSSL FIPS mode(%d) from (%d)",
 				 fips_mode, FIPS_mode());
 			return NULL;
 		}
 	}
-#else
+#elif OPENSSL_VERSION_NUMBER < 0x30000000L
+	/* OpenSSL 3.0+ is handled below */
 	if (fips_mode)
 	{
-		DBG1(DBG_LIB, "openssl FIPS mode(%d) unavailable", fips_mode);
+		DBG1(DBG_LIB, "OpenSSL FIPS mode(%d) unavailable", fips_mode);
 		return NULL;
 	}
 #endif
@@ -973,8 +974,23 @@ plugin_t *openssl_plugin_create()
 #endif /* OPENSSL_VERSION_NUMBER */

 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
-	if (lib->settings->get_bool(lib->settings, "%s.plugins.openssl.load_legacy",
-								TRUE, lib->ns))
+	if (fips_mode)
+	{
+		OSSL_PROVIDER *fips;
+
+		fips = OSSL_PROVIDER_load(NULL, "fips");
+		if (!fips)
+		{
+			DBG1(DBG_LIB, "unable to load OpenSSL FIPS provider");
+			return NULL;
+		}
+		array_insert_create(&this->providers, ARRAY_TAIL, fips);
+		/* explicitly load the base provider containing encoding functions */
+		array_insert_create(&this->providers, ARRAY_TAIL,
+							OSSL_PROVIDER_load(NULL, "base"));
+	}
+	else if (lib->settings->get_bool(lib->settings, "%s.plugins.openssl.load_legacy",
+									 TRUE, lib->ns))
 	{
 		/* load the legacy provider for algorithms like MD4, DES, BF etc. */
 		array_insert_create(&this->providers, ARRAY_TAIL,
@@ -989,7 +1005,7 @@ plugin_t *openssl_plugin_create()
 	/* we do this here as it may have been enabled via openssl.conf */
 	fips_mode = FIPS_mode();
 	dbg(DBG_LIB, strpfx(lib->ns, "charon") ? 1 : 2,
-		"openssl FIPS mode(%d) - %sabled ", fips_mode, fips_mode ? "en" : "dis");
+		"OpenSSL FIPS mode(%d) - %sabled ", fips_mode, fips_mode ? "en" : "dis");
 #endif /* OPENSSL_FIPS */

 #if OPENSSL_VERSION_NUMBER < 0x1010100fL