From ac1367056d59a86a5f8e8a446f8a6302fed4cf6b Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Mon, 22 Jul 2024 16:31:50 +0900 Subject: [PATCH] session: Tolerate non-approved DH parameter usage in FIPS mode The SecretSession 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 --- egg/egg-fips-gnutls.c | 36 ++++++++++++++++++++++++++++++++++++ egg/egg-fips-libgcrypt.c | 33 +++++++++++++++++++++++++++++++++ egg/egg-fips.h | 31 +++++++++++++++++++++++++++++++ egg/meson.build | 2 ++ libsecret/secret-session.c | 9 +++++++++ 5 files changed, 111 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 0000000..c883f2a --- /dev/null +++ b/egg/egg-fips-gnutls.c @@ -0,0 +1,36 @@ +/* + * libsecret + * + * 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 0000000..fc22716 --- /dev/null +++ b/egg/egg-fips-libgcrypt.c @@ -0,0 +1,33 @@ +/* + * libsecret + * + * 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 0000000..092c91a --- /dev/null +++ b/egg/egg-fips.h @@ -0,0 +1,31 @@ +/* + * libsecret + * + * 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 32072f5..f3ae3a4 100644 --- a/egg/meson.build +++ b/egg/meson.build @@ -18,6 +18,7 @@ if with_crypto if with_gcrypt libegg_sources += [ 'egg-dh-libgcrypt.c', + 'egg-fips-libgcrypt.c', 'egg-hkdf-libgcrypt.c', 'egg-keyring1-libgcrypt.c', 'egg-libgcrypt.c', @@ -25,6 +26,7 @@ if with_crypto elif with_gnutls libegg_sources += [ 'egg-dh-gnutls.c', + 'egg-fips-gnutls.c', 'egg-hkdf-gnutls.c', 'egg-keyring1-gnutls.c', ] diff --git a/libsecret/secret-session.c b/libsecret/secret-session.c index 375984c..8b52e58 100644 --- a/libsecret/secret-session.c +++ b/libsecret/secret-session.c @@ -19,6 +19,7 @@ #ifdef WITH_CRYPTO #include "egg/egg-dh.h" +#include "egg/egg-fips.h" #include "egg/egg-hkdf.h" #endif @@ -78,6 +79,7 @@ request_open_session_aes (SecretSession *session) { GBytes *buffer; GVariant *argument; + EggFipsMode fips_mode; g_assert (session->params == NULL); g_assert (session->privat == NULL); @@ -98,9 +100,12 @@ request_open_session_aes (SecretSession *session) g_printerr ("\n"); #endif + fips_mode = egg_fips_get_mode (); + egg_fips_set_mode (EGG_FIPS_MODE_DISABLED); if (!egg_dh_gen_pair (session->params, 0, &session->publi, &session->privat)) g_return_val_if_reached (NULL); + egg_fips_set_mode (fips_mode); buffer = egg_dh_pubkey_export (session->publi); g_return_val_if_fail (buffer != NULL, NULL); @@ -121,6 +126,7 @@ response_open_session_aes (SecretSession *session, const gchar *sig; egg_dh_pubkey *peer; GBytes *ikm; + EggFipsMode fips_mode; sig = g_variant_get_type_string (response); g_return_val_if_fail (sig != NULL, FALSE); @@ -147,7 +153,10 @@ response_open_session_aes (SecretSession *session, g_printerr ("\n"); #endif + fips_mode = egg_fips_get_mode (); + egg_fips_set_mode (EGG_FIPS_MODE_DISABLED); ikm = egg_dh_gen_secret (peer, session->privat, session->params); + egg_fips_set_mode (fips_mode); egg_dh_pubkey_free (peer); #if 0