Blob Blame History Raw
From f8eb7b225affe8b6b9f02ab6a90fd2e73181a526 Mon Sep 17 00:00:00 2001
From: Milan Broz <gmazyland@gmail.com>
Date: Mon, 13 Sep 2021 19:45:05 +0200
Subject: [PATCH 03/11] Do not load own OpenSSL backend context in FIPS mode.

In the FIPS mode keep configuration up to the system wide config.
---
 lib/crypto_backend/crypto_backend.h |  2 +-
 lib/crypto_backend/crypto_gcrypt.c  |  2 +-
 lib/crypto_backend/crypto_kernel.c  |  2 +-
 lib/crypto_backend/crypto_nettle.c  |  2 +-
 lib/crypto_backend/crypto_nss.c     |  2 +-
 lib/crypto_backend/crypto_openssl.c | 39 +++++++++++++++++------------
 lib/setup.c                         |  2 +-
 lib/utils_fips.c                    |  8 +++---
 lib/utils_fips.h                    |  4 ++-
 tests/crypto-vectors.c              |  2 +-
 10 files changed, 37 insertions(+), 28 deletions(-)

diff --git a/lib/crypto_backend/crypto_backend.h b/lib/crypto_backend/crypto_backend.h
index 5278c345..88cc2d59 100644
--- a/lib/crypto_backend/crypto_backend.h
+++ b/lib/crypto_backend/crypto_backend.h
@@ -31,7 +31,7 @@ struct crypt_hmac;
 struct crypt_cipher;
 struct crypt_storage;
 
-int crypt_backend_init(void);
+int crypt_backend_init(bool fips);
 void crypt_backend_destroy(void);
 
 #define CRYPT_BACKEND_KERNEL (1 << 0)	/* Crypto uses kernel part, for benchmark */
diff --git a/lib/crypto_backend/crypto_gcrypt.c b/lib/crypto_backend/crypto_gcrypt.c
index 2845382e..67f26067 100644
--- a/lib/crypto_backend/crypto_gcrypt.c
+++ b/lib/crypto_backend/crypto_gcrypt.c
@@ -94,7 +94,7 @@ static void crypt_hash_test_whirlpool_bug(void)
 		crypto_backend_whirlpool_bug = 1;
 }
 
-int crypt_backend_init(void)
+int crypt_backend_init(bool fips __attribute__((unused)))
 {
 	int r;
 
diff --git a/lib/crypto_backend/crypto_kernel.c b/lib/crypto_backend/crypto_kernel.c
index 2e3d65b2..ce84cfac 100644
--- a/lib/crypto_backend/crypto_kernel.c
+++ b/lib/crypto_backend/crypto_kernel.c
@@ -117,7 +117,7 @@ static int crypt_kernel_socket_init(struct sockaddr_alg *sa, int *tfmfd, int *op
 	return 0;
 }
 
-int crypt_backend_init(void)
+int crypt_backend_init(bool fips __attribute__((unused)))
 {
 	struct utsname uts;
 	struct sockaddr_alg sa = {
diff --git a/lib/crypto_backend/crypto_nettle.c b/lib/crypto_backend/crypto_nettle.c
index 0860a52d..c9b9f5f8 100644
--- a/lib/crypto_backend/crypto_nettle.c
+++ b/lib/crypto_backend/crypto_nettle.c
@@ -213,7 +213,7 @@ static struct hash_alg *_get_alg(const char *name)
 	return NULL;
 }
 
-int crypt_backend_init(void)
+int crypt_backend_init(bool fips __attribute__((unused)))
 {
 	return 0;
 }
diff --git a/lib/crypto_backend/crypto_nss.c b/lib/crypto_backend/crypto_nss.c
index ebe9de0e..a84d3d65 100644
--- a/lib/crypto_backend/crypto_nss.c
+++ b/lib/crypto_backend/crypto_nss.c
@@ -75,7 +75,7 @@ static struct hash_alg *_get_alg(const char *name)
 	return NULL;
 }
 
-int crypt_backend_init(void)
+int crypt_backend_init(bool fips __attribute__((unused)))
 {
 	int r;
 
diff --git a/lib/crypto_backend/crypto_openssl.c b/lib/crypto_backend/crypto_openssl.c
index 92eeb33c..2a490ce5 100644
--- a/lib/crypto_backend/crypto_openssl.c
+++ b/lib/crypto_backend/crypto_openssl.c
@@ -88,7 +88,7 @@ struct hash_alg {
 #if OPENSSL_VERSION_NUMBER < 0x10100000L || \
     (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
 
-static void openssl_backend_init(void)
+static void openssl_backend_init(bool fips __attribute__((unused)))
 {
 	OpenSSL_add_all_algorithms();
 }
@@ -150,7 +150,7 @@ static void openssl_backend_exit(void)
 #endif
 }
 
-static int openssl_backend_init(void)
+static int openssl_backend_init(bool fips)
 {
 /*
  * OpenSSL >= 3.0.0 provides some algorithms in legacy provider
@@ -158,23 +158,30 @@ static int openssl_backend_init(void)
 #if OPENSSL_VERSION_MAJOR >= 3
 	int r;
 
-	ossl_ctx = OSSL_LIB_CTX_new();
-	if (!ossl_ctx)
-		return -EINVAL;
+	/*
+	 * In FIPS mode we keep default OpenSSL context & global config
+	 */
+	if (!fips) {
+		ossl_ctx = OSSL_LIB_CTX_new();
+		if (!ossl_ctx)
+			return -EINVAL;
 
-	ossl_default = OSSL_PROVIDER_try_load(ossl_ctx, "default", 0);
-	if (!ossl_default) {
-		OSSL_LIB_CTX_free(ossl_ctx);
-		return -EINVAL;
-	}
+		ossl_default = OSSL_PROVIDER_try_load(ossl_ctx, "default", 0);
+		if (!ossl_default) {
+			OSSL_LIB_CTX_free(ossl_ctx);
+			return -EINVAL;
+		}
 
-	/* Optional */
-	ossl_legacy = OSSL_PROVIDER_try_load(ossl_ctx, "legacy", 0);
+		/* Optional */
+		ossl_legacy = OSSL_PROVIDER_try_load(ossl_ctx, "legacy", 0);
+	}
 
-	r = snprintf(backend_version, sizeof(backend_version), "%s %s%s",
+	r = snprintf(backend_version, sizeof(backend_version), "%s %s%s%s",
 		OpenSSL_version(OPENSSL_VERSION),
 		ossl_default ? "[default]" : "",
-		ossl_legacy  ? "[legacy]" : "");
+		ossl_legacy  ? "[legacy]" : "",
+		fips  ? "[fips]" : "");
+
 	if (r < 0 || (size_t)r >= sizeof(backend_version)) {
 		openssl_backend_exit();
 		return -EINVAL;
@@ -193,12 +200,12 @@ static const char *openssl_backend_version(void)
 }
 #endif
 
-int crypt_backend_init(void)
+int crypt_backend_init(bool fips)
 {
 	if (crypto_backend_initialised)
 		return 0;
 
-	if (openssl_backend_init())
+	if (openssl_backend_init(fips))
 		return -EINVAL;
 
 	crypto_backend_initialised = 1;
diff --git a/lib/setup.c b/lib/setup.c
index dc5459f5..a5dfd843 100644
--- a/lib/setup.c
+++ b/lib/setup.c
@@ -227,7 +227,7 @@ int init_crypto(struct crypt_device *ctx)
 		return r;
 	}
 
-	r = crypt_backend_init();
+	r = crypt_backend_init(crypt_fips_mode());
 	if (r < 0)
 		log_err(ctx, _("Cannot initialize crypto backend."));
 
diff --git a/lib/utils_fips.c b/lib/utils_fips.c
index 4fa22fb9..0c2b6434 100644
--- a/lib/utils_fips.c
+++ b/lib/utils_fips.c
@@ -24,9 +24,9 @@
 #include "utils_fips.h"
 
 #if !ENABLE_FIPS
-int crypt_fips_mode(void) { return 0; }
+bool crypt_fips_mode(void) { return false; }
 #else
-static int kernel_fips_mode(void)
+static bool kernel_fips_mode(void)
 {
 	int fd;
 	char buf[1] = "";
@@ -36,10 +36,10 @@ static int kernel_fips_mode(void)
 		close(fd);
 	}
 
-	return (buf[0] == '1') ? 1 : 0;
+	return (buf[0] == '1');
 }
 
-int crypt_fips_mode(void)
+bool crypt_fips_mode(void)
 {
 	return kernel_fips_mode() && !access("/etc/system-fips", F_OK);
 }
diff --git a/lib/utils_fips.h b/lib/utils_fips.h
index 51b110b5..13cfc9fb 100644
--- a/lib/utils_fips.h
+++ b/lib/utils_fips.h
@@ -21,6 +21,8 @@
 #ifndef _UTILS_FIPS_H
 #define _UTILS_FIPS_H
 
-int crypt_fips_mode(void);
+#include <stdbool.h>
+
+bool crypt_fips_mode(void);
 
 #endif /* _UTILS_FIPS_H */
diff --git a/tests/crypto-vectors.c b/tests/crypto-vectors.c
index 025585de..6484e97a 100644
--- a/tests/crypto-vectors.c
+++ b/tests/crypto-vectors.c
@@ -1301,7 +1301,7 @@ int main(__attribute__ ((unused)) int argc, __attribute__ ((unused))char *argv[]
 		exit(77);
 	}
 
-	if (crypt_backend_init())
+	if (crypt_backend_init(fips_mode()))
 		exit_test("Crypto backend init error.", EXIT_FAILURE);
 
 	printf("Test vectors using %s crypto backend.\n", crypt_backend_version());
-- 
2.27.0