Accepting request 262968 from network:vpn

- Updated strongswan-hmac package description (bsc#856322).

- Disabled explicit gpg validation; osc source_validator does it.
- Guarded fipscheck and hmac package in the spec file for >13.1.

- Added generation of fips hmac hash files using fipshmac utility
  and a _fipscheck script to verify binaries/libraries/plugings
  shipped in the strongswan-hmac package.
  With enabled fips in the kernel, the ipsec script will call it
  before any action or in a enforced/manual "ipsec _fipscheck" call.
  Added config file to load openssl and kernel af-alg plugins, but
  not all the other modules which provide further/alternative algs.
  Applied a filter disallowing non-approved algorithms in fips mode.
  (fate#316931,bnc#856322).
  [+ strongswan_fipscheck.patch, strongswan_fipsfilter.patch]
- Fixed file list in the optional (disabled) strongswan-test package.
- Fixed build of the strongswan built-in integrity checksum library
  and enabled building it only on architectures tested to work.
- Fix to use bug number 897048 instead 856322 in last changes entry.
- Applied an upstream patch reverting to store algorithms in the
  registration order again as ordering them by identifier caused
  weaker algorithms to be proposed first by default (bsc#897512).
  [+0001-restore-registration-algorithm-order.bug897512.patch]

- Re-enabled gcrypt plugin and reverted to not enforce fips again
  as this breaks gcrypt and openssl plugins when the fips pattern
  option is not installed (fate#316931,bnc#856322).
  [- strongswan-fips-disablegcrypt.patch]
- Added empty strongswan-hmac package supposed to provide fips hmac
  files and enforce fips compliant operation later (bnc#856322).

OBS-URL: https://build.opensuse.org/request/show/262968
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/strongswan?expand=0&rev=58
This commit is contained in:
Dominique Leuenberger 2014-11-26 09:33:53 +00:00 committed by Git OBS Bridge
commit 1902611f9f
9 changed files with 1169 additions and 49 deletions

View File

@ -0,0 +1,413 @@
From 76ad8a6f4c83c999b9eb6d1a3506b1a8e593307e Mon Sep 17 00:00:00 2001
From: Tobias Brunner <tobias@strongswan.org>
Date: Fri, 20 Jun 2014 16:22:15 +0200
Subject: [PATCH] Merge branch 'algorithm-order'
Upstream: yes
References: bsc#897512
Restores the behavior we had before 2e22333fb (except for RNGs), that is,
algorithms are stored in the registration order again. Which is not optimal
as we must rely on plugins to register them in a sensible order, but ordering
them by identifier definitely caused weaker algorithms to be proposed first
in the default proposal, which was even worse.
---
src/libstrongswan/crypto/crypto_factory.c | 18 +-
src/libstrongswan/tests/Makefile.am | 1 +
.../tests/suites/test_crypto_factory.c | 312 +++++++++++++++++++++
src/libstrongswan/tests/tests.h | 1 +
4 files changed, 327 insertions(+), 5 deletions(-)
create mode 100644 src/libstrongswan/tests/suites/test_crypto_factory.c
diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c
index 6dea30e..96fbc0d 100644
--- a/src/libstrongswan/crypto/crypto_factory.c
+++ b/src/libstrongswan/crypto/crypto_factory.c
@@ -392,10 +392,10 @@ METHOD(crypto_factory_t, create_dh, diffie_hellman_t*,
/**
* Insert an algorithm entry to a list
*
- * Entries are sorted by algorithm identifier (which is important for RNGs)
- * while maintaining the order in which algorithms were added, unless they were
+ * Entries maintain the order in which algorithms were added, unless they were
* benchmarked and speed is provided, which then is used to order entries of
* the same algorithm.
+ * An exception are RNG entries, which are sorted by algorithm identifier.
*/
static void add_entry(private_crypto_factory_t *this, linked_list_t *list,
int algo, const char *plugin_name,
@@ -403,6 +403,7 @@ static void add_entry(private_crypto_factory_t *this, linked_list_t *list,
{
enumerator_t *enumerator;
entry_t *entry, *current;
+ bool sort = (list == this->rngs), found = FALSE;
INIT(entry,
.algo = algo,
@@ -415,12 +416,19 @@ static void add_entry(private_crypto_factory_t *this, linked_list_t *list,
enumerator = list->create_enumerator(list);
while (enumerator->enumerate(enumerator, &current))
{
- if (current->algo > algo)
+ if (sort && current->algo > algo)
{
break;
}
- else if (current->algo == algo && speed &&
- current->speed < speed)
+ else if (current->algo == algo)
+ {
+ if (speed > current->speed)
+ {
+ break;
+ }
+ found = TRUE;
+ }
+ else if (found)
{
break;
}
diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am
index 331a548..0bdf2b3 100644
--- a/src/libstrongswan/tests/Makefile.am
+++ b/src/libstrongswan/tests/Makefile.am
@@ -42,6 +42,7 @@ tests_SOURCES = tests.h tests.c \
suites/test_host.c \
suites/test_hasher.c \
suites/test_crypter.c \
+ suites/test_crypto_factory.c \
suites/test_pen.c \
suites/test_asn1.c \
suites/test_asn1_parser.c \
diff --git a/src/libstrongswan/tests/suites/test_crypto_factory.c b/src/libstrongswan/tests/suites/test_crypto_factory.c
new file mode 100644
index 0000000..94f45da
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_crypto_factory.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <crypto/crypto_factory.h>
+
+static rng_t *rng_create(rng_quality_t quality)
+{
+ rng_quality_t *q = malloc_thing(rng_quality_t);
+ *q = quality;
+ return (rng_t*)q;
+}
+
+static rng_t *rng_create_weak(rng_quality_t quality)
+{
+ ck_assert(quality == RNG_WEAK);
+ return rng_create(RNG_WEAK);
+}
+
+static rng_t *rng_create_strong(rng_quality_t quality)
+{
+ ck_assert(quality <= RNG_STRONG);
+ return rng_create(RNG_STRONG);
+}
+
+static rng_t *rng_create_true(rng_quality_t quality)
+{
+ ck_assert(quality <= RNG_TRUE);
+ return rng_create(RNG_TRUE);
+}
+
+static rng_t *rng_create_true_second(rng_quality_t quality)
+{
+ fail("should never be called");
+ return rng_create(RNG_TRUE);
+}
+
+static rng_quality_t rng_weak = RNG_WEAK;
+static rng_quality_t rng_strong = RNG_STRONG;
+static rng_quality_t rng_true = RNG_TRUE;
+
+static struct {
+ rng_quality_t *exp_weak;
+ rng_quality_t *exp_strong;
+ rng_quality_t *exp_true;
+ struct {
+ rng_quality_t *q;
+ rng_constructor_t create;
+ } data[4];
+} rng_data[] = {
+ { NULL, NULL, NULL, {
+ { NULL, NULL }
+ }},
+ { &rng_weak, NULL, NULL, {
+ { &rng_weak, rng_create_weak },
+ { NULL, NULL }
+ }},
+ { &rng_strong, &rng_strong, NULL, {
+ { &rng_strong, rng_create_strong },
+ { NULL, NULL }
+ }},
+ { &rng_true, &rng_true, &rng_true, {
+ { &rng_true, rng_create_true },
+ { NULL, NULL }
+ }},
+ { &rng_true, &rng_true, &rng_true, {
+ { &rng_true, rng_create_true },
+ { &rng_true, rng_create_true_second },
+ { NULL, NULL }
+ }},
+ { &rng_weak, &rng_true, &rng_true, {
+ { &rng_weak, rng_create_weak },
+ { &rng_true, rng_create_true },
+ { NULL, NULL }
+ }},
+ { &rng_weak, &rng_strong, &rng_true, {
+ { &rng_true, rng_create_true },
+ { &rng_strong, rng_create_strong },
+ { &rng_weak, rng_create_weak },
+ { NULL, NULL }
+ }},
+ { &rng_weak, &rng_strong, &rng_true, {
+ { &rng_weak, rng_create_weak },
+ { &rng_strong, rng_create_strong },
+ { &rng_true, rng_create_true },
+ { NULL, NULL }
+ }},
+};
+
+static void verify_rng(crypto_factory_t *factory, rng_quality_t request,
+ rng_quality_t *expected)
+{
+ rng_quality_t *res;
+
+ res = (rng_quality_t*)factory->create_rng(factory, request);
+ if (!expected)
+ {
+ ck_assert(!res);
+ }
+ else
+ {
+ ck_assert(res);
+ ck_assert_int_eq(*expected, *res);
+ free(res);
+ }
+}
+
+START_TEST(test_create_rng)
+{
+ crypto_factory_t *factory;
+ int i;
+
+ factory = crypto_factory_create();
+ for (i = 0; rng_data[_i].data[i].q; i++)
+ {
+ ck_assert(factory->add_rng(factory, *rng_data[_i].data[i].q, "test",
+ rng_data[_i].data[i].create));
+ }
+ verify_rng(factory, RNG_WEAK, rng_data[_i].exp_weak);
+ verify_rng(factory, RNG_STRONG, rng_data[_i].exp_strong);
+ verify_rng(factory, RNG_TRUE, rng_data[_i].exp_true);
+ for (i = 0; rng_data[_i].data[i].q; i++)
+ {
+ factory->remove_rng(factory, rng_data[_i].data[i].create);
+ }
+ factory->destroy(factory);
+}
+END_TEST
+
+static diffie_hellman_t *dh_create(char *plugin)
+{
+ return (diffie_hellman_t*)plugin;
+}
+
+static diffie_hellman_t *dh_create_modp1024(diffie_hellman_group_t group, ...)
+{
+ ck_assert(group == MODP_1024_BIT);
+ return dh_create("plugin1");
+}
+
+static diffie_hellman_t *dh_create_modp1024_second(diffie_hellman_group_t group,
+ ...)
+{
+ ck_assert(group == MODP_1024_BIT);
+ return dh_create("plugin2");
+}
+
+static diffie_hellman_t *dh_create_modp2048(diffie_hellman_group_t group, ...)
+{
+ ck_assert(group == MODP_2048_BIT);
+ return dh_create("plugin1");
+}
+
+static diffie_hellman_t *dh_create_modp2048_second(diffie_hellman_group_t group,
+ ...)
+{
+ ck_assert(group == MODP_2048_BIT);
+ return dh_create("plugin2");
+}
+
+static struct {
+ char *exp1024;
+ char *exp2048;
+ struct {
+ diffie_hellman_group_t g;
+ dh_constructor_t create;
+ char *plugin;
+ } data[4];
+} dh_data[] = {
+ { NULL, NULL, {
+ { MODP_NONE, NULL, NULL }
+ }},
+ { "plugin1", NULL, {
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL, NULL }
+ }},
+ { "plugin1", NULL, {
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_1024_BIT, dh_create_modp1024_second, "plugin2" },
+ { MODP_NONE, NULL, NULL }
+ }},
+ { "plugin2", NULL, {
+ { MODP_1024_BIT, dh_create_modp1024_second, "plugin2" },
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL, NULL }
+ }},
+ { "plugin1", "plugin1", {
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_2048_BIT, dh_create_modp2048, "plugin1" },
+ { MODP_NONE, NULL }
+ }},
+ { "plugin1", "plugin1", {
+ { MODP_2048_BIT, dh_create_modp2048, "plugin1" },
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL }
+ }},
+ { "plugin1", "plugin1", {
+ { MODP_2048_BIT, dh_create_modp2048, "plugin1" },
+ { MODP_2048_BIT, dh_create_modp2048_second, "plugin2" },
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL }
+ }},
+ { "plugin1", "plugin2", {
+ { MODP_2048_BIT, dh_create_modp2048_second, "plugin2" },
+ { MODP_2048_BIT, dh_create_modp2048, "plugin1" },
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL }
+ }},
+};
+
+static void verify_dh(crypto_factory_t *factory, diffie_hellman_group_t request,
+ char *expected)
+{
+ char *plugin;
+
+ plugin = (char*)factory->create_dh(factory, request);
+ if (!expected)
+ {
+ ck_assert(!plugin);
+ }
+ else
+ {
+ ck_assert(plugin);
+ ck_assert_str_eq(expected, plugin);
+ }
+}
+
+START_TEST(test_create_dh)
+{
+ enumerator_t *enumerator;
+ crypto_factory_t *factory;
+ diffie_hellman_group_t group;
+ char *plugin;
+ int i, len = 0;
+
+
+ factory = crypto_factory_create();
+ for (i = 0; dh_data[_i].data[i].g != MODP_NONE; i++)
+ {
+ ck_assert(factory->add_dh(factory, dh_data[_i].data[i].g,
+ dh_data[_i].data[i].plugin,
+ dh_data[_i].data[i].create));
+ }
+ verify_dh(factory, MODP_1024_BIT, dh_data[_i].exp1024);
+ verify_dh(factory, MODP_2048_BIT, dh_data[_i].exp2048);
+
+ len = countof(dh_data[_i].data);
+ enumerator = factory->create_dh_enumerator(factory);
+ for (i = 0; enumerator->enumerate(enumerator, &group, &plugin) && i < len;)
+ {
+ ck_assert_int_eq(dh_data[_i].data[i].g, group);
+ while (dh_data[_i].data[i].g == group)
+ { /* skip other entries by the same group */
+ i++;
+ }
+ switch (group)
+ {
+ case MODP_1024_BIT:
+ ck_assert(dh_data[_i].exp1024);
+ ck_assert_str_eq(dh_data[_i].exp1024, plugin);
+ break;
+ case MODP_2048_BIT:
+ ck_assert(dh_data[_i].exp2048);
+ ck_assert_str_eq(dh_data[_i].exp2048, plugin);
+ break;
+ default:
+ fail("unexpected DH group");
+ break;
+ }
+ }
+ ck_assert(!enumerator->enumerate(enumerator));
+ ck_assert_int_eq(dh_data[_i].data[i].g, MODP_NONE);
+ enumerator->destroy(enumerator);
+
+ for (i = 0; dh_data[_i].data[i].g != MODP_NONE; i++)
+ {
+ factory->remove_dh(factory, dh_data[_i].data[i].create);
+ }
+ factory->destroy(factory);
+}
+END_TEST
+
+Suite *crypto_factory_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("crypto-factory");
+
+ tc = tcase_create("create_rng");
+ tcase_add_loop_test(tc, test_create_rng, 0, countof(rng_data));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("create_dh");
+ tcase_add_loop_test(tc, test_create_dh, 0, countof(dh_data));
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h
index 82a5137..ab0f642 100644
--- a/src/libstrongswan/tests/tests.h
+++ b/src/libstrongswan/tests/tests.h
@@ -35,6 +35,7 @@ TEST_SUITE(host_suite_create)
TEST_SUITE(printf_suite_create)
TEST_SUITE(hasher_suite_create)
TEST_SUITE(crypter_suite_create)
+TEST_SUITE(crypto_factory_suite_create)
TEST_SUITE(pen_suite_create)
TEST_SUITE(asn1_suite_create)
TEST_SUITE(asn1_parser_suite_create)
--
2.1.2

View File

@ -15,16 +15,40 @@ This requires adoption of either the "conn %default" or all other IKEv1
keyexchange=ikev1
The charon daemon in strongswan 5.x versions supports IKEv1 and IKEv2,
thus a separate pluto IKEv1 daemon is not needed / not shipped any more.
The strongswan package does no provide any files any more, but triggers
the installation of both, IKEv1 (pluto) and IKEv2 (charon) daemons and the
traditional starter scripts inclusive of the /etc/init.d/ipsec init script
and /etc/ipsec.conf file.
There is a new strongswan-nm package with a NetworkManager plugin to
control the charon IKEv2 daemon through D-Bus, designed to work using the
NetworkManager-strongswan graphical user interface.
The strongswan package does not provide any files except of this README,
but triggers the installation of the charon daemon and the "traditional"
strongswan-ipsec package providing the "ipsec" script and service.
The ipsec.service is an alias link to the "strongswan.service" systemd
service unit and created by "systemctl enable strongswan.service".
There is a new strongswan-nm package with a NetworkManager specific charon-nm
binary controlling the charon daemon through D-Bus and designed to work using
the NetworkManager-strongswan graphical user interface.
It does not depend on the traditional starter scripts, but on the IKEv2
charon daemon and plugins only.
The stongswan-hmac package provides the fips hmac hash files, a _fipscheck
script and a /etc/strongswan.d/charon/zzz_fips-enforce.conf config file,
which disables all non-openssl algorithm implementations.
When fips operation mode is enabled in the kernel using the fips=1 boot
parameter, the strongswan fips checks are executed in front of any start
action of the "ipsec" script provided by the "strongswan-ipsec" package
and a verification problem causes a failure as required by fips-140-2.
Further, it is not required to enable the fips_mode in the openssl plugin
(/etc/strongswan.d/charon/openssl.conf); the kernel entablement enables
it automatically as needed.
The "ipsec _fipscheck" command allows to execute the fips checks manually
without a check if fips is enabled (/proc/sys/crypto/fips_enabled is 1),
e.g. for testing purposes.
Have a lot of fun...

52
fips-enforce.conf Normal file
View File

@ -0,0 +1,52 @@
#
# When fips is enabled (fips=1 kernel parameter), only certified openssl
# and kernel crypto API (af-alg) algorithms are supported.
#
# The strongswan-hmac package is supposed to be used/installed when fips
# is enabled and provides the hmac hashes, a "ipsec _fipscheck" script
# verifying the components and this blacklist disabling other plugins
# providing further and/or alternative algorithm implementations.
#
gcrypt {
load = no
}
blowfish {
load = no
}
random {
load = no
}
des {
load = no
}
aes {
load = no
}
rc2 {
load = no
}
ctr {
load = no
}
cmac {
load = no
}
xcbc {
load = no
}
md4 {
load = no
}
md5 {
load = no
}
sha1 {
load = no
}
sha2 {
load = no
}
ccm {
load = no
}

69
fipscheck.sh.in Normal file
View File

@ -0,0 +1,69 @@
#! /bin/bash
#
# Copyright (C) 2014 SUSE LINUX GmbH, Nuernberg, Germany.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, see <http://www.gnu.org/licenses/>.
#
# Author: Marius Tomaschewski <mt@suse.de>
#
IPSEC_DIR="@IPSEC_DIR@"
IPSEC_LIBDIR="@IPSEC_LIBDIR@"
IPSEC_BINDIR="@IPSEC_BINDIR@"
IPSEC_SBINDIR="@IPSEC_SBINDIR@"
fipscheck_bin="/usr/bin/fipscheck"
# minimal usage hint
if test $# -gt 0 ; then
echo "usage: ipsec _fipscheck" >&2
exit 2
fi
#
# "ipsec xxx" starts this script only if crypto/fips_enabled=1,
# except while a manually enforced check via "ipsec _fipscheck".
#
#read 2>/dev/null fips_enabled < /proc/sys/crypto/fips_enabled
#test "X$fips_enabled" = "X1" || exit 0
# verify that fipscheck is installed
test -x "$fipscheck_bin" || {
test "X$FIPSCHECK_DEBUG" = "Xerror" && \
echo "${0##*/}: $fipscheck_bin utility missed" >&2
exit 4
}
shopt -s nullglob
files=()
for h in ${IPSEC_DIR}/.*.hmac \
${IPSEC_LIBDIR}/.*.hmac \
${IPSEC_LIBDIR}/imcvs/.*.hmac \
${IPSEC_LIBDIR}/plugins/.*.hmac \
${IPSEC_SBINDIR}/.ipsec.hmac \
;
do
dir="${h%/*}"
name="${h##*/.}"
file="${dir}/${name%.hmac}"
# some part is not installed
test -f "${file}" && files+=("$file")
done
if test ${#files[@]} -gt 0 ; then
$fipscheck_bin ${files[@]} ; exit $?
elif test "X$FIPSCHECK_DEBUG" = "Xerror" ; then
echo "${0##*/}: unable to find any checksum/hmac file" >&2
fi
exit 3

View File

@ -1,15 +0,0 @@
References: fate#316931
Index: strongswan-5.1.3/conf/plugins/gcrypt.conf
===================================================================
--- strongswan-5.1.3.orig/conf/plugins/gcrypt.conf
+++ strongswan-5.1.3/conf/plugins/gcrypt.conf
@@ -2,7 +2,7 @@ gcrypt {
# Whether to load the plugin. Can also be an integer to increase the
# priority of this plugin.
- load = yes
+ load = no
# Use faster random numbers in gcrypt; for testing only, produces weak keys!
# quick_random = no

View File

@ -1,3 +1,47 @@
-------------------------------------------------------------------
Tue Nov 25 11:22:06 UTC 2014 - mt@suse.de
- Updated strongswan-hmac package description (bsc#856322).
-------------------------------------------------------------------
Fri Nov 21 12:03:59 UTC 2014 - mt@suse.de
- Disabled explicit gpg validation; osc source_validator does it.
- Guarded fipscheck and hmac package in the spec file for >13.1.
-------------------------------------------------------------------
Thu Nov 20 07:43:43 UTC 2014 - mt@suse.de
- Added generation of fips hmac hash files using fipshmac utility
and a _fipscheck script to verify binaries/libraries/plugings
shipped in the strongswan-hmac package.
With enabled fips in the kernel, the ipsec script will call it
before any action or in a enforced/manual "ipsec _fipscheck" call.
Added config file to load openssl and kernel af-alg plugins, but
not all the other modules which provide further/alternative algs.
Applied a filter disallowing non-approved algorithms in fips mode.
(fate#316931,bnc#856322).
[+ strongswan_fipscheck.patch, strongswan_fipsfilter.patch]
- Fixed file list in the optional (disabled) strongswan-test package.
- Fixed build of the strongswan built-in integrity checksum library
and enabled building it only on architectures tested to work.
- Fix to use bug number 897048 instead 856322 in last changes entry.
- Applied an upstream patch reverting to store algorithms in the
registration order again as ordering them by identifier caused
weaker algorithms to be proposed first by default (bsc#897512).
[+0001-restore-registration-algorithm-order.bug897512.patch]
-------------------------------------------------------------------
Fri Sep 26 16:02:09 UTC 2014 - mt@suse.de
- Re-enabled gcrypt plugin and reverted to not enforce fips again
as this breaks gcrypt and openssl plugins when the fips pattern
option is not installed (fate#316931,bnc#856322).
[- strongswan-fips-disablegcrypt.patch]
- Added empty strongswan-hmac package supposed to provide fips hmac
files and enforce fips compliant operation later (bnc#856322).
- Cleaned up conditional build flags in the rpm spec file.
-------------------------------------------------------------------
Thu Jul 3 13:39:45 UTC 2014 - meissner@suse.com

View File

@ -31,16 +31,27 @@ Release: 0
%else
%bcond_with tests
%endif
%if 0%{suse_version} > 1110
%bcond_without mysql
%if 0%{suse_version} > 1310
%bcond_without fipscheck
%else
%bcond_with mysql
%bcond_with fipscheck
%endif
%ifarch %{ix86} ppc64le
%bcond_without integrity
%else
%bcond_with integrity
%endif
%if 0%{suse_version} > 1110
%bcond_without farp
%bcond_without afalg
%bcond_without mysql
%bcond_without sqlite
%bcond_without gcrypt
%bcond_without nm
%else
%bcond_with farp
%bcond_with afalg
%bcond_with mysql
%bcond_with sqlite
%bcond_with gcrypt
%bcond_with nm
@ -61,16 +72,23 @@ Source2: %{name}.init.in
Source3: %{name}-%{version}-rpmlintrc
Source4: README.SUSE
Source5: %{name}.keyring
%if %{with fipscheck}
Source6: fipscheck.sh.in
Source7: fips-enforce.conf
%endif
Patch1: %{name}_modprobe_syslog.patch
Patch2: %{name}_ipsec_service.patch
Patch3: %{name}-fips-disablegcrypt.patch
%if %{with fipscheck}
Patch3: %{name}_fipscheck.patch
Patch4: %{name}_fipsfilter.patch
%endif
Patch5: 0001-restore-registration-algorithm-order.bug897512.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: bison
BuildRequires: curl-devel
BuildRequires: flex
BuildRequires: gmp-devel
BuildRequires: gperf
BuildRequires: gpg-offline
BuildRequires: libcap-devel
BuildRequires: libopenssl-devel
BuildRequires: libsoup-devel
@ -91,11 +109,21 @@ BuildRequires: libgcrypt-devel
BuildRequires: NetworkManager-devel
%endif
%if %{with systemd}
BuildRequires: pkgconfig(systemd)
%{?systemd_requires}
%endif
BuildRequires: iptables
%if %{with systemd}
%{!?_rundir: %global _rundir /run}
%{!?_tmpfilesdir: %global _tmpfilesdir /usr/lib/tmpfiles.d}
%else
%{!?_rundir: %global _rundir /var/run}
%endif
BuildRequires: autoconf
BuildRequires: automake
%if %{with fipscheck}
BuildRequires: fipscheck
%endif
BuildRequires: libtool
%description
StrongSwan is an OpenSource IPsec-based VPN Solution for Linux
@ -161,6 +189,24 @@ StrongSwan is an OpenSource IPsec-based VPN Solution for Linux
This package provides the strongswan library and plugins.
%if %{with fipscheck}
%package hmac
Summary: HMAC files for FIPS-140-2 integrity
Group: Productivity/Networking/Security
Requires: fipscheck
Requires: strongswan-ipsec = %{version}
Requires: strongswan-libs0 = %{version}
%description hmac
The package provides HMAC hash files for FIPS-140-2 integrity checks,
a config file disabling alternative algorithm implementations and a
_fipscheck helper script preforming the integrity checks before e.g.
"ipsec start" action is executed, when FIPS-140-2 compliant operation
mode is enabled.
%endif
%package ipsec
Summary: OpenSource IPsec-based VPN Solution
Group: Productivity/Networking/Security
@ -240,39 +286,58 @@ and the load testing plugin for IKEv2 daemon.
%endif
%prep
%gpg_verify %{S:1}
%setup -q -n %{name}-%{upstream_version}
%patch1 -p0
%patch2 -p0
%patch3 -p1
%if %{with fipscheck}
%patch3 -p0
%patch4 -p1
%endif
%patch5 -p1
sed -e 's|@libexecdir@|%_libexecdir|g' \
< $RPM_SOURCE_DIR/strongswan.init.in \
> strongswan.init
%if %{with fipscheck}
sed -e 's|@IPSEC_DIR@|%{_libexecdir}/ipsec|g' \
-e 's|@IPSEC_LIBDIR@|%{_libdir}/ipsec|g' \
-e 's|@IPSEC_SBINDIR@|%{_sbindir}|g' \
-e 's|@IPSEC_BINDIR@|%{_bindir}|g' \
< $RPM_SOURCE_DIR/fipscheck.sh.in \
> _fipscheck
%endif
%build
CFLAGS="$RPM_OPT_FLAGS -W -Wall -Wno-pointer-sign -Wno-strict-aliasing -Wno-unused-parameter"
export RPM_OPT_FLAGS CFLAGS
#libtoolize --force
#autoreconf
autoreconf --force --install
%configure \
--enable-conftest \
%if %{with integrity}
--enable-integrity-test \
%endif
--with-capabilities=libcap \
--with-plugindir=%{strongswan_plugins} \
--with-fips=2 \
--with-resolv-conf=%{_rundir}/%{name}/resolv.conf \
--with-piddir=%{_rundir}/%{name} \
%if %{with systemd}
--with-systemdsystemunitdir=%{_unitdir} \
%endif
--enable-pkcs11 \
--enable-openssl \
--enable-agent \
%if %{with gcrypt}
--enable-gcrypt \
%else
--disable-gcrypt \
%endif
--enable-blowfish \
--enable-ctr \
--enable-ccm \
--enable-gcm \
--enable-unity \
--enable-md4 \
%if %{with afalg}
--enable-af-alg \
%endif
--enable-eap-sim \
--enable-eap-sim-file \
--enable-eap-sim-pcsc \
@ -305,7 +370,9 @@ export RPM_OPT_FLAGS CFLAGS
--enable-imv-scanner \
--enable-ha \
--enable-dhcp \
%if %{with farp}
--enable-farp \
%endif
--enable-smp \
--enable-sql \
--enable-attr-sql \
@ -322,15 +389,13 @@ export RPM_OPT_FLAGS CFLAGS
%if %{with sqlite}
--enable-sqlite \
%endif
%if %{with gcrypt}
--enable-gcrypt \
%endif
%if %{with nm}
--enable-nm \
%else
--disable-nm \
%endif
%if %{with tests}
--enable-conftest \
--enable-load-tester \
--enable-test-vectors \
%endif
@ -344,14 +409,44 @@ make %{?_smp_mflags:%_smp_mflags}
export RPM_BUILD_ROOT
install -d -m755 ${RPM_BUILD_ROOT}%{_sbindir}/
install -d -m755 ${RPM_BUILD_ROOT}%{_sysconfdir}/ipsec.d/
%if ! %{with systemd}
%if %{with systemd}
ln -sf %_sbindir/service ${RPM_BUILD_ROOT}%_sbindir/rcstrongswan
%else
install -d -m755 ${RPM_BUILD_ROOT}%{_sysconfdir}/init.d/
install -m755 strongswan.init ${RPM_BUILD_ROOT}%{_sysconfdir}/init.d/ipsec
ln -s %{_sysconfdir}/init.d/ipsec ${RPM_BUILD_ROOT}%{_sbindir}/rcipsec
%endif
#
# Ensure, plugin -> library dependencies can be resolved
# (e.g. libtls) to avoid plugin segment checksum errors.
#
LD_LIBRARY_PATH="$RPM_BUILD_ROOT-$$%{strongswan_libdir}" \
make install DESTDIR="$RPM_BUILD_ROOT"
#
# checksums are calculated during make install using the
# installed binaries/libraries... but find-debuginfo.sh
# extracts debuginfo/debugsource breaking file checksums.
# let find-debuginfo.sh run on a build root copy and then
# calculate the checksums.
#
%if %{with integrity}
%{?__debug_package:
if test -x %{_rpmconfigdir}/find-debuginfo.sh ; then
cp -a "${RPM_BUILD_ROOT}" "${RPM_BUILD_ROOT}-$$"
RPM_BUILD_ROOT="$RPM_BUILD_ROOT-$$" \
%{_rpmconfigdir}/find-debuginfo.sh \
%{?_find_debuginfo_opts} "${RPM_BUILD_ROOT}-$$"
make -C src/checksum clean
rm -f src/checksum/checksum_builder
LD_LIBRARY_PATH="$RPM_BUILD_ROOT-$$%{strongswan_libdir}" \
make -C src/checksum install DESTDIR="$RPM_BUILD_ROOT-$$"
mv "$RPM_BUILD_ROOT-$$%{strongswan_libdir}/libchecksum.so" \
"$RPM_BUILD_ROOT%{strongswan_libdir}/libchecksum.so"
rm -rf "${RPM_BUILD_ROOT}-$$"
fi
}
%endif
#
rm -f ${RPM_BUILD_ROOT}%{_sysconfdir}/ipsec.secrets
cat << EOT > ${RPM_BUILD_ROOT}%{_sysconfdir}/ipsec.secrets
#
@ -362,6 +457,12 @@ cat << EOT > ${RPM_BUILD_ROOT}%{_sysconfdir}/ipsec.secrets
#
EOT
#
%if ! %{with mysql}
rm -f $RPM_BUILD_ROOT%{strongswan_templates}/database/sql/mysql.sql
%endif
%if ! %{with sqlite}
rm -f $RPM_BUILD_ROOT%{strongswan_templates}/database/sql/sqlite.sql
%endif
rm -f $RPM_BUILD_ROOT%{strongswan_libdir}/lib{charon,hydra,strongswan,pttls}.so
rm -f $RPM_BUILD_ROOT%{strongswan_libdir}/lib{radius,simaka,tls,tnccs,imcv}.so
find $RPM_BUILD_ROOT%{strongswan_libdir} -type f -name "*.la" -delete
@ -372,26 +473,62 @@ install -c -m644 TODO NEWS README COPYING LICENSE \
${RPM_BUILD_ROOT}%{strongswan_docdir}/
install -c -m644 ${RPM_SOURCE_DIR}/README.SUSE \
${RPM_BUILD_ROOT}%{strongswan_docdir}/
%if %{with systemd}
%{__install} -d -m 0755 %{buildroot}%{_tmpfilesdir}
echo 'd %{_rundir}/%{name} 0770 root root' > %{buildroot}%{_tmpfilesdir}/%{name}.conf
%endif
%if %{with fipscheck}
#
# note: keep the following, _fipscheck's and file lists in sync
#
install -c -m750 _fipscheck ${RPM_BUILD_ROOT}%{_libexecdir}/ipsec/
install -c -m644 ${RPM_SOURCE_DIR}/fips-enforce.conf \
${RPM_BUILD_ROOT}%{strongswan_configs}/charon/zzz_fips-enforce.conf
# create fips hmac hashes _after_ install post run
%{expand:%%global __os_install_post {%__os_install_post
for f in $RPM_BUILD_ROOT%{strongswan_libdir}/lib*.so.*.*.* \
$RPM_BUILD_ROOT%{strongswan_libdir}/imcvs/*.so \
$RPM_BUILD_ROOT%{strongswan_plugins}/*.so \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/charon \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/charon-nm \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/stroke \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/starter \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/pool \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/scepclient \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/pt-tls-client \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/imv_policy_manager \
$RPM_BUILD_ROOT%{_libexecdir}/ipsec/_fipscheck \
$RPM_BUILD_ROOT%{_sbindir}/ipsec \
;
do
/usr/bin/fipshmac "$f"
done
}}
%endif
%post libs0 -p /sbin/ldconfig
%post libs0
/sbin/ldconfig
%{?tmpfiles_create:%tmpfiles_create %{_tmpfilesdir}/%{name}.conf}
%{!?tmpfiles_create:test -d %{_rundir}/%{name} || %{__mkdir_p} %{_rundir}/%{name}}
%postun libs0 -p /sbin/ldconfig
%pre ipsec
%if %{with systemd}
%service_add_pre %{name}.service
%endif
%post ipsec
%if ! %{with systemd}
%if %{with systemd}
%service_add_post %{name}.service
%else
%{fillup_and_insserv ipsec}
%endif
%{?tmpfiles_create: %tmpfiles_create %{_tmpfilesdir}/%{name}.conf }
%service_add_post %{name}.service
%preun ipsec
%if ! %{with systemd}
%if %{with systemd}
%service_del_preun %{name}.service
%else
%{stop_on_removal ipsec}
%endif
if test -s %{_sysconfdir}/ipsec.secrets.rpmsave ; then
@ -402,20 +539,38 @@ if test -s %{_sysconfdir}/ipsec.conf.rpmsave ; then
cp -p --backup=numbered %{_sysconfdir}/ipsec.conf.rpmsave \
%{_sysconfdir}/ipsec.conf.rpmsave.old
fi
%service_del_preun %{name}.service
%postun ipsec
%if ! %{with systemd}
%if %{with systemd}
%service_del_postun %{name}.service
%else
%{insserv_cleanup}
%endif
%service_del_postun %{name}.service
%files
%defattr(-,root,root)
%dir %{strongswan_docdir}
%{strongswan_docdir}/README.SUSE
%if %{with fipscheck}
%files hmac
%defattr(-,root,root)
%dir %{strongswan_configs}
%dir %{strongswan_configs}/charon
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/zzz_fips-enforce.conf
%dir %{strongswan_libdir}
%{strongswan_libdir}/.*.hmac
%{strongswan_libdir}/imcvs/.*.hmac
%dir %{strongswan_plugins}
%{strongswan_plugins}/.*.hmac
%dir %{_libexecdir}/ipsec
%{_libexecdir}/ipsec/_fipscheck
%{_libexecdir}/ipsec/.*.hmac
%{_sbindir}/.ipsec.hmac
%endif
%files ipsec
%defattr(-,root,root)
%config(noreplace) %attr(600,root,root) %{_sysconfdir}/ipsec.conf
@ -431,6 +586,7 @@ fi
%dir %attr(700,root,root) %{_sysconfdir}/ipsec.d/private
%if %{with systemd}
%{_unitdir}/strongswan.service
%{_sbindir}/rcstrongswan
%else
%config %{_sysconfdir}/init.d/ipsec
%{_sbindir}/rcipsec
@ -446,7 +602,9 @@ fi
%{_libexecdir}/ipsec/_copyright
%{_libexecdir}/ipsec/_updown
%{_libexecdir}/ipsec/_updown_espmark
%if %{with test}
%{_libexecdir}/ipsec/conftest
%endif
%{_libexecdir}/ipsec/duplicheck
%{_libexecdir}/ipsec/pool
%{_libexecdir}/ipsec/pt-tls-client
@ -459,7 +617,6 @@ fi
%dir %{strongswan_plugins}
%{strongswan_plugins}/libstrongswan-stroke.so
%{strongswan_plugins}/libstrongswan-updown.so
%{_tmpfilesdir}/%{name}.conf
%files doc
%defattr(-,root,root)
@ -477,6 +634,9 @@ fi
%files libs0
%defattr(-,root,root)
%if %{with systemd}
%{_tmpfilesdir}/%{name}.conf
%endif
%config(noreplace) %attr(600,root,root) %{_sysconfdir}/strongswan.conf
%dir %{strongswan_configs}
%dir %{strongswan_configs}/charon
@ -489,7 +649,9 @@ fi
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/tools.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/addrblock.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/aes.conf
%if %{with afalg}
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/af-alg.conf
%endif
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/agent.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/attr.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/attr-sql.conf
@ -523,10 +685,14 @@ fi
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/eap-tls.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/eap-tnc.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/eap-ttls.conf
%if %{with farp}
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/farp.conf
%endif
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/fips-prf.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/gcm.conf
%if %{with gcrypt}
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/gcrypt.conf
%endif
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/gmp.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/ha.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/hmac.conf
@ -573,7 +739,9 @@ fi
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/xauth-pam.conf
%config(noreplace) %attr(600,root,root) %{strongswan_configs}/charon/xcbc.conf
%dir %{strongswan_libdir}
%if %{with integrity}
%{strongswan_libdir}/libchecksum.so
%endif
%{strongswan_libdir}/libcharon.so.*
%{strongswan_libdir}/libhydra.so.*
%{strongswan_libdir}/libpttls.so.*
@ -591,7 +759,9 @@ fi
%dir %{strongswan_plugins}
%{strongswan_plugins}/libstrongswan-addrblock.so
%{strongswan_plugins}/libstrongswan-aes.so
%if %{with afalg}
%{strongswan_plugins}/libstrongswan-af-alg.so
%endif
%{strongswan_plugins}/libstrongswan-agent.so
%{strongswan_plugins}/libstrongswan-attr.so
%{strongswan_plugins}/libstrongswan-attr-sql.so
@ -625,7 +795,9 @@ fi
%{strongswan_plugins}/libstrongswan-eap-tls.so
%{strongswan_plugins}/libstrongswan-eap-tnc.so
%{strongswan_plugins}/libstrongswan-eap-ttls.so
%if %{with farp}
%{strongswan_plugins}/libstrongswan-farp.so
%endif
%{strongswan_plugins}/libstrongswan-fips-prf.so
%{strongswan_plugins}/libstrongswan-gcm.so
%if %{with gcrypt}
@ -685,7 +857,9 @@ fi
%{strongswan_templates}/config/strongswan.conf
%{strongswan_templates}/config/plugins/addrblock.conf
%{strongswan_templates}/config/plugins/aes.conf
%if %{with afalg}
%{strongswan_templates}/config/plugins/af-alg.conf
%endif
%{strongswan_templates}/config/plugins/agent.conf
%{strongswan_templates}/config/plugins/attr-sql.conf
%{strongswan_templates}/config/plugins/attr.conf
@ -719,10 +893,14 @@ fi
%{strongswan_templates}/config/plugins/eap-tls.conf
%{strongswan_templates}/config/plugins/eap-tnc.conf
%{strongswan_templates}/config/plugins/eap-ttls.conf
%if %{with farp}
%{strongswan_templates}/config/plugins/farp.conf
%endif
%{strongswan_templates}/config/plugins/fips-prf.conf
%{strongswan_templates}/config/plugins/gcm.conf
%if %{with gcrypt}
%{strongswan_templates}/config/plugins/gcrypt.conf
%endif
%{strongswan_templates}/config/plugins/gmp.conf
%{strongswan_templates}/config/plugins/ha.conf
%{strongswan_templates}/config/plugins/hmac.conf
@ -831,6 +1009,18 @@ fi
%files tests
%defattr(-,root,root)
%dir %{strongswan_configs}
%dir %{strongswan_configs}/charon
%{strongswan_configs}/charon/load-tester.conf
%{strongswan_configs}/charon/test-vectors.conf
%dir %{strongswan_templates}
%dir %{strongswan_templates}/config
%dir %{strongswan_templates}/config/plugins
%{strongswan_templates}/config/plugins/load-tester.conf
%{strongswan_templates}/config/plugins/test-vectors.conf
%dir %{_libexecdir}/ipsec
%{_libexecdir}/ipsec/conftest
%{_libexecdir}/ipsec/load-tester
%dir %{strongswan_libdir}
%dir %{strongswan_plugins}
%{strongswan_plugins}/libstrongswan-load-tester.so

View File

@ -0,0 +1,89 @@
--- src/ipsec/_ipsec.in
+++ src/ipsec/_ipsec.in 2014/11/07 11:28:25
@@ -44,6 +44,26 @@ export IPSEC_DIR IPSEC_BINDIR IPSEC_SBIN
IPSEC_DISTRO="Institute for Internet Technologies and Applications\nUniversity of Applied Sciences Rapperswil, Switzerland"
+fipscheck()
+{
+ # when fips operation mode is not enabled, just report OK
+ read 2>/dev/null fips_enabled < /proc/sys/crypto/fips_enabled
+ test "X$fips_enabled" = "X1" || return 0
+
+ # complain when _fipscheck is missed
+ test -x "$IPSEC_DIR/_fipscheck" || {
+ echo "ipsec: please install strongswan-hmac package required in fips mode" >&2
+ return 4
+ }
+
+ # now execute it
+ $IPSEC_DIR/_fipscheck || {
+ rc=$?
+ echo "ipsec: strongSwan fips file integrity check failed" >&2
+ return $rc
+ }
+}
+
case "$1" in
'')
echo "Usage: $IPSEC_SCRIPT command argument ..."
@@ -166,6 +186,7 @@ rereadall|purgeocsp|listcounters|resetco
shift
if [ -e $IPSEC_CHARON_PID ]
then
+ fipscheck || exit $?
$IPSEC_STROKE "$op" "$@"
rc="$?"
fi
@@ -175,6 +196,7 @@ purgeike|purgecrls|purgecerts)
rc=7
if [ -e $IPSEC_CHARON_PID ]
then
+ fipscheck || exit $?
$IPSEC_STROKE "$1"
rc="$?"
fi
@@ -208,6 +230,7 @@ route|unroute)
fi
if [ -e $IPSEC_CHARON_PID ]
then
+ fipscheck || exit $?
$IPSEC_STROKE "$op" "$1"
rc="$?"
fi
@@ -217,6 +240,7 @@ secrets)
rc=7
if [ -e $IPSEC_CHARON_PID ]
then
+ fipscheck || exit $?
$IPSEC_STROKE rereadsecrets
rc="$?"
fi
@@ -224,6 +248,7 @@ secrets)
;;
start)
shift
+ fipscheck || exit $?
if [ -d /var/lock/subsys ]; then
touch /var/lock/subsys/ipsec
fi
@@ -297,6 +322,7 @@ up)
rc=7
if [ -e $IPSEC_CHARON_PID ]
then
+ fipscheck || exit $?
$IPSEC_STROKE up "$1"
rc="$?"
fi
@@ -332,6 +358,11 @@ esac
cmd="$1"
shift
+case $cmd in
+_fipscheck|_copyright|pki) ;;
+*) fipscheck || exit $? ;;
+esac
+
path="$IPSEC_DIR/$cmd"
if [ ! -x "$path" ]

254
strongswan_fipsfilter.patch Normal file
View File

@ -0,0 +1,254 @@
diff --git a/src/libcharon/config/proposal.c b/src/libcharon/config/proposal.c
index 2ecdb4f..85767ab 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,130 @@ 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_1024_BIT:
+ case MODP_1536_BIT:
+ case MODP_2048_BIT:
+ case MODP_3072_BIT:
+ case MODP_4096_BIT:
+ case MODP_8192_BIT:
+ case MODP_1024_160:
+ case MODP_2048_224:
+ case MODP_2048_256:
+ case ECP_192_BIT:
+ case ECP_224_BIT:
+ case ECP_256_BIT:
+ case ECP_384_BIT:
+ case ECP_521_BIT:
+ case ECP_224_BP:
+ case ECP_256_BP:
+ case ECP_384_BP:
+ case ECP_512_BP:
+ 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 +629,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 +773,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 +801,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 +829,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 +851,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 +873,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 +921,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;
}