mpi/ec: fix when 'unsigned long' is 32-bit but limb size is 64-bit
[libgcrypt.git] / tests / cavs_driver.pl
index fa80fb8..bc93feb 100755 (executable)
@@ -1,6 +1,6 @@
 #!/usr/bin/env perl
 #
-# $Id: cavs_driver.pl 1395 2008-11-10 15:18:03Z smueller $
+# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $
 #
 # CAVS test driver (based on the OpenSSL driver)
 # Written by: Stephan Müller <sm@atsec.com>
@@ -11,7 +11,7 @@
 # in the Software without restriction, including without limitation the rights
 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 # copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions: 
+# furnished to do so, subject to the following conditions:
 #
 # The above copyright notice and this permission notice shall be included in
 # all copies or substantial portions of the Software.
@@ -65,6 +65,7 @@
 #      SigVer15
 #      (SigVerRSA is not applicable for OpenSSL as X9.31 padding
 #              is not done through openssl dgst)
+#      KeyGen RSA X9.31
 #
 # SHA
 #      SHA[1|224|256|384|512]ShortMsg
@@ -138,21 +139,21 @@ my $encdec;
 #
 # Derive an RSA key from the given X9.31 parameters.
 # $1: modulus size
-# $2: E   in hex form 
-# $3: Xp1 in hex form 
-# $4: Xp2 in hex form 
-# $5: Xp  in hex form 
-# $6: Xq1 in hex form 
-# $7: Xq2 in hex form 
-# $8: Xq  in hex form 
+# $2: E   in hex form
+# $3: Xp1 in hex form
+# $4: Xp2 in hex form
+# $5: Xp  in hex form
+# $6: Xq1 in hex form
+# $7: Xq2 in hex form
+# $8: Xq  in hex form
 # return: string with the calculated values in hex format, where each value
-#        is separated from the previous with a \n in the following order:
+#        is separated from the previous with a \n in the following order:
 #         P\n
 #         Q\n
+#         N\n
 #         D\n
 my $rsa_derive;
 
-
 # Sign a message with RSA
 # $1: data to be signed in hex form
 # $2: Hash algo
@@ -241,10 +242,9 @@ my $dsa_pqggen;
 # $2: P in hex form
 # $3: Q in hex form
 # $4: G in hex form
-# $5: Y in hex form  
+# $5: Y in hex form
 my $dsa_genpubkey;
 
-
 # Verify a message with DSA
 # $1: data to be verified in hex form
 # $2: file holding the public DSA key in PEM format
@@ -255,7 +255,7 @@ my $dsa_verify;
 
 # generate a new DSA key with the following properties:
 #      PEM format
-# $1 keyfile name 
+# $1 keyfile name
 # return: file created, hash with keys of P, Q, G in hex format
 my $gen_dsakey;
 
@@ -378,31 +378,32 @@ sub libgcrypt_encdec($$$$$) {
 
 sub libgcrypt_rsa_derive($$$$$$$$) {
        my $n   = shift;
-        my $e   = shift;
-        my $xp1 = shift;
-        my $xp2 = shift;
-        my $xp  = shift;
-        my $xq1 = shift;
-        my $xq2 = shift;
-        my $xq  = shift;
-        my $sexp;
-        my @tmp;
-
-        $n = sprintf ("%u", $n);
-        $e = sprintf ("%u", hex($e));
-        $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")"
-                . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")"
-                . "(derive-parms"
-                . "(Xp1 #$xp1#)"
-                . "(Xp2 #$xp2#)"
-                . "(Xp  #$xp#)"
-                . "(Xq1 #$xq1#)"
-                . "(Xq2 #$xq2#)"
-                . "(Xq  #$xq#))))\n";
-
-        return pipe_through_program($sexp, "fipsdrv rsa-derive");
+       my $e   = shift;
+       my $xp1 = shift;
+       my $xp2 = shift;
+       my $xp  = shift;
+       my $xq1 = shift;
+       my $xq2 = shift;
+       my $xq  = shift;
+       my $sexp;
+       my @tmp;
+
+       $n = sprintf ("%u", $n);
+       $e = sprintf ("%u", hex($e));
+       $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")"
+               . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")"
+               . "(derive-parms"
+               . "(Xp1 #$xp1#)"
+               . "(Xp2 #$xp2#)"
+               . "(Xp  #$xp#)"
+               . "(Xq1 #$xq1#)"
+               . "(Xq2 #$xq2#)"
+               . "(Xq  #$xq#))))\n";
+
+       return pipe_through_program($sexp, "fipsdrv rsa-derive");
 }
 
+
 sub libgcrypt_rsa_sign($$$) {
        my $data = shift;
        my $hashalgo = shift;
@@ -496,7 +497,7 @@ sub libgcrypt_hmac($$$$) {
        my $hashtype = shift;
 
        my $program = "fipsdrv --key $key --algo $hashtype hmac-sha";
-       return pipe_through_program($msg, $program);    
+       return pipe_through_program($msg, $program);
 }
 
 sub libgcrypt_dsa_pqggen($) {
@@ -510,16 +511,16 @@ sub libgcrypt_gen_dsakey($) {
        my $file = shift;
 
        my $program = "fipsdrv --keysize 1024 --key $file dsa-gen";
-        my $tmp;
-        my %ret;
+       my $tmp;
+       my %ret;
 
        die "ARCFOUR not available for DSA" if $opt{'R'};
 
-        $tmp = pipe_through_program("", $program);
+       $tmp = pipe_through_program("", $program);
        die "dsa key gen failed: file $file not created" if (! -f $file);
 
-        @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp);
-        return %ret;
+       @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp);
+       return %ret;
 }
 
 sub libgcrypt_dsa_genpubkey($$$$$) {
@@ -529,26 +530,26 @@ sub libgcrypt_dsa_genpubkey($$$$$) {
        my $g = shift;
        my $y = shift;
 
-        my $sexp;
+       my $sexp;
 
-        $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))"; 
+       $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))";
 
        open(FH, ">", $filename) or die;
        print FH $sexp;
-       close FH;  
+       close FH;
 }
 
 sub libgcrypt_dsa_sign($$) {
        my $data = shift;
        my $keyfile = shift;
-        my $tmp;
-        my %ret; 
-        
+       my $tmp;
+       my %ret;
+
        die "ARCFOUR not available for DSA" if $opt{'R'};
 
        $tmp = pipe_through_program($data, "fipsdrv --key $keyfile dsa-sign");
-        @ret{'Y', 'R', 'S'} = split(/\n/, $tmp);
-        return %ret;
+       @ret{'Y', 'R', 'S'} = split(/\n/, $tmp);
+       return %ret;
 }
 
 sub libgcrypt_dsa_verify($$$$) {
@@ -556,25 +557,23 @@ sub libgcrypt_dsa_verify($$$$) {
        my $keyfile = shift;
        my $r = shift;
        my $s = shift;
-        
-        my $ret;
+
+       my $ret;
 
        die "ARCFOUR not available for DSA" if $opt{'R'};
 
        my $sigfile = "$keyfile.sig";
        open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?";
-       print FH "(sig-val(dsa(r #$r)(s #$s#)))";
+       print FH "(sig-val(dsa(r #$r#)(s #$s#)))";
        close FH;
 
-       $ret = pipe_through_program($data, 
-                 "fipsdrv --verbose --key $keyfile --signature $sigfile dsa-verify");
-        unlink ($sigfile);
+       $ret = pipe_through_program($data,
+               "fipsdrv --key $keyfile --signature $sigfile dsa-verify");
+       unlink ($sigfile);
        # Parse through the output information
        return ($ret =~ /GOOD signature/);
 }
 
-
-
 ######### End of libgcrypt implementation ################
 
 ################################################################
@@ -624,7 +623,7 @@ sub pipe_through_program($@) {
 
        my ($CO, $CI);
        my $pid = open2($CO, $CI, @args);
-       
+
        my $out = "";
        my $len = length($in);
        my $first = 1;
@@ -660,7 +659,7 @@ sub pipe_through_program($@) {
        }
        close $CO or die "broken pipe: $!";
        waitpid $pid, 0;
-       
+
        return $out;
 }
 
@@ -882,7 +881,7 @@ sub der_pos_bigint($) {
 # returns number as signed DER integer encoding
 sub der_int($) {
        my $n = shift;
-       
+
        return der_bigint(int_base256_signed($n));
 }
 
@@ -959,11 +958,11 @@ sub der_unit_test {
 # OpenSSL missing functionality workarounds
 
 ## Format of an RSA public key:
-#    0:d=0  hl=3 l= 159 cons: SEQUENCE          
-#    3:d=1  hl=2 l=  13 cons:  SEQUENCE          
+#    0:d=0  hl=3 l= 159 cons: SEQUENCE
+#    3:d=1  hl=2 l=  13 cons:  SEQUENCE
 #    5:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
-#   16:d=2  hl=2 l=   0 prim:   NULL              
-#   18:d=1  hl=3 l= 141 prim:  BIT STRING        
+#   16:d=2  hl=2 l=   0 prim:   NULL
+#   18:d=1  hl=3 l= 141 prim:  BIT STRING
 #                              [ sequence: INTEGER (n), INTEGER (e) ]
 
 # generate RSA pub key in PEM format
@@ -1074,7 +1073,7 @@ sub kat($$$$$$$$) {
                $out .= "KEY3 = $key3\n";
                $key1= $key1 . $key3;
        }
-       
+
        $out .= "IV = $iv\n" if (defined($iv) && $iv ne "");
        if ($enc) {
                $out .= "PLAINTEXT = $pt\n";
@@ -1140,7 +1139,7 @@ sub hmac_kat($$$$) {
        $out .= "Tlen = $tlen\n";
        $out .= "Key = $key\n";
        $out .= "Msg = $msg\n";
-       $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n\n";
+       $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n";
 
        return $out;
 }
@@ -1216,10 +1215,14 @@ sub crypto_mct($$$$$$$$) {
 
                # TDES inner loop implements logic within driver
                if ($cipher =~ /des/) {
+                       # Need to provide a dummy IV in case of ECB mode.
+                       my $iv_arg = (defined($iv) && $iv ne "")
+                                       ? bin2hex($iv)
+                                       : "00"x(length($source_data));
                        print $CI "1\n"
                                  .$iloop."\n"
                                  .bin2hex($key1)."\n"
-                                 .bin2hex($iv)."\n"
+                                 .$iv_arg."\n"
                                  .bin2hex($source_data)."\n\n" or die;
                        chomp(my $line = <$CO>);
                        $calc_data = hex2bin($line);
@@ -1228,7 +1231,7 @@ sub crypto_mct($$$$$$$$) {
                        chomp($line = <$CO>);
                        $old_old_calc_data = hex2bin($line);
                        chomp($line = <$CO>);
-                       $iv = hex2bin($line);
+                       $iv = hex2bin($line) if (defined($iv) && $iv ne "");
                        chomp($line = <$CO>);
                        $next_source = hex2bin($line);
                        # Skip over empty line.
@@ -1247,7 +1250,7 @@ sub crypto_mct($$$$$$$$) {
                                #print STDERR "calc_data=", bin2hex($calc_data), "\n";
 
                                if ( (!$enc && $ciph =~ /des/) ||
-                                    $ciph =~ /rc4/ || 
+                                    $ciph =~ /rc4/ ||
                                     $cipher =~ /ecb/ ) {
                                        #TDES in decryption mode, RC4 and ECB mode
                                        #have a special rule
@@ -1266,7 +1269,7 @@ sub crypto_mct($$$$$$$$) {
                 } else {
                         $out .= "PLAINTEXT = ". bin2hex($calc_data). "\n\n";
                 }
-               
+
                if ( $ciph =~ /aes/ ) {
                        $key1 ^= substr($old_calc_data . $calc_data, -$keylen);
                        #print STDERR bin2hex($key1)."\n";
@@ -1309,13 +1312,13 @@ sub crypto_mct($$$$$$$$) {
                } elsif (!$enc && $cipher =~ /des-ede3-cfb/) {
                        #TDES decryption CFB has a special rule
                        $source_data = $next_source;
+               } elsif ( $ciph =~ /rc4/ || $cipher eq "des-ede3" || $cipher =~ /ecb/) {
+                       #No resetting of IV as the IV is all zero set initially (i.e. no IV)
+                       $source_data = $calc_data;
                } elsif (! $enc && $ciph =~ /des/ ) {
                        #TDES in decryption mode has a special rule
                        $iv = $old_calc_data;
                        $source_data = $calc_data;
-               } elsif ( $ciph =~ /rc4/ || $cipher =~ /ecb/ ) {
-                       #No resetting of IV as the IV is all zero set initially (i.e. no IV)
-                       $source_data = $calc_data;
                } else {
                        $iv = $calc_data;
                        $source_data = $old_calc_data;
@@ -1378,7 +1381,7 @@ sub rsa_siggen($$$) {
 
 # RSA SigVer test
 # $1: Message to be verified in hex form
-# $2: Hash algoritm
+# $2: Hash algorithm
 # $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
@@ -1416,6 +1419,48 @@ sub rsa_sigver($$$$$) {
        return $out;
 }
 
+# RSA X9.31 key generation test
+# $1 modulus size
+# $2 e
+# $3 xp1
+# $4 xp2
+# $5 Xp
+# $6 xq1
+# $7 xq2
+# $8 Xq
+# return: string formatted as expected by CAVS
+sub rsa_keygen($$$$$$$$) {
+       my $modulus = shift;
+       my $e = shift;
+       my $xp1 = shift;
+       my $xp2 = shift;
+       my $Xp = shift;
+       my $xq1 = shift;
+       my $xq2 = shift;
+       my $Xq = shift;
+
+       my $out = "";
+
+       my $ret = &$rsa_derive($modulus, $e, $xp1, $xp2, $Xp, $xq1, $xq2, $Xq);
+
+       my ($P, $Q, $N, $D) = split(/\n/, $ret);
+
+       $out .= "e = $e\n";
+       $out .= "xp1 = $xp1\n";
+       $out .= "xp2 = $xp2\n";
+       $out .= "Xp = $Xp\n";
+       $out .= "p = $P\n";
+       $out .= "xq1 = $xq1\n";
+       $out .= "xq2 = $xq2\n";
+       $out .= "Xq = $Xq\n";
+       $out .= "q = $Q\n";
+       $out .= "n = $N\n";
+       $out .= "d = $D\n\n";
+
+       return $out;
+
+}
+
 # X9.31 RNG test
 # $1 key for the AES cipher
 # $2 DT value
@@ -1473,6 +1518,11 @@ sub dsa_pqggen_driver($$) {
                die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen"
                        if (!defined($P) || !defined($Q) || !defined($G) ||
                            !defined($Seed) || !defined($c) || !defined($H));
+
+               # now change the counter to decimal as CAVS wants decimal
+               # counter value although all other is HEX
+               $c = hex($c);
+
                $out .= "P = $P\n";
                $out .= "Q = $Q\n";
                $out .= "G = $G\n";
@@ -1539,7 +1589,7 @@ sub dsa_sigver($$$$$$$$) {
        # but since it is not run on a security sensitive
        # system, I hope that this is fine
        my $keyfile = "dsa_sigver.tmp.$$";
-       &dsa_genpubkey($keyfile, $p, $q, $g, $y);
+       &$dsa_genpubkey($keyfile, $p, $q, $g, $y);
 
        $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n");
 
@@ -1614,7 +1664,12 @@ sub parse($$) {
        my $capital_g = "";
        my $capital_y = "";
        my $capital_r = "";
-       my $capital_s = "";
+       my $xp1 = "";
+       my $xp2 = "";
+       my $Xp = "";
+       my $xq1 = "";
+       my $xq2 = "";
+       my $Xq = "";
 
        my $mode = "";
 
@@ -1638,14 +1693,14 @@ sub parse($$) {
                # '# "SigVer PKCS#1 Ver 1.5" information for "IBMRHEL5"'
                # '# "SigGen PKCS#1 Ver 1.5" information for "IBMRHEL5"'
                # '#RC4VS MCT test data'
-               
+
                # avoid false positives from user specified 'for "PRODUCT"' strings
                my $tmpline = $line;
                $tmpline =~ s/ for ".*"//;
 
                ##### Extract cipher
                # XXX there may be more - to be added
-               if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen)/) {
+               if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) {
                        if ($tmpline    =~ /CBC/)   { $mode="cbc"; }
                        elsif ($tmpline =~ /ECB/)   { $mode="ecb"; }
                        elsif ($tmpline =~ /OFB/)   { $mode="ofb"; }
@@ -1694,9 +1749,13 @@ sub parse($$) {
 
                        if ($tt == 0) {
                        ##### Identify the test type
-                               if ($tmpline =~ /SigVer/ && $opt{'D'} ) {
+                               if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) {
+                                       $tt = 13;
+                                       die "Interface function rsa_derive for RSA key generation not defined for tested library"
+                                               if (!defined($rsa_derive));
+                               } elsif ($tmpline =~ /SigVer/ && $opt{'D'} ) {
                                        $tt = 12;
-                                       die "Interface function dsa_verify or dsa_genpubey for dSA verification not defined for tested library"
+                                       die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library"
                                                if (!defined($dsa_verify) || !defined($dsa_genpubkey));
                                } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) {
                                        $tt = 11;
@@ -1873,43 +1932,68 @@ sub parse($$) {
                                if ($tlen ne "");
                        $tlen=$1;
                }
-               elsif ($line =~ /^N\s*=\s*(.)/) { #DSA PQGGen
+               elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen
                        die "N seen twice - check input file"
                                if ($capital_n);
                        $capital_n = $1;
                }
-               elsif ($line =~ /^P\s*=\s*(.)/) { #DSA SigVer
+               elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer
                        die "P seen twice - check input file"
                                if ($capital_p);
                        $capital_p = $1;
                        $out .= $line . "\n"; # print it
                }
-               elsif ($line =~ /^Q\s*=\s*(.)/) { #DSA SigVer
+               elsif ($line =~ /^Q\s*=\s*(.*)/) { #DSA SigVer
                        die "Q seen twice - check input file"
                                if ($capital_q);
                        $capital_q = $1;
                        $out .= $line . "\n"; # print it
                }
-               elsif ($line =~ /^G\s*=\s*(.)/) { #DSA SigVer
+               elsif ($line =~ /^G\s*=\s*(.*)/) { #DSA SigVer
                        die "G seen twice - check input file"
                                if ($capital_g);
                        $capital_g = $1;
                        $out .= $line . "\n"; # print it
                }
-               elsif ($line =~ /^Y\s*=\s*(.)/) { #DSA SigVer
+               elsif ($line =~ /^Y\s*=\s*(.*)/) { #DSA SigVer
                        die "Y seen twice - check input file"
                                if ($capital_y);
                        $capital_y = $1;
                }
-               elsif ($line =~ /^R\s*=\s*(.)/) { #DSA SigVer
+               elsif ($line =~ /^R\s*=\s*(.*)/) { #DSA SigVer
                        die "R seen twice - check input file"
                                if ($capital_r);
                        $capital_r = $1;
                }
-               elsif ($line =~ /^S\s*=\s*(.)/) { #DSA SigVer
-                       die "S seen twice - check input file"
-                               if ($capital_s);
-                       $capital_s = $1;
+               elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen
+                       die "xp1 seen twice - check input file"
+                               if ($xp1);
+                       $xp1 = $1;
+               }
+               elsif ($line =~ /^xp2\s*=\s*(.*)/) { #RSA key gen
+                       die "xp2 seen twice - check input file"
+                               if ($xp2);
+                       $xp2 = $1;
+               }
+               elsif ($line =~ /^Xp\s*=\s*(.*)/) { #RSA key gen
+                       die "Xp seen twice - check input file"
+                               if ($Xp);
+                       $Xp = $1;
+               }
+               elsif ($line =~ /^xq1\s*=\s*(.*)/) { #RSA key gen
+                       die "xq1 seen twice - check input file"
+                               if ($xq1);
+                       $xq1 = $1;
+               }
+               elsif ($line =~ /^xq2\s*=\s*(.*)/) { #RSA key gen
+                       die "xq2 seen twice - check input file"
+                               if ($xq2);
+                       $xq2 = $1;
+               }
+               elsif ($line =~ /^Xq\s*=\s*(.*)/) { #RSA key gen
+                       die "Xq seen twice - check input file"
+                               if ($Xq);
+                       $Xq = $1;
                }
                else {
                        $out .= $line . "\n";
@@ -2009,7 +2093,7 @@ sub parse($$) {
                            $capital_g ne "" &&
                            $capital_y ne "" &&
                            $capital_r ne "" &&
-                           $capital_s ne "" &&
+                           $signature ne "" &&
                            $pt ne "") {
                                $out .= dsa_sigver($modulus,
                                                   $capital_p,
@@ -2017,7 +2101,7 @@ sub parse($$) {
                                                   $capital_g,
                                                   $capital_y,
                                                   $capital_r,
-                                                  $capital_s,
+                                                  $signature,
                                                   $pt);
 
                                # We do not clear the domain values PQG and
@@ -2027,10 +2111,36 @@ sub parse($$) {
                                # are already printed above
                                $capital_y = "";
                                $capital_r = "";
-                               $capital_s = "";
+                               $signature = "";
                                $pt = "";
                        }
                }
+               elsif ($tt == 13) {
+                       if($modulus ne "" &&
+                          $e ne "" &&
+                          $xp1 ne "" &&
+                          $xp2 ne "" &&
+                          $Xp ne "" &&
+                          $xq1 ne "" &&
+                          $xq2 ne "" &&
+                          $Xq ne "") {
+                               $out .= rsa_keygen($modulus,
+                                                  $e,
+                                                  $xp1,
+                                                  $xp2,
+                                                  $Xp,
+                                                  $xq1,
+                                                  $xq2,
+                                                  $Xq);
+                               $e = "";
+                               $xp1 = "";
+                               $xp2 = "";
+                               $Xp = "";
+                               $xq1 = "";
+                               $xq2 = "";
+                               $Xq = "";
+                       }
+               }
                elsif ($tt > 0) {
                        die "Test case $tt not defined";
                }
@@ -2051,7 +2161,8 @@ sub cleanup() {
        unlink("rsa_sigver.tmp.$$.sig");
        unlink("rsa_sigver.tmp.$$.der");
        unlink("rsa_sigver.tmp.$$.cnf");
-
+       unlink("dsa_siggen.tmp.$$");
+       unlink("dsa_sigver.tmp.$$");
        unlink("dsa_sigver.tmp.$$.sig");
        exit;
 }
@@ -2081,16 +2192,17 @@ sub main() {
                $rsa_sign =     \&libgcrypt_rsa_sign;
                $rsa_verify =   \&libgcrypt_rsa_verify;
                $gen_rsakey =   \&libgcrypt_gen_rsakey;
+               $rsa_derive =   \&libgcrypt_rsa_derive;
                $hash =         \&libgcrypt_hash;
                $state_cipher = \&libgcrypt_state_cipher;
                $state_cipher_des =     \&libgcrypt_state_cipher_des;
                $state_rng =    \&libgcrypt_state_rng;
                $hmac =         \&libgcrypt_hmac;
                $dsa_pqggen =   \&libgcrypt_dsa_pqggen;
-               $gen_dsakey =   \&libgcrypt_gen_dsakey;
-               $dsa_sign =     \&libgcrypt_dsa_sign;
-               $dsa_verify =   \&libgcrypt_dsa_verify;
-                $dsa_genpubkey = \&libgcrypt_dsa_genpubkey;
+               $gen_dsakey =   \&libgcrypt_gen_dsakey;
+               $dsa_sign =     \&libgcrypt_dsa_sign;
+               $dsa_verify =   \&libgcrypt_dsa_verify;
+               $dsa_genpubkey = \&libgcrypt_dsa_genpubkey;
         } else {
                 die "Invalid interface option given";
         }
@@ -2121,7 +2233,7 @@ sub main() {
        # Do the job
        parse($infile, $outfile);
 
-       unlink("rsa_siggen.tmp.$$");
+       cleanup();
 
 }