From c2a7f26ecf8caec125146f4f3f186bbf9b4a8acf Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Tue, 16 Jul 2024 23:58:39 +0900 Subject: [PATCH 1/5] build: Add egg-fips module This adds a new egg-fips module, which provides access to the system FIPS mode, so we can conditionalize used algorithms based on that. Signed-off-by: Daiki Ueno --- egg/egg-fips-gnutls.c | 36 ++++++++++++++++++++++++++++++++++++ egg/egg-fips-libgcrypt.c | 33 +++++++++++++++++++++++++++++++++ egg/egg-fips.h | 31 +++++++++++++++++++++++++++++++ egg/meson.build | 2 ++ 4 files changed, 102 insertions(+) create mode 100644 egg/egg-fips-gnutls.c create mode 100644 egg/egg-fips-libgcrypt.c create mode 100644 egg/egg-fips.h diff --git a/egg/egg-fips-gnutls.c b/egg/egg-fips-gnutls.c new file mode 100644 index 00000000..c10ba312 --- /dev/null +++ b/egg/egg-fips-gnutls.c @@ -0,0 +1,36 @@ +/* + * gcr + * + * Copyright (C) 2024 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include "config.h" + +#include "egg-fips.h" + +#include + +EggFipsMode +egg_fips_get_mode (void) +{ + return gnutls_fips140_mode_enabled (); +} + +void +egg_fips_set_mode (EggFipsMode mode) +{ + gnutls_fips140_set_mode (mode, GNUTLS_FIPS140_SET_MODE_THREAD); +} diff --git a/egg/egg-fips-libgcrypt.c b/egg/egg-fips-libgcrypt.c new file mode 100644 index 00000000..ce43e9cb --- /dev/null +++ b/egg/egg-fips-libgcrypt.c @@ -0,0 +1,33 @@ +/* + * gcr + * + * Copyright (C) 2024 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#include "config.h" +#include "egg-fips.h" + +EggFipsMode +egg_fips_get_mode (void) +{ + return EGG_FIPS_MODE_DISABLED; +} + +void +egg_fips_set_mode (EggFipsMode mode) +{ + (void)mode; +} diff --git a/egg/egg-fips.h b/egg/egg-fips.h new file mode 100644 index 00000000..b1e9175e --- /dev/null +++ b/egg/egg-fips.h @@ -0,0 +1,31 @@ +/* + * gcr + * + * Copyright (C) 2024 Red Hat, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see . + */ + +#ifndef EGG_FIPS_H_ +#define EGG_FIPS_H_ + +typedef enum { + EGG_FIPS_MODE_DISABLED = 0, + /* Other values are specific to each backend */ +} EggFipsMode; + +EggFipsMode egg_fips_get_mode (void); +void egg_fips_set_mode (EggFipsMode mode); + +#endif /* EGG_FIPS_H_ */ diff --git a/egg/meson.build b/egg/meson.build index 4dc166e8..e2ad4d51 100644 --- a/egg/meson.build +++ b/egg/meson.build @@ -23,6 +23,7 @@ if with_gcrypt libegg_sources += [ 'egg-crypto-libgcrypt.c', 'egg-dh-libgcrypt.c', + 'egg-fips-libgcrypt.c', 'egg-hkdf-libgcrypt.c', 'egg-libgcrypt.c', 'egg-openssl.c', @@ -32,6 +33,7 @@ elif with_gnutls libegg_sources += [ 'egg-crypto-gnutls.c', 'egg-dh-gnutls.c', + 'egg-fips-gnutls.c', 'egg-hkdf-gnutls.c', ] endif -- GitLab From d9819c2b2198a7834c4c53ecde0413265aee079b Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Wed, 17 Jul 2024 00:00:44 +0900 Subject: [PATCH 2/5] gcr: Skip non-compliant parser tests under FIPS Signed-off-by: Daiki Ueno --- gcr/test-parser.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/gcr/test-parser.c b/gcr/test-parser.c index 90a8d10c..161a08d0 100644 --- a/gcr/test-parser.c +++ b/gcr/test-parser.c @@ -23,6 +23,7 @@ #include "config.h" #include "egg/egg-error.h" +#include "egg/egg-fips.h" #include "egg/egg-secure-memory.h" #include "egg/egg-testing.h" @@ -334,6 +335,7 @@ main (int argc, char **argv) gchar *lower; gchar *test; int ret; + EggFipsMode fips_mode; g_test_init (&argc, &argv, NULL); g_set_prgname ("test-parser"); @@ -342,6 +344,8 @@ main (int argc, char **argv) dir = g_dir_open (SRCDIR "/gcr/fixtures", 0, &error); g_assert_no_error (error); + fips_mode = egg_fips_get_mode (); + for (;;) { filename = g_dir_read_name (dir); if (!filename) @@ -349,6 +353,23 @@ main (int argc, char **argv) if (filename[0] == '.') continue; + if (fips_mode && + (g_str_equal (filename, "der-key-PBE-MD5-DES.p8") || + g_str_equal (filename, "der-key-PBE-SHA1-3DES.p8") || + g_str_equal (filename, "der-key-PBE-SHA1-DES.p8") || + g_str_equal (filename, "der-key-PBE-SHA1-RC2-40.p8") || + g_str_equal (filename, "der-key-PBE-SHA1-RC4-128.p8") || + g_str_equal (filename, "der-key-encrypted-pkcs5.p8") || + g_str_equal (filename, "der-key-v2-des.p8") || + g_str_equal (filename, "der-key-v2-des3.p8") || + g_str_equal (filename, "email.p12") || + g_str_equal (filename, "pem-pkcs8.key") || + g_str_equal (filename, "pem-rsa-enc.key") || + g_str_equal (filename, "personal.p12") || + g_str_equal (filename, "unclient.p12") || + g_str_equal (filename, "usr0052-firefox.p12"))) + continue; + #ifdef WITH_GNUTLS #if GNUTLS_VERSION_NUMBER < 0x030805 /* Not yet supported in GnuTLS */ -- GitLab From 41818b8cf054c9d33e295e30dec18d638f8ccc79 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Wed, 17 Jul 2024 00:01:55 +0900 Subject: [PATCH 3/5] gcr: Tolerate non-approved DH parameter usage in FIPS mode The GcrSecretExchange protocol uses a weak Diffie-Hellman parameters which are not approved by FIPS. While this is not ideal, the protocol is not designed as a general protection mechanism of data in transit, but just as a safety net against when the dbus-daemon (or dbus-broker) crashes and dumps a core, and thus bumping the protocol to use a larger DH group would be overkill. This patch temporarily disables the FIPS check around the GnuTLS DH API calls to avoid errors. Signed-off-by: Daiki Ueno --- gcr/gcr-secret-exchange.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/gcr/gcr-secret-exchange.c b/gcr/gcr-secret-exchange.c index 7c83ac13..943b2afe 100644 --- a/gcr/gcr-secret-exchange.c +++ b/gcr/gcr-secret-exchange.c @@ -23,6 +23,7 @@ #include "egg/egg-crypto.h" #include "egg/egg-dh.h" +#include "egg/egg-fips.h" #include "egg/egg-hkdf.h" #include "egg/egg-padding.h" @@ -597,6 +598,7 @@ gcr_secret_exchange_default_generate_exchange_key (GcrSecretExchange *exchange, { GcrSecretExchangeDefault *data = exchange->pv->default_exchange; GBytes *buffer; + EggFipsMode fips_mode; g_debug ("generating public key"); @@ -615,9 +617,14 @@ gcr_secret_exchange_default_generate_exchange_key (GcrSecretExchange *exchange, egg_dh_privkey_free (data->priv); data->priv = NULL; + fips_mode = egg_fips_get_mode (); + egg_fips_set_mode (EGG_FIPS_MODE_DISABLED); if (!egg_dh_gen_pair (data->params, 0, - &data->pub, &data->priv)) + &data->pub, &data->priv)) { + egg_fips_set_mode (fips_mode); g_return_val_if_reached (FALSE); + } + egg_fips_set_mode (fips_mode); buffer = egg_dh_pubkey_export (data->pub); g_return_val_if_fail (buffer != NULL, FALSE); @@ -634,6 +641,7 @@ gcr_secret_exchange_default_derive_transport_key (GcrSecretExchange *exchange, GBytes *buffer; egg_dh_pubkey *peer_pubkey; GBytes *ikm; + EggFipsMode fips_mode; g_debug ("deriving transport key"); @@ -644,7 +652,10 @@ gcr_secret_exchange_default_derive_transport_key (GcrSecretExchange *exchange, g_bytes_unref (buffer); /* Build up a key we can use */ + fips_mode = egg_fips_get_mode (); + egg_fips_set_mode (EGG_FIPS_MODE_DISABLED); ikm = egg_dh_gen_secret (peer_pubkey, data->priv, data->params); + egg_fips_set_mode (fips_mode); g_return_val_if_fail (ikm != NULL, FALSE); egg_dh_pubkey_free (peer_pubkey); -- GitLab From a1c2fc89a787e23d1dc023298023dc620e318dba Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Wed, 17 Jul 2024 09:51:31 +0900 Subject: [PATCH 4/5] .gitlab-ci.yml: Call meson setup with -Dcrypto option Signed-off-by: Daiki Ueno --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7dc97393..49162969 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,7 +23,7 @@ fedora:Werror: - dnf upgrade -y --enablerepo=updates-testing --refresh --advisory=FEDORA-2024-f69ecb0511 - dnf builddep -y gcr script: - - meson setup _build -Dwerror=true -Dc_args=-Wno-error=deprecated-declarations -Dgtk_doc=false + - meson setup _build -Dwerror=true -Dc_args=-Wno-error=deprecated-declarations -Dgtk_doc=false -Dcrypto=$CRYPTO - meson compile -C _build - dbus-run-session -- meson test -C _build artifacts: @@ -49,7 +49,7 @@ fedora:asan: - dnf upgrade -y --enablerepo=updates-testing --refresh --advisory=FEDORA-2024-f69ecb0511 - dnf builddep -y gcr script: - - meson setup _build -Db_sanitize=address -Dgtk_doc=false + - meson setup _build -Db_sanitize=address -Dgtk_doc=false -Dcrypto=$CRYPTO - export G_SLICE=always-malloc G_DEBUG=gc-friendly ASAN_OPTIONS=abort_on_error=1:fast_unwind_on_malloc=0 - dbus-run-session -- meson test -C _build allow_failure: true @@ -74,7 +74,7 @@ fedora:ubsan: - dnf upgrade -y --enablerepo=updates-testing --refresh --advisory=FEDORA-2024-f69ecb0511 - dnf builddep -y gcr script: - - meson setup _build -Db_sanitize=undefined -Dgtk_doc=false + - meson setup _build -Db_sanitize=undefined -Dgtk_doc=false -Dcrypto=$CRYPTO - dbus-run-session -- meson test -C _build artifacts: name: "gcr-ubsan-${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}" -- GitLab From e4f4bd8024642b3c1b0f932abc6bba2bd19be80f Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Wed, 17 Jul 2024 10:15:57 +0900 Subject: [PATCH 5/5] .gitlab-ci.yml: Exercise -Dcrypto=gnutls build in FIPS mode Signed-off-by: Daiki Ueno --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 49162969..d1112e5e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,7 @@ variables: matrix: - CRYPTO: libgcrypt - CRYPTO: gnutls + GNUTLS_FORCE_FIPS_MODE: [0, 1] fedora:Werror: image: fedora:latest -- GitLab