Disable non-allowed algorithms in FIPS mode
authorVitezslav Cizek <vcizek@suse.com>
Thu, 29 Oct 2015 16:13:16 +0000 (17:13 +0100)
committerWerner Koch <wk@gnupg.org>
Fri, 18 Mar 2016 14:48:15 +0000 (15:48 +0100)
* cipher/cipher.c (_gcry_cipher_init),
* cipher/mac.c (_gcry_mac_init),
* cipher/md.c (_gcry_md_init),
* cipher/pubkey.c (_gcry_pk_init): In the FIPS mode, disable all the
non-allowed ciphers.
* cipher/md5.c: Mark MD5 as not allowed in FIPS.
* src/g10lib.h (_gcry_mac_init): New.
* src/global.c (global_init): Call the new _gcry_mac_init.
* tests/basic.c (check_ciphers): Fix a typo.
--

When running in the FIPS mode, disable all the ciphers that don't have
the fips flag set.
Skip the non-allowed algos during testing in the FIPS mode.

Thanks to Ludwig Nussel.
Signed-off-by: Vitezslav Cizek <vcizek@suse.com>
Signed-off-by: Vitezslav Cizek <vcizek@suse.com>
cipher/cipher.c
cipher/mac.c
cipher/md.c
cipher/md5.c
cipher/pubkey.c
src/g10lib.h
src/global.c
tests/basic.c

index 802ffad..a013846 100644 (file)
@@ -1514,6 +1514,17 @@ _gcry_cipher_get_algo_blklen (int algo)
 gcry_err_code_t
 _gcry_cipher_init (void)
 {
+  if (fips_mode())
+    {
+      /* disable algorithms that are disallowed in fips */
+      int idx;
+      gcry_cipher_spec_t *spec;
+
+      for (idx = 0; (spec = cipher_list[idx]); idx++)
+        if (!spec->flags.fips)
+          spec->flags.disabled = 1;
+    }
+
   return 0;
 }
 
index b8a5534..46be7b7 100644 (file)
@@ -116,6 +116,23 @@ static gcry_mac_spec_t *mac_list[] = {
   NULL,
 };
 
+/* Explicitly initialize this module.  */
+gcry_err_code_t
+_gcry_mac_init (void)
+{
+  if (fips_mode())
+    {
+      /* disable algorithms that are disallowed in fips */
+      int idx;
+      gcry_mac_spec_t *spec;
+
+      for (idx = 0; (spec = mac_list[idx]); idx++)
+        if (!spec->flags.fips)
+          spec->flags.disabled = 1;
+    }
+
+  return 0;
+}
 
 \f
 /* Return the spec structure for the MAC algorithm ALGO.  For an
index 15d944d..281db12 100644 (file)
@@ -1296,6 +1296,17 @@ _gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
 gcry_err_code_t
 _gcry_md_init (void)
 {
+  if (fips_mode())
+    {
+      /* disable algorithms that are disallowed in fips */
+      int idx;
+      gcry_md_spec_t *spec;
+
+      for (idx = 0; (spec = digest_list[idx]); idx++)
+        if (!spec->flags.fips)
+          spec->flags.disabled = 1;
+    }
+
   return 0;
 }
 
index 66cc5f6..ed942cf 100644 (file)
@@ -310,7 +310,7 @@ static gcry_md_oid_spec_t oid_spec_md5[] =
 
 gcry_md_spec_t _gcry_digest_spec_md5 =
   {
-    GCRY_MD_MD5, {0, 1},
+    GCRY_MD_MD5, {0, 0},
     "MD5", asn, DIM (asn), oid_spec_md5, 16,
     md5_init, _gcry_md_block_write, md5_final, md5_read, NULL,
     sizeof (MD5_CONTEXT)
index b321a89..8ec15fd 100644 (file)
@@ -926,6 +926,17 @@ _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
 gcry_err_code_t
 _gcry_pk_init (void)
 {
+  if (fips_mode())
+    {
+      /* disable algorithms that are disallowed in fips */
+      int idx;
+      gcry_pk_spec_t *spec;
+
+      for (idx = 0; (spec = pubkey_list[idx]); idx++)
+        if (!spec->flags.fips)
+          spec->flags.disabled = 1;
+    }
+
   return 0;
 }
 
index 7352556..af68870 100644 (file)
@@ -381,6 +381,7 @@ typedef struct fast_wipememory_s
 
 gcry_err_code_t _gcry_cipher_init (void);
 gcry_err_code_t _gcry_md_init (void);
+gcry_err_code_t _gcry_mac_init (void);
 gcry_err_code_t _gcry_pk_init (void);
 gcry_err_code_t _gcry_secmem_module_init (void);
 gcry_err_code_t _gcry_mpi_init (void);
index 4d69b27..8669a46 100644 (file)
@@ -105,6 +105,9 @@ global_init (void)
   err = _gcry_md_init ();
   if (err)
     goto fail;
+  err = _gcry_mac_init ();
+  if (err)
+    goto fail;
   err = _gcry_pk_init ();
   if (err)
     goto fail;
index 5e7ee44..876ee2e 100644 (file)
@@ -698,6 +698,14 @@ check_ctr_cipher (void)
       if (!tv[i].algo)
         continue;
 
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
       if (!err)
        err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0);
@@ -929,6 +937,14 @@ check_cfb_cipher (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       if (verbose)
         fprintf (stderr, "    checking CFB mode for %s [%i]\n",
                 gcry_cipher_algo_name (tv[i].algo),
@@ -1100,6 +1116,14 @@ check_ofb_cipher (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       if (verbose)
         fprintf (stderr, "    checking OFB mode for %s [%i]\n",
                 gcry_cipher_algo_name (tv[i].algo),
@@ -1402,6 +1426,14 @@ _check_gcm_cipher (unsigned int step)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       if (verbose)
         fprintf (stderr, "    checking GCM mode for %s [%i]\n",
                  gcry_cipher_algo_name (tv[i].algo),
@@ -2423,6 +2455,14 @@ check_ccm_cipher (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       if (verbose)
         fprintf (stderr, "    checking CCM mode for %s [%i]\n",
                  gcry_cipher_algo_name (tv[i].algo),
@@ -3924,6 +3964,13 @@ check_stream_cipher (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
       if (verbose)
         fprintf (stderr, "    checking stream mode for %s [%i] (%s)\n",
                 gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].name);
@@ -4368,6 +4415,14 @@ check_stream_cipher_large_block (void)
 
   for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
+      if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    tv[i].algo);
+          continue;
+        }
+
       if (verbose)
         fprintf (stderr, "    checking large block stream for %s [%i] (%s)\n",
                 gcry_cipher_algo_name (tv[i].algo), tv[i].algo, tv[i].name);
@@ -5219,11 +5274,11 @@ check_ciphers (void)
 
   for (i = 0; algos2[i]; i++)
     {
-      if (gcry_cipher_test_algo (algos[i]) && in_fips_mode)
+      if (gcry_cipher_test_algo (algos2[i]) && in_fips_mode)
         {
           if (verbose)
             fprintf (stderr, "  algorithm %d not available in fips mode\n",
-                    algos[i]);
+                    algos2[i]);
           continue;
         }
       if (verbose)
@@ -6399,8 +6454,7 @@ check_digests (void)
           show_md_not_available (algos[i].md);
           continue;
         }
-      if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5)
-          && in_fips_mode)
+      if (gcry_md_test_algo (algos[i].md) && in_fips_mode)
         {
           if (verbose)
             fprintf (stderr, "  algorithm %d not available in fips mode\n",
@@ -6832,8 +6886,7 @@ check_hmac (void)
           show_old_hmac_not_available (algos[i].md);
           continue;
         }
-      if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5)
-          && in_fips_mode)
+      if (gcry_md_test_algo (algos[i].md) && in_fips_mode)
         {
           if (verbose)
             fprintf (stderr, "  algorithm %d not available in fips mode\n",
@@ -7809,8 +7862,7 @@ check_mac (void)
           show_mac_not_available (algos[i].algo);
           continue;
         }
-      if ((gcry_mac_test_algo (algos[i].algo)
-          || algos[i].algo == GCRY_MAC_HMAC_MD5) && in_fips_mode)
+      if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode)
         {
           if (verbose)
             fprintf (stderr, "  algorithm %d not available in fips mode\n",