File strongswan_fipsfilter.patch of Package strongswan

From 8f3f1bd6907df8221a93c849ed4b43474444e13b Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.de>
Date: Mon, 5 Jan 2015 14:57:39 +0100
Subject: [PATCH] strongswan: filter algorithms for fips mode

References: fate#316931,bnc#856322

From 818cd5f1b6455237a82f385b60a2513cdd9c5eef Mon Sep 17 00:00:00 2001
From: Nirmoy Das <ndas@suse.de>
Date: Mon, 17 Jul 2017 15:15:14 +0200
Subject: [PATCH] strongswan_fipsfilter

---
 src/libcharon/config/proposal.c | 184 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 165 insertions(+), 19 deletions(-)

diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 6c71f78..0640140 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -27,6 +27,11 @@
 #include <crypto/prfs/prf.h>
 #include <crypto/crypters/crypter.h>
 #include <crypto/signers/signer.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
 
 ENUM(protocol_id_names, PROTO_NONE, PROTO_IPCOMP,
 	"PROTO_NONE",
@@ -190,6 +195,122 @@ METHOD(proposal_t, strip_dh, void,
 	enumerator->destroy(enumerator);
 }
 
+static bool kernel_fips_enabled(void)
+{
+	char buf[1] = { '\0' };
+	int fd;
+
+	fd = open("/proc/sys/crypto/fips_enabled", O_RDONLY);
+	if (fd >= 0) {
+		while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR);
+		close(fd);
+	}
+	return buf[0] == '1';
+}
+
+static bool fips_enabled(void)
+{
+	static int enabled = -1;
+	if (enabled == -1)
+		enabled = kernel_fips_enabled();
+	return enabled;
+}
+
+static bool fips_filter(protocol_id_t protocol, transform_type_t type, u_int16_t alg)
+{
+	switch (protocol)
+	{
+		case PROTO_IKE:
+		case PROTO_ESP:
+		case PROTO_AH:
+			break;
+		default:
+			/* not applicable protocol */
+			return TRUE;
+	}
+
+	switch (type)
+	{
+		case ENCRYPTION_ALGORITHM:
+			switch (alg)
+			{
+				/* crypter */
+				case ENCR_3DES:
+				case ENCR_AES_CBC:
+				case ENCR_AES_CTR:
+				/* aead */
+				case ENCR_AES_GCM_ICV8:
+				case ENCR_AES_GCM_ICV12:
+				case ENCR_AES_GCM_ICV16:
+				case ENCR_AES_CCM_ICV8:
+				case ENCR_AES_CCM_ICV12:
+				case ENCR_AES_CCM_ICV16:
+					return TRUE;
+				default:
+					break;
+			}
+			break;
+		case INTEGRITY_ALGORITHM:
+			switch (alg)
+			{
+				case AUTH_HMAC_SHA1_96:
+				case AUTH_HMAC_SHA1_160:
+				case AUTH_HMAC_SHA2_256_96:
+				case AUTH_HMAC_SHA2_256_128:
+				case AUTH_HMAC_SHA2_384_192:
+				case AUTH_HMAC_SHA2_512_256:
+				case AUTH_AES_CMAC_96:
+					return TRUE;
+				default:
+					break;
+			}
+			break;
+		case PSEUDO_RANDOM_FUNCTION:
+			switch (alg)
+			{
+				case PRF_HMAC_SHA1:
+				case PRF_HMAC_SHA2_256:
+				case PRF_HMAC_SHA2_384:
+				case PRF_HMAC_SHA2_512:
+				case PRF_AES128_CMAC:
+					return TRUE;
+				default:
+					break;
+			}
+			break;
+		case DIFFIE_HELLMAN_GROUP:
+			switch (alg)
+			{
+				case MODP_2048_BIT:
+				case MODP_3072_BIT:
+				case MODP_4096_BIT:
+				case MODP_8192_BIT:
+				case MODP_2048_224:
+				case MODP_2048_256:
+				case ECP_224_BIT:
+				case ECP_256_BIT:
+				case ECP_384_BIT:
+				case ECP_521_BIT:
+					return TRUE;
+				default:
+					break;
+			}
+			break;
+		case EXTENDED_SEQUENCE_NUMBERS:
+			switch (alg)
+			{
+				case EXT_SEQ_NUMBERS:
+				case NO_EXT_SEQ_NUMBERS:
+					return TRUE;
+				default:
+					break;
+			}
+		default:
+			break;
+	}
+	return !fips_enabled();
+}
+
 /**
  * Select a matching proposal from this and other, insert into selected.
  */
@@ -611,6 +732,11 @@ static bool add_string_algo(private_proposal_t *this, const char *alg)
 		return FALSE;
 	}
 
+	if (!fips_filter(this->protocol, token->type, token->algorithm))
+	{
+		DBG1(DBG_CFG, "algorithm '%s' not permitted in fips mode", alg);
+		return FALSE;
+	}
 	add_algorithm(this, token->type, token->algorithm, token->keysize);
 
 	return TRUE;
@@ -753,6 +879,9 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
 		enumerator = lib->crypto->create_aead_enumerator(lib->crypto);
 		while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
 		{
+			if (!fips_filter(PROTO_IKE, ENCRYPTION_ALGORITHM, encryption))
+				continue;
+
 			switch (encryption)
 			{
 				case ENCR_AES_GCM_ICV16:
@@ -806,6 +935,9 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
 		enumerator = lib->crypto->create_crypter_enumerator(lib->crypto);
 		while (enumerator->enumerate(enumerator, &encryption, &plugin_name))
 		{
+			if (!fips_filter(PROTO_IKE, ENCRYPTION_ALGORITHM, encryption))
+				continue;
+
 			switch (encryption)
 			{
 				case ENCR_AES_CBC:
@@ -850,6 +982,9 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
 		enumerator = lib->crypto->create_signer_enumerator(lib->crypto);
 		while (enumerator->enumerate(enumerator, &integrity, &plugin_name))
 		{
+			if (!fips_filter(PROTO_IKE, INTEGRITY_ALGORITHM, integrity))
+				continue;
+
 			switch (integrity)
 			{
 				case AUTH_HMAC_SHA2_256_128:
@@ -905,6 +1040,9 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
 	enumerator = lib->crypto->create_prf_enumerator(lib->crypto);
 	while (enumerator->enumerate(enumerator, &prf, &plugin_name))
 	{
+		if (!fips_filter(PROTO_IKE, PSEUDO_RANDOM_FUNCTION, prf))
+			continue;
+
 		switch (prf)
 		{
 			case PRF_HMAC_SHA1:
@@ -964,6 +1102,9 @@ static bool proposal_add_supported_ike(private_proposal_t *this, bool aead)
 	enumerator = lib->crypto->create_dh_enumerator(lib->crypto);
 	while (enumerator->enumerate(enumerator, &group, &plugin_name))
 	{
+		if (!fips_filter(PROTO_IKE, DIFFIE_HELLMAN_GROUP, group))
+			continue;
+
 		switch (group)
 		{
 			case MODP_NULL:
@@ -1004,6 +1145,10 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
 {
 	private_proposal_t *this = (private_proposal_t*)proposal_create(protocol, 0);
 
+#define fips_add_algorithm(this, type, alg, len)	\
+	if (fips_filter(this->protocol, type, alg))	\
+		add_algorithm(this, type, alg, len);
+
 	switch (protocol)
 	{
 		case PROTO_IKE:
@@ -1014,31 +1159,32 @@ proposal_t *proposal_create_default(protocol_id_t protocol)
 			}
 			break;
 		case PROTO_ESP:
-			add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC,          128);
-			add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC,          192);
-			add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC,          256);
-			add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES,               0);
-			add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH,         256);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_256_128,  0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_384_192,  0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_512_256,  0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA1_96,       0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_AES_XCBC_96,        0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_MD5_96,        0);
-			add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+			fips_add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC,          128);
+			fips_add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC,          192);
+			fips_add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_AES_CBC,          256);
+			fips_add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_3DES,               0);
+			fips_add_algorithm(this, ENCRYPTION_ALGORITHM, ENCR_BLOWFISH,         256);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_256_128,  0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_384_192,  0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_512_256,  0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA1_96,       0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_AES_XCBC_96,        0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_MD5_96,        0);
+			fips_add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
 			break;
 		case PROTO_AH:
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_256_128,  0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_384_192,  0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_512_256,  0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA1_96,       0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_AES_XCBC_96,        0);
-			add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_MD5_96,        0);
-			add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_256_128,  0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_384_192,  0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA2_512_256,  0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_SHA1_96,       0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_AES_XCBC_96,        0);
+			fips_add_algorithm(this, INTEGRITY_ALGORITHM,  AUTH_HMAC_MD5_96,        0);
+			fips_add_algorithm(this, EXTENDED_SEQUENCE_NUMBERS, NO_EXT_SEQ_NUMBERS, 0);
 			break;
 		default:
 			break;
 	}
+#undef fips_add_algorithm
 	return &this->public;
 }
 
-- 
2.13.2
openSUSE Build Service is sponsored by