|
|
diff -up libgcrypt-1.5.3/random/drbg.c.drbg-cavs libgcrypt-1.5.3/random/drbg.c |
|
|
--- libgcrypt-1.5.3/random/drbg.c.drbg-cavs 2017-02-28 14:28:55.695906569 +0100 |
|
|
+++ libgcrypt-1.5.3/random/drbg.c 2017-02-28 14:28:55.700906686 +0100 |
|
|
@@ -2130,6 +2130,16 @@ gcry_drbg_cavs_test (struct gcry_drbg_te |
|
|
if (ret) |
|
|
goto outbuf; |
|
|
|
|
|
+ if (test->entropyrsd) |
|
|
+ { |
|
|
+ gcry_drbg_string_fill (&testentropy, test->entropyrsd, |
|
|
+ test->entropyrsdlen); |
|
|
+ gcry_drbg_string_fill (&addtl, test->addtlrsd, |
|
|
+ test->addtlrsdlen); |
|
|
+ if (gcry_drbg_reseed (drbg, &addtl)) |
|
|
+ goto outbuf; |
|
|
+ } |
|
|
+ |
|
|
gcry_drbg_string_fill (&addtl, test->addtla, test->addtllen); |
|
|
if (test->entpra) |
|
|
{ |
|
|
diff -up libgcrypt-1.5.3/random/random.h.drbg-cavs libgcrypt-1.5.3/random/random.h |
|
|
--- libgcrypt-1.5.3/random/random.h.drbg-cavs 2017-02-28 14:28:55.686906357 +0100 |
|
|
+++ libgcrypt-1.5.3/random/random.h 2017-02-28 14:28:55.700906686 +0100 |
|
|
@@ -69,6 +69,10 @@ struct gcry_drbg_test_vector |
|
|
size_t perslen; |
|
|
unsigned char *expected; |
|
|
size_t expectedlen; |
|
|
+ unsigned char *entropyrsd; |
|
|
+ size_t entropyrsdlen; |
|
|
+ unsigned char *addtlrsd; |
|
|
+ size_t addtlrsdlen; |
|
|
}; |
|
|
|
|
|
gpg_err_code_t gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, |
|
|
diff -up libgcrypt-1.5.3/tests/cavs_driver.pl.drbg-cavs libgcrypt-1.5.3/tests/cavs_driver.pl |
|
|
--- libgcrypt-1.5.3/tests/cavs_driver.pl.drbg-cavs 2017-02-28 14:28:55.674906074 +0100 |
|
|
+++ libgcrypt-1.5.3/tests/cavs_driver.pl 2017-02-28 14:41:46.086048300 +0100 |
|
|
@@ -192,15 +192,17 @@ my $rsa_derive; |
|
|
# Sign a message with RSA |
|
|
# $1: data to be signed in hex form |
|
|
# $2: Hash algo |
|
|
-# $3: Key file in PEM format with the private key |
|
|
+# $3: PSS flag |
|
|
+# $4: Key file in PEM format with the private key |
|
|
# return: digest in hex format |
|
|
my $rsa_sign; |
|
|
|
|
|
# Verify a message with RSA |
|
|
# $1: data to be verified in hex form |
|
|
# $2: hash algo |
|
|
-# $3: file holding the public RSA key in PEM format |
|
|
-# $4: file holding the signature in binary form |
|
|
+# $3: PSS flag |
|
|
+# $4: file holding the public RSA key in PEM format |
|
|
+# $5: file holding the signature in binary form |
|
|
# return: 1 == verified / 0 == not verified |
|
|
my $rsa_verify; |
|
|
|
|
|
@@ -329,6 +331,8 @@ my $rsa_keygen; |
|
|
|
|
|
my $rsa_keygen_kat; |
|
|
|
|
|
+my $drbg_kat; |
|
|
+ |
|
|
################################################################ |
|
|
##### OpenSSL interface functions |
|
|
################################################################ |
|
|
@@ -350,9 +354,10 @@ sub openssl_encdec($$$$$) { |
|
|
return bin2hex($data); |
|
|
} |
|
|
|
|
|
-sub openssl_rsa_sign($$$) { |
|
|
+sub openssl_rsa_sign($$$$) { |
|
|
my $data = shift; |
|
|
my $cipher = shift; |
|
|
+ my $pss = shift; # unsupported |
|
|
my $keyfile = shift; |
|
|
|
|
|
$data=hex2bin($data); |
|
|
@@ -365,6 +370,7 @@ sub openssl_rsa_sign($$$) { |
|
|
sub openssl_rsa_verify($$$$) { |
|
|
my $data = shift; |
|
|
my $cipher = shift; |
|
|
+ my $pss = shift; # unsupported |
|
|
my $keyfile = shift; |
|
|
my $sigfile = shift; |
|
|
|
|
|
@@ -497,27 +503,38 @@ sub libgcrypt_rsa_keygen_kat($$$$) { |
|
|
} |
|
|
|
|
|
|
|
|
-sub libgcrypt_rsa_sign($$$) { |
|
|
+sub libgcrypt_rsa_sign($$$$) { |
|
|
my $data = shift; |
|
|
my $hashalgo = shift; |
|
|
+ my $pss = shift; |
|
|
my $keyfile = shift; |
|
|
|
|
|
die "ARCFOUR not available for RSA" if $opt{'R'}; |
|
|
|
|
|
+ if ($pss) { |
|
|
+ return pipe_through_program($data, |
|
|
+ "fipsdrv --pss --algo $hashalgo --key $keyfile rsa-sign"); |
|
|
+ } |
|
|
return pipe_through_program($data, |
|
|
"fipsdrv --pkcs1 --algo $hashalgo --key $keyfile rsa-sign"); |
|
|
} |
|
|
|
|
|
-sub libgcrypt_rsa_verify($$$$) { |
|
|
+sub libgcrypt_rsa_verify($$$$$) { |
|
|
my $data = shift; |
|
|
my $hashalgo = shift; |
|
|
+ my $pss = shift; |
|
|
my $keyfile = shift; |
|
|
my $sigfile = shift; |
|
|
|
|
|
die "ARCFOUR not available for RSA" if $opt{'R'}; |
|
|
+ |
|
|
+ if ($pss) { |
|
|
+ $data = pipe_through_program($data, |
|
|
+ "fipsdrv --pss --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify"); |
|
|
+ } else { |
|
|
$data = pipe_through_program($data, |
|
|
"fipsdrv --pkcs1 --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify"); |
|
|
- |
|
|
+ } |
|
|
# Parse through the output information |
|
|
return ($data =~ /GOOD signature/); |
|
|
} |
|
|
@@ -543,6 +560,16 @@ sub libgcrypt_hash($$) { |
|
|
return pipe_through_program($pt, $program); |
|
|
} |
|
|
|
|
|
+sub libgcrypt_hash_mct($$) { |
|
|
+ my $pt = shift; |
|
|
+ my $hashalgo = shift; |
|
|
+ |
|
|
+ my $program = "fipsdrv --algo $hashalgo --loop 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"; |
|
|
@@ -693,6 +720,35 @@ sub libgcrypt_dsa_verify($$$$) { |
|
|
return ($ret =~ /GOOD signature/); |
|
|
} |
|
|
|
|
|
+sub libgcrypt_drbg_kat($$$$$$$$$$$$$$$$$) { |
|
|
+ my $mode = shift; |
|
|
+ my $cipher = shift; |
|
|
+ my $pr = shift; |
|
|
+ my $ent = shift; |
|
|
+ my $entlen = shift; |
|
|
+ my $nonce = shift; |
|
|
+ my $noncelen = shift; |
|
|
+ my $entrs = shift; |
|
|
+ my $addtlrs = shift; |
|
|
+ my $entpra = shift; |
|
|
+ my $entprb = shift; |
|
|
+ my $addtla = shift; |
|
|
+ my $addtlb = shift; |
|
|
+ my $addtllen = shift; |
|
|
+ my $pers = shift; |
|
|
+ my $perslen = shift; |
|
|
+ my $expectedlen = shift; |
|
|
+ |
|
|
+ my $entprlen = $entlen; |
|
|
+ |
|
|
+ # concatenate entropy and nonce |
|
|
+ $ent .= $nonce; |
|
|
+ $entlen = $entlen + $noncelen; |
|
|
+ |
|
|
+ return lc(pipe_through_program("$mode\n$pr\n$entlen\n$ent\n$perslen\n$pers\n$expectedlen\n$addtllen\n$entrs\n$addtlrs\n$addtla\n$addtlb\n$entprlen\n$entpra\n$entprb\n", "./fipsdrv --algo $cipher drbg")); |
|
|
+} |
|
|
+ |
|
|
+ |
|
|
######### End of libgcrypt implementation ################ |
|
|
|
|
|
################################################################ |
|
|
@@ -1468,13 +1524,17 @@ sub hash_mct($$) { |
|
|
my $md0=$pt; |
|
|
my $md1=$pt; |
|
|
my $md2=$pt; |
|
|
- for (my $i=0; $i<1000; ++$i) { |
|
|
- #print STDERR "outer loop $j; inner loop $i\n"; |
|
|
- my $mi= $md0 . $md1 . $md2; |
|
|
- $md0=$md1; |
|
|
- $md1=$md2; |
|
|
- $md2 = &$hash($mi, $cipher); |
|
|
- $md2 =~ s/\n//; |
|
|
+ if ($opt{'I'} && $opt{'I'} eq 'libgcrypt') { |
|
|
+ $md2 = &libgcrypt_hash_mct($pt, $cipher); |
|
|
+ } else { |
|
|
+ for (my $i=0; $i<1000; ++$i) { |
|
|
+ #print STDERR "outer loop $j; inner loop $i\n"; |
|
|
+ my $mi= $md0 . $md1 . $md2; |
|
|
+ $md0=$md1; |
|
|
+ $md1=$md2; |
|
|
+ $md2 = &$hash($mi, $cipher); |
|
|
+ $md2 =~ s/\n//; |
|
|
+ } |
|
|
} |
|
|
$out .= "MD = $md2\n\n"; |
|
|
$pt=$md2; |
|
|
@@ -1483,21 +1543,65 @@ sub hash_mct($$) { |
|
|
return $out; |
|
|
} |
|
|
|
|
|
+sub drbg_kat_driver($$$$$$$$$$$$$$$$$) { |
|
|
+ my $mode = shift; |
|
|
+ my $cipher = shift; |
|
|
+ my $pr = shift; |
|
|
+ my $ent = shift; |
|
|
+ my $entlen = shift; |
|
|
+ my $nonce = shift; |
|
|
+ my $noncelen = shift; |
|
|
+ my $entrs = shift; |
|
|
+ my $addtlrs = shift; |
|
|
+ my $entpra = shift; |
|
|
+ my $entprb = shift; |
|
|
+ my $addtla = shift; |
|
|
+ my $addtlb = shift; |
|
|
+ my $addtllen = shift; |
|
|
+ my $pers = shift; |
|
|
+ my $perslen = shift; |
|
|
+ my $expectedlen = shift; |
|
|
+ |
|
|
+ my $out = ""; |
|
|
+ |
|
|
+ $out .= "ReturnedBits = " . &$drbg_kat($mode, |
|
|
+ $cipher, |
|
|
+ $pr, |
|
|
+ $ent, |
|
|
+ $entlen, |
|
|
+ $nonce, |
|
|
+ $noncelen, |
|
|
+ $entrs, |
|
|
+ $addtlrs, |
|
|
+ $entpra, |
|
|
+ $entprb, |
|
|
+ $addtla, |
|
|
+ $addtlb, |
|
|
+ $addtllen, |
|
|
+ $pers, |
|
|
+ $perslen, |
|
|
+ $expectedlen) . "\n"; |
|
|
+ |
|
|
+ return $out; |
|
|
+} |
|
|
+ |
|
|
# RSA SigGen test |
|
|
# $1: Message to be signed in hex form |
|
|
# $2: Hash algorithm |
|
|
-# $3: file name with RSA key in PEM form |
|
|
+# $3: Use PSS |
|
|
+# $4: file name with RSA key in PEM form |
|
|
# return: string formatted as expected by CAVS |
|
|
-sub rsa_siggen($$$) { |
|
|
+sub rsa_siggen($$$$) { |
|
|
my $data = shift; |
|
|
my $cipher = shift; |
|
|
+ my $pss = shift; |
|
|
my $keyfile = shift; |
|
|
|
|
|
my $out = ""; |
|
|
|
|
|
$out .= "SHAAlg = $cipher\n"; |
|
|
$out .= "Msg = $data\n"; |
|
|
- $out .= "S = " . &$rsa_sign($data, lc($cipher), $keyfile) . "\n"; |
|
|
+ $out .= "S = " . &$rsa_sign($data, lc($cipher), $pss, $keyfile) . "\n"; |
|
|
|
|
|
return $out; |
|
|
} |
|
|
@@ -1505,13 +1609,15 @@ sub rsa_siggen($$$) { |
|
|
# RSA SigVer test |
|
|
# $1: Message to be verified in hex form |
|
|
# $2: Hash algoritm |
|
|
-# $3: Signature of message in hex form |
|
|
-# $4: n of the RSA key in hex in hex form |
|
|
-# $5: e of the RSA key in hex in hex form |
|
|
+# $3: Use PSS |
|
|
+# $4: Signature of message in hex form |
|
|
+# $5: n of the RSA key in hex in hex form |
|
|
+# $6: e of the RSA key in hex in hex form |
|
|
# return: string formatted as expected by CAVS |
|
|
-sub rsa_sigver($$$$$) { |
|
|
+sub rsa_sigver($$$$$$) { |
|
|
my $data = shift; |
|
|
my $cipher = shift; |
|
|
+ my $pss = shift; |
|
|
my $signature = shift; |
|
|
my $n = shift; |
|
|
my $e = shift; |
|
|
@@ -1534,7 +1640,7 @@ sub rsa_sigver($$$$$) { |
|
|
print FH hex2bin($signature); |
|
|
close FH; |
|
|
|
|
|
- $out .= "Result = " . (&$rsa_verify($data, lc($cipher), $keyfile, $sigfile) ? "P\n" : "F\n"); |
|
|
+ $out .= "Result = " . (&$rsa_verify($data, lc($cipher), $pss, $keyfile, $sigfile) ? "P\n" : "F\n"); |
|
|
|
|
|
unlink($keyfile); |
|
|
unlink($sigfile); |
|
|
@@ -1905,13 +2011,14 @@ sub rsa_keygen_driver($$) { |
|
|
# $2 p in hex form |
|
|
# $3 q in hex form |
|
|
# return: string formatted as expected by CAVS |
|
|
-sub rsa_keygen_kat_driver($$$) { |
|
|
+sub rsa_keygen_kat_driver($$$$) { |
|
|
my $mod = shift; |
|
|
+ my $e = shift; |
|
|
my $p = shift; |
|
|
my $q = shift; |
|
|
|
|
|
my $out = ""; |
|
|
- my $ret = &$rsa_keygen_kat($mod, $p, $q); |
|
|
+ my $ret = &$rsa_keygen_kat($mod, $e, $p, $q); |
|
|
my ($Result) = split(/\n/, $ret); |
|
|
die "Return value does not contain all expected values of Result for rsa_keygen_kat" |
|
|
if (!defined($Result)); |
|
|
@@ -1999,8 +2106,24 @@ sub parse($$) { |
|
|
my $xq1 = ""; |
|
|
my $xq2 = ""; |
|
|
my $Xq = ""; |
|
|
+ my $pr = 0; |
|
|
+ my $ent = ""; |
|
|
+ my $entlen = 0; |
|
|
+ my $nonce = ""; |
|
|
+ my $noncelen = 0; |
|
|
+ my $entrs = ""; |
|
|
+ my $addtlrs = ""; |
|
|
+ my $entpra = "x"; |
|
|
+ my $entprb = "x"; |
|
|
+ my $addtla = "x"; |
|
|
+ my $addtlb = "x"; |
|
|
+ my $addtllen = 0; |
|
|
+ my $pers = ""; |
|
|
+ my $perslen = 0; |
|
|
+ my $expectedlen = 0; |
|
|
|
|
|
my $mode = ""; |
|
|
+ my $pss = 0; |
|
|
|
|
|
open(IN, "<$infile"); |
|
|
while(<IN>) { |
|
|
@@ -2029,7 +2152,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|KeyGen RSA|KeyGen - Random Probably Prime|KeyPair|PQGVer)/) { |
|
|
+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyGen - Random Probably Prime|KeyPair|PQGVer|DRBG800-90A)/) { |
|
|
if ($tmpline =~ /CBC/) { $mode="cbc"; } |
|
|
elsif ($tmpline =~ /ECB/) { $mode="ecb"; } |
|
|
elsif ($tmpline =~ /OFB/) { $mode="ofb"; } |
|
|
@@ -2078,7 +2201,11 @@ sub parse($$) { |
|
|
|
|
|
if ($tt == 0) { |
|
|
##### Identify the test type |
|
|
- if ($tmpline =~ /KeyGen - Random Probably Prime Known Answer Test/) { |
|
|
+ if ($tmpline =~ /DRBG800-90A/) { |
|
|
+ $tt = 20; |
|
|
+ die "Interface function drbg_kat for DRBG KAT not defined for tested library" |
|
|
+ if (!defined($drbg_kat)); |
|
|
+ } elsif ($tmpline =~ /KeyGen - Random Probably Prime Known Answer Test/) { |
|
|
$tt = 19; |
|
|
die "Interface function rsa_keygen_kat for RSA key generation KAT not defined for tested library" |
|
|
if (!defined($rsa_keygen_kat)); |
|
|
@@ -2123,10 +2250,16 @@ sub parse($$) { |
|
|
die "Interface function state_rng for RNG KAT not defined for tested library" |
|
|
if (!defined($state_rng)); |
|
|
} elsif ($tmpline =~ /SigVer/ ) { |
|
|
+ if ($tmpline =~ /RSASSA-PSS/) { |
|
|
+ $pss = 1; |
|
|
+ } |
|
|
$tt = 6; |
|
|
die "Interface function rsa_verify or gen_rsakey for RSA verification not defined for tested library" |
|
|
if (!defined($rsa_verify) || !defined($gen_rsakey)); |
|
|
} elsif ($tmpline =~ /SigGen/ ) { |
|
|
+ if ($tmpline =~ /RSASSA-PSS/) { |
|
|
+ $pss = 1; |
|
|
+ } |
|
|
$tt = 5; |
|
|
die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library" |
|
|
if (!defined($rsa_sign) || !defined($gen_rsakey)); |
|
|
@@ -2252,7 +2385,7 @@ sub parse($$) { |
|
|
$out .= "G = " . $pqg{'G'} . "\n\n"; |
|
|
} |
|
|
} |
|
|
- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests |
|
|
+ elsif ($line =~ /^\[mod\s*=\s*(.*)\]/) { # found in RSA requests |
|
|
$modulus = $1; |
|
|
$out .= $line . "\n\n"; # print it |
|
|
# generate the private key with given bit length now |
|
|
@@ -2277,10 +2410,21 @@ sub parse($$) { |
|
|
$n=$1; |
|
|
} |
|
|
elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests |
|
|
- $e=$1; |
|
|
if ($tt == 19) { |
|
|
+ if ($modulus ne "" && |
|
|
+ $e ne "" && |
|
|
+ $prandom ne "") { |
|
|
+ $out .= rsa_keygen_kat_driver($modulus, |
|
|
+ $e, |
|
|
+ $prandom, |
|
|
+ "00"); |
|
|
+ $prandom = ""; |
|
|
+ $qrandom = ""; |
|
|
+ $e = ""; |
|
|
+ } |
|
|
$out .= $line . "\n"; # print it |
|
|
} |
|
|
+ $e=$1; |
|
|
} |
|
|
elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests |
|
|
die "S seen twice - input file crap" if ($signature ne ""); |
|
|
@@ -2306,6 +2450,89 @@ sub parse($$) { |
|
|
if ($tlen ne ""); |
|
|
$tlen=$1; |
|
|
} |
|
|
+ elsif ($tt == 20) { |
|
|
+ if ($line =~ /Hash_DRBG/) { # HASH DRBG request |
|
|
+ $mode = "hash"; |
|
|
+ } |
|
|
+ elsif ($line =~ /HMAC_DRBG/) { # HMAC DRBG request |
|
|
+ $mode = "hmac"; |
|
|
+ } |
|
|
+ elsif ($line =~ /CTR_DRBG/) { # CTR DRBG request |
|
|
+ $mode = "ctr"; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[SHA-1\]/) { |
|
|
+ $cipher= "sha-1"; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[SHA-256\]/) { |
|
|
+ $cipher= "sha-256"; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[SHA-384\]/) { |
|
|
+ $cipher= "sha-384"; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[SHA-512\]/) { |
|
|
+ $cipher= "sha-512"; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[AES-128 use df\]/) { |
|
|
+ $cipher= "aes-128"; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[AES-192 use df\]/) { |
|
|
+ $cipher= "aes-192"; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[AES-256 use df\]/) { |
|
|
+ $cipher= "aes-256"; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[PredictionResistance\s*=\s*True\]/) { |
|
|
+ $pr = 1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[PredictionResistance\s*=\s*False\]/) { |
|
|
+ $pr = 0; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[EntropyInputLen\s*=\s*(.*)\]/) { |
|
|
+ $entlen = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[NonceLen\s*=\s*(.*)\]/) { |
|
|
+ $noncelen = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[PersonalizationStringLen\s*=\s*(.*)\]/) { |
|
|
+ $perslen = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[AdditionalInputLen\s*=\s*(.*)\]/) { |
|
|
+ $addtllen = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^\[ReturnedBitsLen\s*=\s*(.*)\]/) { |
|
|
+ $expectedlen = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^EntropyInput\s*=\s*(.*)/) { |
|
|
+ $ent = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^EntropyInputReseed\s*=\s*(.*)/) { |
|
|
+ $entrs = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^Nonce\s*=\s*(.*)/) { |
|
|
+ $nonce = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^PersonalizationString\s*=\s*(.*)/) { |
|
|
+ $pers = $1; |
|
|
+ } |
|
|
+ elsif ($line =~ /^AdditionalInput\s*=\s*(.*)/) { |
|
|
+ if ($addtla eq "x") { |
|
|
+ $addtla = $1; |
|
|
+ } else { |
|
|
+ $addtlb = $1; |
|
|
+ } |
|
|
+ } |
|
|
+ elsif ($line =~ /^EntropyInputPR\s*=\s*(.*)/) { |
|
|
+ if ($entpra eq "x") { |
|
|
+ $entpra = $1; |
|
|
+ } else { |
|
|
+ $entprb = $1; |
|
|
+ } |
|
|
+ } |
|
|
+ elsif ($line =~ /^AdditionalInputReseed\s*=\s*(.*)/) { |
|
|
+ $addtlrs = $1; |
|
|
+ } |
|
|
+ $out .= $line . "\n"; # print it |
|
|
+ } |
|
|
elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair |
|
|
die "N seen twice - check input file" |
|
|
if ($capital_n); |
|
|
@@ -2396,10 +2623,6 @@ sub parse($$) { |
|
|
$qrandom = $1; |
|
|
$out .= $line . "\n"; # print it |
|
|
} |
|
|
- elsif ($tt == 19 && $line =~ /^ / && $qrandom eq "") { #RSA key gen KAT |
|
|
- $qrandom = "00"; |
|
|
- $out .= $line . "\n"; # print it |
|
|
- } |
|
|
else { |
|
|
$out .= $line . "\n"; |
|
|
} |
|
|
@@ -2442,13 +2665,13 @@ sub parse($$) { |
|
|
} |
|
|
elsif ($tt == 5) { |
|
|
if ($pt ne "" && $cipher ne "" && $rsa_keyfile ne "") { |
|
|
- $out .= rsa_siggen($pt, $cipher, $rsa_keyfile); |
|
|
+ $out .= rsa_siggen($pt, $cipher, $pss, $rsa_keyfile); |
|
|
$pt = ""; |
|
|
} |
|
|
} |
|
|
elsif ($tt == 6) { |
|
|
if ($pt ne "" && $cipher ne "" && $signature ne "" && $n ne "" && $e ne "") { |
|
|
- $out .= rsa_sigver($pt, $cipher, $signature, $n, $e); |
|
|
+ $out .= rsa_sigver($pt, $cipher, $pss, $signature, $n, $e); |
|
|
$pt = ""; |
|
|
$signature = ""; |
|
|
} |
|
|
@@ -2635,6 +2858,37 @@ sub parse($$) { |
|
|
$e = ""; |
|
|
} |
|
|
} |
|
|
+ elsif ($tt == 20) { |
|
|
+ if (($pr == 1 && $entpra ne "x" && $entprb ne "x") || |
|
|
+ ($pr == 0 && $addtla ne "x" && $addtlb ne "x")) { |
|
|
+ $out .= drbg_kat_driver($mode, |
|
|
+ $cipher, |
|
|
+ $pr, |
|
|
+ $ent, |
|
|
+ $entlen, |
|
|
+ $nonce, |
|
|
+ $noncelen, |
|
|
+ $entrs, |
|
|
+ $addtlrs, |
|
|
+ $entpra, |
|
|
+ $entprb, |
|
|
+ $addtla, |
|
|
+ $addtlb, |
|
|
+ $addtllen, |
|
|
+ $pers, |
|
|
+ $perslen, |
|
|
+ $expectedlen); |
|
|
+ $entpra = "x"; |
|
|
+ $entprb = "x"; |
|
|
+ $addtla = "x"; |
|
|
+ $addtlb = "x"; |
|
|
+ $ent = ""; |
|
|
+ $nonce = ""; |
|
|
+ $pers = ""; |
|
|
+ $entrs = ""; |
|
|
+ $addtlrs = ""; |
|
|
+ } |
|
|
+ } |
|
|
elsif ($tt > 0) { |
|
|
die "Test case $tt not defined"; |
|
|
} |
|
|
@@ -2701,6 +2955,7 @@ sub main() { |
|
|
$dsa_genpubkey = \&libgcrypt_dsa_genpubkey; |
|
|
$rsa_keygen = \&libgcrypt_rsa_keygen; |
|
|
$rsa_keygen_kat = \&libgcrypt_rsa_keygen_kat; |
|
|
+ $drbg_kat = \&libgcrypt_drbg_kat; |
|
|
} else { |
|
|
die "Invalid interface option given"; |
|
|
} |
|
|
diff -up libgcrypt-1.5.3/tests/fipsdrv.c.drbg-cavs libgcrypt-1.5.3/tests/fipsdrv.c |
|
|
--- libgcrypt-1.5.3/tests/fipsdrv.c.drbg-cavs 2017-02-28 14:28:55.674906074 +0100 |
|
|
+++ libgcrypt-1.5.3/tests/fipsdrv.c 2017-02-28 14:43:28.320456712 +0100 |
|
|
@@ -22,6 +22,7 @@ |
|
|
#endif |
|
|
#include <stdio.h> |
|
|
#include <stdlib.h> |
|
|
+#include <stdint.h> |
|
|
#include <string.h> |
|
|
#include <stdarg.h> |
|
|
#include <errno.h> |
|
|
@@ -893,8 +894,10 @@ print_mpi_line (gcry_mpi_t a, int no_lz) |
|
|
die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); |
|
|
|
|
|
p = buf; |
|
|
- while (*p) |
|
|
- *p++ = tolower(*p); |
|
|
+ while (*p) { |
|
|
+ *p = tolower(*p); |
|
|
+ ++p; |
|
|
+ } |
|
|
p = buf; |
|
|
if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) |
|
|
p += 2; |
|
|
@@ -1256,6 +1259,46 @@ run_digest (int digest_algo, const void |
|
|
gcry_md_close (hd); |
|
|
} |
|
|
|
|
|
+/* Run inner loop of digest mct operation. */ |
|
|
+static void |
|
|
+run_digest_mct_loop (int digest_algo, const void *data, size_t datalen, int iter) |
|
|
+{ |
|
|
+ gpg_error_t err; |
|
|
+ gcry_md_hd_t hd; |
|
|
+ const unsigned char *digest; |
|
|
+ unsigned int digestlen; |
|
|
+ int i; |
|
|
+ unsigned char *buf; |
|
|
+ |
|
|
+ err = gcry_md_open (&hd, digest_algo, 0); |
|
|
+ if (err) |
|
|
+ die ("gcry_md_open failed for algo %d: %s\n", |
|
|
+ digest_algo, gpg_strerror (err)); |
|
|
+ |
|
|
+ digestlen = gcry_md_get_algo_dlen (digest_algo); |
|
|
+ if (digestlen != datalen) |
|
|
+ die ("Unexpected seed size %u for Hash mct algo %d\n", datalen, digest_algo); |
|
|
+ |
|
|
+ buf = malloc (3*datalen); |
|
|
+ if (!buf) |
|
|
+ die ("Buffer allocation failed\n"); |
|
|
+ |
|
|
+ memcpy (buf, data, datalen); |
|
|
+ memcpy (buf + datalen, data, datalen); |
|
|
+ memcpy (buf + 2*datalen, data, datalen); |
|
|
+ |
|
|
+ for (i = 0; i < iter; ++i) |
|
|
+ { |
|
|
+ gcry_md_reset (hd); |
|
|
+ gcry_md_write (hd, buf, 3*datalen); |
|
|
+ digest = gcry_md_read (hd, digest_algo); |
|
|
+ memmove (buf, buf + datalen, 2*datalen); |
|
|
+ memcpy (buf + 2*datalen, digest, datalen); |
|
|
+ } |
|
|
+ print_buffer (digest, digestlen); |
|
|
+ gcry_md_close (hd); |
|
|
+} |
|
|
+ |
|
|
|
|
|
/* Run a HMAC operation. */ |
|
|
static void |
|
|
@@ -1403,7 +1446,7 @@ run_rsa_keygen (const void *data, size_t |
|
|
gcry_sexp_release (l1); |
|
|
if (!mpi) |
|
|
die ("parameter %c missing in private-key\n", parmlist[idx]); |
|
|
- print_mpi_line (mpi, 1); |
|
|
+ print_mpi_line (mpi, parmlist[idx] != 'd'); |
|
|
gcry_mpi_release (mpi); |
|
|
} |
|
|
|
|
|
@@ -1592,7 +1635,7 @@ run_rsa_gen (int keysize, int pubexp) |
|
|
encoded KEYFILE and the hash algorithm HASHALGO. */ |
|
|
static void |
|
|
run_rsa_sign (const void *data, size_t datalen, |
|
|
- int hashalgo, int pkcs1, const char *keyfile) |
|
|
+ int hashalgo, int pkcs1, int pss, const char *keyfile) |
|
|
|
|
|
{ |
|
|
gpg_error_t err; |
|
|
@@ -1616,6 +1659,20 @@ run_rsa_sign (const void *data, size_t d |
|
|
gcry_md_algo_name (hashalgo), |
|
|
(int)hashsize, hash); |
|
|
} |
|
|
+ else if (pss) |
|
|
+ { |
|
|
+ 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 pss)(hash %s %b))", |
|
|
+ gcry_md_algo_name (hashalgo), |
|
|
+ (int)hashsize, hash); |
|
|
+ } |
|
|
else |
|
|
{ |
|
|
gcry_mpi_t tmp; |
|
|
@@ -1683,7 +1740,7 @@ run_rsa_sign (const void *data, size_t d |
|
|
binary signature in SIGFILE. */ |
|
|
static void |
|
|
run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1, |
|
|
- const char *keyfile, const char *sigfile) |
|
|
+ int pss, const char *keyfile, const char *sigfile) |
|
|
|
|
|
{ |
|
|
gpg_error_t err; |
|
|
@@ -1703,6 +1760,20 @@ run_rsa_verify (const void *data, size_t |
|
|
gcry_md_algo_name (hashalgo), |
|
|
(int)hashsize, hash); |
|
|
} |
|
|
+ else if (pss) |
|
|
+ { |
|
|
+ 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 pss)(hash %s %b))", |
|
|
+ gcry_md_algo_name (hashalgo), |
|
|
+ (int)hashsize, hash); |
|
|
+ } |
|
|
else |
|
|
{ |
|
|
gcry_mpi_t tmp; |
|
|
@@ -2220,7 +2291,150 @@ run_dsa_verify (const void *data, size_t |
|
|
gcry_sexp_release (s_data); |
|
|
} |
|
|
|
|
|
+struct gcry_drbg_test_vector |
|
|
+{ |
|
|
+ uint32_t flags; |
|
|
+ unsigned char *entropy; |
|
|
+ size_t entropylen; |
|
|
+ unsigned char *entpra; |
|
|
+ unsigned char *entprb; |
|
|
+ size_t entprlen; |
|
|
+ unsigned char *addtla; |
|
|
+ unsigned char *addtlb; |
|
|
+ size_t addtllen; |
|
|
+ unsigned char *pers; |
|
|
+ size_t perslen; |
|
|
+ unsigned char *expected; |
|
|
+ size_t expectedlen; |
|
|
+ unsigned char *entropyrsd; |
|
|
+ size_t entropyrsdlen; |
|
|
+ unsigned char *addtlrsd; |
|
|
+ size_t addtlrsdlen; |
|
|
+ }; |
|
|
+ |
|
|
+static uint32_t |
|
|
+decode_drbg_flags(const char *algo, const char *mode, const char *pr) |
|
|
+{ |
|
|
+ uint32_t flags = 0; |
|
|
+ |
|
|
+ if (*pr == '1') |
|
|
+ flags = GCRY_DRBG_PREDICTION_RESIST; |
|
|
+ |
|
|
+ if (!strcmp(algo, "sha-1")) |
|
|
+ flags |= GCRY_DRBG_HASHSHA1; |
|
|
+ else if (!strcmp(algo, "sha-256")) |
|
|
+ flags |= GCRY_DRBG_HASHSHA256; |
|
|
+ else if (!strcmp(algo, "sha-384")) |
|
|
+ flags |= GCRY_DRBG_HASHSHA384; |
|
|
+ else if (!strcmp(algo, "sha-512")) |
|
|
+ flags |= GCRY_DRBG_HASHSHA512; |
|
|
+ else if (!strcmp(algo, "aes-128")) |
|
|
+ flags |= GCRY_DRBG_SYM128; |
|
|
+ else if (!strcmp(algo, "aes-192")) |
|
|
+ flags |= GCRY_DRBG_SYM192; |
|
|
+ else if (!strcmp(algo, "aes-256")) |
|
|
+ flags |= GCRY_DRBG_SYM256; |
|
|
+ |
|
|
+ if (!strcmp(mode, "hmac")) |
|
|
+ flags |= GCRY_DRBG_HMAC; |
|
|
+ else if (!strcmp(mode, "ctr")) |
|
|
+ flags |= GCRY_DRBG_CTRAES; |
|
|
+ |
|
|
+ return flags; |
|
|
+} |
|
|
+ |
|
|
+static void |
|
|
+run_drbg_test (const char *algo, void *data, size_t datalen) |
|
|
+{ |
|
|
+ char *ptr = data; |
|
|
+ char *mode; |
|
|
+ char *pr; |
|
|
+ char *entlen; |
|
|
+ char *ent; |
|
|
+ char *perslen; |
|
|
+ char *pers; |
|
|
+ char *expectedlen; |
|
|
+ char *addtllen; |
|
|
+ char *entrsd; |
|
|
+ char *addtlrsd; |
|
|
+ char *addtla; |
|
|
+ char *addtlb; |
|
|
+ char *entprlen; |
|
|
+ char *entpra; |
|
|
+ char *entprb; |
|
|
+ unsigned char *buf; |
|
|
+ size_t len; |
|
|
+ struct gcry_drbg_test_vector vect; |
|
|
+ |
|
|
+ mode = strsep(&ptr, "\n"); |
|
|
+ pr = strsep(&ptr, "\n"); |
|
|
+ entlen = strsep(&ptr, "\n"); |
|
|
+ ent = strsep(&ptr, "\n"); |
|
|
+ perslen = strsep(&ptr, "\n"); |
|
|
+ pers = strsep(&ptr, "\n"); |
|
|
+ expectedlen = strsep(&ptr, "\n"); |
|
|
+ addtllen = strsep(&ptr, "\n"); |
|
|
+ entrsd = strsep(&ptr, "\n"); |
|
|
+ addtlrsd = strsep(&ptr, "\n"); |
|
|
+ addtla = strsep(&ptr, "\n"); |
|
|
+ addtlb = strsep(&ptr, "\n"); |
|
|
+ entprlen = strsep(&ptr, "\n"); |
|
|
+ entpra = strsep(&ptr, "\n"); |
|
|
+ entprb = strsep(&ptr, "\n"); |
|
|
+ |
|
|
+ if (entprb == NULL) { |
|
|
+ fprintf(stderr, "ERROR - Missing input data\n"); |
|
|
+ return; |
|
|
+ } |
|
|
+ |
|
|
+ vect.flags = decode_drbg_flags(algo, mode, pr); |
|
|
+ |
|
|
+ vect.entropy = hex2buffer(ent, &len); |
|
|
+ vect.entropylen = atoi(entlen) / 8; |
|
|
+ if (len != vect.entropylen) { |
|
|
+ fprintf(stderr, "ERROR - inconsistent input data\n"); |
|
|
+ return; |
|
|
+ } |
|
|
+ vect.pers = hex2buffer(pers, &len); |
|
|
+ vect.perslen = atoi(perslen) / 8; |
|
|
+ if (len != vect.perslen) { |
|
|
+ fprintf(stderr, "ERROR - inconsistent input data\n"); |
|
|
+ return; |
|
|
+ } |
|
|
+ vect.expectedlen = atoi(expectedlen) / 8; |
|
|
+ vect.expected = NULL; |
|
|
+ vect.addtlrsdlen = vect.addtllen = atoi(addtllen) / 8; |
|
|
+ vect.addtla = hex2buffer(addtla, &len); |
|
|
+ vect.addtlb = hex2buffer(addtlb, &len); |
|
|
+ vect.entropyrsdlen = vect.entprlen = atoi(entprlen) / 8; |
|
|
+ vect.entpra = hex2buffer(entpra, &len); |
|
|
+ vect.entprb = hex2buffer(entprb, &len); |
|
|
+ if (*entrsd != '\0') { |
|
|
+ vect.entropyrsd = hex2buffer(entrsd, &len); |
|
|
+ if (len != vect.entropyrsdlen) { |
|
|
+ fprintf(stderr, "ERROR - inconsistent input data\n"); |
|
|
+ return; |
|
|
+ } |
|
|
+ if (*addtlrsd != '\0') { |
|
|
+ vect.addtlrsd = hex2buffer(addtlrsd, &len); |
|
|
+ if (len != vect.addtlrsdlen) { |
|
|
+ fprintf(stderr, "ERROR - inconsistent input data\n"); |
|
|
+ return; |
|
|
+ } |
|
|
+ } else { |
|
|
+ vect.addtlrsd = NULL; |
|
|
+ } |
|
|
+ } else { |
|
|
+ vect.entropyrsd = NULL; |
|
|
+ vect.addtlrsd = NULL; |
|
|
+ } |
|
|
+ |
|
|
+ buf = gcry_xmalloc(vect.expectedlen); |
|
|
|
|
|
+ gcry_control(75, &vect, buf); |
|
|
+ |
|
|
+ print_data_line(buf, vect.expectedlen); |
|
|
+} |
|
|
|
|
|
|
|
|
static void |
|
|
@@ -2251,6 +2465,7 @@ usage (int show_help) |
|
|
" --signature NAME Take signature from file NAME\n" |
|
|
" --chunk N Read in chunks of N bytes (implies --binary)\n" |
|
|
" --pkcs1 Use PKCS#1 encoding\n" |
|
|
+ " --pss Use PKCS#1 PSS encoding\n" |
|
|
" --mct-server Run a monte carlo test server\n" |
|
|
" --loop Enable random loop mode\n" |
|
|
" --progress Print pogress indicators\n" |
|
|
@@ -2268,6 +2483,7 @@ main (int argc, char **argv) |
|
|
int no_fips = 0; |
|
|
int progress = 0; |
|
|
int use_pkcs1 = 0; |
|
|
+ int use_pss = 0; |
|
|
const char *mode_string; |
|
|
const char *key_string = NULL; |
|
|
const char *iv_string = NULL; |
|
|
@@ -2398,6 +2614,11 @@ main (int argc, char **argv) |
|
|
use_pkcs1 = 1; |
|
|
argc--; argv++; |
|
|
} |
|
|
+ else if (!strcmp (*argv, "--pss")) |
|
|
+ { |
|
|
+ use_pss = 1; |
|
|
+ argc--; argv++; |
|
|
+ } |
|
|
else if (!strcmp (*argv, "--mct-server")) |
|
|
{ |
|
|
mct_server = 1; |
|
|
@@ -2414,7 +2635,10 @@ main (int argc, char **argv) |
|
|
usage (0); |
|
|
mode_string = *argv; |
|
|
|
|
|
- if (!strcmp (mode_string, "rsa-derive")) |
|
|
+ if (!strcmp (mode_string, "rsa-derive") || |
|
|
+ !strcmp (mode_string, "rsa-keygen") || |
|
|
+ !strcmp (mode_string, "rsa-keygen-kat") || |
|
|
+ !strcmp(mode_string, "drbg")) |
|
|
binary_input = 1; |
|
|
|
|
|
if (argc == 2 && strcmp (argv[1], "-")) |
|
|
@@ -2557,7 +2781,14 @@ main (int argc, char **argv) |
|
|
if (!data) |
|
|
die ("no data available (do not use --chunk)\n"); |
|
|
|
|
|
- run_digest (algo, data, datalen); |
|
|
+ if (loop_mode) |
|
|
+ { |
|
|
+ run_digest_mct_loop (algo, data, datalen, 1000); |
|
|
+ } |
|
|
+ else |
|
|
+ { |
|
|
+ run_digest (algo, data, datalen); |
|
|
+ } |
|
|
} |
|
|
else if (!strcmp (mode_string, "random")) |
|
|
{ |
|
|
@@ -2602,6 +2833,12 @@ main (int argc, char **argv) |
|
|
|
|
|
deinit_external_rng_test (context); |
|
|
} |
|
|
+ else if (!strcmp (mode_string, "drbg")) |
|
|
+ { |
|
|
+ if (!algo_string) |
|
|
+ die ("--algo required in this mode\n"); |
|
|
+ run_drbg_test (algo_string, data, datalen); |
|
|
+ } |
|
|
else if (!strcmp (mode_string, "hmac-sha")) |
|
|
{ |
|
|
int algo; |
|
|
@@ -2679,7 +2916,7 @@ main (int argc, char **argv) |
|
|
if (!data) |
|
|
die ("no data available (do not use --chunk)\n"); |
|
|
|
|
|
- run_rsa_sign (data, datalen, algo, use_pkcs1, key_string); |
|
|
+ run_rsa_sign (data, datalen, algo, use_pkcs1, use_pss, key_string); |
|
|
|
|
|
} |
|
|
else if (!strcmp (mode_string, "rsa-verify")) |
|
|
@@ -2702,7 +2939,7 @@ main (int argc, char **argv) |
|
|
if (access (signature_string, R_OK)) |
|
|
die ("option --signature needs to specify an existing file\n"); |
|
|
|
|
|
- run_rsa_verify (data, datalen, algo, use_pkcs1, key_string, |
|
|
+ run_rsa_verify (data, datalen, algo, use_pkcs1, use_pss, key_string, |
|
|
signature_string); |
|
|
|
|
|
} |
|
|
@@ -2783,12 +3020,6 @@ main (int argc, char **argv) |
|
|
|
|
|
gcry_free (data); |
|
|
|
|
|
- /* Because Libgcrypt does not enforce FIPS mode in all cases we let |
|
|
- the process die if Libgcrypt is not anymore in FIPS mode after |
|
|
- the actual operation. */ |
|
|
- if (!no_fips && !gcry_fips_mode_active ()) |
|
|
- die ("FIPS mode is not anymore active\n"); |
|
|
- |
|
|
if (verbose) |
|
|
fputs (PGM ": ready\n", stderr); |
|
|
|
|
|
|