From 24807307831943ad3147c287daa33d546873e1ce Mon Sep 17 00:00:00 2001 From: Michael Catanzaro Date: Wed, 23 Jun 2021 08:56:04 -0500 Subject: [PATCH] Update GHmac patchset and reenable glib2-static Resolves: #1971823 --- glib2.spec | 32 +-- gnutls-hmac.patch | 481 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 464 insertions(+), 49 deletions(-) diff --git a/glib2.spec b/glib2.spec index e7d0e72..52576cf 100644 --- a/glib2.spec +++ b/glib2.spec @@ -1,17 +1,16 @@ Name: glib2 Version: 2.68.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: A library of handy utility functions License: LGPLv2+ URL: http://www.gtk.org Source0: http://download.gnome.org/sources/glib/2.68/glib-%{version}.tar.xz -%if 0%{?rhel} -# Required for RHEL core crypto components policy. +# Required for RHEL core crypto components policy. Good for Fedora too. +# https://bugzilla.redhat.com/show_bug.cgi?id=1630260 # https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903 Patch0: gnutls-hmac.patch -%endif # Add patches to move applications into systemd scopes in compliance with # https://systemd.io/DESKTOP_ENVIRONMENTS/ @@ -31,10 +30,6 @@ BuildRequires: libselinux-devel BuildRequires: meson # for sys/sdt.h BuildRequires: systemtap-sdt-devel -%if 0%{?rhel} -# For gnutls-hmac.patch -BuildRequires: pkgconfig(gnutls) -%endif BuildRequires: pkgconfig(libelf) BuildRequires: pkgconfig(libffi) BuildRequires: pkgconfig(libpcre) @@ -43,6 +38,15 @@ BuildRequires: pkgconfig(sysprof-capture-4) BuildRequires: pkgconfig(zlib) BuildRequires: python3-devel +# For gnutls-hmac.patch. We now dlopen libgnutls.so.30 so that we can build a +# static glib2 without depending on a static build of GnuTLS as well. This will +# ensure we notice if the GnuTLS soname bumps, so that we can update our patch. +%if 0%{?__isa_bits} == 64 +Requires: libgnutls.so.30()(64bit) +%else +Requires: libgnutls.so.30 +%endif + # for GIO content-type support Recommends: shared-mime-info @@ -79,14 +83,12 @@ BuildArch: noarch %description doc The glib2-doc package includes documentation for the GLib library. -%if !0%{?rhel} %package static Summary: glib static Requires: %{name}-devel = %{version}-%{release} %description static The %{name}-static subpackage contains static libraries for %{name}. -%endif %package tests Summary: Tests for the glib2 package @@ -114,12 +116,8 @@ rm glib/pcre/*.[ch] -Dglib_debug=disabled \ -Dgtk_doc=true \ -Dinstalled_tests=true \ -%if 0%{?rhel} -Dgnutls=true \ -%endif -%if !0%{?rhel} --default-library=both \ -%endif %{nil} %meson_build @@ -229,20 +227,22 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas &> /dev/null || : %files doc %{_datadir}/gtk-doc/ -%if !0%{?rhel} %files static %{_libdir}/libgio-2.0.a %{_libdir}/libglib-2.0.a %{_libdir}/libgmodule-2.0.a %{_libdir}/libgobject-2.0.a %{_libdir}/libgthread-2.0.a -%endif %files tests %{_libexecdir}/installed-tests %{_datadir}/installed-tests %changelog +* Wed Jun 23 2021 Michael Catanzaro - 2.68.2-2 +- Update GHmac patchset and reenable glib2-static +- Resolves: #1971823 + * Wed May 19 2021 Michael Catanzaro - 2.68.2-1 - Update to 2.68.2 - Resolves: #1961039 diff --git a/gnutls-hmac.patch b/gnutls-hmac.patch index 5d193f4..b6c3dc4 100644 --- a/gnutls-hmac.patch +++ b/gnutls-hmac.patch @@ -1,7 +1,7 @@ -From 12e9cd51eb0ef07c3554cd035f92d8b7b5b82304 Mon Sep 17 00:00:00 2001 +From 86412ea2265ae018ba6146d525cafce78782c0fc Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 7 Jun 2019 18:44:43 +0000 -Subject: [PATCH 1/2] ghmac: Split off wrapper functions into ghmac-utils.c +Subject: [PATCH 1/4] ghmac: Split off wrapper functions into ghmac-utils.c Prep for adding a GnuTLS HMAC implementation; these are just utility functions that call the "core" API. @@ -284,10 +284,10 @@ index 49fd272f0..4f181f21f 100644 - (const guchar *) str, length); -} diff --git a/glib/meson.build b/glib/meson.build -index 8c18e6de4..329b8d197 100644 +index 28bfae200..0a37d19ea 100644 --- a/glib/meson.build +++ b/glib/meson.build -@@ -253,6 +253,7 @@ glib_sources = files( +@@ -254,6 +254,7 @@ glib_sources = files( 'ggettext.c', 'ghash.c', 'ghmac.c', @@ -296,13 +296,12 @@ index 8c18e6de4..329b8d197 100644 'ghostutils.c', 'giochannel.c', -- -2.29.2 +2.31.1 - -From 231ed985074af4a354405cf1961fabf9c60bce43 Mon Sep 17 00:00:00 2001 +From a5ee9970772e182de1c249ee514e87ef38e08360 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Fri, 7 Jun 2019 19:36:54 +0000 -Subject: [PATCH 2/2] Add a gnutls backend for GHmac +Subject: [PATCH 2/4] Add a gnutls backend for GHmac For RHEL we want apps to use FIPS-certified crypto libraries, and HMAC apparently counts as "keyed" and hence needs to @@ -316,18 +315,47 @@ Most distributors ship glib-networking built with GnuTLS, and most apps use glib-networking, so this isn't a net-new library in most cases. -mcatanzaro note: I've updated Colin's original patch to implement -g_hmac_copy() using gnutls_hmac_copy(), which didn't exist when Colin -developed this patch. +======================================================================= + +mcatanzaro note: + +I've updated Colin's original patch with several enhancements: + +Implement g_hmac_copy() using gnutls_hmac_copy(), which didn't exist +when Colin developed this patch. + +Removed use of GSlice + +Better error checking in g_hmac_new(). It is possible for +gnutls_hmac_init() to fail if running in FIPS mode and an MD5 digest is +requested. In this case, we should return NULL rather than returning a +broken GHmac with a NULL gnutls_hmac_hd_t. This was leading to a later +null pointer dereference inside gnutls_hmac_update(). Applications are +responsible for checking to ensure the return value of g_hmac_new() is +not NULL since it is annotated as nullable. Added documentation to +indicate this possibility. + +Properly handle length -1 in g_hmac_update(). This means we've been +given a NUL-terminated string and should use strlen(). GnuTLS doesn't +accept -1, so let's call strlen() ourselves. + +Crash the application with g_error() if gnutls_hmac() fails for any +reason. This is necessary because g_hmac_update() is not fallible, so we +have no way to indicate error. Crashing seems better than returning the +wrong result later when g_hmac_get_string() or g_hmac_get_digest() is +later called. (Those functions are also not fallible.) Fortunately, I +don't think this error should actually be hit in practice. + +https://gitlab.gnome.org/GNOME/glib/-/merge_requests/903 --- - glib/gchecksum.c | 9 ++- - glib/gchecksumprivate.h | 32 ++++++++ - glib/ghmac-gnutls.c | 164 ++++++++++++++++++++++++++++++++++++++++ - glib/ghmac.c | 3 + + glib/gchecksum.c | 9 +- + glib/gchecksumprivate.h | 32 +++++++ + glib/ghmac-gnutls.c | 187 ++++++++++++++++++++++++++++++++++++++++ + glib/ghmac.c | 15 ++++ glib/meson.build | 10 ++- meson.build | 7 ++ meson_options.txt | 5 ++ - 7 files changed, 224 insertions(+), 6 deletions(-) + 7 files changed, 259 insertions(+), 6 deletions(-) create mode 100644 glib/gchecksumprivate.h create mode 100644 glib/ghmac-gnutls.c @@ -406,10 +434,10 @@ index 000000000..86c7a3b61 \ No newline at end of file diff --git a/glib/ghmac-gnutls.c b/glib/ghmac-gnutls.c new file mode 100644 -index 000000000..f1a74a849 +index 000000000..a55375060 --- /dev/null +++ b/glib/ghmac-gnutls.c -@@ -0,0 +1,164 @@ +@@ -0,0 +1,186 @@ +/* ghmac.h - data hashing functions + * + * Copyright (C) 2011 Collabora Ltd. @@ -464,9 +492,11 @@ index 000000000..f1a74a849 + gsize key_len) +{ + gnutls_mac_algorithm_t algo; -+ GHmac *hmac = g_slice_new0 (GHmac); ++ GHmac *hmac = g_new0 (GHmac, 1); ++ int ret; ++ + hmac->ref_count = 1; -+ hmac->digest_type = digest_type; ++ hmac->digest_type = digest_type; + + switch (digest_type) + { @@ -489,7 +519,15 @@ index 000000000..f1a74a849 + g_return_val_if_reached (NULL); + } + -+ gnutls_hmac_init (&hmac->hmac, algo, key, key_len); ++ ret = gnutls_hmac_init (&hmac->hmac, algo, key, key_len); ++ if (ret != 0) ++ { ++ /* There is no way to report an error here, but one possible cause of ++ * failure is that the requested digest may be disabled by FIPS mode. ++ */ ++ g_free (hmac->hmac); ++ return NULL; ++ } + + return hmac; +} @@ -501,11 +539,15 @@ index 000000000..f1a74a849 + + g_return_val_if_fail (hmac != NULL, NULL); + -+ copy = g_slice_new0 (GHmac); ++ copy = g_new0 (GHmac, 1); + copy->ref_count = 1; + copy->digest_type = hmac->digest_type; + copy->hmac = gnutls_hmac_copy (hmac->hmac); + ++ /* g_hmac_copy is not allowed to fail, so we'll have to crash on error. */ ++ if (!copy->hmac) ++ g_error ("gnutls_hmac_copy failed"); ++ + return copy; +} + @@ -528,7 +570,7 @@ index 000000000..f1a74a849 + { + gnutls_hmac_deinit (hmac->hmac, NULL); + g_free (hmac->digest_str); -+ g_slice_free (GHmac, hmac); ++ g_free (hmac); + } +} + @@ -538,10 +580,18 @@ index 000000000..f1a74a849 + const guchar *data, + gssize length) +{ ++ int ret; ++ + g_return_if_fail (hmac != NULL); + g_return_if_fail (length == 0 || data != NULL); + -+ gnutls_hmac (hmac->hmac, data, length); ++ if (length == -1) ++ length = strlen ((const char *)data); ++ ++ /* g_hmac_update is not allowed to fail, so we'll have to crash on error. */ ++ ret = gnutls_hmac (hmac->hmac, data, length); ++ if (ret != 0) ++ g_error ("gnutls_hmac failed: %s", gnutls_strerror (ret)); +} + +const gchar * @@ -575,7 +625,7 @@ index 000000000..f1a74a849 + *digest_len = g_checksum_type_get_length (hmac->digest_type); +} diff --git a/glib/ghmac.c b/glib/ghmac.c -index 4f181f21f..c62d9ce4e 100644 +index 4f181f21f..0e39ea40a 100644 --- a/glib/ghmac.c +++ b/glib/ghmac.c @@ -33,6 +33,9 @@ @@ -588,11 +638,30 @@ index 4f181f21f..c62d9ce4e 100644 /** * SECTION:hmac +@@ -84,6 +87,18 @@ struct _GHmac + * Support for digests of type %G_CHECKSUM_SHA512 has been added in GLib 2.42. + * Support for %G_CHECKSUM_SHA384 was added in GLib 2.52. + * ++ * Note that #GHmac creation may fail, in which case this function will ++ * return %NULL. Since there is no error parameter, it is not possible ++ * to indicate why. ++ * ++ * In Fedora, CentOS Stream, and Red Hat Enterprise Linux, GLib is ++ * configured to use GnuTLS to implement #GHmac in order to support FIPS ++ * compliance. This introduces additional failure possibilities that are ++ * not present in upstream GLib. For example, the creation of a #GHmac ++ * will fail if @digest_type is %G_CHECKSUM_MD5 and the system is ++ * running in FIPS mode. #GHmac creation may also fail if GLib is unable ++ * to load GnuTLS. ++ * + * Returns: the newly created #GHmac, or %NULL. + * Use g_hmac_unref() to free the memory allocated by it. + * diff --git a/glib/meson.build b/glib/meson.build -index 329b8d197..2942a7e9b 100644 +index 0a37d19ea..b17c89dd9 100644 --- a/glib/meson.build +++ b/glib/meson.build -@@ -252,7 +252,6 @@ glib_sources = files( +@@ -253,7 +253,6 @@ glib_sources = files( 'gfileutils.c', 'ggettext.c', 'ghash.c', @@ -600,7 +669,7 @@ index 329b8d197..2942a7e9b 100644 'ghmac-utils.c', 'ghook.c', 'ghostutils.c', -@@ -308,6 +307,7 @@ glib_sources = files( +@@ -309,6 +308,7 @@ glib_sources = files( 'guriprivate.h', 'gutils.c', 'gutilsprivate.h', @@ -608,7 +677,7 @@ index 329b8d197..2942a7e9b 100644 'guuid.c', 'gvariant.c', 'gvariant-core.c', -@@ -352,6 +352,12 @@ else +@@ -353,6 +353,12 @@ else glib_dtrace_hdr = [] endif @@ -621,7 +690,7 @@ index 329b8d197..2942a7e9b 100644 pcre_static_args = [] if use_pcre_static_flag -@@ -378,7 +384,7 @@ libglib = library('glib-2.0', +@@ -379,7 +385,7 @@ libglib = library('glib-2.0', # intl.lib is not compatible with SAFESEH link_args : [noseh_link_args, glib_link_flags, win32_ldflags], include_directories : configinc, @@ -631,10 +700,10 @@ index 329b8d197..2942a7e9b 100644 objc_args : glib_c_args, ) diff --git a/meson.build b/meson.build -index 0d892fb2d..091029fea 100644 +index a0ee8b774..064dba800 100644 --- a/meson.build +++ b/meson.build -@@ -2078,6 +2078,13 @@ if host_system == 'linux' +@@ -2104,6 +2104,13 @@ if host_system == 'linux' glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found()) endif @@ -665,5 +734,351 @@ index 072765361..d2370042f 100644 type : 'boolean', value : false, -- -2.29.2 +2.31.1 +From cde56a63aa12ae7c30f85af7d058fa5e666aa2e9 Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Wed, 16 Jun 2021 20:35:00 -0500 +Subject: [PATCH 3/4] dlopen GnuTLS instead of linking directly + +I'd like to enable our GnuTLS GHmac patchset in Fedora in order to +ensure it is receiving sufficient real-world testing, since we've +discovered several bugs thus far. Problem is Fedora has one requirement +that RHEL does not: it needs to build glib as a static lib. This is +needed by QEMU in Fedora for complicated technical reasons that I don't +understand. However, nothing in RHEL needs it. This means we failed to +notice that glib2-static is broken in RHEL, because there is no +gnutls-static! We could fix this by adding a gnutls-static package, but +that seems like overkill, and adding more static libraries where they're +not truly necessary is not the direction we want to move in anyway. So +instead, let's just dlopen GnuTLS to sidestep this problem entirely. + +This would not be a good solution for upstream, but upstream has made +clear that this patchset is already non-upstreamable, so it will be fine +for our purposes. +--- + glib/ghmac-gnutls.c | 101 ++++++++++++++++++++++++++++++++++++++++++-- + glib/ghmac.c | 2 +- + glib/meson.build | 2 +- + meson.build | 6 +-- + 4 files changed, 102 insertions(+), 9 deletions(-) + +diff --git a/glib/ghmac-gnutls.c b/glib/ghmac-gnutls.c +index a55375060..0469d2bd0 100644 +--- a/glib/ghmac-gnutls.c ++++ b/glib/ghmac-gnutls.c +@@ -19,8 +19,8 @@ + + #include "config.h" + ++#include + #include +-#include + + #include "ghmac.h" + +@@ -31,13 +31,16 @@ + #include "gstrfuncs.h" + #include "gchecksumprivate.h" + #include "gtestutils.h" ++#include "gthread.h" + #include "gtypes.h" + #include "glibintl.h" + +-#ifndef HAVE_GNUTLS ++#ifndef USE_GNUTLS + #error "build configuration error" + #endif + ++typedef gpointer gnutls_hmac_hd_t; ++ + struct _GHmac + { + int ref_count; +@@ -46,15 +49,107 @@ struct _GHmac + gchar *digest_str; + }; + ++typedef enum ++{ ++ GNUTLS_MAC_MD5 = 2, ++ GNUTLS_MAC_SHA1 = 3, ++ GNUTLS_MAC_SHA256 = 6, ++ GNUTLS_MAC_SHA384 = 7, ++ GNUTLS_MAC_SHA512 = 8, ++} gnutls_mac_algorithm_t; ++ ++/* Why are we dlopening GnuTLS instead of linking to it directly? Because we ++ * want to be able to build GLib as a static library without depending on a ++ * static build of GnuTLS. QEMU depends on static linking with GLib, but Fedora ++ * does not ship a static build of GnuTLS, and this allows us to avoid changing ++ * that. ++ */ ++static int (*gnutls_hmac_init) (gnutls_hmac_hd_t *dig, gnutls_mac_algorithm_t algorithm, const void *key, size_t keylen); ++static gnutls_hmac_hd_t (*gnutls_hmac_copy) (gnutls_hmac_hd_t handle); ++static void (*gnutls_hmac_deinit) (gnutls_hmac_hd_t handle, void *digest); ++static int (*gnutls_hmac) (gnutls_hmac_hd_t handle, const void *ptext, size_t ptext_len); ++static void (*gnutls_hmac_output) (gnutls_hmac_hd_t handle, void *digest); ++static const char * (*gnutls_strerror) (int error); ++ ++static gsize gnutls_initialize_attempted = 0; ++static gboolean gnutls_initialize_successful = FALSE; ++ ++static void ++initialize_gnutls (void) ++{ ++ gpointer libgnutls; ++ ++ libgnutls = dlopen ("libgnutls.so.30", RTLD_LAZY | RTLD_GLOBAL); ++ if (!libgnutls) ++ { ++ g_warning ("Cannot use GHmac: failed to load libgnutls.so.30: %s", dlerror ()); ++ return; ++ } ++ ++ gnutls_hmac_init = dlsym (libgnutls, "gnutls_hmac_init"); ++ if (!gnutls_hmac_init) ++ { ++ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_init: %s", dlerror ()); ++ return; ++ } ++ ++ gnutls_hmac_copy = dlsym (libgnutls, "gnutls_hmac_copy"); ++ if (!gnutls_hmac_copy) ++ { ++ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_copy: %s", dlerror ()); ++ return; ++ } ++ ++ gnutls_hmac_deinit = dlsym (libgnutls, "gnutls_hmac_deinit"); ++ if (!gnutls_hmac_deinit) ++ { ++ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_deinit: %s", dlerror ()); ++ return; ++ } ++ ++ gnutls_hmac = dlsym (libgnutls, "gnutls_hmac"); ++ if (!gnutls_hmac) ++ { ++ g_warning ("Cannot use GHmac: failed to load gnutls_hmac: %s", dlerror ()); ++ return; ++ } ++ ++ gnutls_hmac_output = dlsym (libgnutls, "gnutls_hmac_output"); ++ if (!gnutls_hmac_output) ++ { ++ g_warning ("Cannot use GHmac: failed to load gnutls_hmac_output: %s", dlerror ()); ++ return; ++ } ++ ++ gnutls_strerror = dlsym (libgnutls, "gnutls_strerror"); ++ if (!gnutls_strerror) ++ { ++ g_warning ("Cannot use GHmac: failed to load gnutls_strerror: %s", dlerror ()); ++ return; ++ } ++ ++ gnutls_initialize_successful = TRUE; ++} ++ + GHmac * + g_hmac_new (GChecksumType digest_type, + const guchar *key, + gsize key_len) + { + gnutls_mac_algorithm_t algo; +- GHmac *hmac = g_new0 (GHmac, 1); ++ GHmac *hmac; + int ret; + ++ if (g_once_init_enter (&gnutls_initialize_attempted)) ++ { ++ initialize_gnutls (); ++ g_once_init_leave (&gnutls_initialize_attempted, 1); ++ } ++ ++ if (!gnutls_initialize_successful) ++ return NULL; ++ ++ hmac = g_new0 (GHmac, 1); + hmac->ref_count = 1; + hmac->digest_type = digest_type; + +diff --git a/glib/ghmac.c b/glib/ghmac.c +index 0e39ea40a..2d9be91b8 100644 +--- a/glib/ghmac.c ++++ b/glib/ghmac.c +@@ -33,7 +33,7 @@ + #include "gtypes.h" + #include "glibintl.h" + +-#ifdef HAVE_GNUTLS ++#ifdef USE_GNUTLS + #error "build configuration error" + #endif + +diff --git a/glib/meson.build b/glib/meson.build +index b17c89dd9..a015f7755 100644 +--- a/glib/meson.build ++++ b/glib/meson.build +@@ -385,7 +385,7 @@ libglib = library('glib-2.0', + # intl.lib is not compatible with SAFESEH + link_args : [noseh_link_args, glib_link_flags, win32_ldflags], + include_directories : configinc, +- dependencies : pcre_deps + libgnutls_dep + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep], ++ dependencies : pcre_deps + [thread_dep, librt] + libintl_deps + libiconv + platform_deps + [gnulib_libm_dependency, libm] + [libsysprof_capture_dep] + [libdl_dep], + c_args : glib_c_args, + objc_args : glib_c_args, + ) +diff --git a/meson.build b/meson.build +index 064dba800..7aae7dfea 100644 +--- a/meson.build ++++ b/meson.build +@@ -2104,11 +2104,9 @@ if host_system == 'linux' + glib_conf.set('HAVE_LIBMOUNT', libmount_dep.found()) + endif + +-# gnutls is used optionally by ghmac +-libgnutls_dep = [] ++# gnutls is used optionally by GHmac + if get_option('gnutls') +- libgnutls_dep = [dependency('gnutls', version : '>=3.6.9', required : true)] +- glib_conf.set('HAVE_GNUTLS', 1) ++ glib_conf.set('USE_GNUTLS', 1) + endif + + if host_system == 'windows' +-- +2.31.1 + +From b61ea19037287cae2e6152e9616767a691bf4af0 Mon Sep 17 00:00:00 2001 +From: Michael Catanzaro +Date: Wed, 16 Jun 2021 20:46:24 -0500 +Subject: [PATCH 4/4] Add test for GHmac in FIPS mode + +This will test a few problems that we hit recently: + +g_hmac_copy() is broken, https://bugzilla.redhat.com/show_bug.cgi?id=1786538 + +Crash in g_hmac_update() in FIPS mode, https://bugzilla.redhat.com/show_bug.cgi?id=1971533 + +Crash when passing -1 length to g_hmac_update() (discovered in #1971533) + +We'll also test to ensure MD5 fails, and stop compiling the other MD5 +tests. +--- + glib/tests/hmac.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + +diff --git a/glib/tests/hmac.c b/glib/tests/hmac.c +index 3ac3206df..6698c4d19 100644 +--- a/glib/tests/hmac.c ++++ b/glib/tests/hmac.c +@@ -1,7 +1,10 @@ ++#include "config.h" ++ + #include + #include + #include + ++#ifndef USE_GNUTLS + /* HMAC-MD5 test vectors as per RFC 2202 */ + + /* Test 1 */ +@@ -81,6 +84,7 @@ guint8 key_md5_test7[] = { + guint8 result_md5_test7[] = { + 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 0x1f, 0xb1, + 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e }; ++#endif + + /* HMAC-SHA1, HMAC-SHA256, HMAC-SHA384 and HMAC-SHA512 test vectors + * as per RFCs 2202 and 4868. +@@ -299,6 +303,7 @@ typedef struct { + gconstpointer result; + } HmacCase; + ++#ifndef USE_GNUTLS + HmacCase hmac_md5_tests[] = { + { G_CHECKSUM_MD5, key_md5_test1, 16, "Hi There", 8, result_md5_test1 }, + { G_CHECKSUM_MD5, "Jefe", 4, "what do ya want for nothing?", 28, +@@ -317,6 +322,7 @@ HmacCase hmac_md5_tests[] = { + 73, result_md5_test7 }, + { -1, NULL, 0, NULL, 0, NULL }, + }; ++#endif + + HmacCase hmac_sha1_tests[] = { + { G_CHECKSUM_SHA1, key_sha_test1, 20, "Hi There", 8, result_sha1_test1 }, +@@ -493,11 +499,44 @@ test_hmac_for_bytes (void) + g_bytes_unref (data); + } + ++#ifdef USE_GNUTLS ++static void ++test_gnutls_fips_mode (void) ++{ ++ GHmac *hmac; ++ GHmac *copy; ++ ++ /* No MD5 in FIPS mode. */ ++ hmac = g_hmac_new (G_CHECKSUM_MD5, "abc123", sizeof ("abc123")); ++ g_assert_null (hmac); ++ ++ /* SHA-256 should be good. */ ++ hmac = g_hmac_new (G_CHECKSUM_SHA256, "abc123", sizeof ("abc123")); ++ g_assert_nonnull (hmac); ++ ++ /* Ensure g_hmac_update() does not crash when called with -1. */ ++ g_hmac_update (hmac, "You win again, gravity!", -1); ++ ++ /* Ensure g_hmac_copy() does not crash. */ ++ copy = g_hmac_copy (hmac); ++ g_assert_nonnull (hmac); ++ g_hmac_unref (hmac); ++ ++ g_assert_cmpstr (g_hmac_get_string (copy), ==, "795ba6900bcb22e8ce65c2ec02db4e85697da921deb960ee3143bf88a4a60f83"); ++ g_hmac_unref (copy); ++} ++#endif ++ + int + main (int argc, + char **argv) + { + int i; ++ ++#ifdef USE_GNUTLS ++ g_setenv ("GNUTLS_FORCE_FIPS_MODE", "1", FALSE); ++#endif ++ + g_test_init (&argc, &argv, NULL); + + for (i = 0 ; hmac_sha1_tests[i].key_len > 0 ; i++) +@@ -532,6 +571,7 @@ main (int argc, + g_free (name); + } + ++#ifndef USE_GNUTLS + for (i = 0 ; hmac_md5_tests[i].key_len > 0 ; i++) + { + gchar *name = g_strdup_printf ("/hmac/md5-%d", i + 1); +@@ -539,6 +579,7 @@ main (int argc, + (void (*)(const void *)) test_hmac); + g_free (name); + } ++#endif + + g_test_add_func ("/hmac/ref-unref", test_hmac_ref_unref); + g_test_add_func ("/hmac/copy", test_hmac_copy); +@@ -546,5 +587,9 @@ main (int argc, + g_test_add_func ("/hmac/for-string", test_hmac_for_string); + g_test_add_func ("/hmac/for-bytes", test_hmac_for_bytes); + ++#ifdef USE_GNUTLS ++ g_test_add_func ("/hmac/gnutls-fips-mode", test_gnutls_fips_mode); ++#endif ++ + return g_test_run (); + } +-- +2.31.1