From 8f3f1bd6907df8221a93c849ed4b43474444e13b Mon Sep 17 00:00:00 2001 From: Marius Tomaschewski 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 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 #include #include +#include +#include +#include +#include +#include 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