Six DSA sign test.
authorWerner Koch <wk@gnupg.org>
Thu, 22 Jan 2009 10:38:22 +0000 (10:38 +0000)
committerWerner Koch <wk@gnupg.org>
Thu, 22 Jan 2009 10:38:22 +0000 (10:38 +0000)
Add stuff to help debugging.

tests/ChangeLog
tests/cavs_driver.pl
tests/fipsdrv.c
tests/pubkey.c

index 73bba53..bf9eae6 100644 (file)
@@ -1,3 +1,13 @@
+2009-01-22  Werner Koch  <wk@g10code.com>
+
+       * fipsdrv.c (run_dsa_sign): Use hash of the data.
+       (dsa_gen_with_seed): New.
+       (run_dsa_pqg_gen): Add args SEED and SEEDLEN and use them.
+       (main): Optically take a seed for dsa-pgq-gen.
+       (standalone_mode): New.
+       (main): Add option --standalone.
+       (print_dsa_domain_parameters): Implement standalone mode.
+
 2009-01-21  Werner Koch  <wk@g10code.com>
 
        * fipsdrv.c (run_dsa_verify): Use gcry_mpi_scan again.
index bb5d6fc..19a15b6 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 #
-# $Id: cavs_driver.pl 1488 2009-01-16 14:29:00Z smueller $
+# $Id: cavs_driver.pl 1494 2009-01-21 19:30:16Z smueller $
 #
 # CAVS test driver (based on the OpenSSL driver)
 # Written by: Stephan Müller <sm@atsec.com>
@@ -65,6 +65,7 @@
 #      SigVer15
 #      (SigVerRSA is not applicable for OpenSSL as X9.31 padding
 #              is not done through openssl dgst)
+#      KeyGen RSA X9.31
 #
 # SHA
 #      SHA[1|224|256|384|512]ShortMsg
@@ -149,7 +150,7 @@ my $encdec;
 #        is separated from the previous with a \n in the following order:
 #         P\n
 #         Q\n
-#         N\
+#         N\n
 #         D\n
 my $rsa_derive;
 
@@ -567,7 +568,7 @@ sub libgcrypt_dsa_verify($$$$) {
        close FH;
 
        $ret = pipe_through_program($data,
-               "fipsdrv --verbose --key $keyfile --signature $sigfile dsa-verify");
+               "fipsdrv --key $keyfile --signature $sigfile dsa-verify");
        unlink ($sigfile);
        # Parse through the output information
        return ($ret =~ /GOOD signature/);
@@ -1418,6 +1419,48 @@ sub rsa_sigver($$$$$) {
        return $out;
 }
 
+# RSA X9.31 key generation test
+# $1 modulus size
+# $2 e
+# $3 xp1
+# $4 xp2
+# $5 Xp
+# $6 xq1
+# $7 xq2
+# $8 Xq
+# return: string formatted as expected by CAVS
+sub rsa_keygen($$$$$$$$) {
+       my $modulus = shift;
+       my $e = shift;
+       my $xp1 = shift;
+       my $xp2 = shift;
+       my $Xp = shift;
+       my $xq1 = shift;
+       my $xq2 = shift;
+       my $Xq = shift;
+
+       my $out = "";
+
+       my $ret = &$rsa_derive($modulus, $e, $xp1, $xp2, $Xp, $xq1, $xq2, $Xq);
+
+       my ($P, $Q, $N, $D) = split(/\n/, $ret);
+
+       $out .= "e = $e\n";     
+       $out .= "xp1 = $xp1\n"; 
+       $out .= "xp2 = $xp2\n"; 
+       $out .= "Xp = $Xp\n";   
+       $out .= "p = $P\n";
+       $out .= "xq1 = $xq1\n"; 
+       $out .= "xq2 = $xq2\n"; 
+       $out .= "Xq = $Xq\n";   
+       $out .= "q = $Q\n";
+       $out .= "n = $N\n";
+       $out .= "d = $D\n\n";
+
+       return $out;
+       
+}
+
 # X9.31 RNG test
 # $1 key for the AES cipher
 # $2 DT value
@@ -1616,6 +1659,12 @@ sub parse($$) {
        my $capital_g = "";
        my $capital_y = "";
        my $capital_r = "";
+       my $xp1 = "";
+       my $xp2 = "";
+       my $Xp = "";
+       my $xq1 = "";
+       my $xq2 = "";
+       my $Xq = "";
 
        my $mode = "";
 
@@ -1646,7 +1695,7 @@ sub parse($$) {
 
                ##### Extract cipher
                # XXX there may be more - to be added
-               if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen)/) {
+               if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) {
                        if ($tmpline    =~ /CBC/)   { $mode="cbc"; }
                        elsif ($tmpline =~ /ECB/)   { $mode="ecb"; }
                        elsif ($tmpline =~ /OFB/)   { $mode="ofb"; }
@@ -1695,7 +1744,11 @@ sub parse($$) {
 
                        if ($tt == 0) {
                        ##### Identify the test type
-                               if ($tmpline =~ /SigVer/ && $opt{'D'} ) {
+                               if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) {
+                                       $tt = 13;
+                                       die "Interface function rsa_derive for RSA key generation not defined for tested library"
+                                               if (!defined($rsa_derive));
+                               } elsif ($tmpline =~ /SigVer/ && $opt{'D'} ) {
                                        $tt = 12;
                                        die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library"
                                                if (!defined($dsa_verify) || !defined($dsa_genpubkey));
@@ -1907,6 +1960,36 @@ sub parse($$) {
                                if ($capital_r);
                        $capital_r = $1;
                }
+               elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen
+                       die "xp1 seen twice - check input file"
+                               if ($xp1);
+                       $xp1 = $1;
+               }
+               elsif ($line =~ /^xp2\s*=\s*(.*)/) { #RSA key gen
+                       die "xp2 seen twice - check input file"
+                               if ($xp2);
+                       $xp2 = $1;
+               }
+               elsif ($line =~ /^Xp\s*=\s*(.*)/) { #RSA key gen
+                       die "Xp seen twice - check input file"
+                               if ($Xp);
+                       $Xp = $1;
+               }
+               elsif ($line =~ /^xq1\s*=\s*(.*)/) { #RSA key gen
+                       die "xq1 seen twice - check input file"
+                               if ($xq1);
+                       $xq1 = $1;
+               }
+               elsif ($line =~ /^xq2\s*=\s*(.*)/) { #RSA key gen
+                       die "xq2 seen twice - check input file"
+                               if ($xq2);
+                       $xq2 = $1;
+               }
+               elsif ($line =~ /^Xq\s*=\s*(.*)/) { #RSA key gen
+                       die "Xq seen twice - check input file"
+                               if ($Xq);
+                       $Xq = $1;
+               }
                else {
                        $out .= $line . "\n";
                }
@@ -2027,6 +2110,32 @@ sub parse($$) {
                                $pt = "";
                        }
                }
+               elsif ($tt == 13) {
+                       if($modulus ne "" &&
+                          $e ne "" &&
+                          $xp1 ne "" &&
+                          $xp2 ne "" &&
+                          $Xp ne "" &&
+                          $xq1 ne "" &&
+                          $xq2 ne "" &&
+                          $Xq ne "") {
+                               $out .= rsa_keygen($modulus,
+                                                  $e,
+                                                  $xp1,
+                                                  $xp2,
+                                                  $Xp,
+                                                  $xq1,
+                                                  $xq2,
+                                                  $Xq);
+                               $e = "";
+                               $xp1 = "";
+                               $xp2 = "";
+                               $Xp = "";
+                               $xq1 = "";
+                               $xq2 = "";
+                               $Xq = "";
+                       }
+               }
                elsif ($tt > 0) {
                        die "Test case $tt not defined";
                }
@@ -2078,6 +2187,7 @@ sub main() {
                $rsa_sign =     \&libgcrypt_rsa_sign;
                $rsa_verify =   \&libgcrypt_rsa_verify;
                $gen_rsakey =   \&libgcrypt_gen_rsakey;
+               $rsa_derive =   \&libgcrypt_rsa_derive;
                $hash =         \&libgcrypt_hash;
                $state_cipher = \&libgcrypt_state_cipher;
                $state_cipher_des =     \&libgcrypt_state_cipher_des;
index 2bf2804..f80e30c 100644 (file)
@@ -76,9 +76,13 @@ static int binary_output;
 /* Base64 output flag.  */
 static int base64_output;
 
-/* We need to know whetehr we are in loop_mode.  */
+/* We need to know whether we are in loop_mode.  */
 static int loop_mode;
 
+/* If true some functions are modified to print the output in the CAVS
+   response file format.  */
+static int standalone_mode;
+
 
 /* ASN.1 classes.  */
 enum
@@ -890,7 +894,7 @@ print_mpi_line (gcry_mpi_t a, int no_lz)
 
   p = buf;
   if (no_lz && p[0] == '0' && p[1] == '0' && p[2])
-    p +=2;
+    p += 2;
     
   printf ("%s\n", p);
   if (ferror (stdout))
@@ -1693,6 +1697,36 @@ dsa_gen (int keysize)
 }
 
 
+/* Generate a DSA key of size KEYSIZE and return the complete
+   S-expression.  */
+static gcry_sexp_t
+dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen)
+{
+  gpg_error_t err;
+  gcry_sexp_t keyspec, key;
+
+  err = gcry_sexp_build (&keyspec, NULL, 
+                         "(genkey"
+                         "  (dsa"
+                         "    (nbits %d)"
+                         "    (use-fips186-2)"
+                         "    (derive-parms"
+                         "      (seed %b))))",
+                         keysize, (int)seedlen, seed);
+  if (err)
+    die ("gcry_sexp_build failed for DSA key generation: %s\n",
+         gpg_strerror (err));
+
+  err = gcry_pk_genkey (&key, keyspec);
+  if (err)
+    die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err));
+  
+  gcry_sexp_release (keyspec);
+
+  return key;
+}
+
+
 /* Print the domain parameter as well as the derive information.  KEY
    is the complete key as returned by dsa_gen.  We print to stdout
    with one parameter per line in hex format using this order: p, q,
@@ -1727,6 +1761,8 @@ print_dsa_domain_parameters (gcry_sexp_t key)
       if (!mpi)
         die ("no value for %c parameter in returned public key\n","pqg"[idx]);
       gcry_sexp_release (l2);
+      if (standalone_mode)
+        printf ("%c = ", "PQG"[idx]);
       print_mpi_line (mpi, 1);
       gcry_mpi_release (mpi);
     }
@@ -1749,6 +1785,8 @@ print_dsa_domain_parameters (gcry_sexp_t key)
   data = gcry_sexp_nth_data (l2, 1, &datalen);
   if (!data)
     die ("no seed value in returned key\n");
+  if (standalone_mode)
+    printf ("Seed = ");
   print_data_line (data, datalen);
   gcry_sexp_release (l2);
 
@@ -1758,7 +1796,10 @@ print_dsa_domain_parameters (gcry_sexp_t key)
   string = gcry_sexp_nth_string (l2, 1);
   if (!string)
     die ("no counter value in returned key\n");
-  printf ("%lX\n", strtoul (string, NULL, 10));
+  if (standalone_mode)
+    printf ("c = %ld\n", strtoul (string, NULL, 10));
+  else
+    printf ("%lX\n", strtoul (string, NULL, 10));
   gcry_free (string);
   gcry_sexp_release (l2);
 
@@ -1768,6 +1809,8 @@ print_dsa_domain_parameters (gcry_sexp_t key)
   mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG);
   if (!mpi)
     die ("no h value in returned key\n");
+  if (standalone_mode)
+    printf ("H = ");
   print_mpi_line (mpi, 1);
   gcry_mpi_release (mpi);
   gcry_sexp_release (l2);
@@ -1778,13 +1821,17 @@ print_dsa_domain_parameters (gcry_sexp_t key)
 
 /* Generate DSA domain parameters for a modulus size of KEYSIZE.  The
    result is printed to stdout with one parameter per line in hex
-   format and in this order: p, q, g, seed, counter, h.  */
+   format and in this order: p, q, g, seed, counter, h.  If SEED is
+   not NULL this seed value will be used for the generation.  */
 static void
-run_dsa_pqg_gen (int keysize)
+run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen)
 {
   gcry_sexp_t key;
 
-  key = dsa_gen (keysize);
+  if (seed)
+    key = dsa_gen_with_seed (keysize, seed, seedlen);
+  else
+    key = dsa_gen (keysize);
   print_dsa_domain_parameters (key);
   gcry_sexp_release (key);
 }
@@ -1825,9 +1872,11 @@ run_dsa_sign (const void *data, size_t datalen, const char *keyfile)
 {
   gpg_error_t err;
   gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2;
+  char hash[20];
   gcry_mpi_t tmpmpi;
 
-  err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, data, datalen, NULL);
+  gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen);
+  err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL);
   if (!err)
     {
       err = gcry_sexp_build (&s_data, NULL,
@@ -2121,6 +2170,11 @@ main (int argc, char **argv)
           mct_server = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--standalone"))
+        {
+          standalone_mode = 1;
+          argc--; argv++;
+        }
     }          
 
   if (!argc || argc > 2)
@@ -2163,7 +2217,6 @@ main (int argc, char **argv)
       && !mct_server
       && strcmp (mode_string, "random")
       && strcmp (mode_string, "rsa-gen")
-      && strcmp (mode_string, "dsa-pqg-gen")
       && strcmp (mode_string, "dsa-gen") )
     {
       data = read_file (input, !binary_input, &datalen);
@@ -2415,7 +2468,7 @@ main (int argc, char **argv)
       keysize = keysize_string? atoi (keysize_string) : 0;
       if (keysize < 1024 || keysize > 3072)
         die ("invalid keysize specified; needs to be 1024 .. 3072\n");
-      run_dsa_pqg_gen (keysize);
+      run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen);
     }
   else if (!strcmp (mode_string, "dsa-gen"))
     {
index 9e47589..e5ec464 100644 (file)
@@ -527,7 +527,7 @@ get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
   if (rc)
     die ("error generating DSA key: %s\n", gcry_strerror (rc));
     
-  if (verbose > 1 || 1)
+  if (verbose > 1)
     show_sexp ("generated DSA key (fips 186 with seed):\n", key);
 
   pub_key = gcry_sexp_find_token (key, "public-key", 0);