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