LCOV - code coverage report
Current view: top level - tests - pubkey.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 350 502 69.7 %
Date: 2016-09-12 12:23:59 Functions: 19 23 82.6 %

          Line data    Source code
       1             : /* pubkey.c - Public key encryption/decryption tests
       2             :  *      Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of Libgcrypt.
       5             :  *
       6             :  * Libgcrypt is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU Lesser General Public License as
       8             :  * published by the Free Software Foundation; either version 2.1 of
       9             :  * the License, or (at your option) any later version.
      10             :  *
      11             :  * Libgcrypt is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public
      17             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #ifdef HAVE_CONFIG_H
      21             : #include <config.h>
      22             : #endif
      23             : #include <stdarg.h>
      24             : #include <stdio.h>
      25             : #include <stdlib.h>
      26             : #include <string.h>
      27             : 
      28             : 
      29             : #include "../src/gcrypt-int.h"
      30             : 
      31             : #define my_isascii(c) (!((c) & 0x80))
      32             : #define digitp(p)   (*(p) >= '0' && *(p) <= '9')
      33             : #define hexdigitp(a) (digitp (a)                     \
      34             :                       || (*(a) >= 'A' && *(a) <= 'F')  \
      35             :                       || (*(a) >= 'a' && *(a) <= 'f'))
      36             : #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
      37             :                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
      38             : #define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
      39             : #define DIM(v)               (sizeof(v)/sizeof((v)[0]))
      40             : #define DIMof(type,member)   DIM(((type *)0)->member)
      41             : 
      42             : 
      43             : /* Sample RSA keys, taken from basic.c.  */
      44             : 
      45             : static const char sample_private_key_1[] =
      46             : "(private-key\n"
      47             : " (openpgp-rsa\n"
      48             : "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
      49             :       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
      50             :       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
      51             :       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
      52             : "  (e #010001#)\n"
      53             : "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
      54             :       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
      55             :       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
      56             :       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
      57             : "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
      58             :       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
      59             : "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
      60             :       "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
      61             : "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
      62             :       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
      63             : " )\n"
      64             : ")\n";
      65             : 
      66             : /* The same key as above but without p, q and u to test the non CRT case. */
      67             : static const char sample_private_key_1_1[] =
      68             : "(private-key\n"
      69             : " (openpgp-rsa\n"
      70             : "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
      71             :       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
      72             :       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
      73             :       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
      74             : "  (e #010001#)\n"
      75             : "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
      76             :       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
      77             :       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
      78             :       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
      79             : " )\n"
      80             : ")\n";
      81             : 
      82             : /* The same key as above but just without q to test the non CRT case.  This
      83             :    should fail. */
      84             : static const char sample_private_key_1_2[] =
      85             : "(private-key\n"
      86             : " (openpgp-rsa\n"
      87             : "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
      88             :       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
      89             :       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
      90             :       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
      91             : "  (e #010001#)\n"
      92             : "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
      93             :       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
      94             :       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
      95             :       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
      96             : "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
      97             :       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
      98             : "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
      99             :       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
     100             : " )\n"
     101             : ")\n";
     102             : 
     103             : static const char sample_public_key_1[] =
     104             : "(public-key\n"
     105             : " (rsa\n"
     106             : "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
     107             :       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
     108             :       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
     109             :       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
     110             : "  (e #010001#)\n"
     111             : " )\n"
     112             : ")\n";
     113             : 
     114             : 
     115             : static int verbose;
     116             : static int error_count;
     117             : 
     118             : 
     119             : /* If we have a decent libgpg-error we can use some gcc attributes.  */
     120             : #ifdef GPGRT_ATTR_NORETURN
     121             : static void die (const char *format, ...) GPGRT_ATTR_NR_PRINTF(1,2);
     122             : static void fail (const char *format, ...) GPGRT_ATTR_PRINTF(1,2);
     123             : static void info (const char *format, ...) GPGRT_ATTR_PRINTF(1,2);
     124             : #endif /*GPGRT_ATTR_NORETURN*/
     125             : 
     126             : 
     127             : static void
     128           0 : die (const char *format, ...)
     129             : {
     130             :   va_list arg_ptr ;
     131             : 
     132           0 :   va_start( arg_ptr, format ) ;
     133           0 :   vfprintf (stderr, format, arg_ptr );
     134           0 :   va_end(arg_ptr);
     135           0 :   if (*format && format[strlen(format)-1] != '\n')
     136           0 :     putc ('\n', stderr);
     137           0 :   exit (1);
     138             : }
     139             : 
     140             : static void
     141           0 : fail (const char *format, ...)
     142             : {
     143             :   va_list arg_ptr;
     144             : 
     145           0 :   va_start (arg_ptr, format);
     146           0 :   vfprintf (stderr, format, arg_ptr);
     147           0 :   va_end (arg_ptr);
     148           0 :   error_count++;
     149           0 : }
     150             : 
     151             : static void
     152           0 : info (const char *format, ...)
     153             : {
     154             :   va_list arg_ptr;
     155             : 
     156           0 :   va_start (arg_ptr, format);
     157           0 :   vfprintf (stderr, format, arg_ptr);
     158           0 :   va_end (arg_ptr);
     159           0 : }
     160             : 
     161             : static void
     162           0 : show_sexp (const char *prefix, gcry_sexp_t a)
     163             : {
     164             :   char *buf;
     165             :   size_t size;
     166             : 
     167           0 :   if (prefix)
     168           0 :     fputs (prefix, stderr);
     169           0 :   size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
     170           0 :   buf = gcry_xmalloc (size);
     171             : 
     172           0 :   gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
     173           0 :   fprintf (stderr, "%.*s", (int)size, buf);
     174           0 :   gcry_free (buf);
     175           0 : }
     176             : 
     177             : /* from ../cipher/pubkey-util.c */
     178             : static gpg_err_code_t
     179           4 : _gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
     180             : {
     181             :   char buf[50];
     182             :   const char *s;
     183             :   size_t n;
     184             : 
     185           4 :   *r_nbits = 0;
     186             : 
     187           4 :   list = gcry_sexp_find_token (list, "nbits", 0);
     188           4 :   if (!list)
     189           0 :     return 0; /* No NBITS found.  */
     190             : 
     191           4 :   s = gcry_sexp_nth_data (list, 1, &n);
     192           4 :   if (!s || n >= DIM (buf) - 1 )
     193             :     {
     194             :       /* NBITS given without a cdr.  */
     195           0 :       gcry_sexp_release (list);
     196           0 :       return GPG_ERR_INV_OBJ;
     197             :     }
     198           4 :   memcpy (buf, s, n);
     199           4 :   buf[n] = 0;
     200           4 :   *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
     201           4 :   gcry_sexp_release (list);
     202           4 :   return 0;
     203             : }
     204             : 
     205             : /* Convert STRING consisting of hex characters into its binary
     206             :    representation and return it as an allocated buffer. The valid
     207             :    length of the buffer is returned at R_LENGTH.  The string is
     208             :    delimited by end of string.  The function returns NULL on
     209             :    error.  */
     210             : static void *
     211           2 : data_from_hex (const char *string, size_t *r_length)
     212             : {
     213             :   const char *s;
     214             :   unsigned char *buffer;
     215             :   size_t length;
     216             : 
     217           2 :   buffer = gcry_xmalloc (strlen(string)/2+1);
     218           2 :   length = 0;
     219          65 :   for (s=string; *s; s +=2 )
     220             :     {
     221          63 :       if (!hexdigitp (s) || !hexdigitp (s+1))
     222           0 :         die ("error parsing hex string `%s'\n", string);
     223          63 :       ((unsigned char*)buffer)[length++] = xtoi_2 (s);
     224             :     }
     225           2 :   *r_length = length;
     226           2 :   return buffer;
     227             : }
     228             : 
     229             : 
     230             : static void
     231           2 : extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
     232             : {
     233             :   gcry_sexp_t l1;
     234             :   const void *a;
     235             :   size_t alen;
     236             :   void *b;
     237             :   size_t blen;
     238             : 
     239           2 :   l1 = gcry_sexp_find_token (sexp, name, 0);
     240           2 :   a = gcry_sexp_nth_data (l1, 1, &alen);
     241           2 :   b = data_from_hex (expected, &blen);
     242           2 :   if (!a)
     243           0 :     fail ("parameter \"%s\" missing in key\n", name);
     244           2 :   else if ( alen != blen || memcmp (a, b, alen) )
     245             :     {
     246           0 :       fail ("parameter \"%s\" does not match expected value\n", name);
     247           0 :       if (verbose)
     248             :         {
     249           0 :           info ("expected: %s\n", expected);
     250           0 :           show_sexp ("sexp: ", sexp);
     251             :         }
     252             :     }
     253           2 :   gcry_free (b);
     254           2 :   gcry_sexp_release (l1);
     255           2 : }
     256             : 
     257             : 
     258             : static void
     259          28 : check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
     260             :                   gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
     261             : {
     262             :   gcry_sexp_t plain1, cipher, l;
     263             :   gcry_mpi_t x0, x1;
     264             :   int rc;
     265             :   int have_flags;
     266             : 
     267             :   /* Extract data from plaintext.  */
     268          28 :   l = gcry_sexp_find_token (plain0, "value", 0);
     269          28 :   x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
     270          28 :   gcry_sexp_release (l);
     271             : 
     272             :   /* Encrypt data.  */
     273          28 :   rc = gcry_pk_encrypt (&cipher, plain0, pkey);
     274          28 :   if (rc)
     275           0 :     die ("encryption failed: %s\n", gcry_strerror (rc));
     276             : 
     277          28 :   l = gcry_sexp_find_token (cipher, "flags", 0);
     278          28 :   have_flags = !!l;
     279          28 :   gcry_sexp_release (l);
     280             : 
     281             :   /* Decrypt data.  */
     282          28 :   rc = gcry_pk_decrypt (&plain1, cipher, skey);
     283          28 :   gcry_sexp_release (cipher);
     284          28 :   if (rc)
     285             :     {
     286           0 :       if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
     287             :         {
     288           0 :           gcry_mpi_release (x0);
     289          28 :           return; /* This is the expected failure code.  */
     290             :         }
     291           0 :       die ("decryption failed: %s\n", gcry_strerror (rc));
     292             :     }
     293             : 
     294             :   /* Extract decrypted data.  Note that for compatibility reasons, the
     295             :      output of gcry_pk_decrypt depends on whether a flags lists (even
     296             :      if empty) occurs in its input data.  Because we passed the output
     297             :      of encrypt directly to decrypt, such a flag value won't be there
     298             :      as of today.  We check it anyway. */
     299          28 :   l = gcry_sexp_find_token (plain1, "value", 0);
     300          28 :   if (l)
     301             :     {
     302           0 :       if (!have_flags)
     303           0 :         die ("compatibility mode of pk_decrypt broken\n");
     304           0 :       gcry_sexp_release (plain1);
     305           0 :       x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
     306           0 :       gcry_sexp_release (l);
     307             :     }
     308             :   else
     309             :     {
     310          28 :       if (have_flags)
     311           0 :         die ("compatibility mode of pk_decrypt broken\n");
     312          28 :       x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
     313          28 :       gcry_sexp_release (plain1);
     314             :     }
     315             : 
     316             :   /* Compare.  */
     317          28 :   if (gcry_mpi_cmp (x0, x1))
     318           0 :     die ("data corrupted\n");
     319          28 :   gcry_mpi_release (x0);
     320          28 :   gcry_mpi_release (x1);
     321             : }
     322             : 
     323             : static void
     324          14 : check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
     325             :             gpg_err_code_t decrypt_fail_code)
     326             : {
     327             :   gcry_sexp_t plain;
     328             :   gcry_mpi_t x;
     329             :   int rc;
     330             : 
     331             :   /* Create plain text.  */
     332          14 :   x = gcry_mpi_new (nbits_data);
     333          14 :   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
     334             : 
     335          14 :   rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
     336          14 :   if (rc)
     337           0 :     die ("converting data for encryption failed: %s\n",
     338             :          gcry_strerror (rc));
     339             : 
     340          14 :   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
     341          14 :   gcry_sexp_release (plain);
     342          14 :   gcry_mpi_release (x);
     343             : 
     344             :   /* Create plain text.  */
     345          14 :   x = gcry_mpi_new (nbits_data);
     346          14 :   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
     347             : 
     348          14 :   rc = gcry_sexp_build (&plain, NULL,
     349             :                         "(data (flags raw no-blinding) (value %m))", x);
     350          14 :   gcry_mpi_release (x);
     351          14 :   if (rc)
     352           0 :     die ("converting data for encryption failed: %s\n",
     353             :          gcry_strerror (rc));
     354             : 
     355          14 :   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
     356          14 :   gcry_sexp_release (plain);
     357          14 : }
     358             : 
     359             : static void
     360           6 : get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
     361             : {
     362             :   gcry_sexp_t pub_key, sec_key;
     363             :   int rc;
     364             :   static const char *secret;
     365             : 
     366             : 
     367           6 :   switch (secret_variant)
     368             :     {
     369           2 :     case 0: secret = sample_private_key_1; break;
     370           2 :     case 1: secret = sample_private_key_1_1; break;
     371           2 :     case 2: secret = sample_private_key_1_2; break;
     372           0 :     default: die ("BUG\n");
     373             :     }
     374             : 
     375           6 :   rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
     376             :                         strlen (sample_public_key_1));
     377           6 :   if (!rc)
     378           6 :     rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
     379           6 :   if (rc)
     380           0 :     die ("converting sample keys failed: %s\n", gcry_strerror (rc));
     381             : 
     382           6 :   *pkey = pub_key;
     383           6 :   *skey = sec_key;
     384           6 : }
     385             : 
     386             : static void
     387           2 : get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
     388             : {
     389             :   gcry_sexp_t key_spec, key, pub_key, sec_key;
     390             :   int rc;
     391             : 
     392           2 :   rc = gcry_sexp_new (&key_spec,
     393             :                       "(genkey (rsa (nbits 4:2048)))", 0, 1);
     394           2 :   if (rc)
     395           0 :     die ("error creating S-expression: %s\n", gcry_strerror (rc));
     396           2 :   rc = gcry_pk_genkey (&key, key_spec);
     397           2 :   gcry_sexp_release (key_spec);
     398           2 :   if (rc)
     399           0 :     die ("error generating RSA key: %s\n", gcry_strerror (rc));
     400             : 
     401           2 :   if (verbose > 1)
     402           0 :     show_sexp ("generated RSA key:\n", key);
     403             : 
     404           2 :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     405           2 :   if (! pub_key)
     406           0 :     die ("public part missing in key\n");
     407             : 
     408           2 :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     409           2 :   if (! sec_key)
     410           0 :     die ("private part missing in key\n");
     411             : 
     412           2 :   gcry_sexp_release (key);
     413           2 :   *pkey = pub_key;
     414           2 :   *skey = sec_key;
     415           2 : }
     416             : 
     417             : 
     418             : static void
     419           2 : get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
     420             : {
     421             :   gcry_sexp_t key_spec, key, pub_key, sec_key;
     422             :   int rc;
     423             : 
     424           2 :   rc = gcry_sexp_new (&key_spec,
     425             :                       "(genkey (rsa (nbits 4:2048)(use-x931)))", 0, 1);
     426           2 :   if (rc)
     427           0 :     die ("error creating S-expression: %s\n", gcry_strerror (rc));
     428           2 :   rc = gcry_pk_genkey (&key, key_spec);
     429           2 :   gcry_sexp_release (key_spec);
     430           2 :   if (rc)
     431           0 :     die ("error generating RSA key: %s\n", gcry_strerror (rc));
     432             : 
     433           2 :   if (verbose > 1)
     434           0 :     show_sexp ("generated RSA (X9.31) key:\n", key);
     435             : 
     436           2 :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     437           2 :   if (!pub_key)
     438           0 :     die ("public part missing in key\n");
     439             : 
     440           2 :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     441           2 :   if (!sec_key)
     442           0 :     die ("private part missing in key\n");
     443             : 
     444           2 :   gcry_sexp_release (key);
     445           2 :   *pkey = pub_key;
     446           2 :   *skey = sec_key;
     447           2 : }
     448             : 
     449             : 
     450             : static void
     451           4 : get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
     452             : {
     453             :   gcry_sexp_t key_spec, key, pub_key, sec_key;
     454             :   int rc;
     455             : 
     456           4 :   rc = gcry_sexp_new
     457             :     (&key_spec,
     458             :      (fixed_x
     459             :       ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
     460             :       : "(genkey (elg (nbits 3:512)))"),
     461             :      0, 1);
     462             : 
     463           4 :   if (rc)
     464           0 :     die ("error creating S-expression: %s\n", gcry_strerror (rc));
     465           4 :   rc = gcry_pk_genkey (&key, key_spec);
     466           4 :   gcry_sexp_release (key_spec);
     467           4 :   if (rc)
     468           0 :     die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
     469             : 
     470           4 :   if (verbose > 1)
     471           0 :     show_sexp ("generated ELG key:\n", key);
     472             : 
     473           4 :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     474           4 :   if (!pub_key)
     475           0 :     die ("public part missing in key\n");
     476             : 
     477           4 :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     478           4 :   if (!sec_key)
     479           0 :     die ("private part missing in key\n");
     480             : 
     481           4 :   gcry_sexp_release (key);
     482           4 :   *pkey = pub_key;
     483           4 :   *skey = sec_key;
     484           4 : }
     485             : 
     486             : 
     487             : static void
     488           4 : get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key)
     489             : {
     490             :   gcry_sexp_t key_spec, key, pub_key, sec_key;
     491             :   int rc;
     492             : 
     493           4 :   rc = gcry_sexp_new (&key_spec,
     494             :                       transient_key
     495             :                       ? "(genkey (dsa (nbits 4:2048)(transient-key)))"
     496             :                       : "(genkey (dsa (nbits 4:2048)))",
     497             :                       0, 1);
     498           4 :   if (rc)
     499           0 :     die ("error creating S-expression: %s\n", gcry_strerror (rc));
     500           4 :   rc = gcry_pk_genkey (&key, key_spec);
     501           4 :   gcry_sexp_release (key_spec);
     502           4 :   if (rc)
     503           0 :     die ("error generating DSA key: %s\n", gcry_strerror (rc));
     504             : 
     505           4 :   if (verbose > 1)
     506           0 :     show_sexp ("generated DSA key:\n", key);
     507             : 
     508           4 :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     509           4 :   if (!pub_key)
     510           0 :     die ("public part missing in key\n");
     511             : 
     512           4 :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     513           4 :   if (!sec_key)
     514           0 :     die ("private part missing in key\n");
     515             : 
     516           4 :   gcry_sexp_release (key);
     517           4 :   *pkey = pub_key;
     518           4 :   *skey = sec_key;
     519           4 : }
     520             : 
     521             : 
     522             : static void
     523           2 : get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
     524             : {
     525             :   gcry_sexp_t key_spec, key, pub_key, sec_key;
     526             :   int rc;
     527             : 
     528           2 :   rc = gcry_sexp_new
     529             :     (&key_spec, "(genkey (dsa (nbits 4:2048)(use-fips186)))",  0, 1);
     530           2 :   if (rc)
     531           0 :     die ("error creating S-expression: %s\n", gcry_strerror (rc));
     532           2 :   rc = gcry_pk_genkey (&key, key_spec);
     533           2 :   gcry_sexp_release (key_spec);
     534           2 :   if (rc)
     535           0 :     die ("error generating DSA key: %s\n", gcry_strerror (rc));
     536             : 
     537           2 :   if (verbose > 1)
     538           0 :     show_sexp ("generated DSA key (fips 186):\n", key);
     539             : 
     540           2 :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     541           2 :   if (!pub_key)
     542           0 :     die ("public part missing in key\n");
     543             : 
     544           2 :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     545           2 :   if (!sec_key)
     546           0 :     die ("private part missing in key\n");
     547             : 
     548           2 :   gcry_sexp_release (key);
     549           2 :   *pkey = pub_key;
     550           2 :   *skey = sec_key;
     551           2 : }
     552             : 
     553             : 
     554             : static void
     555           2 : get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
     556             : {
     557             :   gcry_sexp_t key_spec, key, pub_key, sec_key;
     558             :   int rc;
     559             : 
     560           2 :   rc = gcry_sexp_new
     561             :     (&key_spec,
     562             :      "(genkey (dsa (transient-key)(domain"
     563             :      "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
     564             :      "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
     565             :      "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
     566             :      "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
     567             :      "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
     568             :      "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
     569             :      "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
     570             :      "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
     571             :      "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
     572             :      ")))", 0, 1);
     573           2 :   if (rc)
     574           0 :     die ("error creating S-expression: %s\n", gcry_strerror (rc));
     575           2 :   rc = gcry_pk_genkey (&key, key_spec);
     576           2 :   gcry_sexp_release (key_spec);
     577           2 :   if (rc)
     578           0 :     die ("error generating DSA key: %s\n", gcry_strerror (rc));
     579             : 
     580           2 :   if (verbose > 1)
     581           0 :     show_sexp ("generated DSA key:\n", key);
     582             : 
     583           2 :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     584           2 :   if (!pub_key)
     585           0 :     die ("public part missing in key\n");
     586             : 
     587           2 :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     588           2 :   if (!sec_key)
     589           0 :     die ("private part missing in key\n");
     590             : 
     591           2 :   gcry_sexp_release (key);
     592           2 :   *pkey = pub_key;
     593           2 :   *skey = sec_key;
     594           2 : }
     595             : 
     596             : #if 0
     597             : static void
     598             : get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
     599             : {
     600             :   gcry_sexp_t key_spec, key, pub_key, sec_key;
     601             :   int rc;
     602             : 
     603             :   rc = gcry_sexp_new
     604             :     (&key_spec,
     605             :      "(genkey (dsa (transient-key)(use-fips186)(domain"
     606             :      "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921"
     607             :      "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7"
     608             :      "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0"
     609             :      "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)"
     610             :      "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)"
     611             :      "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab"
     612             :      "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad"
     613             :      "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e"
     614             :      "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)"
     615             :      ")))", 0, 1);
     616             :   if (rc)
     617             :     die ("error creating S-expression: %s\n", gcry_strerror (rc));
     618             :   rc = gcry_pk_genkey (&key, key_spec);
     619             :   gcry_sexp_release (key_spec);
     620             :   if (rc)
     621             :     die ("error generating DSA key: %s\n", gcry_strerror (rc));
     622             : 
     623             :   if (verbose > 1)
     624             :     show_sexp ("generated DSA key:\n", key);
     625             : 
     626             :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     627             :   if (!pub_key)
     628             :     die ("public part missing in key\n");
     629             : 
     630             :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     631             :   if (!sec_key)
     632             :     die ("private part missing in key\n");
     633             : 
     634             :   gcry_sexp_release (key);
     635             :   *pkey = pub_key;
     636             :   *skey = sec_key;
     637             : }
     638             : #endif /*0*/
     639             : 
     640             : static void
     641           2 : get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
     642             : {
     643             :   gcry_sexp_t key_spec, key, pub_key, sec_key;
     644             :   int rc;
     645             : 
     646           2 :   rc = gcry_sexp_new
     647             :     (&key_spec,
     648             :      "(genkey"
     649             :      "  (dsa"
     650             :      "    (nbits 4:2048)"
     651             :      "    (use-fips186)"
     652             :      "    (transient-key)"
     653             :      "    (derive-parms"
     654             :      "      (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))",
     655             :      0, 1);
     656           2 :   if (rc)
     657           0 :     die ("error creating S-expression: %s\n", gcry_strerror (rc));
     658           2 :   rc = gcry_pk_genkey (&key, key_spec);
     659           2 :   gcry_sexp_release (key_spec);
     660           2 :   if (rc)
     661           0 :     die ("error generating DSA key: %s\n", gcry_strerror (rc));
     662             : 
     663           2 :   if (verbose > 1)
     664           0 :     show_sexp ("generated DSA key (fips 186 with seed):\n", key);
     665             : 
     666           2 :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     667           2 :   if (!pub_key)
     668           0 :     die ("public part missing in key\n");
     669             : 
     670           2 :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     671           2 :   if (!sec_key)
     672           0 :     die ("private part missing in key\n");
     673             : 
     674           2 :   gcry_sexp_release (key);
     675           2 :   *pkey = pub_key;
     676           2 :   *skey = sec_key;
     677           2 : }
     678             : 
     679             : 
     680             : static void
     681           2 : check_run (void)
     682             : {
     683             :   gpg_error_t err;
     684             :   gcry_sexp_t pkey, skey;
     685             :   int variant;
     686             : 
     687           8 :   for (variant=0; variant < 3; variant++)
     688             :     {
     689           6 :       if (verbose)
     690           0 :         fprintf (stderr, "Checking sample key (%d).\n", variant);
     691           6 :       get_keys_sample (&pkey, &skey, variant);
     692             :       /* Check gcry_pk_testkey which requires all elements.  */
     693           6 :       err = gcry_pk_testkey (skey);
     694           6 :       if ((variant == 0 && err)
     695           6 :           || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
     696           0 :           die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
     697             :       /* Run the usual check but expect an error from variant 2.  */
     698           6 :       check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
     699           6 :       gcry_sexp_release (pkey);
     700           6 :       gcry_sexp_release (skey);
     701             :     }
     702             : 
     703           2 :   if (verbose)
     704           0 :     fprintf (stderr, "Checking generated RSA key.\n");
     705           2 :   get_keys_new (&pkey, &skey);
     706           2 :   check_keys (pkey, skey, 800, 0);
     707           2 :   gcry_sexp_release (pkey);
     708           2 :   gcry_sexp_release (skey);
     709             : 
     710           2 :   if (verbose)
     711           0 :     fprintf (stderr, "Checking generated RSA key (X9.31).\n");
     712           2 :   get_keys_x931_new (&pkey, &skey);
     713           2 :   check_keys (pkey, skey, 800, 0);
     714           2 :   gcry_sexp_release (pkey);
     715           2 :   gcry_sexp_release (skey);
     716             : 
     717           2 :   if (verbose)
     718           0 :     fprintf (stderr, "Checking generated Elgamal key.\n");
     719           2 :   get_elg_key_new (&pkey, &skey, 0);
     720           2 :   check_keys (pkey, skey, 400, 0);
     721           2 :   gcry_sexp_release (pkey);
     722           2 :   gcry_sexp_release (skey);
     723             : 
     724           2 :   if (verbose)
     725           0 :     fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
     726           2 :   get_elg_key_new (&pkey, &skey, 1);
     727           2 :   check_keys (pkey, skey, 800, 0);
     728           2 :   gcry_sexp_release (pkey);
     729           2 :   gcry_sexp_release (skey);
     730             : 
     731           2 :   if (verbose)
     732           0 :     fprintf (stderr, "Generating DSA key.\n");
     733           2 :   get_dsa_key_new (&pkey, &skey, 0);
     734             :   /* Fixme:  Add a check function for DSA keys.  */
     735           2 :   gcry_sexp_release (pkey);
     736           2 :   gcry_sexp_release (skey);
     737             : 
     738           2 :   if (!gcry_fips_mode_active ())
     739             :     {
     740           2 :       if (verbose)
     741           0 :         fprintf (stderr, "Generating transient DSA key.\n");
     742           2 :       get_dsa_key_new (&pkey, &skey, 1);
     743             :       /* Fixme:  Add a check function for DSA keys.  */
     744           2 :       gcry_sexp_release (pkey);
     745           2 :       gcry_sexp_release (skey);
     746             :     }
     747             : 
     748           2 :   if (verbose)
     749           0 :     fprintf (stderr, "Generating DSA key (FIPS 186).\n");
     750           2 :   get_dsa_key_fips186_new (&pkey, &skey);
     751             :   /* Fixme:  Add a check function for DSA keys.  */
     752           2 :   gcry_sexp_release (pkey);
     753           2 :   gcry_sexp_release (skey);
     754             : 
     755           2 :   if (verbose)
     756           0 :     fprintf (stderr, "Generating DSA key with given domain.\n");
     757           2 :   get_dsa_key_with_domain_new (&pkey, &skey);
     758             :   /* Fixme:  Add a check function for DSA keys.  */
     759           2 :   gcry_sexp_release (pkey);
     760           2 :   gcry_sexp_release (skey);
     761             : 
     762             :   /* We need new test vectors for get_dsa_key_fips186_with_domain_new.  */
     763           2 :   if (verbose)
     764           0 :     fprintf (stderr, "Generating DSA key with given domain (FIPS 186)"
     765             :              " - skipped.\n");
     766             :   /* get_dsa_key_fips186_with_domain_new (&pkey, &skey); */
     767             :   /* /\* Fixme:  Add a check function for DSA keys.  *\/ */
     768             :   /* gcry_sexp_release (pkey); */
     769             :   /* gcry_sexp_release (skey); */
     770             : 
     771           2 :   if (verbose)
     772           0 :     fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n");
     773           2 :   get_dsa_key_fips186_with_seed_new (&pkey, &skey);
     774             :   /* Fixme:  Add a check function for DSA keys.  */
     775           2 :   gcry_sexp_release (pkey);
     776           2 :   gcry_sexp_release (skey);
     777           2 : }
     778             : 
     779             : 
     780             : 
     781             : static gcry_mpi_t
     782           4 : key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name)
     783             : {
     784             :   gcry_sexp_t l1, l2;
     785             :   gcry_mpi_t result;
     786             : 
     787           4 :   l1 = gcry_sexp_find_token (sexp, topname, 0);
     788           4 :   if (!l1)
     789           0 :     return NULL;
     790             : 
     791           4 :   l2 = gcry_sexp_find_token (l1, name, 0);
     792           4 :   if (!l2)
     793             :     {
     794           0 :       gcry_sexp_release (l1);
     795           0 :       return NULL;
     796             :     }
     797             : 
     798           4 :   result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
     799           4 :   gcry_sexp_release (l2);
     800           4 :   gcry_sexp_release (l1);
     801           4 :   return result;
     802             : }
     803             : 
     804             : 
     805             : static void
     806           4 : check_x931_derived_key (int what)
     807             : {
     808             :   static struct {
     809             :     const char *param;
     810             :     const char *expected_d;
     811             :   } testtable[] = {
     812             :     { /* First example from X9.31 (D.1.1).  */
     813             :       "(genkey\n"
     814             :       "  (rsa\n"
     815             :       "    (nbits 4:1024)\n"
     816             :       "    (rsa-use-e 1:3)\n"
     817             :       "    (derive-parms\n"
     818             :       "      (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n"
     819             :       "      (Xp2 #192E8AAC41C576C822D93EA433#)\n"
     820             :       "      (Xp  #D8CD81F035EC57EFE822955149D3BFF70C53520D\n"
     821             :       "            769D6D76646C7A792E16EBD89FE6FC5B605A6493\n"
     822             :       "            39DFC925A86A4C6D150B71B9EEA02D68885F5009\n"
     823             :       "            B98BD984#)\n"
     824             :       "      (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n"
     825             :       "      (Xq2 #134E4CAA16D2350A21D775C404#)\n"
     826             :       "      (Xq  #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n"
     827             :       "            7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n"
     828             :       "            6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n"
     829             :       "            321DE34A#))))\n",
     830             :       "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173"
     831             :       "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961"
     832             :       "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE"
     833             :       "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13"
     834             :       "241D3C4B"
     835             :     },
     836             : 
     837             :     { /* Second example from X9.31 (D.2.1).  */
     838             :       "(genkey\n"
     839             :       "  (rsa\n"
     840             :       "    (nbits 4:1536)\n"
     841             :       "    (rsa-use-e 1:3)\n"
     842             :       "    (derive-parms\n"
     843             :       "      (Xp1 #18272558B61316348297EACA74#)\n"
     844             :       "      (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n"
     845             :       "      (Xp  #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n"
     846             :       "            0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n"
     847             :       "            60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n"
     848             :       "            318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n"
     849             :       "            EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n"
     850             :       "      (Xq1 #11FDDA6E8128DC1629F75192BA#)\n"
     851             :       "      (Xq2 #18AB178ECA907D72472F65E480#)\n"
     852             :       "      (Xq  #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n"
     853             :       "            CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n"
     854             :       "            B734E3FBD15862EBC59FA0425DFA131E549136E8\n"
     855             :       "            E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n"
     856             :       "            EA14B9D5F2A263DC65626E4D6CEAC767#))))\n",
     857             :       "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1"
     858             :       "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2"
     859             :       "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383"
     860             :       "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9"
     861             :       "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C"
     862             :       "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0"
     863             :       "BBCCB9F65C83"
     864             :       /* Note that this example in X9.31 gives this value for D:
     865             : 
     866             :         "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44"
     867             :         "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8"
     868             :         "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E"
     869             :         "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7"
     870             :         "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270"
     871             :         "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342"
     872             :         "EF32E7D9720B"
     873             : 
     874             :         This is a bug in X9.31, obviously introduced by using
     875             : 
     876             :            d = e^{-1} mod (p-1)(q-1)
     877             : 
     878             :          instead of using the universal exponent as required by 4.1.3:
     879             : 
     880             :            d = e^{-1} mod lcm(p-1,q-1)
     881             : 
     882             :          The examples in X9.31 seem to be pretty buggy, see
     883             :          cipher/primegen.c for another bug.  Not only that I had to
     884             :          spend 100 USD for the 66 pages of the document, it also took
     885             :          me several hours to figure out that the bugs are in the
     886             :          document and not in my code.
     887             :        */
     888             :     },
     889             : 
     890             :     { /* First example from NIST RSAVS (B.1.1).  */
     891             :       "(genkey\n"
     892             :       "  (rsa\n"
     893             :       "    (nbits 4:1024)\n"
     894             :       "    (rsa-use-e 1:3)\n"
     895             :       "    (derive-parms\n"
     896             :       "      (Xp1 #1ed3d6368e101dab9124c92ac8#)\n"
     897             :       "      (Xp2 #16e5457b8844967ce83cab8c11#)\n"
     898             :       "      (Xp  #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n"
     899             :       "            ab262da1dcda8194720672a4e02229a0c71f60ae\n"
     900             :       "            c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n"
     901             :       "            cab44595#)\n"
     902             :       "      (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n"
     903             :       "      (Xq2 #1f9cca85f185341516d92e82fd#)\n"
     904             :       "      (Xq  #c8387fd38fa33ddcea6a9de1b2d55410663502db\n"
     905             :       "            c225655a9310cceac9f4cf1bce653ec916d45788\n"
     906             :       "            f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n"
     907             :       "            2f389eda#))))\n",
     908             :       "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b"
     909             :       "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd"
     910             :       "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a"
     911             :       "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0"
     912             :       "dc7e8feb"
     913             :     },
     914             : 
     915             :     { /* Second example from NIST RSAVS (B.1.1).  */
     916             :       "(genkey\n"
     917             :       "  (rsa\n"
     918             :       "    (nbits 4:1536)\n"
     919             :       "    (rsa-use-e 1:3)\n"
     920             :       "    (derive-parms\n"
     921             :       "      (Xp1 #1e64c1af460dff8842c22b64d0#)\n"
     922             :       "      (Xp2 #1e948edcedba84039c81f2ac0c#)\n"
     923             :       "      (Xp  #c8c67df894c882045ede26a9008ab09ea0672077\n"
     924             :       "            d7bc71d412511cd93981ddde8f91b967da404056\n"
     925             :       "            c39f105f7f239abdaff92923859920f6299e82b9\n"
     926             :       "            5bd5b8c959948f4a034d81613d6235a3953b49ce\n"
     927             :       "            26974eb7bb1f14843841281b363b9cdb#)\n"
     928             :       "      (Xq1 #1f3df0f017ddd05611a97b6adb#)\n"
     929             :       "      (Xq2 #143edd7b22d828913abf24ca4d#)\n"
     930             :       "      (Xq  #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n"
     931             :       "            b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n"
     932             :       "            7552195fae8b061077e03920814d8b9cfb5a3958\n"
     933             :       "            b3a82c2a7fc97e55db543948d3396289245336ec\n"
     934             :       "            9e3cb308cc655aebd766340da8921383#))))\n",
     935             :       "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184"
     936             :       "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536"
     937             :       "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461"
     938             :       "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a"
     939             :       "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2"
     940             :       "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4"
     941             :       "2ccf8a84835b"
     942             :     }
     943             :   };
     944             :   gpg_error_t err;
     945           4 :   gcry_sexp_t key_spec = NULL, key = NULL, pub_key = NULL, sec_key = NULL;
     946           4 :   gcry_mpi_t d_expected = NULL, d_have = NULL;
     947             : 
     948           4 :   if (what < 0 && what >= sizeof testtable)
     949           0 :     die ("invalid WHAT value\n");
     950             : 
     951           4 :   err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1);
     952           4 :   if (err)
     953           0 :     die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err));
     954             : 
     955             :   {
     956             :     unsigned nbits;
     957           4 :     err = _gcry_pk_util_get_nbits(key_spec, &nbits);
     958           4 :     if (err)
     959           0 :       die ("nbits not found\n");
     960           4 :     if (gcry_fips_mode_active() && nbits < 2048)
     961             :       {
     962           0 :         info("RSA key test with %d bits skipped in fips mode\n", nbits);
     963           0 :         goto leave;
     964             :       }
     965             :   }
     966             : 
     967           4 :   err = gcry_pk_genkey (&key, key_spec);
     968           4 :   gcry_sexp_release (key_spec);
     969           4 :   if (err)
     970             :     {
     971           0 :       fail ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err));
     972           0 :       goto leave;
     973             :     }
     974             : 
     975           4 :   pub_key = gcry_sexp_find_token (key, "public-key", 0);
     976           4 :   if (!pub_key)
     977           0 :     die ("public part missing in key [%d]\n", what);
     978             : 
     979           4 :   sec_key = gcry_sexp_find_token (key, "private-key", 0);
     980           4 :   if (!sec_key)
     981           0 :     die ("private part missing in key [%d]\n", what);
     982             : 
     983           4 :   err = gcry_mpi_scan
     984           4 :     (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL);
     985           4 :   if (err)
     986           0 :     die ("error converting string [%d]\n", what);
     987             : 
     988           4 :   if (verbose > 1)
     989           0 :     show_sexp ("generated key:\n", key);
     990             : 
     991           4 :   d_have = key_param_from_sexp (sec_key, "rsa", "d");
     992           4 :   if (!d_have)
     993           0 :     die ("parameter d not found in RSA secret key [%d]\n", what);
     994           4 :   if (gcry_mpi_cmp (d_expected, d_have))
     995             :     {
     996           0 :       show_sexp (NULL, sec_key);
     997           0 :       die ("parameter d does match expected value [%d]\n", what);
     998             :     }
     999             : leave:
    1000           4 :   gcry_mpi_release (d_expected);
    1001           4 :   gcry_mpi_release (d_have);
    1002             : 
    1003           4 :   gcry_sexp_release (key);
    1004           4 :   gcry_sexp_release (pub_key);
    1005           4 :   gcry_sexp_release (sec_key);
    1006           4 : }
    1007             : 
    1008             : 
    1009             : 
    1010             : static void
    1011           1 : check_ecc_sample_key (void)
    1012             : {
    1013             :   static const char ecc_private_key[] =
    1014             :     "(private-key\n"
    1015             :     " (ecdsa\n"
    1016             :     "  (curve \"NIST P-256\")\n"
    1017             :     "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
    1018             :     "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n"
    1019             :     "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
    1020             :     "))";
    1021             :   static const char ecc_private_key_wo_q[] =
    1022             :     "(private-key\n"
    1023             :     " (ecdsa\n"
    1024             :     "  (curve \"NIST P-256\")\n"
    1025             :     "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
    1026             :     "))";
    1027             :   static const char ecc_public_key[] =
    1028             :     "(public-key\n"
    1029             :     " (ecdsa\n"
    1030             :     "  (curve \"NIST P-256\")\n"
    1031             :     "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
    1032             :     "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)"
    1033             :     "))";
    1034             :   static const char hash_string[] =
    1035             :     "(data (flags raw)\n"
    1036             :     " (value #00112233445566778899AABBCCDDEEFF"
    1037             :     /* */    "000102030405060708090A0B0C0D0E0F#))";
    1038             :   static const char hash2_string[] =
    1039             :     "(data (flags raw)\n"
    1040             :     " (hash sha1 #00112233445566778899AABBCCDDEEFF"
    1041             :     /* */    "000102030405060708090A0B0C0D0E0F"
    1042             :     /* */    "000102030405060708090A0B0C0D0E0F"
    1043             :     /* */    "00112233445566778899AABBCCDDEEFF#))";
    1044             :   /* hash2, but longer than curve length, so it will be truncated */
    1045             :   static const char hash3_string[] =
    1046             :     "(data (flags raw)\n"
    1047             :     " (hash sha1 #00112233445566778899AABBCCDDEEFF"
    1048             :     /* */    "000102030405060708090A0B0C0D0E0F"
    1049             :     /* */    "000102030405060708090A0B0C0D0E0F"
    1050             :     /* */    "00112233445566778899AABBCCDDEEFF"
    1051             :     /* */    "000102030405060708090A0B0C0D0E0F#))";
    1052             : 
    1053             :   gpg_error_t err;
    1054             :   gcry_sexp_t key, hash, hash2, hash3, sig, sig2;
    1055             : 
    1056           1 :   if (verbose)
    1057           0 :     fprintf (stderr, "Checking sample ECC key.\n");
    1058             : 
    1059           1 :   if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
    1060           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1061             : 
    1062           1 :   if ((err = gcry_sexp_new (&hash2, hash2_string, 0, 1)))
    1063           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1064             : 
    1065           1 :   if ((err = gcry_sexp_new (&hash3, hash3_string, 0, 1)))
    1066           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1067             : 
    1068           1 :   if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
    1069           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1070             : 
    1071           1 :   if ((err = gcry_pk_sign (&sig, hash, key)))
    1072           0 :     die ("gcry_pk_sign failed: %s", gpg_strerror (err));
    1073             : 
    1074           1 :   gcry_sexp_release (key);
    1075           1 :   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    1076           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1077             : 
    1078           1 :   if ((err = gcry_pk_verify (sig, hash, key)))
    1079           0 :     die ("gcry_pk_verify failed: %s", gpg_strerror (err));
    1080             : 
    1081             :   /* Verify hash truncation */
    1082           1 :   gcry_sexp_release (key);
    1083           1 :   if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
    1084           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1085             : 
    1086           1 :   if ((err = gcry_pk_sign (&sig2, hash2, key)))
    1087           0 :     die ("gcry_pk_sign failed: %s", gpg_strerror (err));
    1088             : 
    1089           1 :   gcry_sexp_release (sig);
    1090           1 :   if ((err = gcry_pk_sign (&sig, hash3, key)))
    1091           0 :     die ("gcry_pk_sign failed: %s", gpg_strerror (err));
    1092             : 
    1093           1 :   gcry_sexp_release (key);
    1094           1 :   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    1095           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1096             : 
    1097           1 :   if ((err = gcry_pk_verify (sig, hash2, key)))
    1098           0 :     die ("gcry_pk_verify failed: %s", gpg_strerror (err));
    1099             : 
    1100           1 :   if ((err = gcry_pk_verify (sig2, hash3, key)))
    1101           0 :     die ("gcry_pk_verify failed: %s", gpg_strerror (err));
    1102             : 
    1103             :   /* Now try signing without the Q parameter.  */
    1104             : 
    1105           1 :   gcry_sexp_release (key);
    1106           1 :   if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
    1107           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1108             : 
    1109           1 :   gcry_sexp_release (sig);
    1110           1 :   if ((err = gcry_pk_sign (&sig, hash, key)))
    1111           0 :     die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err));
    1112             : 
    1113           1 :   gcry_sexp_release (key);
    1114           1 :   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    1115           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1116             : 
    1117           1 :   if ((err = gcry_pk_verify (sig, hash, key)))
    1118           0 :     die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err));
    1119             : 
    1120           1 :   gcry_sexp_release (sig);
    1121           1 :   gcry_sexp_release (sig2);
    1122           1 :   gcry_sexp_release (key);
    1123           1 :   gcry_sexp_release (hash);
    1124           1 :   gcry_sexp_release (hash2);
    1125           1 :   gcry_sexp_release (hash3);
    1126           1 : }
    1127             : 
    1128             : 
    1129             : static void
    1130           1 : check_ed25519ecdsa_sample_key (void)
    1131             : {
    1132             :   static const char ecc_private_key[] =
    1133             :     "(private-key\n"
    1134             :     " (ecc\n"
    1135             :     "  (curve \"Ed25519\")\n"
    1136             :     "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
    1137             :     "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
    1138             :     "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
    1139             :     "))";
    1140             :   static const char ecc_private_key_wo_q[] =
    1141             :     "(private-key\n"
    1142             :     " (ecc\n"
    1143             :     "  (curve \"Ed25519\")\n"
    1144             :     "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
    1145             :     "))";
    1146             :   static const char ecc_public_key[] =
    1147             :     "(public-key\n"
    1148             :     " (ecc\n"
    1149             :     "  (curve \"Ed25519\")\n"
    1150             :     "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
    1151             :     "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
    1152             :     "))";
    1153             :   static const char ecc_public_key_comp[] =
    1154             :     "(public-key\n"
    1155             :     " (ecc\n"
    1156             :     "  (curve \"Ed25519\")\n"
    1157             :     "  (q #047b57c2c1d3ded93332b52d588dd45863478b658387413a718779c0dd1a6d95#)"
    1158             :     "))";
    1159             :   static const char hash_string[] =
    1160             :     "(data (flags rfc6979)\n"
    1161             :     " (hash sha256 #00112233445566778899AABBCCDDEEFF"
    1162             :     /* */          "000102030405060708090A0B0C0D0E0F#))";
    1163             : 
    1164             :   gpg_error_t err;
    1165             :   gcry_sexp_t key, hash, sig;
    1166             : 
    1167           1 :   if (verbose)
    1168           0 :     fprintf (stderr, "Checking sample Ed25519/ECDSA key.\n");
    1169             : 
    1170             :   /* Sign.  */
    1171           1 :   if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
    1172           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1173           1 :   if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
    1174           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1175           1 :   if ((err = gcry_pk_sign (&sig, hash, key)))
    1176           0 :     die ("gcry_pk_sign failed: %s", gpg_strerror (err));
    1177             : 
    1178             :   /* Verify.  */
    1179           1 :   gcry_sexp_release (key);
    1180           1 :   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    1181           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1182           1 :   if ((err = gcry_pk_verify (sig, hash, key)))
    1183           0 :     die ("gcry_pk_verify failed: %s", gpg_strerror (err));
    1184             : 
    1185             :   /* Verify again using a compressed public key.  */
    1186           1 :   gcry_sexp_release (key);
    1187           1 :   if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
    1188           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1189           1 :   if ((err = gcry_pk_verify (sig, hash, key)))
    1190           0 :     die ("gcry_pk_verify failed (comp): %s", gpg_strerror (err));
    1191             : 
    1192             :   /* Sign without a Q parameter.  */
    1193           1 :   gcry_sexp_release (key);
    1194           1 :   if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
    1195           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1196           1 :   gcry_sexp_release (sig);
    1197           1 :   if ((err = gcry_pk_sign (&sig, hash, key)))
    1198           0 :     die ("gcry_pk_sign w/o Q failed: %s", gpg_strerror (err));
    1199             : 
    1200             :   /* Verify.  */
    1201           1 :   gcry_sexp_release (key);
    1202           1 :   if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
    1203           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1204           1 :   if ((err = gcry_pk_verify (sig, hash, key)))
    1205           0 :     die ("gcry_pk_verify signed w/o Q failed: %s", gpg_strerror (err));
    1206             : 
    1207             :   /* Verify again using a compressed public key.  */
    1208           1 :   gcry_sexp_release (key);
    1209           1 :   if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
    1210           0 :     die ("line %d: %s", __LINE__, gpg_strerror (err));
    1211           1 :   if ((err = gcry_pk_verify (sig, hash, key)))
    1212           0 :     die ("gcry_pk_verify signed w/o Q failed (comp): %s", gpg_strerror (err));
    1213             : 
    1214           1 :   extract_cmp_data (sig, "r", ("a63123a783ef29b8276e08987daca4"
    1215             :                                "655d0179e22199bf63691fd88eb64e15"));
    1216           1 :   extract_cmp_data (sig, "s", ("0d9b45c696ab90b96b08812b485df185"
    1217             :                                "623ddaf5d02fa65ca5056cb6bd0f16f1"));
    1218             : 
    1219           1 :   gcry_sexp_release (sig);
    1220           1 :   gcry_sexp_release (key);
    1221           1 :   gcry_sexp_release (hash);
    1222           1 : }
    1223             : 
    1224             : 
    1225             : int
    1226           1 : main (int argc, char **argv)
    1227             : {
    1228           1 :   int debug = 0;
    1229             :   int i;
    1230             : 
    1231           1 :   if (argc > 1 && !strcmp (argv[1], "--verbose"))
    1232           0 :     verbose = 1;
    1233           1 :   else if (argc > 1 && !strcmp (argv[1], "--debug"))
    1234             :     {
    1235           0 :       verbose = 2;
    1236           0 :       debug = 1;
    1237             :     }
    1238             : 
    1239           1 :   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
    1240           1 :   if (!gcry_check_version (GCRYPT_VERSION))
    1241           0 :     die ("version mismatch\n");
    1242           1 :   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
    1243           1 :   if (debug)
    1244           0 :     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
    1245             :   /* No valuable keys are create, so we can speed up our RNG. */
    1246           1 :   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
    1247             : 
    1248           3 :   for (i=0; i < 2; i++)
    1249           2 :     check_run ();
    1250             : 
    1251           5 :   for (i=0; i < 4; i++)
    1252           4 :     check_x931_derived_key (i);
    1253             : 
    1254           1 :   check_ecc_sample_key ();
    1255           1 :   if (!gcry_fips_mode_active ())
    1256           1 :     check_ed25519ecdsa_sample_key ();
    1257             : 
    1258           1 :   return !!error_count;
    1259             : }

Generated by: LCOV version 1.11