[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