[svn] gcry - r1348 - trunk/tests

svn author wk cvs at cvs.gnupg.org
Mon Oct 6 18:31:38 CEST 2008


Author: wk
Date: 2008-10-06 18:31:37 +0200 (Mon, 06 Oct 2008)
New Revision: 1348

Modified:
   trunk/tests/ChangeLog
   trunk/tests/cavs_driver.pl
   trunk/tests/fipsdrv.c
Log:
New CAVS driver from upstream.
Fixed RSA FIPS tests.


Modified: trunk/tests/ChangeLog
===================================================================
--- trunk/tests/ChangeLog	2008-10-02 19:30:08 UTC (rev 1347)
+++ trunk/tests/ChangeLog	2008-10-06 16:31:37 UTC (rev 1348)
@@ -1,3 +1,15 @@
+2008-10-06  Werner Koch  <wk at g10code.com>
+
+	* cavs_driver.pl: New version from upstream.
+	(libgcrypt_rsa_verify($$$$)): Pass pkcs1.
+	(libgcrypt_rsa_sign($$$)): Pass pkcs1 and hash algo.
+
+	* fipsdrv.c (run_rsa_sign): Hash data in pkcs1 mode.
+	(run_rsa_verify): Ditto.
+	(read_key_file): Rename to read_private_key_file.  Factor public
+	key code out to..
+	(read_public_key_file): .. new.
+
 2008-10-02  Werner Koch  <wk at g10code.com>
 
 	* fipsdrv.c (print_buffer): Add base64 printing code.
@@ -5,6 +17,7 @@
 	(run_rsa_gen, run_rsa_sign): New.
 	(main): Add modes rsa-gen, rsa-sign and rsa-verify.
 
+	
 2008-09-29  Werner Koch  <wk at g10code.com>
 
 	* fipsdrv.c: Merge code from fipsrngdrv.c

Modified: trunk/tests/cavs_driver.pl
===================================================================
--- trunk/tests/cavs_driver.pl	2008-10-02 19:30:08 UTC (rev 1347)
+++ trunk/tests/cavs_driver.pl	2008-10-06 16:31:37 UTC (rev 1348)
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 #
-# Id: cavs_driver.pl 1236 2008-09-17 13:00:06Z smueller
+# $Id: cavs_driver.pl 1243 2008-09-18 18:42:57Z smueller $
 #
 # CAVS test driver (based on the OpenSSL driver)
 # Written by: Stephan Müller <sm at atsec.com>
@@ -294,7 +294,6 @@
 	return pipe_through_program($data,$program);
 }
 
-
 sub libgcrypt_rsa_sign($$$) {
 	my $data = shift;
 	my $hashalgo = shift;
@@ -302,49 +301,44 @@
 
 	die "ARCFOUR not available for RSA" if $opt{'R'};
 	return pipe_through_program($data,
-                  "fipsdrv --verbose --algo $hashalgo --key $keyfile rsa-sign");
+		"fipsdrv --verbose --pkcs1 --algo $hashalgo --key $keyfile rsa-sign");
 }
 
-
 sub libgcrypt_rsa_verify($$$$) {
 	my $data = shift;
-	my $cipher = shift;
+	my $hashalgo = shift;
 	my $keyfile = shift;
 	my $sigfile = shift;
 
-	$data = hex2bin($data);
 	die "ARCFOUR not available for RSA" if $opt{'R'};
 	$data = pipe_through_program($data,
-                   "fipsdrv --verbose --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify");
+		"fipsdrv --verbose --pkcs1 --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify");
 
 	# Parse through the output information
 	return ($data =~ /GOOD signature/);
 }
 
-
 sub libgcrypt_gen_rsakey($$) {
 	my $keylen = shift;
 	my $file = shift;
 
 	die "ARCFOUR not available for RSA" if $opt{'R'};
 	my @args = ("fipsdrv --keysize $keylen rsa-gen > $file");
-        system(@args) == 0
+	system(@args) == 0
 		or die "system @args failed: $?";
 	die "system @args failed: file $file not created" if (! -f $file);
 }
 
-
 sub libgcrypt_hash($$) {
 	my $pt = shift;
 	my $hashalgo = shift;
 
-        my $program = "fipsdrv --no-fips --algo $hashalgo digest";
+	my $program = "fipsdrv --no-fips --algo $hashalgo digest";
 	die "ARCFOUR not available for hashes" if $opt{'R'};
-        
+
 	return pipe_through_program($pt, $program);
 }
 
-
 sub libgcrypt_state_cipher($$$$$) {
 	my $cipher = shift;
 	my $enc = (shift) ? "encrypt": "decrypt";
@@ -356,7 +350,6 @@
 	return $program;
 }
 
-
 sub libgcrypt_state_rng($$$) {
 	my $key = shift;
 	my $dt = shift;
@@ -372,11 +365,41 @@
 	my $hashtype = shift;
 
 	my $program = "fipsdrv --no-fips --key $key --algo $hashtype hmac-sha";
-	return pipe_through_program($msg, $program);
+	return pipe_through_program($msg, $program);	
 }
 
 ######### End of libgcrypt implementation ################
 
+################################################################
+###### Vendor1 interface functions
+################################################################
+
+sub vendor1_encdec($$$$$) {
+	my $key=shift;
+	my $iv=shift;
+	my $cipher=shift;
+	my $enc = (shift) ? "encrypt" : "decrypt";
+	my $data=shift;
+
+	$data=hex2bin($data);
+	my $program = "./aes $enc $key";
+	$data=pipe_through_program($data,$program);
+	return bin2hex($data);
+}
+
+sub vendor1_state_cipher($$$$$) {
+	my $cipher = shift;
+	my $encdec = shift;
+	my $bufsize = shift;
+	my $key = shift;
+	my $iv = shift;
+
+	$key = bin2hex($key);
+	my $enc = $encdec ? "encrypt": "decrypt";
+	my $out = "./aes $enc $key $bufsize";
+	return $out;
+}
+
 ##### No other interface functions below this point ######
 ##########################################################
 
@@ -878,7 +901,7 @@
 		$key1= $key1 . $key3;
 	}
 	
-	$out .= "IV = $iv\n";
+	$out .= "IV = $iv\n" if (defined($iv) && $iv ne "");
 	if ($enc) {
 		$out .= "PLAINTEXT = $pt\n";
 		$out .= "CIPHERTEXT = " . encrypt($key1, $iv, $cipher, $pt) . "\n";
@@ -997,7 +1020,8 @@
 		}
         	my $keylen = length($key1);
 
-                $out .= "IV = ". bin2hex($iv). "\n";
+                $out .= "IV = ". bin2hex($iv) . "\n"
+			if (defined($iv) && $iv ne "");
 
                 if ($enc) {
                         $out .= "PLAINTEXT = ". bin2hex($source_data). "\n";
@@ -1016,12 +1040,12 @@
                         $old_calc_data = $calc_data;
 
 			# $calc_data = AES($key, $calc_data);
-		        #print STDERR "source_data=", bin2hex($source_data), "\n";
+			#print STDERR "source_data=", bin2hex($source_data), "\n";
 			syswrite $CI, $source_data or die;
 			my $len = sysread $CO, $calc_data, $bufsize;
-		        #print STDERR "len=$len, bufsize=$bufsize\n";
+			#print STDERR "len=$len, bufsize=$bufsize\n";
 			die if $len ne $bufsize;
-		        #print STDERR "calc_data=", bin2hex($calc_data), "\n";
+			#print STDERR "calc_data=", bin2hex($calc_data), "\n";
 
 			if ( (!$enc && $ciph =~ /des/) ||
 			     $ciph =~ /rc4/ ) {
@@ -1235,10 +1259,10 @@
 	print STDERR "Usage:
 $0 [-R] [-I name] <CAVS-test vector file>
 
--R       execution of ARCFOUR instead of OpenSSL
--I NAME  Use interface style NAME:
-            openssl     OpenSSL (default)
-            libgcrypt   Libgcrypt";
+-R	execution of ARCFOUR instead of OpenSSL
+-I NAME	Use interface style NAME:
+		openssl     OpenSSL (default)
+		libgcrypt   Libgcrypt";
 }
 
 # Parser of CAVS test vector file
@@ -1394,7 +1418,7 @@
 				$tt = 2;
 				die "Interface function state_cipher for Stateful Cipher operation defined for tested library"
 					if (!defined($state_cipher));
-			} elsif ($cipher eq "sha" && $tt!=5 && $tt!=6) {
+			} elsif ($cipher =~ /^sha\d+/ && $tt!=5 && $tt!=6) {
 				$tt = 3;
 				die "Interface function hash for Hashing not defined for tested library"
 					if (!defined($hash));
@@ -1523,7 +1547,7 @@
 
 		# call tests if all input data is there
 		if ($tt == 1) {
- 			if ($key1 ne "" && $iv ne "" && $pt ne "" && $cipher ne "") {
+ 			if ($key1 ne "" && $pt ne "" && $cipher ne "") {
 				$out .= kat($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
 				$keytype = "";
 				$key1 = "";
@@ -1534,7 +1558,7 @@
 			}
 		}
 		elsif ($tt == 2) {
-			if ($key1 ne "" && $iv ne "" && $pt ne "" && $cipher ne "") {
+			if ($key1 ne "" && $pt ne "" && $cipher ne "") {
 				$out .= crypto_mct($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
 				$keytype = "";
 				$key1 = "";
@@ -1629,26 +1653,26 @@
 
 	##### Set library
 
-        if ( ! defined $opt{'I'} || $opt{'I'} eq 'openssl' ) {
-	        print STDERR "Using OpenSSL interface functions\n";
-                $encdec =	\&openssl_encdec;
-                $rsa_sign =	\&openssl_rsa_sign;
-                $rsa_verify =	\&openssl_rsa_verify;
-                $gen_rsakey =	\&openssl_gen_rsakey;
-                $hash =		\&openssl_hash;
-                $state_cipher =	\&openssl_state_cipher;
-        } elsif ( $opt{'I'} eq 'libgcrypt' ) {
-                print STDERR "Using libgcrypt interface functions\n";
-                $encdec =	\&libgcrypt_encdec;
-                $rsa_sign =	\&libgcrypt_rsa_sign;
-                $rsa_verify =	\&libgcrypt_rsa_verify;
-                $gen_rsakey =	\&libgcrypt_gen_rsakey;
-                $hash =		\&libgcrypt_hash;
-                $state_cipher =	\&libgcrypt_state_cipher;
-                $state_rng =	\&libgcrypt_state_rng;
-                $hmac =		\&libgcrypt_hmac;
+	if ( ! defined $opt{'I'} || $opt{'I'} eq 'openssl' ) {
+		print STDERR "Using OpenSSL interface functions\n";
+		$encdec =	\&openssl_encdec;
+		$rsa_sign =	\&openssl_rsa_sign;
+		$rsa_verify =	\&openssl_rsa_verify;
+		$gen_rsakey =	\&openssl_gen_rsakey;
+		$hash =		\&openssl_hash;
+		$state_cipher =	\&openssl_state_cipher;
+	} elsif ( $opt{'I'} eq 'libgcrypt' ) {
+		print STDERR "Using libgcrypt interface functions\n";
+		$encdec =	\&libgcrypt_encdec;
+		$rsa_sign =	\&libgcrypt_rsa_sign;
+		$rsa_verify =	\&libgcrypt_rsa_verify;
+		$gen_rsakey =	\&libgcrypt_gen_rsakey;
+		$hash =		\&libgcrypt_hash;
+		$state_cipher =	\&libgcrypt_state_cipher;
+		$state_rng =	\&libgcrypt_state_rng;
+		$hmac =		\&libgcrypt_hmac;
         } else {
-                die "Invalid interface option given"; 
+                die "Invalid interface option given";
         }
 
 	my $infile=$ARGV[0];

Modified: trunk/tests/fipsdrv.c
===================================================================
--- trunk/tests/fipsdrv.c	2008-10-02 19:30:08 UTC (rev 1347)
+++ trunk/tests/fipsdrv.c	2008-10-06 16:31:37 UTC (rev 1348)
@@ -431,11 +431,11 @@
 }
 
 
-/* Read the file FNAME assuming it is a PEM encoded private or public
-   key file and return an S-expression.  With SHOW set, the key
-   parameters are printed.  */
+/* Read the file FNAME assuming it is a PEM encoded private key file
+   and return an S-expression.  With SHOW set, the key parameters are
+   printed.  */
 static gcry_sexp_t
-read_key_file (const char *fname, int private, int show)
+read_private_key_file (const char *fname, int show)
 {
   gcry_error_t err;
   FILE *fp;
@@ -445,7 +445,7 @@
   size_t derlen;
   struct tag_info ti;
   gcry_mpi_t keyparms[8];
-  int n_keyparms = private? 8 : 2;
+  int n_keyparms = 8;
   int idx;
   gcry_sexp_t s_key;
 
@@ -470,7 +470,7 @@
     goto bad_asn1;
   if (ti.length != 1 || *der)
     goto bad_asn1;  /* The value of the first integer is no 0. */
-  der += ti.length; derlen += ti.length;
+  der += ti.length; derlen -= ti.length;
 
   for (idx=0; idx < n_keyparms; idx++)
     {
@@ -488,51 +488,135 @@
       err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
       if (err)
         die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
-      der += ti.length; derlen += ti.length;
+      der += ti.length; derlen -= ti.length;
     }
   if (idx != n_keyparms)
     die ("not enough RSA key parameters\n");
 
   gcry_free (buffer);
 
-  if (private)
+  /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
+  /* First check that p < q; if not swap p and q and recompute u.  */ 
+  if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
     {
-      /* Convert from OpenSSL parameter ordering to the OpenPGP order. */
-      /* First check that p < q; if not swap p and q and recompute u.  */ 
-      if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0)
+      gcry_mpi_swap (keyparms[3], keyparms[4]);
+      gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
+    }
+  
+  /* Build the S-expression.  */
+  err = gcry_sexp_build (&s_key, NULL,
+                         "(private-key(rsa(n%m)(e%m)"
+                         /**/            "(d%m)(p%m)(q%m)(u%m)))",
+                         keyparms[0], keyparms[1], keyparms[2],
+                         keyparms[3], keyparms[4], keyparms[7] );
+  if (err)
+    die ("error building S-expression: %s\n", gpg_strerror (err));
+  
+  for (idx=0; idx < n_keyparms; idx++)
+    gcry_mpi_release (keyparms[idx]);
+  
+  return s_key;
+  
+ bad_asn1:
+  die ("invalid ASN.1 structure in `%s'\n", fname);
+  return NULL; /*NOTREACHED*/
+}
+
+
+/* Read the file FNAME assuming it is a PEM encoded public key file
+   and return an S-expression.  With SHOW set, the key parameters are
+   printed.  */
+static gcry_sexp_t
+read_public_key_file (const char *fname, int show)
+{
+  gcry_error_t err;
+  FILE *fp;
+  char *buffer;
+  size_t buflen;
+  const unsigned char *der;
+  size_t derlen;
+  struct tag_info ti;
+  gcry_mpi_t keyparms[2];
+  int n_keyparms = 2;
+  int idx;
+  gcry_sexp_t s_key;
+
+  fp = fopen (fname, binary_input?"rb":"r");
+  if (!fp)
+    die ("can't open `%s': %s\n", fname, strerror (errno));
+  buffer = read_file (fp, 0, &buflen);
+  if (!buffer)
+    die ("error reading `%s'\n", fname);
+  fclose (fp);
+
+  buflen = base64_decode (buffer, buflen);
+  
+  /* Parse the ASN.1 structure.  */
+  der = (const unsigned char*)buffer;
+  derlen = buflen;
+  if ( parse_tag (&der, &derlen, &ti)
+       || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+    goto bad_asn1;
+  if ( parse_tag (&der, &derlen, &ti)
+       || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+    goto bad_asn1;
+  /* We skip the description of the key parameters and assume it is RSA.  */
+  der += ti.length; derlen -= ti.length;
+  
+  if ( parse_tag (&der, &derlen, &ti)
+       || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef)
+    goto bad_asn1;
+  if (ti.length < 1 || *der)
+    goto bad_asn1;  /* The number of unused bits needs to be 0. */
+  der += 1; derlen -= 1;
+
+  /* Parse the BIT string.  */
+  if ( parse_tag (&der, &derlen, &ti)
+       || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef)
+    goto bad_asn1;
+
+  for (idx=0; idx < n_keyparms; idx++)
+    {
+      if ( parse_tag (&der, &derlen, &ti)
+           || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef)
+        goto bad_asn1;
+      if (show)
         {
-          gcry_mpi_swap (keyparms[3], keyparms[4]);
-          gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]);
+          char prefix[2];
+
+          prefix[0] = idx < 2? "ne"[idx] : '?';
+          prefix[1] = 0;
+          showhex (prefix, der, ti.length);
         }
-      
-      /* Build the S-expression.  */
-      err = gcry_sexp_build (&s_key, NULL,
-                             "(private-key(rsa(n%m)(e%m)"
-                             /**/            "(d%m)(p%m)(q%m)(u%m)))",
-                             keyparms[0], keyparms[1], keyparms[2],
-                             keyparms[3], keyparms[4], keyparms[7] );
+      err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL);
+      if (err)
+        die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err));
+      der += ti.length; derlen -= ti.length;
     }
-  else
-    {
-      err = gcry_sexp_build (&s_key, NULL,
-                             "(public-key(rsa(n%m)(e%m)))",
-                             keyparms[0], keyparms[1]);
+  if (idx != n_keyparms)
+    die ("not enough RSA key parameters\n");
 
-    }
+  gcry_free (buffer);
+
+  /* Build the S-expression.  */
+  err = gcry_sexp_build (&s_key, NULL,
+                         "(public-key(rsa(n%m)(e%m)))",
+                         keyparms[0], keyparms[1] );
   if (err)
     die ("error building S-expression: %s\n", gpg_strerror (err));
   
   for (idx=0; idx < n_keyparms; idx++)
     gcry_mpi_release (keyparms[idx]);
-
+  
   return s_key;
-
+  
  bad_asn1:
   die ("invalid ASN.1 structure in `%s'\n", fname);
   return NULL; /*NOTREACHED*/
 }
 
 
+
 /* Read the file FNAME assuming it is a binary signature result and
    return an an S-expression suitable for gcry_pk_verify.  */
 static gcry_sexp_t
@@ -1062,11 +1146,20 @@
   size_t outlen;
   
 /*   showhex ("D", data, datalen); */
+  if (pkcs1)
+    {
+      unsigned char hash[50];
+      unsigned int hashsize;
 
-  if (pkcs1)
-    err = gcry_sexp_build (&s_data, NULL,
-                           "(data (flags pkcs1)(hash %s %b))",
-                           gcry_md_algo_name (hashalgo), (int)datalen, data);
+      hashsize = gcry_md_get_algo_dlen (hashalgo);
+      if (!hashsize || hashsize > sizeof hash)
+        die ("digest too long for buffer or unknown hash algorithm\n");
+      gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+      err = gcry_sexp_build (&s_data, NULL,
+                             "(data (flags pkcs1)(hash %s %b))",
+                             gcry_md_algo_name (hashalgo),
+                             (int)hashsize, hash);
+    }
   else
     {
       gcry_mpi_t tmp;
@@ -1083,12 +1176,12 @@
     die ("gcry_sexp_build failed for RSA data input: %s\n",
          gpg_strerror (err));
 
-  s_key = read_key_file (keyfile, 1, 0);
+  s_key = read_private_key_file (keyfile, 0);
 
   err = gcry_pk_sign (&s_sig, s_data, s_key);
   if (err)
     {
-      gcry_sexp_release (read_key_file (keyfile, 1, 1));
+      gcry_sexp_release (read_private_key_file (keyfile, 1));
       die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n",
            (int)datalen, keyfile, gpg_strerror (err));
     }
@@ -1141,9 +1234,19 @@
   gcry_sexp_t s_data, s_key, s_sig;
   
   if (pkcs1)
-    err = gcry_sexp_build (&s_data, NULL,
-                           "(data (flags pkcs1)(hash %s %b))",
-                           gcry_md_algo_name (hashalgo), (int)datalen, data);
+    {
+      unsigned char hash[64];
+      unsigned int hashsize;
+
+      hashsize = gcry_md_get_algo_dlen (hashalgo);
+      if (!hashsize || hashsize > sizeof hash)
+        die ("digest too long for buffer or unknown hash algorithm\n");
+      gcry_md_hash_buffer (hashalgo, hash, data, datalen);
+      err = gcry_sexp_build (&s_data, NULL,
+                             "(data (flags pkcs1)(hash %s %b))",
+                             gcry_md_algo_name (hashalgo),
+                             (int)hashsize, hash);
+    }
   else
     {
       gcry_mpi_t tmp;
@@ -1160,15 +1263,15 @@
     die ("gcry_sexp_build failed for RSA data input: %s\n",
          gpg_strerror (err));
 
-  s_key = read_key_file (keyfile, 0, 0);
+  s_key = read_public_key_file (keyfile, 0);
 
   s_sig = read_sig_file (sigfile);
 
   err = gcry_pk_verify (s_sig, s_data, s_key);
   if (!err)
-    puts ("GOOD signature\n");
+    puts ("GOOD signature");
   else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE)
-    puts ("BAD signature\n");
+    puts ("BAD signature");
   else
     printf ("ERROR (%s)\n", gpg_strerror (err));
 




More information about the Gnupg-commits mailing list