api: New function gcry_get_config.
[libgcrypt.git] / tests / keygen.c
index 4bcea20..6b6a60a 100644 (file)
 
 
 #define PGM "keygen"
+#include "t-common.h"
 
-#define xmalloc(a)    gcry_xmalloc ((a))
-#define xcalloc(a,b)  gcry_xcalloc ((a),(b))
-#define xstrdup(a)    gcry_xstrdup ((a))
-#define xfree(a)      gcry_free ((a))
-#define pass()        do { ; } while (0)
-
-
-static int verbose;
-static int debug;
-static int error_count;
 static int in_fips_mode;
 
 
-static void
-die (const char *format, ...)
-{
-  va_list arg_ptr ;
-
-  fflush (stdout);
-  fprintf (stderr, "%s: ", PGM);
-  va_start( arg_ptr, format ) ;
-  vfprintf (stderr, format, arg_ptr );
-  va_end(arg_ptr);
-  if (*format && format[strlen(format)-1] != '\n')
-    putc ('\n', stderr);
-  exit (1);
-}
-
-static void
-fail (const char *format, ...)
-{
-  va_list arg_ptr;
-
-  fflush (stdout);
-  fprintf (stderr, "%s: ", PGM);
-  /* if (wherestr) */
-  /*   fprintf (stderr, "%s: ", wherestr); */
-  va_start (arg_ptr, format);
-  vfprintf (stderr, format, arg_ptr);
-  va_end (arg_ptr);
-  if (*format && format[strlen(format)-1] != '\n')
-    putc ('\n', stderr);
-  error_count++;
-  if (error_count >= 50)
-    die ("stopped after 50 errors.");
-}
-
-static void
-show (const char *format, ...)
-{
-  va_list arg_ptr;
-
-  fprintf (stderr, "%s: ", PGM);
-  va_start (arg_ptr, format);
-  vfprintf (stderr, format, arg_ptr);
-  if (*format && format[strlen(format)-1] != '\n')
-    putc ('\n', stderr);
-  va_end (arg_ptr);
-}
-
-
 /* static void */
 /* show_note (const char *format, ...) */
 /* { */
@@ -197,7 +140,7 @@ check_rsa_keys (void)
   int rc;
 
   if (verbose)
-    show ("creating 2048 bit RSA key\n");
+    info ("creating 2048 bit RSA key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (rsa\n"
@@ -211,7 +154,7 @@ check_rsa_keys (void)
     die ("error generating RSA key: %s\n", gpg_strerror (rc));
 
   if (verbose)
-    show ("creating 1024 bit RSA key\n");
+    info ("creating 1024 bit RSA key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (rsa\n"
@@ -219,6 +162,8 @@ check_rsa_keys (void)
                       " ))", 0, 1);
   if (rc)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
+
+  gcry_sexp_release (key);
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
   if (rc && !in_fips_mode)
@@ -234,23 +179,20 @@ check_rsa_keys (void)
     }
   gcry_sexp_release (key);
 
-
   if (verbose)
-    show ("creating 1024 bit RSA key with e=65539\n");
+    info ("creating 2048 bit RSA key with e=65539\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (rsa\n"
-                      "  (nbits 4:1024)\n"
+                      "  (nbits 4:2048)\n"
                       "  (rsa-use-e 5:65539)\n"
                       " ))", 0, 1);
   if (rc)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc && !in_fips_mode)
+  if (rc)
     fail ("error generating RSA key: %s\n", gpg_strerror (rc));
-  else if (!rc && in_fips_mode)
-    fail ("generating RSA key must not work!");
 
   if (!rc)
     check_generated_rsa_key (key, 65539);
@@ -258,7 +200,7 @@ check_rsa_keys (void)
 
 
   if (verbose)
-    show ("creating 512 bit RSA key with e=257\n");
+    info ("creating 512 bit RSA key with e=257\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (rsa\n"
@@ -274,12 +216,16 @@ check_rsa_keys (void)
   else if (!rc && in_fips_mode)
     fail ("generating 512 bit RSA key must not work!");
 
+  if (verbose && rc && in_fips_mode)
+    info ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+
   if (!rc)
     check_generated_rsa_key (key, 257);
   gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating 512 bit RSA key with default e\n");
+    info ("creating 512 bit RSA key with default e\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (rsa\n"
@@ -295,6 +241,11 @@ check_rsa_keys (void)
   else if (!rc && in_fips_mode)
     fail ("generating 512 bit RSA key must not work!");
 
+  if (verbose && rc && in_fips_mode)
+    info ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+
+
   if (!rc)
     check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
   gcry_sexp_release (key);
@@ -308,7 +259,7 @@ check_elg_keys (void)
   int rc;
 
   if (verbose)
-    show ("creating 1024 bit Elgamal key\n");
+    info ("creating 1024 bit Elgamal key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (elg\n"
@@ -336,7 +287,7 @@ check_dsa_keys (void)
   /* Check that DSA generation works and that it can grok the qbits
      argument. */
   if (verbose)
-    show ("creating 5 1024 bit DSA keys\n");
+    info ("creating 5 1024 bit DSA keys\n");
   for (i=0; i < 5; i++)
     {
       rc = gcry_sexp_new (&keyparm,
@@ -358,7 +309,7 @@ check_dsa_keys (void)
     }
 
   if (verbose)
-    show ("creating 1536 bit DSA key\n");
+    info ("creating 1536 bit DSA key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (dsa\n"
@@ -378,7 +329,7 @@ check_dsa_keys (void)
   gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating 3072 bit DSA key\n");
+    info ("creating 3072 bit DSA key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (dsa\n"
@@ -396,7 +347,7 @@ check_dsa_keys (void)
   gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating 2048/256 bit DSA key\n");
+    info ("creating 2048/256 bit DSA key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (dsa\n"
@@ -414,7 +365,7 @@ check_dsa_keys (void)
   gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating 2048/224 bit DSA key\n");
+    info ("creating 2048/224 bit DSA key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (dsa\n"
@@ -480,7 +431,7 @@ check_ecc_keys (void)
   for (testno=0; curves[testno]; testno++)
     {
       if (verbose)
-        show ("creating ECC key using curve %s\n", curves[testno]);
+        info ("creating ECC key using curve %s\n", curves[testno]);
       if (!strcmp (curves[testno], "Ed25519"))
         {
           /* Ed25519 isn't allowed in fips mode */
@@ -511,37 +462,53 @@ check_ecc_keys (void)
     }
 
   if (verbose)
-    show ("creating ECC key using curve Ed25519 for ECDSA\n");
+    info ("creating ECC key using curve Ed25519 for ECDSA\n");
   rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve Ed25519)))");
   if (rc)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc)
+  if (rc && !in_fips_mode)
     die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
          gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating Ed25519 key must not work!");
 
-  if (verbose > 1)
-    show_sexp ("ECC key:\n", key);
+  if (verbose && rc && in_fips_mode)
+    info ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
 
-  check_generated_ecc_key (key);
+  if (!rc)
+    {
+      if (verbose > 1)
+        show_sexp ("ECC key:\n", key);
+
+      check_generated_ecc_key (key);
+    }
   gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
+    info ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
   rc = gcry_sexp_build (&keyparm, NULL,
                         "(genkey(ecc(curve Ed25519)(flags nocomp)))");
   if (rc)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc)
+  if (rc && !in_fips_mode)
     die ("error generating ECC key using curve Ed25519 for ECDSA"
          " (nocomp): %s\n",
          gpg_strerror (rc));
+  else if (!rc && in_fips_mode)
+    fail ("generating Ed25519 key must not work in FIPS mode!");
+
+  if (verbose && rc && in_fips_mode)
+    info ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+  gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating ECC key using curve NIST P-384 for ECDSA\n");
+    info ("creating ECC key using curve NIST P-384 for ECDSA\n");
 
   /* Must be specified as nistp384 (one word), because ecc_generate
    * uses _gcry_sexp_nth_string which takes the first word of the name
@@ -562,7 +529,7 @@ check_ecc_keys (void)
   gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating ECC key using curve NIST P-384 for ECDSA (nocomp)\n");
+    info ("creating ECC key using curve NIST P-384 for ECDSA (nocomp)\n");
   rc = gcry_sexp_build (&keyparm, NULL,
                         "(genkey(ecc(curve nistp384)(flags nocomp)))");
   if (rc)
@@ -582,24 +549,34 @@ check_ecc_keys (void)
 
 
   if (verbose)
-    show ("creating ECC key using curve Ed25519 for ECDSA (transient-key)\n");
+    info ("creating ECC key using curve Ed25519 for ECDSA (transient-key)\n");
   rc = gcry_sexp_build (&keyparm, NULL,
                         "(genkey(ecc(curve Ed25519)(flags transient-key)))");
   if (rc)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc)
+  if (rc && !in_fips_mode)
     die ("error generating ECC key using curve Ed25519 for ECDSA"
          " (transient-key): %s\n",
          gpg_strerror (rc));
-  if (verbose > 1)
-    show_sexp ("ECC key:\n", key);
-  check_generated_ecc_key (key);
+  else if (!rc && in_fips_mode)
+    fail ("generating Ed25519 key must not work in FIPS mode!");
+
+  if (verbose && rc && in_fips_mode)
+    info ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+
+  if (!rc)
+    {
+      if (verbose > 1)
+        show_sexp ("ECC key:\n", key);
+      check_generated_ecc_key (key);
+    }
   gcry_sexp_release (key);
 
   if (verbose)
-    show ("creating ECC key using curve Ed25519 for ECDSA "
+    info ("creating ECC key using curve Ed25519 for ECDSA "
           "(transient-key no-keytest)\n");
   rc = gcry_sexp_build (&keyparm, NULL,
                         "(genkey(ecc(curve Ed25519)"
@@ -608,13 +585,23 @@ check_ecc_keys (void)
     die ("error creating S-expression: %s\n", gpg_strerror (rc));
   rc = gcry_pk_genkey (&key, keyparm);
   gcry_sexp_release (keyparm);
-  if (rc)
+  if (rc && !in_fips_mode)
     die ("error generating ECC key using curve Ed25519 for ECDSA"
          " (transient-key no-keytest): %s\n",
          gpg_strerror (rc));
-  if (verbose > 1)
-    show_sexp ("ECC key:\n", key);
-  check_generated_ecc_key (key);
+  else if (!rc && in_fips_mode)
+    fail ("generating Ed25519 key must not work in FIPS mode!");
+
+  if (verbose && rc && in_fips_mode)
+    info ("... correctly rejected key creation in FIPS mode (%s)\n",
+          gpg_strerror (rc));
+
+  if (!rc)
+    {
+      if (verbose > 1)
+        show_sexp ("ECC key:\n", key);
+      check_generated_ecc_key (key);
+    }
   gcry_sexp_release (key);
 }
 
@@ -627,7 +614,7 @@ check_nonce (void)
   int oops=0;
 
   if (verbose)
-    show ("checking gcry_create_nonce\n");
+    info ("checking gcry_create_nonce\n");
 
   gcry_create_nonce (a, sizeof a);
   for (i=0; i < 10; i++)
@@ -682,6 +669,8 @@ usage (int mode)
          "Options:\n"
          "  --verbose       be verbose\n"
          "  --debug         flyswatter\n"
+         "  --fips          run in FIPS mode\n"
+         "  --no-quick      To not use the quick RNG hack\n"
          "  --progress      print progress indicators\n",
          mode? stderr : stdout);
   if (mode)
@@ -692,7 +681,9 @@ int
 main (int argc, char **argv)
 {
   int last_argc = -1;
+  int opt_fips = 0;
   int with_progress = 0;
+  int no_quick = 0;
 
   if (argc)
     { argc--; argv++; }
@@ -721,31 +712,52 @@ main (int argc, char **argv)
           debug++;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--fips"))
+        {
+          argc--; argv++;
+          opt_fips = 1;
+        }
       else if (!strcmp (*argv, "--progress"))
         {
           argc--; argv++;
           with_progress = 1;
         }
+      else if (!strcmp (*argv, "--no-quick"))
+        {
+          argc--; argv++;
+          no_quick = 1;
+        }
       else if (!strncmp (*argv, "--", 2))
         die ("unknown option '%s'", *argv);
       else
         break;
     }
 
+  xgcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
+  if (opt_fips)
+    xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
+
   if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch\n");
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+  if (!opt_fips)
+    xgcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+
+  xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
   if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+    xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
   /* No valuable keys are create, so we can speed up our RNG. */
-  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  if (!no_quick)
+    xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
   if (with_progress)
     gcry_set_progress_handler (progress_cb, NULL);
 
   if ( gcry_fips_mode_active () )
     in_fips_mode = 1;
 
+  if (opt_fips && !in_fips_mode)
+    die ("failed to switch into FIPS mode\n");
+
   if (!argc)
     {
       check_rsa_keys ();