1
0
forked from pool/strongswan
strongswan/strongswan_fipsfilter.patch
Marius Tomaschewski fadffa6d60 - Disallow brainpool elliptic curve groups in fips mode (bnc#856322).
[* strongswan_fipsfilter.patch]

- Applied an upstream fix for a denial-of-service vulnerability,
  which can be triggered by an IKEv2 Key Exchange payload, that
  contains the Diffie-Hellman group 1025 (bsc#910491,CVE-2014-9221).
  [+ 0006-strongswan-5.1.2-5.2.1_modp_custom.CVE-2014-9221.patch]
- Adjusted whilelist of approved algorithms in fips mode (bsc#856322).
  [* strongswan_fipsfilter.patch]
- Renamed patch file to match it's patch number:
  [- 0001-restore-registration-algorithm-order.bug897512.patch,
   + 0005-restore-registration-algorithm-order.bug897512.patch]

OBS-URL: https://build.opensuse.org/package/show/network:vpn/strongswan?expand=0&rev=84
2015-01-05 13:04:19 +00:00

257 lines
7.7 KiB
Diff

From aa709f291994a74271271b6dd61563cc3844e3ad Mon Sep 17 00:00:00 2001
From: Marius Tomaschewski <mt@suse.de>
Date: Tue, 16 Dec 2014 23:19:20 +0100
Subject: [PATCH] strongswan: filter algorithms for fips mode
References: fate#316931,bnc#856322
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 2ecdb4f..a858162 100644
--- a/src/libcharon/config/proposal.c
+++ b/src/libcharon/config/proposal.c
@@ -26,6 +26,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",
@@ -185,6 +190,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.
*/
@@ -500,6 +621,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;
@@ -639,6 +765,8 @@ static void proposal_add_supported_ike(private_proposal_t *this)
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:
@@ -665,6 +793,9 @@ static void proposal_add_supported_ike(private_proposal_t *this)
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_CCM_ICV8:
@@ -690,6 +821,8 @@ static void proposal_add_supported_ike(private_proposal_t *this)
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_SHA1_96:
@@ -710,6 +843,8 @@ static void proposal_add_supported_ike(private_proposal_t *this)
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:
@@ -730,6 +865,8 @@ static void proposal_add_supported_ike(private_proposal_t *this)
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:
@@ -776,31 +913,35 @@ 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:
proposal_add_supported_ike(this);
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_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_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_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_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.2.0