]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added support for fips states.
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 11 Nov 2013 17:07:17 +0000 (18:07 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 27 Nov 2013 10:41:05 +0000 (11:41 +0100)
This implies that when in FIPS mode and the library is not in operational
state (i.e., all self checks succeeded), crypto functionality of the library will fail.
This includes:
* API functions of gnutls/crypto.h
* API functions of gnutls/abstract.h
* API functions of gnutls/x509.h
* gnutls_init()
* API functions of gnutls/xssl.h

21 files changed:
configure.ac
lib/Makefile.am
lib/fips.c [new file with mode: 0644]
lib/fips.h [new file with mode: 0644]
lib/gnutls_cipher_int.c
lib/gnutls_errors.c
lib/gnutls_global.c
lib/gnutls_hash_int.c
lib/gnutls_privkey.c
lib/gnutls_pubkey.c
lib/gnutls_state.c
lib/includes/gnutls/gnutls.h.in
lib/pkcs11_privkey.c
lib/random.c
lib/x509/common.h
lib/x509/crl.c
lib/x509/crq.c
lib/x509/privkey.c
lib/x509/verify-high.c
lib/x509/x509.c
lib/xssl.c

index 8387847ed6668a8e67d0c1287c1e71b96b9eddad..7681b56b79620a20fdc208712e434bf1754f1479 100644 (file)
@@ -125,6 +125,16 @@ AM_CONDITIONAL(HAVE_GCC, test "$GCC" = "yes")
 AC_ARG_ENABLE(self-checks,
   AS_HELP_STRING([--enable-self-checks], [enable self checking functionality]),
     enable_self_checks=$enableval, enable_self_checks=no)
+
+AC_ARG_ENABLE(fips140-mode,
+  AS_HELP_STRING([--enable-fips140-mode], [enable FIPS140-2 mode (implies self checks)]),
+    enable_fips=$enableval, enable_fips=no)
+AM_CONDITIONAL(ENABLE_FIPS140, test "$enable_fips" = "yes")
+if [ test "$enable_fips" = "yes" ];then
+   enable_self_checks=yes
+   AC_DEFINE([ENABLE_FIPS140], 1, [Enable FIPS140-2 mode])
+fi
+
 AM_CONDITIONAL(ENABLE_SELF_CHECKS, test "$enable_self_checks" = "yes")
 if [ test "$enable_self_checks" = "yes" ];then
    AC_DEFINE([ENABLE_SELF_CHECKS], 1, [Self checks are included in the library])
@@ -729,6 +739,7 @@ if features are disabled)
   RSA-EXPORT compat:    $ac_enable_rsa_export
   Unicode support:      $ac_have_unicode
   Self checks:          $enable_self_checks
+  FIPS140 mode:         $enable_fips
 ])
 
 AC_MSG_NOTICE([Optional applications:
index 2f5d5e5fea2dde835f96b8ace0e77019e76f2f19..62deb9b6dfdc66ac066f1ccbd1f93ab15a3ce159 100644 (file)
@@ -78,7 +78,7 @@ COBJECTS = gnutls_range.c gnutls_record.c \
        gnutls_rsa_export.c gnutls_helper.c gnutls_supplemental.c       \
        random.c crypto-api.c gnutls_privkey.c gnutls_pcert.c           \
        gnutls_pubkey.c locks.c gnutls_dtls.c system_override.c \
-       crypto-backend.c verify-tofu.c pin.c tpm.c
+       crypto-backend.c verify-tofu.c pin.c tpm.c fips.c
 
 if ENABLE_SELF_CHECKS
 COBJECTS += crypto-selftests.c crypto-selftests-pk.c
@@ -105,7 +105,7 @@ HFILES = abstract_int.h debug.h gnutls_compress.h gnutls_cipher.h   \
        gnutls_state.h gnutls_x509.h crypto-backend.h                   \
        gnutls_srp.h auth/srp.h auth/srp_passwd.h       \
        gnutls_helper.h gnutls_supplemental.h crypto.h random.h system.h\
-       locks.h gnutls_mbuffers.h gnutls_ecc.h pin.h 
+       locks.h gnutls_mbuffers.h gnutls_ecc.h pin.h fips.h
 
 if ENABLE_PKCS11
 HFILES += pkcs11_int.h
diff --git a/lib/fips.c b/lib/fips.c
new file mode 100644 (file)
index 0000000..726dae6
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS 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 library 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifdef ENABLE_FIPS140
+
+# include <gnutls_int.h>
+# include <gnutls/gnutls.h>
+# include <unistd.h>
+
+unsigned int _gnutls_fips_mode = STATE_POWERON;
+
+unsigned _gnutls_fips_mode_enabled(void)
+{
+       /* FIXME: There are some subtle differences here. Check it out later */
+       if (access("/proc/sys/crypto/fips_enabled", R_OK) == 0 &&
+               access("/etc/system-fips", R_OK) == 0)
+               return 1;
+       
+       return 0;
+}
+
+int _gnutls_fips_perform_self_checks(void)
+{
+       _gnutls_switch_fips_state(FIPS_STATE_SELFTEST);
+       
+       /* Tests the FIPS algorithms */
+       
+       /* ciphers */
+       ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_128_CBC);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_192_CBC);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_CBC);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+       
+       ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_3DES_CBC);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_128_GCM);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_GCM);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       /* MAC (includes message digest test) */
+       ret = gnutls_mac_self_test(0, GNUTLS_MAC_MD5);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA1);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA224);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA256);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA384);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA512);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       /* PK */
+       ret = gnutls_pk_self_test(0, GNUTLS_PK_RSA);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       ret = gnutls_pk_self_test(0, GNUTLS_PK_ECDSA);
+       if (ret < 0) {
+               gnutls_assert();
+               goto error;
+       }
+
+       return 0;
+error:
+       _gnutls_switch_fips_state(FIPS_STATE_ERROR);
+       return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERR);
+}
+
+#endif
diff --git a/lib/fips.h b/lib/fips.h
new file mode 100644 (file)
index 0000000..9cd17a4
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2013 Red Hat
+ *
+ * Author: Nikos Mavrogiannopoulos
+ *
+ * This file is part of GnuTLS.
+ *
+ * The GnuTLS 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 library 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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+#ifndef FIPS_H
+# define FIPS_H
+
+#include <gnutls/gnutls.h>
+
+typedef enum {
+  FIPS_STATE_POWERON,
+  FIPS_STATE_INIT,
+  FIPS_STATE_SELFTEST,
+  FIPS_STATE_OPERATIONAL,
+  FIPS_STATE_ERROR,
+  FIPS_STATE_SHUTDOWN
+} gnutls_fips_state_t;
+
+#ifdef ENABLE_FIPS140
+
+/* do not access directly */
+extern unsigned int _gnutls_fips_mode;
+
+inline static 
+void _gnutls_switch_fips_state(gnutls_fips_state_t state)
+{
+       _gnutls_fips_mode = state;
+}
+
+inline static gnutls_fips_state_t _gnutls_get_fips_state(void)
+{
+       return _gnutls_fips_mode;
+}
+
+int _gnutls_fips_perform_self_checks(void);
+unsigned _gnutls_fips_mode_enabled(void);
+
+# define FAIL_IF_FIPS_ERROR \
+       if (_gnutls_get_fips_state() != FIPS_STATE_OPERATIONAL) return GNUTLS_E_LIB_IN_ERROR_STATE
+
+void _gnutls_switch_fips_state(gnutls_fips_state_t state);
+
+#else
+
+# define _gnutls_switch_fips_state(x) 0
+# define _gnutls_get_fips_state() STATE_OPERATIONAL
+# define FAIL_IF_FIPS_ERROR 0
+# define _gnutls_fips_perform_self_checks() 0
+# define _gnutls_fips_mode_enabled() 0
+#endif
+
+#endif /* FIPS_H */
index d6483ab2d8c44ccb17b43b904229747072d08e57..184156725e60daab2e7b513a91b0369931c7f23d 100644 (file)
@@ -27,6 +27,7 @@
 #include <gnutls_datum.h>
 #include <gnutls/crypto.h>
 #include <crypto.h>
+#include <fips.h>
 #include <algorithms.h>
 
 #define SR(x, cleanup) if ( (x)<0 ) { \
@@ -61,6 +62,8 @@ _gnutls_cipher_init(cipher_hd_st * handle, const cipher_entry_st * e,
 
        if (unlikely(e == NULL || e->id == GNUTLS_CIPHER_NULL))
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
+               
+        FAIL_IF_FIPS_ERROR;
 
        handle->e = e;
 
@@ -144,6 +147,8 @@ int _gnutls_auth_cipher_init(auth_cipher_hd_st * handle,
        if (unlikely(e == NULL))
                return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
 
+        FAIL_IF_FIPS_ERROR;
+
        memset(handle, 0, sizeof(*handle));
 
        if (e->id != GNUTLS_CIPHER_NULL) {
index 3c932859fa303fd9440c9a4f4ce90f0336a22ec9..2c46552799a8c650b847cee6a64b689c5b0402a4 100644 (file)
@@ -396,6 +396,12 @@ static const gnutls_error_entry error_algorithms[] = {
        ERROR_ENTRY(N_
                    ("No common application protocol could be negotiated."),
                    GNUTLS_E_NO_APPLICATION_PROTOCOL, 1),
+       ERROR_ENTRY(N_("Error while performing self checks."),
+                   GNUTLS_E_SELF_TEST_ERROR, 1),
+       ERROR_ENTRY(N_("There is no self test for this algorithm."),
+                   GNUTLS_E_NO_SELF_TEST, 1),
+       ERROR_ENTRY(N_("An error has been detected in the library and cannot continue operations."),
+                   GNUTLS_E_LIB_IN_ERROR_STATE, 1),
        {NULL, NULL, 0, 0}
 };
 
index 6dbc534dc024504fdf97ea0dcf050a7d616e9721..12912f73d96dbb2cc8bec11cda1234c86b095854 100644 (file)
@@ -32,6 +32,7 @@
 #include <system.h>
 #include <accelerated/cryptodev.h>
 #include <accelerated/accelerated.h>
+#include <fips.h>
 
 #include "sockets.h"
 #include "gettext.h"
@@ -201,6 +202,8 @@ int gnutls_global_init(void)
 
        if (_gnutls_init++)
                goto out;
+
+       _gnutls_switch_fips_state(FIPS_STATE_INIT);
                
        e = getenv("GNUTLS_DEBUG_LEVEL");
        if (e != NULL) {
@@ -279,8 +282,17 @@ int gnutls_global_init(void)
 #endif
 
        _gnutls_cryptodev_init();
+       
+       if (_gnutls_fips_mode_enabled()) {
+               result = _gnutls_fips_perform_self_checks();
+               if (result < 0) {
+                       gnutls_assert();
+                       goto out;
+               }
+               _gnutls_switch_fips_state(FIPS_STATE_OPERATIONAL);
+       }
 
-      out:
+out:
        return result;
 }
 
index 7f16a54d3e392326e786a7578ea8fccf5db5f239..ddeff10bdb60fe24b36b5cb1682fc1a56d6cde59 100644 (file)
 #include <gnutls_hash_int.h>
 #include <gnutls_errors.h>
 #include <algorithms.h>
+#include <fips.h>
 
 int _gnutls_hash_init(digest_hd_st * dig, const mac_entry_st * e)
 {
        int result;
        const gnutls_crypto_digest_st *cc = NULL;
 
+       FAIL_IF_FIPS_ERROR;
+
        dig->e = e;
 
        /* check if a digest has been registered 
@@ -84,6 +87,8 @@ _gnutls_hash_fast(gnutls_digest_algorithm_t algorithm,
 {
        int ret;
        const gnutls_crypto_digest_st *cc = NULL;
+       
+       FAIL_IF_FIPS_ERROR;
 
        /* check if a digest has been registered 
         */
@@ -117,6 +122,8 @@ _gnutls_mac_fast(gnutls_mac_algorithm_t algorithm, const void *key,
        int ret;
        const gnutls_crypto_mac_st *cc = NULL;
 
+       FAIL_IF_FIPS_ERROR;
+
        /* check if a digest has been registered 
         */
        cc = _gnutls_get_crypto_mac(algorithm);
@@ -164,6 +171,8 @@ _gnutls_mac_init(mac_hd_st * mac, const mac_entry_st * e,
        int result;
        const gnutls_crypto_mac_st *cc = NULL;
 
+       FAIL_IF_FIPS_ERROR;
+
        mac->e = e;
        mac->mac_len = _gnutls_mac_get_algo_len(e);
 
@@ -245,6 +254,8 @@ _gnutls_mac_init_ssl3(digest_hd_st * ret, const mac_entry_st * e,
        uint8_t ipad[48];
        int padsize, result;
 
+       FAIL_IF_FIPS_ERROR;
+
        padsize = get_padsize((gnutls_digest_algorithm_t) e->id);
        if (padsize == 0) {
                gnutls_assert();
index 48afb06604561bc0bd865b837fc1713e334fa368..81507fa7f90c104247bc3bfec3ff03c4d8453257 100644 (file)
@@ -33,6 +33,7 @@
 #include <openpgp/gnutls_openpgp.h>
 #include <gnutls_sig.h>
 #include <algorithms.h>
+#include <fips.h>
 #include <abstract_int.h>
 
 /**
@@ -237,6 +238,8 @@ _gnutls_privkey_get_public_mpis(gnutls_privkey_t key,
  **/
 int gnutls_privkey_init(gnutls_privkey_t * key)
 {
+       FAIL_IF_FIPS_ERROR;
+
        *key = gnutls_calloc(1, sizeof(struct gnutls_privkey_st));
        if (*key == NULL) {
                gnutls_assert();
index d8979f77c0a78d850cd6193e5372321d2c9390d4..21826b866d83e83ec51c6c1678e9fffa307de034 100644 (file)
@@ -34,6 +34,7 @@
 #include <x509/common.h>
 #include <x509_b64.h>
 #include <abstract_int.h>
+#include <fips.h>
 #include <gnutls_ecc.h>
 
 
@@ -110,6 +111,8 @@ int gnutls_pubkey_get_key_usage(gnutls_pubkey_t key, unsigned int *usage)
  **/
 int gnutls_pubkey_init(gnutls_pubkey_t * key)
 {
+       FAIL_IF_FIPS_ERROR;
+
        *key = gnutls_calloc(1, sizeof(struct gnutls_pubkey_st));
        if (*key == NULL) {
                gnutls_assert();
index 231e6b0b64aa028944bcace1f1ede41c571462e0..21a8f99cee89e6866a6893dc987591117532b72d 100644 (file)
@@ -45,6 +45,7 @@
 #include <gnutls_extensions.h>
 #include <system.h>
 #include <random.h>
+#include <fips.h>
 #include <gnutls/dtls.h>
 
 /* These should really be static, but src/tests.c calls them.  Make
@@ -307,6 +308,8 @@ int gnutls_init(gnutls_session_t * session, unsigned int flags)
 {
        int ret;
        record_parameters_st *epoch;
+       
+       FAIL_IF_FIPS_ERROR;
 
        *session = gnutls_calloc(1, sizeof(struct gnutls_session_int));
        if (*session == NULL)
index 742f44f008542e5803cdba68a89844a24167aff7..541fda6d53a44a64adbfd032eb4e34b965b82fe2 100644 (file)
@@ -2288,6 +2288,7 @@ int gnutls_pk_self_test(unsigned all, gnutls_pk_algorithm_t pk);
 
 #define GNUTLS_E_SELF_TEST_ERROR -400
 #define GNUTLS_E_NO_SELF_TEST -401
+#define GNUTLS_E_LIB_IN_ERROR_STATE -402
 
 #define GNUTLS_E_UNIMPLEMENTED_FEATURE -1250
 
index 7a0aa3891274b5208fa73382793aa117615df55c..d24f6a3dee5de62e72d56e80573231cf5dd63083 100644 (file)
@@ -27,6 +27,7 @@
 #include <pkcs11_int.h>
 #include <gnutls_sig.h>
 #include <gnutls_pk.h>
+#include <fips.h>
 #include <p11-kit/uri.h>
 
 struct gnutls_pkcs11_privkey_st {
@@ -51,6 +52,8 @@ struct gnutls_pkcs11_privkey_st {
  **/
 int gnutls_pkcs11_privkey_init(gnutls_pkcs11_privkey_t * key)
 {
+        FAIL_IF_FIPS_ERROR;
+
        *key = gnutls_calloc(1, sizeof(struct gnutls_pkcs11_privkey_st));
        if (*key == NULL) {
                gnutls_assert();
index 62fa785232e760c939be47fe7d1b7266993f19ca..b5f6cd94f92962f0a5ef5d03a6415b7c637b9256 100644 (file)
@@ -26,6 +26,7 @@
 #include <gnutls_int.h>
 #include <gnutls_errors.h>
 #include <random.h>
+#include <fips.h>
 
 void *gnutls_rnd_ctx;
 
@@ -65,6 +66,7 @@ void _gnutls_rnd_deinit(void)
  **/
 int gnutls_rnd(gnutls_rnd_level_t level, void *data, size_t len)
 {
+       FAIL_IF_FIPS_ERROR;
        return _gnutls_rnd(level, data, len);
 }
 
index 7ad55c2da758d9684d12d571893f19bbadc66bb4..8bc51d1ee0a96b6ae389aee1c3a488fc2967f2e6 100644 (file)
@@ -26,6 +26,7 @@
 #include <algorithms.h>
 #include <abstract_int.h>
 #include <x509/x509_int.h>
+#include <fips.h>
 
 #define MAX_STRING_LEN 512
 
index bd2560dc7865d6f46e7d3fa60da6a1fb3c3821ae..480074ec39c573a7b72dde3b7f09073de0fc20f1 100644 (file)
@@ -46,6 +46,8 @@
  **/
 int gnutls_x509_crl_init(gnutls_x509_crl_t * crl)
 {
+       FAIL_IF_FIPS_ERROR;
+
        *crl = gnutls_calloc(1, sizeof(gnutls_x509_crl_int));
 
        if (*crl) {
index 4e28fedd7c9320eae3b786b9660fd356fc4abda1..67f425a4a4723ce9d45093bb8a901782ad4760a2 100644 (file)
@@ -49,6 +49,8 @@
 int gnutls_x509_crq_init(gnutls_x509_crq_t * crq)
 {
        int result;
+       
+       FAIL_IF_FIPS_ERROR;
 
        *crq = gnutls_calloc(1, sizeof(gnutls_x509_crq_int));
        if (!*crq)
index 1a779772bc29b5af22966aa0eab1948222f000b3..0c94ac52b4d7b9da1dc8efce6517c3a7e4f3481f 100644 (file)
@@ -44,6 +44,8 @@
  **/
 int gnutls_x509_privkey_init(gnutls_x509_privkey_t * key)
 {
+       FAIL_IF_FIPS_ERROR;
+
        *key = gnutls_calloc(1, sizeof(gnutls_x509_privkey_int));
 
        if (*key) {
index 72e66565195cb4fcfd67c0261b937181eb9c80b9..28f89edeeba85e6652420b9d281e602fecb79460 100644 (file)
@@ -75,7 +75,11 @@ int
 gnutls_x509_trust_list_init(gnutls_x509_trust_list_t * list,
                            unsigned int size)
 {
-       gnutls_x509_trust_list_t tmp =
+       gnutls_x509_trust_list_t tmp;
+       
+       FAIL_IF_FIPS_ERROR;
+       
+       tmp =
            gnutls_calloc(1, sizeof(struct gnutls_x509_trust_list_st));
 
        if (!tmp)
index 9bc677d74d5c9552cef6ea33fb519a9f67865a79..0bc8617581c314b63fada5ab308a6e4edbfa967c 100644 (file)
  **/
 int gnutls_x509_crt_init(gnutls_x509_crt_t * cert)
 {
-       gnutls_x509_crt_t tmp =
+       gnutls_x509_crt_t tmp;
+       
+       FAIL_IF_FIPS_ERROR;
+
+       tmp =
            gnutls_calloc(1, sizeof(gnutls_x509_crt_int));
        int result;
 
index 7b9e198d94de42a1e43f98150e3bf9a3b24c926f..11780ee85f6c0706d0e89848eca90a59065325c7 100644 (file)
@@ -25,6 +25,7 @@
 #include <gnutls_num.h>
 #include <gnutls/xssl.h>
 #include <auth/cert.h>
+#include <fips.h>
 #include "vasprintf.h"
 
 #include <xssl.h>
@@ -301,6 +302,8 @@ int xssl_cred_init(xssl_cred_t * c, unsigned vflags,
 int xssl_sinit(xssl_t * isb, gnutls_session_t session, unsigned int flags)
 {
        struct xssl_st *sb;
+       
+       FAIL_IF_FIPS_ERROR;
 
        sb = gnutls_calloc(1, sizeof(*sb));
        if (sb == NULL)
@@ -347,6 +350,8 @@ int xssl_client_init(xssl_t * isb, const char *hostname,
        gnutls_session_t session;
        int ret;
        unsigned len;
+       
+       FAIL_IF_FIPS_ERROR;
 
        ret = gnutls_init(&session, GNUTLS_CLIENT);
        if (ret < 0)