LCOV - code coverage report
Current view: top level - tests - keygen.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 255 459 55.6 %
Date: 2016-12-01 18:32:04 Functions: 8 15 53.3 %

          Line data    Source code
       1             : /* keygen.c  -  key generation regression tests
       2             :  * Copyright (C) 2003, 2005, 2012 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2013, 2015 g10 Code GmbH
       4             :  *
       5             :  * This file is part of Libgcrypt.
       6             :  *
       7             :  * Libgcrypt is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU Lesser General Public License as
       9             :  * published by the Free Software Foundation; either version 2.1 of
      10             :  * the License, or (at your option) any later version.
      11             :  *
      12             :  * Libgcrypt is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #ifdef HAVE_CONFIG_H
      22             : #include <config.h>
      23             : #endif
      24             : #include <stdio.h>
      25             : #include <stdlib.h>
      26             : #include <string.h>
      27             : #include <stdarg.h>
      28             : #include "../src/gcrypt-int.h"
      29             : 
      30             : 
      31             : #define PGM "keygen"
      32             : 
      33             : #define xmalloc(a)    gcry_xmalloc ((a))
      34             : #define xcalloc(a,b)  gcry_xcalloc ((a),(b))
      35             : #define xstrdup(a)    gcry_xstrdup ((a))
      36             : #define xfree(a)      gcry_free ((a))
      37             : #define pass()        do { ; } while (0)
      38             : 
      39             : 
      40             : static int verbose;
      41             : static int debug;
      42             : static int error_count;
      43             : static int in_fips_mode;
      44             : 
      45             : 
      46             : static void
      47           0 : die (const char *format, ...)
      48             : {
      49             :   va_list arg_ptr ;
      50             : 
      51           0 :   fflush (stdout);
      52           0 :   fprintf (stderr, "%s: ", PGM);
      53           0 :   va_start( arg_ptr, format ) ;
      54           0 :   vfprintf (stderr, format, arg_ptr );
      55           0 :   va_end(arg_ptr);
      56           0 :   if (*format && format[strlen(format)-1] != '\n')
      57           0 :     putc ('\n', stderr);
      58           0 :   exit (1);
      59             : }
      60             : 
      61             : static void
      62           0 : fail (const char *format, ...)
      63             : {
      64             :   va_list arg_ptr;
      65             : 
      66           0 :   fflush (stdout);
      67           0 :   fprintf (stderr, "%s: ", PGM);
      68             :   /* if (wherestr) */
      69             :   /*   fprintf (stderr, "%s: ", wherestr); */
      70           0 :   va_start (arg_ptr, format);
      71           0 :   vfprintf (stderr, format, arg_ptr);
      72           0 :   va_end (arg_ptr);
      73           0 :   if (*format && format[strlen(format)-1] != '\n')
      74           0 :     putc ('\n', stderr);
      75           0 :   error_count++;
      76           0 :   if (error_count >= 50)
      77           0 :     die ("stopped after 50 errors.");
      78           0 : }
      79             : 
      80             : static void
      81           0 : show (const char *format, ...)
      82             : {
      83             :   va_list arg_ptr;
      84             : 
      85           0 :   fprintf (stderr, "%s: ", PGM);
      86           0 :   va_start (arg_ptr, format);
      87           0 :   vfprintf (stderr, format, arg_ptr);
      88           0 :   if (*format && format[strlen(format)-1] != '\n')
      89           0 :     putc ('\n', stderr);
      90           0 :   va_end (arg_ptr);
      91           0 : }
      92             : 
      93             : 
      94             : /* static void */
      95             : /* show_note (const char *format, ...) */
      96             : /* { */
      97             : /*   va_list arg_ptr; */
      98             : 
      99             : /*   if (!verbose && getenv ("srcdir")) */
     100             : /*     fputs ("      ", stderr);  /\* To align above "PASS: ".  *\/ */
     101             : /*   else */
     102             : /*     fprintf (stderr, "%s: ", PGM); */
     103             : /*   va_start (arg_ptr, format); */
     104             : /*   vfprintf (stderr, format, arg_ptr); */
     105             : /*   if (*format && format[strlen(format)-1] != '\n') */
     106             : /*     putc ('\n', stderr); */
     107             : /*   va_end (arg_ptr); */
     108             : /* } */
     109             : 
     110             : 
     111             : static void
     112           0 : show_sexp (const char *prefix, gcry_sexp_t a)
     113             : {
     114             :   char *buf;
     115             :   size_t size;
     116             : 
     117           0 :   fprintf (stderr, "%s: ", PGM);
     118           0 :   if (prefix)
     119           0 :     fputs (prefix, stderr);
     120           0 :   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
     121           0 :   buf = xmalloc (size);
     122             : 
     123           0 :   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
     124           0 :   fprintf (stderr, "%.*s", (int)size, buf);
     125           0 :   gcry_free (buf);
     126           0 : }
     127             : 
     128             : 
     129             : static void
     130           0 : show_mpi (const char *prefix, gcry_mpi_t a)
     131             : {
     132             :   char *buf;
     133           0 :   void *bufaddr = &buf;
     134             :   gcry_error_t rc;
     135             : 
     136           0 :   fprintf (stderr, "%s: ", PGM);
     137           0 :   if (prefix)
     138           0 :     fputs (prefix, stderr);
     139           0 :   rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
     140           0 :   if (rc)
     141           0 :     fprintf (stderr, "[error printing number: %s]\n",  gpg_strerror (rc));
     142             :   else
     143             :     {
     144           0 :       fprintf (stderr, "%s\n", buf);
     145           0 :       gcry_free (buf);
     146             :     }
     147           0 : }
     148             : 
     149             : 
     150             : static void
     151           4 : check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e)
     152             : {
     153             :   gcry_sexp_t skey, pkey, list;
     154             : 
     155           4 :   pkey = gcry_sexp_find_token (key, "public-key", 0);
     156           4 :   if (!pkey)
     157           0 :     fail ("public part missing in return value\n");
     158             :   else
     159             :     {
     160           4 :       gcry_mpi_t e = NULL;
     161             : 
     162           4 :       list = gcry_sexp_find_token (pkey, "e", 0);
     163           4 :       if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) )
     164           0 :         fail ("public exponent not found\n");
     165           4 :       else if (!expected_e)
     166             :         {
     167           1 :           if (verbose)
     168           0 :             show_mpi ("public exponent: ", e);
     169             :         }
     170           3 :       else if ( gcry_mpi_cmp_ui (e, expected_e))
     171             :         {
     172           0 :           show_mpi ("public exponent: ", e);
     173           0 :           fail ("public exponent is not %lu\n", expected_e);
     174             :         }
     175           4 :       gcry_sexp_release (list);
     176           4 :       gcry_mpi_release (e);
     177           4 :       gcry_sexp_release (pkey);
     178             :     }
     179             : 
     180           4 :   skey = gcry_sexp_find_token (key, "private-key", 0);
     181           4 :   if (!skey)
     182           0 :     fail ("private part missing in return value\n");
     183             :   else
     184             :     {
     185           4 :       int rc = gcry_pk_testkey (skey);
     186           4 :       if (rc)
     187           0 :         fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
     188           4 :       gcry_sexp_release (skey);
     189             :     }
     190           4 : }
     191             : 
     192             : 
     193             : static void
     194           1 : check_rsa_keys (void)
     195             : {
     196             :   gcry_sexp_t keyparm, key;
     197             :   int rc;
     198             : 
     199           1 :   if (verbose)
     200           0 :     show ("creating 2048 bit RSA key\n");
     201           1 :   rc = gcry_sexp_new (&keyparm,
     202             :                       "(genkey\n"
     203             :                       " (rsa\n"
     204             :                       "  (nbits 4:2048)\n"
     205             :                       " ))", 0, 1);
     206           1 :   if (rc)
     207           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     208           1 :   rc = gcry_pk_genkey (&key, keyparm);
     209           1 :   gcry_sexp_release (keyparm);
     210           1 :   if (rc)
     211           0 :     die ("error generating RSA key: %s\n", gpg_strerror (rc));
     212             : 
     213           1 :   if (verbose)
     214           0 :     show ("creating 1024 bit RSA key\n");
     215           1 :   rc = gcry_sexp_new (&keyparm,
     216             :                       "(genkey\n"
     217             :                       " (rsa\n"
     218             :                       "  (nbits 4:1024)\n"
     219             :                       " ))", 0, 1);
     220           1 :   if (rc)
     221           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     222             : 
     223           1 :   gcry_sexp_release (key);
     224           1 :   rc = gcry_pk_genkey (&key, keyparm);
     225           1 :   gcry_sexp_release (keyparm);
     226           1 :   if (rc && !in_fips_mode)
     227           0 :     fail ("error generating RSA key: %s\n", gpg_strerror (rc));
     228           1 :   else if (!rc && in_fips_mode)
     229           0 :     fail ("generating 1024 bit RSA key must not work!");
     230             : 
     231           1 :   if (!rc)
     232             :     {
     233           1 :       if (verbose > 1)
     234           0 :         show_sexp ("1024 bit RSA key:\n", key);
     235           1 :       check_generated_rsa_key (key, 65537);
     236             :     }
     237           1 :   gcry_sexp_release (key);
     238             : 
     239           1 :   if (verbose)
     240           0 :     show ("creating 2048 bit RSA key with e=65539\n");
     241           1 :   rc = gcry_sexp_new (&keyparm,
     242             :                       "(genkey\n"
     243             :                       " (rsa\n"
     244             :                       "  (nbits 4:2048)\n"
     245             :                       "  (rsa-use-e 5:65539)\n"
     246             :                       " ))", 0, 1);
     247           1 :   if (rc)
     248           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     249           1 :   rc = gcry_pk_genkey (&key, keyparm);
     250           1 :   gcry_sexp_release (keyparm);
     251           1 :   if (rc)
     252           0 :     fail ("error generating RSA key: %s\n", gpg_strerror (rc));
     253             : 
     254           1 :   if (!rc)
     255           1 :     check_generated_rsa_key (key, 65539);
     256           1 :   gcry_sexp_release (key);
     257             : 
     258             : 
     259           1 :   if (verbose)
     260           0 :     show ("creating 512 bit RSA key with e=257\n");
     261           1 :   rc = gcry_sexp_new (&keyparm,
     262             :                       "(genkey\n"
     263             :                       " (rsa\n"
     264             :                       "  (nbits 3:512)\n"
     265             :                       "  (rsa-use-e 3:257)\n"
     266             :                       " ))", 0, 1);
     267           1 :   if (rc)
     268           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     269           1 :   rc = gcry_pk_genkey (&key, keyparm);
     270           1 :   gcry_sexp_release (keyparm);
     271           1 :   if (rc && !in_fips_mode)
     272           0 :     fail ("error generating RSA key: %s\n", gpg_strerror (rc));
     273           1 :   else if (!rc && in_fips_mode)
     274           0 :     fail ("generating 512 bit RSA key must not work!");
     275             : 
     276           1 :   if (verbose && rc && in_fips_mode)
     277           0 :     show ("... correctly rejected key creation in FIPS mode (%s)\n",
     278             :           gpg_strerror (rc));
     279             : 
     280           1 :   if (!rc)
     281           1 :     check_generated_rsa_key (key, 257);
     282           1 :   gcry_sexp_release (key);
     283             : 
     284           1 :   if (verbose)
     285           0 :     show ("creating 512 bit RSA key with default e\n");
     286           1 :   rc = gcry_sexp_new (&keyparm,
     287             :                       "(genkey\n"
     288             :                       " (rsa\n"
     289             :                       "  (nbits 3:512)\n"
     290             :                       "  (rsa-use-e 1:0)\n"
     291             :                       " ))", 0, 1);
     292           1 :   if (rc)
     293           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     294           1 :   rc = gcry_pk_genkey (&key, keyparm);
     295           1 :   gcry_sexp_release (keyparm);
     296           1 :   if (rc && !in_fips_mode)
     297           0 :     fail ("error generating RSA key: %s\n", gpg_strerror (rc));
     298           1 :   else if (!rc && in_fips_mode)
     299           0 :     fail ("generating 512 bit RSA key must not work!");
     300             : 
     301           1 :   if (verbose && rc && in_fips_mode)
     302           0 :     show ("... correctly rejected key creation in FIPS mode (%s)\n",
     303             :           gpg_strerror (rc));
     304             : 
     305             : 
     306           1 :   if (!rc)
     307           1 :     check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
     308           1 :   gcry_sexp_release (key);
     309           1 : }
     310             : 
     311             : 
     312             : static void
     313           1 : check_elg_keys (void)
     314             : {
     315             :   gcry_sexp_t keyparm, key;
     316             :   int rc;
     317             : 
     318           1 :   if (verbose)
     319           0 :     show ("creating 1024 bit Elgamal key\n");
     320           1 :   rc = gcry_sexp_new (&keyparm,
     321             :                       "(genkey\n"
     322             :                       " (elg\n"
     323             :                       "  (nbits 4:1024)\n"
     324             :                       " ))", 0, 1);
     325           1 :   if (rc)
     326           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     327           1 :   rc = gcry_pk_genkey (&key, keyparm);
     328           1 :   gcry_sexp_release (keyparm);
     329           1 :   if (rc)
     330           0 :     die ("error generating Elgamal key: %s\n", gpg_strerror (rc));
     331           1 :   if (verbose > 1)
     332           0 :     show_sexp ("1024 bit Elgamal key:\n", key);
     333           1 :   gcry_sexp_release (key);
     334           1 : }
     335             : 
     336             : 
     337             : static void
     338           1 : check_dsa_keys (void)
     339             : {
     340             :   gcry_sexp_t keyparm, key;
     341             :   int rc;
     342             :   int i;
     343             : 
     344             :   /* Check that DSA generation works and that it can grok the qbits
     345             :      argument. */
     346           1 :   if (verbose)
     347           0 :     show ("creating 5 1024 bit DSA keys\n");
     348           6 :   for (i=0; i < 5; i++)
     349             :     {
     350           5 :       rc = gcry_sexp_new (&keyparm,
     351             :                           "(genkey\n"
     352             :                           " (dsa\n"
     353             :                           "  (nbits 4:1024)\n"
     354             :                           " ))", 0, 1);
     355           5 :       if (rc)
     356           0 :         die ("error creating S-expression: %s\n", gpg_strerror (rc));
     357           5 :       rc = gcry_pk_genkey (&key, keyparm);
     358           5 :       gcry_sexp_release (keyparm);
     359           5 :       if (rc && !in_fips_mode)
     360           0 :         die ("error generating DSA key: %s\n", gpg_strerror (rc));
     361           5 :       else if (!rc && in_fips_mode)
     362           0 :         die ("generating 1024 bit DSA key must not work!");
     363           5 :       if (!i && verbose > 1)
     364           0 :         show_sexp ("1024 bit DSA key:\n", key);
     365           5 :       gcry_sexp_release (key);
     366             :     }
     367             : 
     368           1 :   if (verbose)
     369           0 :     show ("creating 1536 bit DSA key\n");
     370           1 :   rc = gcry_sexp_new (&keyparm,
     371             :                       "(genkey\n"
     372             :                       " (dsa\n"
     373             :                       "  (nbits 4:1536)\n"
     374             :                       "  (qbits 3:224)\n"
     375             :                       " ))", 0, 1);
     376           1 :   if (rc)
     377           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     378           1 :   rc = gcry_pk_genkey (&key, keyparm);
     379           1 :   gcry_sexp_release (keyparm);
     380           1 :   if (rc && !in_fips_mode)
     381           0 :     die ("error generating DSA key: %s\n", gpg_strerror (rc));
     382           1 :   else if (!rc && in_fips_mode)
     383           0 :     die ("generating 1536 bit DSA key must not work!");
     384           1 :   if (verbose > 1)
     385           0 :     show_sexp ("1536 bit DSA key:\n", key);
     386           1 :   gcry_sexp_release (key);
     387             : 
     388           1 :   if (verbose)
     389           0 :     show ("creating 3072 bit DSA key\n");
     390           1 :   rc = gcry_sexp_new (&keyparm,
     391             :                       "(genkey\n"
     392             :                       " (dsa\n"
     393             :                       "  (nbits 4:3072)\n"
     394             :                       "  (qbits 3:256)\n"
     395             :                       " ))", 0, 1);
     396           1 :   if (rc)
     397           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     398           1 :   rc = gcry_pk_genkey (&key, keyparm);
     399           1 :   gcry_sexp_release (keyparm);
     400           1 :   if (rc)
     401           0 :     die ("error generating DSA key: %s\n", gpg_strerror (rc));
     402           1 :   if (verbose > 1)
     403           0 :     show_sexp ("3072 bit DSA key:\n", key);
     404           1 :   gcry_sexp_release (key);
     405             : 
     406           1 :   if (verbose)
     407           0 :     show ("creating 2048/256 bit DSA key\n");
     408           1 :   rc = gcry_sexp_new (&keyparm,
     409             :                       "(genkey\n"
     410             :                       " (dsa\n"
     411             :                       "  (nbits 4:2048)\n"
     412             :                       "  (qbits 3:256)\n"
     413             :                       " ))", 0, 1);
     414           1 :   if (rc)
     415           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     416           1 :   rc = gcry_pk_genkey (&key, keyparm);
     417           1 :   gcry_sexp_release (keyparm);
     418           1 :   if (rc)
     419           0 :     die ("error generating DSA key: %s\n", gpg_strerror (rc));
     420           1 :   if (verbose > 1)
     421           0 :     show_sexp ("2048 bit DSA key:\n", key);
     422           1 :   gcry_sexp_release (key);
     423             : 
     424           1 :   if (verbose)
     425           0 :     show ("creating 2048/224 bit DSA key\n");
     426           1 :   rc = gcry_sexp_new (&keyparm,
     427             :                       "(genkey\n"
     428             :                       " (dsa\n"
     429             :                       "  (nbits 4:2048)\n"
     430             :                       "  (qbits 3:224)\n"
     431             :                       " ))", 0, 1);
     432           1 :   if (rc)
     433           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     434           1 :   rc = gcry_pk_genkey (&key, keyparm);
     435           1 :   gcry_sexp_release (keyparm);
     436           1 :   if (rc)
     437           0 :     die ("error generating DSA key: %s\n", gpg_strerror (rc));
     438           1 :   if (verbose > 1)
     439           0 :     show_sexp ("2048 bit DSA key:\n", key);
     440           1 :   gcry_sexp_release (key);
     441           1 : }
     442             : 
     443             : 
     444             : static void
     445           9 : check_generated_ecc_key (gcry_sexp_t key)
     446             : {
     447             :   gcry_sexp_t skey, pkey;
     448             : 
     449           9 :   pkey = gcry_sexp_find_token (key, "public-key", 0);
     450           9 :   if (!pkey)
     451           0 :     fail ("public part missing in return value\n");
     452             :   else
     453             :     {
     454             :       /* Fixme: Check more stuff.  */
     455           9 :       gcry_sexp_release (pkey);
     456             :     }
     457             : 
     458           9 :   skey = gcry_sexp_find_token (key, "private-key", 0);
     459           9 :   if (!skey)
     460           0 :     fail ("private part missing in return value\n");
     461             :   else
     462             :     {
     463           9 :       int rc = gcry_pk_testkey (skey);
     464           9 :       if (rc)
     465           0 :         fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
     466           9 :       gcry_sexp_release (skey);
     467             :     }
     468             : 
     469             :   /* Finally check that gcry_pk_testkey also works on the entire
     470             :      S-expression.  */
     471             :   {
     472           9 :     int rc = gcry_pk_testkey (key);
     473           9 :     if (rc)
     474           0 :       fail ("gcry_pk_testkey failed on key pair: %s\n", gpg_strerror (rc));
     475             :   }
     476           9 : }
     477             : 
     478             : 
     479             : static void
     480           1 : check_ecc_keys (void)
     481             : {
     482           1 :   const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256",
     483             :                            "Ed25519", NULL };
     484             :   int testno;
     485             :   gcry_sexp_t keyparm, key;
     486             :   int rc;
     487             : 
     488           5 :   for (testno=0; curves[testno]; testno++)
     489             :     {
     490           4 :       if (verbose)
     491           0 :         show ("creating ECC key using curve %s\n", curves[testno]);
     492           4 :       if (!strcmp (curves[testno], "Ed25519"))
     493             :         {
     494             :           /* Ed25519 isn't allowed in fips mode */
     495           1 :           if (in_fips_mode)
     496           0 :             continue;
     497           1 :           rc = gcry_sexp_build (&keyparm, NULL,
     498             :                                 "(genkey(ecc(curve %s)(flags param eddsa)))",
     499             :                                 curves[testno]);
     500             :         }
     501             :       else
     502           3 :         rc = gcry_sexp_build (&keyparm, NULL,
     503             :                               "(genkey(ecc(curve %s)(flags param)))",
     504             :                               curves[testno]);
     505           4 :       if (rc)
     506           0 :         die ("error creating S-expression: %s\n", gpg_strerror (rc));
     507           4 :       rc = gcry_pk_genkey (&key, keyparm);
     508           4 :       gcry_sexp_release (keyparm);
     509           4 :       if (rc)
     510           0 :         die ("error generating ECC key using curve %s: %s\n",
     511             :              curves[testno], gpg_strerror (rc));
     512             : 
     513           4 :       if (verbose > 1)
     514           0 :         show_sexp ("ECC key:\n", key);
     515             : 
     516           4 :       check_generated_ecc_key (key);
     517             : 
     518           4 :       gcry_sexp_release (key);
     519             :     }
     520             : 
     521           1 :   if (verbose)
     522           0 :     show ("creating ECC key using curve Ed25519 for ECDSA\n");
     523           1 :   rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve Ed25519)))");
     524           1 :   if (rc)
     525           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     526           1 :   rc = gcry_pk_genkey (&key, keyparm);
     527           1 :   gcry_sexp_release (keyparm);
     528           1 :   if (rc && !in_fips_mode)
     529           0 :     die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
     530             :          gpg_strerror (rc));
     531           1 :   else if (!rc && in_fips_mode)
     532           0 :     fail ("generating Ed25519 key must not work!");
     533             : 
     534           1 :   if (verbose && rc && in_fips_mode)
     535           0 :     show ("... correctly rejected key creation in FIPS mode (%s)\n",
     536             :           gpg_strerror (rc));
     537             : 
     538           1 :   if (!rc)
     539             :     {
     540           1 :       if (verbose > 1)
     541           0 :         show_sexp ("ECC key:\n", key);
     542             : 
     543           1 :       check_generated_ecc_key (key);
     544             :     }
     545           1 :   gcry_sexp_release (key);
     546             : 
     547           1 :   if (verbose)
     548           0 :     show ("creating ECC key using curve Ed25519 for ECDSA (nocomp)\n");
     549           1 :   rc = gcry_sexp_build (&keyparm, NULL,
     550             :                         "(genkey(ecc(curve Ed25519)(flags nocomp)))");
     551           1 :   if (rc)
     552           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     553           1 :   rc = gcry_pk_genkey (&key, keyparm);
     554           1 :   gcry_sexp_release (keyparm);
     555           1 :   if (rc && !in_fips_mode)
     556           0 :     die ("error generating ECC key using curve Ed25519 for ECDSA"
     557             :          " (nocomp): %s\n",
     558             :          gpg_strerror (rc));
     559           1 :   else if (!rc && in_fips_mode)
     560           0 :     fail ("generating Ed25519 key must not work in FIPS mode!");
     561             : 
     562           1 :   if (verbose && rc && in_fips_mode)
     563           0 :     show ("... correctly rejected key creation in FIPS mode (%s)\n",
     564             :           gpg_strerror (rc));
     565           1 :   gcry_sexp_release (key);
     566             : 
     567           1 :   if (verbose)
     568           0 :     show ("creating ECC key using curve NIST P-384 for ECDSA\n");
     569             : 
     570             :   /* Must be specified as nistp384 (one word), because ecc_generate
     571             :    * uses _gcry_sexp_nth_string which takes the first word of the name
     572             :    * and thus libgcrypt can't find it later in its curves table.  */
     573           1 :   rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve nistp384)))");
     574           1 :   if (rc)
     575           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     576           1 :   rc = gcry_pk_genkey (&key, keyparm);
     577           1 :   gcry_sexp_release (keyparm);
     578           1 :   if (rc)
     579           0 :     die ("error generating ECC key using curve NIST P-384 for ECDSA: %s\n",
     580             :          gpg_strerror (rc));
     581             : 
     582           1 :   if (verbose > 1)
     583           0 :     show_sexp ("ECC key:\n", key);
     584             : 
     585           1 :   check_generated_ecc_key (key);
     586           1 :   gcry_sexp_release (key);
     587             : 
     588           1 :   if (verbose)
     589           0 :     show ("creating ECC key using curve NIST P-384 for ECDSA (nocomp)\n");
     590           1 :   rc = gcry_sexp_build (&keyparm, NULL,
     591             :                         "(genkey(ecc(curve nistp384)(flags nocomp)))");
     592           1 :   if (rc)
     593           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     594           1 :   rc = gcry_pk_genkey (&key, keyparm);
     595           1 :   gcry_sexp_release (keyparm);
     596           1 :   if (rc)
     597           0 :     die ("error generating ECC key using curve NIST P-384 for ECDSA"
     598             :          " (nocomp): %s\n",
     599             :          gpg_strerror (rc));
     600             : 
     601           1 :   if (verbose > 1)
     602           0 :     show_sexp ("ECC key:\n", key);
     603             : 
     604           1 :   check_generated_ecc_key (key);
     605           1 :   gcry_sexp_release (key);
     606             : 
     607             : 
     608           1 :   if (verbose)
     609           0 :     show ("creating ECC key using curve Ed25519 for ECDSA (transient-key)\n");
     610           1 :   rc = gcry_sexp_build (&keyparm, NULL,
     611             :                         "(genkey(ecc(curve Ed25519)(flags transient-key)))");
     612           1 :   if (rc)
     613           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     614           1 :   rc = gcry_pk_genkey (&key, keyparm);
     615           1 :   gcry_sexp_release (keyparm);
     616           1 :   if (rc && !in_fips_mode)
     617           0 :     die ("error generating ECC key using curve Ed25519 for ECDSA"
     618             :          " (transient-key): %s\n",
     619             :          gpg_strerror (rc));
     620           1 :   else if (!rc && in_fips_mode)
     621           0 :     fail ("generating Ed25519 key must not work in FIPS mode!");
     622             : 
     623           1 :   if (verbose && rc && in_fips_mode)
     624           0 :     show ("... correctly rejected key creation in FIPS mode (%s)\n",
     625             :           gpg_strerror (rc));
     626             : 
     627           1 :   if (!rc)
     628             :     {
     629           1 :       if (verbose > 1)
     630           0 :         show_sexp ("ECC key:\n", key);
     631           1 :       check_generated_ecc_key (key);
     632             :     }
     633           1 :   gcry_sexp_release (key);
     634             : 
     635           1 :   if (verbose)
     636           0 :     show ("creating ECC key using curve Ed25519 for ECDSA "
     637             :           "(transient-key no-keytest)\n");
     638           1 :   rc = gcry_sexp_build (&keyparm, NULL,
     639             :                         "(genkey(ecc(curve Ed25519)"
     640             :                         "(flags transient-key no-keytest)))");
     641           1 :   if (rc)
     642           0 :     die ("error creating S-expression: %s\n", gpg_strerror (rc));
     643           1 :   rc = gcry_pk_genkey (&key, keyparm);
     644           1 :   gcry_sexp_release (keyparm);
     645           1 :   if (rc && !in_fips_mode)
     646           0 :     die ("error generating ECC key using curve Ed25519 for ECDSA"
     647             :          " (transient-key no-keytest): %s\n",
     648             :          gpg_strerror (rc));
     649           1 :   else if (!rc && in_fips_mode)
     650           0 :     fail ("generating Ed25519 key must not work in FIPS mode!");
     651             : 
     652           1 :   if (verbose && rc && in_fips_mode)
     653           0 :     show ("... correctly rejected key creation in FIPS mode (%s)\n",
     654             :           gpg_strerror (rc));
     655             : 
     656           1 :   if (!rc)
     657             :     {
     658           1 :       if (verbose > 1)
     659           0 :         show_sexp ("ECC key:\n", key);
     660           1 :       check_generated_ecc_key (key);
     661             :     }
     662           1 :   gcry_sexp_release (key);
     663           1 : }
     664             : 
     665             : 
     666             : static void
     667           1 : check_nonce (void)
     668             : {
     669             :   char a[32], b[32];
     670             :   int i,j;
     671           1 :   int oops=0;
     672             : 
     673           1 :   if (verbose)
     674           0 :     show ("checking gcry_create_nonce\n");
     675             : 
     676           1 :   gcry_create_nonce (a, sizeof a);
     677          11 :   for (i=0; i < 10; i++)
     678             :     {
     679          10 :       gcry_create_nonce (b, sizeof b);
     680          10 :       if (!memcmp (a, b, sizeof a))
     681           0 :         die ("identical nonce found\n");
     682             :     }
     683          11 :   for (i=0; i < 10; i++)
     684             :     {
     685          10 :       gcry_create_nonce (a, sizeof a);
     686          10 :       if (!memcmp (a, b, sizeof a))
     687           0 :         die ("identical nonce found\n");
     688             :     }
     689             : 
     690             :  again:
     691          32 :   for (i=1,j=0; i < sizeof a; i++)
     692          31 :     if (a[0] == a[i])
     693           1 :       j++;
     694           1 :   if (j+1 == sizeof (a))
     695             :     {
     696           0 :       if (oops)
     697           0 :         die ("impossible nonce found\n");
     698           0 :       oops++;
     699           0 :       gcry_create_nonce (a, sizeof a);
     700           0 :       goto again;
     701             :     }
     702           1 : }
     703             : 
     704             : 
     705             : static void
     706           0 : progress_cb (void *cb_data, const char *what, int printchar,
     707             :                   int current, int total)
     708             : {
     709             :   (void)cb_data;
     710             :   (void)what;
     711             :   (void)current;
     712             :   (void)total;
     713             : 
     714           0 :   if (printchar == '\n')
     715           0 :     fputs ( "<LF>", stdout);
     716             :   else
     717           0 :     putchar (printchar);
     718           0 :   fflush (stdout);
     719           0 : }
     720             : 
     721             : 
     722             : static void
     723           0 : usage (int mode)
     724             : {
     725           0 :   fputs ("usage: " PGM " [options] [{rsa|elg|dsa|ecc|nonce}]\n"
     726             :          "Options:\n"
     727             :          "  --verbose       be verbose\n"
     728             :          "  --debug         flyswatter\n"
     729             :          "  --fips          run in FIPS mode\n"
     730             :          "  --progress      print progress indicators\n",
     731             :          mode? stderr : stdout);
     732           0 :   if (mode)
     733           0 :     exit (1);
     734           0 : }
     735             : 
     736             : int
     737           1 : main (int argc, char **argv)
     738             : {
     739           1 :   int last_argc = -1;
     740           1 :   int opt_fips = 0;
     741           1 :   int with_progress = 0;
     742             : 
     743           1 :   if (argc)
     744           1 :     { argc--; argv++; }
     745             : 
     746           2 :   while (argc && last_argc != argc )
     747             :     {
     748           0 :       last_argc = argc;
     749           0 :       if (!strcmp (*argv, "--"))
     750             :         {
     751           0 :           argc--; argv++;
     752           0 :           break;
     753             :         }
     754           0 :       else if (!strcmp (*argv, "--help"))
     755             :         {
     756           0 :           usage (0);
     757           0 :           exit (0);
     758             :         }
     759           0 :       else if (!strcmp (*argv, "--verbose"))
     760             :         {
     761           0 :           verbose++;
     762           0 :           argc--; argv++;
     763             :         }
     764           0 :       else if (!strcmp (*argv, "--debug"))
     765             :         {
     766           0 :           verbose += 2;
     767           0 :           debug++;
     768           0 :           argc--; argv++;
     769             :         }
     770           0 :       else if (!strcmp (*argv, "--fips"))
     771             :         {
     772           0 :           argc--; argv++;
     773           0 :           opt_fips = 1;
     774             :         }
     775           0 :       else if (!strcmp (*argv, "--progress"))
     776             :         {
     777           0 :           argc--; argv++;
     778           0 :           with_progress = 1;
     779             :         }
     780           0 :       else if (!strncmp (*argv, "--", 2))
     781           0 :         die ("unknown option '%s'", *argv);
     782             :       else
     783           0 :         break;
     784             :     }
     785             : 
     786           1 :   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
     787           1 :   if (opt_fips)
     788           0 :     gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0);
     789             : 
     790           1 :   if (!gcry_check_version (GCRYPT_VERSION))
     791           0 :     die ("version mismatch\n");
     792             : 
     793           1 :   if (!opt_fips)
     794           1 :     gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
     795             : 
     796           1 :   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
     797           1 :   if (debug)
     798           0 :     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
     799             :   /* No valuable keys are create, so we can speed up our RNG. */
     800           1 :   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
     801           1 :   if (with_progress)
     802           0 :     gcry_set_progress_handler (progress_cb, NULL);
     803             : 
     804           1 :   if ( gcry_fips_mode_active () )
     805           0 :     in_fips_mode = 1;
     806             : 
     807           1 :   if (opt_fips && !in_fips_mode)
     808           0 :     die ("failed to switch into FIPS mode\n");
     809             : 
     810           1 :   if (!argc)
     811             :     {
     812           1 :       check_rsa_keys ();
     813           1 :       check_elg_keys ();
     814           1 :       check_dsa_keys ();
     815           1 :       check_ecc_keys ();
     816           1 :       check_nonce ();
     817             :     }
     818             :   else
     819             :     {
     820           0 :       for (; argc; argc--, argv++)
     821           0 :         if (!strcmp (*argv, "rsa"))
     822           0 :           check_rsa_keys ();
     823           0 :         else if (!strcmp (*argv, "elg"))
     824           0 :           check_elg_keys ();
     825           0 :         else if (!strcmp (*argv, "dsa"))
     826           0 :           check_dsa_keys ();
     827           0 :         else if (!strcmp (*argv, "ecc"))
     828           0 :           check_ecc_keys ();
     829           0 :         else if (!strcmp (*argv, "nonce"))
     830           0 :           check_nonce ();
     831             :         else
     832           0 :           usage (1);
     833             :     }
     834             : 
     835           1 :   return error_count? 1:0;
     836             : }

Generated by: LCOV version 1.11