Fixed the fips 186 dsa key generation.
[libgcrypt.git] / tests / cavs_driver.pl
1 #!/usr/bin/env perl
2 #
3 # $Id: cavs_driver.pl 1395 2008-11-10 15:18:03Z smueller $
4 #
5 # CAVS test driver (based on the OpenSSL driver)
6 # Written by: Stephan Müller <sm@atsec.com>
7 # Copyright (c) atsec information security corporation
8 #
9 # Permission is hereby granted, free of charge, to any person obtaining a copy
10 # of this software and associated documentation files (the "Software"), to deal
11 # in the Software without restriction, including without limitation the rights
12 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 # copies of the Software, and to permit persons to whom the Software is
14 # furnished to do so, subject to the following conditions: 
15 #
16 # The above copyright notice and this permission notice shall be included in
17 # all copies or substantial portions of the Software.
18 #
19 #                            NO WARRANTY
20 #
21 #    BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
22 #    FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
23 #    OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
24 #    PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
25 #    OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 #    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
27 #    TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
28 #    PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
29 #    REPAIR OR CORRECTION.
30 #
31 #    IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
32 #    WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
33 #    REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
34 #    INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
35 #    OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
36 #    TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
37 #    YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
38 #    PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
39 #    POSSIBILITY OF SUCH DAMAGES.
40 #
41 #
42 # test execution instruction:
43 # 1. get the request files from the lab
44 # 2. call each request file from 1. with this program:
45 #       $0 <FILE>.rep
46 # 3. send the resulting file <FILE>.rsp to the lab
47 #
48 #
49 # Test should be easily adoptable to other implementations
50 # See the first functions for this task
51 #
52 # Following tests are covered (others may also be covered
53 # but have not been tested)
54 #
55 # AES
56 #       [CBC|CFB128|ECB|OFB]GFSbox[128|192|256]
57 #       [CBC|CFB128|ECB|OFB]MCT[128|192|256]
58 #       [CBC|CFB128|ECB|OFB]VarKey[128|192|256]
59 #       [CBC|CFB128|ECB|OFB]KeySbox[128|192|256]
60 #       [CBC|CFB128|ECB|OFB]MMT[128|192|256]
61 #       [CBC|CFB128|ECB|OFB]VarTxt[128|192|256]
62 #
63 # RSA
64 #       SigGen[15|RSA]
65 #       SigVer15
66 #       (SigVerRSA is not applicable for OpenSSL as X9.31 padding
67 #               is not done through openssl dgst)
68 #
69 # SHA
70 #       SHA[1|224|256|384|512]ShortMsg
71 #       SHA[1|224|256|384|512]LongMsg
72 #       SHA[1|224|256|384|512]Monte
73 #
74 # HMAC (SHA - caveat: we only support hash output equal to the block size of
75 #       of the hash - we do not support truncation of the hash; to support
76 #       that, we first need to decipher the HMAC.req file - see hmac_kat() )
77 #       HMAC
78 #
79 # TDES
80 #       T[CBC|CFB??|ECB|OFB]Monte[1|2|3]
81 #       T[CBC|CFB??|ECB|OFB]permop
82 #       T[CBC|CFB??|ECB|OFB]MMT[1|2|3]
83 #       T[CBC|CFB??|ECB|OFB]subtab
84 #       T[CBC|CFB??|ECB|OFB]varkey
85 #       T[CBC|CFB??|ECB|OFB]invperm
86 #       T[CBC|CFB??|ECB|OFB]vartext
87 #
88 # ANSI X9.31 RNG
89 #       ANSI931_AES128MCT
90 #       ANSI931_AES128VST
91 #
92 # DSA
93 #       PQGGen
94 #       SigGen
95 #       SigVer
96 #
97 # RC4 (atsec developed tests)
98 #       RC4KeyBD
99 #       RC4MCT
100 #       RC4PltBD
101 #       RC4REGT
102 #
103
104 use strict;
105 use warnings;
106 use IPC::Open2;
107 use Getopt::Std;
108 use MIME::Base64;
109
110 # Contains the command line options
111 my %opt;
112
113 #################################################################
114 ##### Central interface functions to the external ciphers #######
115 #################################################################
116 # Only these interface routines should be changed in case of
117 # porting to a new cipher library
118 #
119 # For porting to a new library, create implementation of these functions
120 # and then add pointers to the respective implementation of each
121 # function to the given variables.
122
123 # common encryption/decryption routine
124 # $1 key in hex form (please note for 3DES: even when ede3 for three
125 #    independent ciphers is given with the cipher specification, we hand in
126 #    either one key for k1 = k2 = k3, two keys which are concatinated for
127 #    k1 = k3, k2 independent, or three keys which are concatinated for
128 #    k1, k2, k3 independent)
129 # $2 iv in hex form
130 # $3 cipher - the cipher string is defined as specified in the openssl
131 #    enc(1ssl) specification for the option "-ciphername"
132 #    (e.g. aes-128-cbc or des-ede3-cbc)
133 # $4 encrypt=1/decrypt=0
134 # $5 de/encrypted data in hex form
135 # return en/decrypted data in hex form
136 my $encdec;
137
138 # Sign a message with RSA
139 # $1: data to be signed in hex form
140 # $2: Hash algo
141 # $3: Key file in PEM format with the private key
142 # return: digest in hex format
143 my $rsa_sign;
144
145 # Verify a message with RSA
146 # $1: data to be verified in hex form
147 # $2: hash algo
148 # $3: file holding the public RSA key in PEM format
149 # $4: file holding the signature in binary form
150 # return: 1 == verified / 0 == not verified
151 my $rsa_verify;
152
153 # generate a new private RSA key with the following properties:
154 #       exponent is 65537
155 #       PEM format
156 # $1 key size in bit
157 # $2 keyfile name
158 # return: nothing, but file created
159 my $gen_rsakey;
160
161 # Creating a hash
162 # $1: Plaintext in hex form
163 # $2: hash type in the form documented in openssl's dgst(1ssl) - e.g.
164 #     sha1, sha224, sha256, sha384, sha512
165 # return: hash in hex form
166 my $hash;
167
168 # supplying the call to the external cipher implementation
169 # that is being used to keep STDIN and STDOUT open
170 # to maintain the state of the block chaining
171 # $1: cipher
172 # $2: 1=encryption, 0=decryption
173 # $3: buffersize needed for openssl
174 # $4: encryption key in binary form
175 # $5: IV in binary form
176 # return: command line to execute the application
177 my $state_cipher;
178 # the only difference of the DES version is that it implements the inner loop
179 # of the TDES tests
180 my $state_cipher_des;
181
182 # supplying the call to the external cipher implementation
183 # that is being used to keep STDIN and STDOUT open
184 # to maintain the state of the RNG with its seed
185 #
186 # input holds seed values
187 # $1: cipher key in hex format
188 # $2: DT value in hex format
189 # $3: V value in hex format
190 #
191 # return: command line to execute the application
192 #
193 # the application is expected to deliver random values on STDOUT - the script
194 # reads 128 bits repeatedly where the state of the RNG must be retained
195 # between the reads. The output of the RNG on STDOUT is assumed to be binary.
196 my $state_rng;
197
198 # Generate an HMAC based on SHAx
199 # $1: Key to be used for the HMAC in hex format
200 # $2: length of the hash to be calculated in bits
201 # $3: Message for which the HMAC shall be calculated in hex format
202 # $4: hash type (1 - SHA1, 224 - SHA224, and so on)
203 # return: calculated HMAC in hex format
204 my $hmac;
205
206 #
207 # Generate the P, Q, G, Seed, counter, h (value used to generate g) values
208 # for DSA
209 # $1: modulus size
210 # return: string with the calculated values in hex format, where each value
211 #         is separated from the previous with a \n in the following order:
212 #         P\n
213 #         Q\n
214 #         G\n
215 #         Seed\n
216 #         counter\n
217 #         h
218 my $dsa_pqggen;
219
220 # Verify a message with DSA
221 # $1: data to be verified in hex form
222 # $2: file holding the public DSA key in PEM format
223 # $3: R value of the signature
224 # $4: S value of the signature
225 # return: 1 == verified / 0 == not verified
226 my $dsa_verify;
227
228 # generate a new DSA key with the following properties:
229 #       PEM format
230 # $1 keyfile name 
231 # return: file created, hash with keys of P, Q, G in hex format
232 my $gen_dsakey;
233
234 # Sign a message with DSA
235 # $1: data to be signed in hex form
236 # $2: Key file in PEM format with the private key
237 # return: hash of digest information in hex format with Y, R, S as keys
238 my $dsa_sign;
239
240 ################################################################
241 ##### OpenSSL interface functions
242 ################################################################
243 sub openssl_encdec($$$$$) {
244         my $key=shift;
245         my $iv=shift;
246         my $cipher=shift;
247         my $enc = (shift) ? "-e" : "-d";
248         my $data=shift;
249
250         # We only invoke the driver with the IV parameter, if we have
251         # an IV, otherwise, we skip it
252         $iv = "-iv $iv" if ($iv);
253
254         $data=hex2bin($data);
255         my $program="openssl enc -$cipher -nopad -nosalt -K $key $enc $iv";
256         $program = "rc4 -k $key" if $opt{'R'}; #for ARCFOUR, no IV must be given
257         $data=pipe_through_program($data,$program);
258         return bin2hex($data);
259 }
260
261 sub openssl_rsa_sign($$$) {
262         my $data = shift;
263         my $cipher = shift;
264         my $keyfile = shift;
265
266         $data=hex2bin($data);
267         die "ARCFOUR not available for RSA" if $opt{'R'};
268         $data=pipe_through_program($data,
269                 "openssl dgst -$cipher -binary -sign $keyfile");
270         return bin2hex($data);
271 }
272
273 sub openssl_rsa_verify($$$$) {
274         my $data = shift;
275         my $cipher = shift;
276         my $keyfile = shift;
277         my $sigfile = shift;
278
279         $data = hex2bin($data);
280         die "ARCFOUR not available for RSA" if $opt{'R'};
281         $data = pipe_through_program($data,
282                 "openssl dgst -$cipher -binary -verify $keyfile -signature $sigfile");
283
284         # Parse through the OpenSSL output information
285         return ($data =~ /OK/);
286 }
287
288 sub openssl_gen_rsakey($$) {
289         my $keylen = shift;
290         my $file = shift;
291
292         die "ARCFOUR not available for RSA" if $opt{'R'};
293         # generating of a key with exponent 0x10001
294         my @args = ("openssl", "genrsa", "-F4", "-out", "$file", "$keylen");
295         system(@args) == 0
296                 or die "system @args failed: $?";
297         die "system @args failed: file $file not created" if (! -f $file);
298 }
299
300 sub openssl_hash($$) {
301         my $pt = shift;
302         my $cipher = shift;
303
304         die "ARCFOUR not available for hashes" if $opt{'R'};
305         my $hash = hex2bin($pt);
306         #bin2hex not needed as the '-hex' already converts it
307         return pipe_through_program($hash, "openssl dgst -$cipher -hex");
308 }
309
310 sub openssl_state_cipher($$$$$) {
311         my $cipher = shift;
312         my $encdec = shift;
313         my $bufsize = shift;
314         my $key = shift;
315         my $iv = shift;
316
317         my $enc = $encdec ? "-e": "-d";
318
319         # We only invoke the driver with the IV parameter, if we have
320         # an IV, otherwise, we skip it
321         $iv = "-iv ".bin2hex($iv) if ($iv);
322
323         my $out = "openssl enc -'$cipher' $enc -nopad -nosalt -bufsize $bufsize -K ".bin2hex($key)." $iv";
324         #for ARCFOUR, no IV must be given
325         $out = "rc4 -k " . bin2hex($key) if $opt{'R'};
326         return $out;
327 }
328
329 ###### End of OpenSSL interface implementation ############
330
331 ###########################################################
332 ###### libgcrypt implementation
333 ###########################################################
334 sub libgcrypt_encdec($$$$$) {
335         my $key=shift;
336         my $iv=shift;
337         my $cipher=shift;
338         my $enc = (shift) ? "encrypt" : "decrypt";
339         my $data=shift;
340
341         # We only invoke the driver with the IV parameter, if we have
342         # an IV, otherwise, we skip it
343         $iv = "--iv $iv" if ($iv);
344
345         my $program="fipsdrv --key $key $iv --algo $cipher $enc";
346
347         return pipe_through_program($data,$program);
348
349 }
350
351 sub libgcrypt_rsa_sign($$$) {
352         my $data = shift;
353         my $hashalgo = shift;
354         my $keyfile = shift;
355
356         die "ARCFOUR not available for RSA" if $opt{'R'};
357
358         return pipe_through_program($data,
359                 "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile rsa-sign");
360 }
361
362 sub libgcrypt_rsa_verify($$$$) {
363         my $data = shift;
364         my $hashalgo = shift;
365         my $keyfile = shift;
366         my $sigfile = shift;
367
368         die "ARCFOUR not available for RSA" if $opt{'R'};
369         $data = pipe_through_program($data,
370                 "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify");
371
372         # Parse through the output information
373         return ($data =~ /GOOD signature/);
374 }
375
376 sub libgcrypt_gen_rsakey($$) {
377         my $keylen = shift;
378         my $file = shift;
379
380         die "ARCFOUR not available for RSA" if $opt{'R'};
381         my @args = ("fipsdrv --keysize $keylen rsa-gen > $file");
382         system(@args) == 0
383                 or die "system @args failed: $?";
384         die "system @args failed: file $file not created" if (! -f $file);
385 }
386
387 sub libgcrypt_hash($$) {
388         my $pt = shift;
389         my $hashalgo = shift;
390
391         my $program = "fipsdrv --algo $hashalgo digest";
392         die "ARCFOUR not available for hashes" if $opt{'R'};
393
394         return pipe_through_program($pt, $program);
395 }
396
397 sub libgcrypt_state_cipher($$$$$) {
398         my $cipher = shift;
399         my $enc = (shift) ? "encrypt": "decrypt";
400         my $bufsize = shift;
401         my $key = shift;
402         my $iv = shift;
403
404         # We only invoke the driver with the IV parameter, if we have
405         # an IV, otherwise, we skip it
406         $iv = "--iv ".bin2hex($iv) if ($iv);
407
408         my $program="fipsdrv --binary --key ".bin2hex($key)." $iv --algo '$cipher' --chunk '$bufsize' $enc";
409
410         return $program;
411 }
412
413 sub libgcrypt_state_cipher_des($$$$$) {
414         my $cipher = shift;
415         my $enc = (shift) ? "encrypt": "decrypt";
416         my $bufsize = shift;
417         my $key = shift;
418         my $iv = shift;
419
420         # We only invoke the driver with the IV parameter, if we have
421         # an IV, otherwise, we skip it
422         $iv = "--iv ".bin2hex($iv) if ($iv);
423
424         my $program="fipsdrv --algo '$cipher' --mct-server $enc";
425
426         return $program;
427 }
428
429 sub libgcrypt_state_rng($$$) {
430         my $key = shift;
431         my $dt = shift;
432         my $v = shift;
433
434         return "fipsdrv --binary --loop --key $key --iv $v --dt $dt random";
435 }
436
437 sub libgcrypt_hmac($$$$) {
438         my $key = shift;
439         my $maclen = shift;
440         my $msg = shift;
441         my $hashtype = shift;
442
443         my $program = "fipsdrv --key $key --algo $hashtype hmac-sha";
444         return pipe_through_program($msg, $program);    
445 }
446
447 sub libgcrypt_dsa_pqggen($) {
448         my $mod = shift;
449
450         my $program = "fipsdrv --keysize $mod dsa-pqg-gen";
451         return pipe_through_program("", $program);
452 }
453
454 ######### End of libgcrypt implementation ################
455
456 ################################################################
457 ###### Vendor1 interface functions
458 ################################################################
459
460 sub vendor1_encdec($$$$$) {
461         my $key=shift;
462         my $iv=shift;
463         my $cipher=shift;
464         my $enc = (shift) ? "encrypt" : "decrypt";
465         my $data=shift;
466
467         $data=hex2bin($data);
468         my $program = "./aes $enc $key";
469         $data=pipe_through_program($data,$program);
470         return bin2hex($data);
471 }
472
473 sub vendor1_state_cipher($$$$$) {
474         my $cipher = shift;
475         my $encdec = shift;
476         my $bufsize = shift;
477         my $key = shift;
478         my $iv = shift;
479
480         $key = bin2hex($key);
481         my $enc = $encdec ? "encrypt": "decrypt";
482         my $out = "./aes $enc $key $bufsize";
483         return $out;
484 }
485
486 ##### No other interface functions below this point ######
487 ##########################################################
488
489 ##########################################################
490 # General helper routines
491
492 # Executing a program by feeding STDIN and retrieving
493 # STDOUT
494 # $1: data string to be piped to the app on STDIN
495 # rest: program and args
496 # returns: STDOUT of program as string
497 sub pipe_through_program($@) {
498         my $in = shift;
499         my @args = @_;
500
501         my ($CO, $CI);
502         my $pid = open2($CO, $CI, @args);
503         
504         my $out = "";
505         my $len = length($in);
506         my $first = 1;
507         while (1) {
508                 my $rin = "";
509                 my $win = "";
510                 # Output of prog is FD that we read
511                 vec($rin,fileno($CO),1) = 1;
512                 # Input of prog is FD that we write
513                 # check for $first is needed because we can have NULL input
514                 # that is to be written to the app
515                 if ( $len > 0 || $first) {
516                         (vec($win,fileno($CI),1) = 1);
517                         $first=0;
518                 }
519                 # Let us wait for 100ms
520                 my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1);
521                 if ( $wout ) {
522                         my $written = syswrite($CI, $in, $len);
523                         die "broken pipe" if !defined $written;
524                         $len -= $written;
525                         substr($in, 0, $written) = "";
526                         if ($len <= 0) {
527                                 close $CI or die "broken pipe: $!";
528                         }
529                 }
530                 if ( $rout ) {
531                         my $tmp_out = "";
532                         my $bytes_read = sysread($CO, $tmp_out, 4096);
533                         $out .= $tmp_out;
534                         last if ($bytes_read == 0);
535                 }
536         }
537         close $CO or die "broken pipe: $!";
538         waitpid $pid, 0;
539         
540         return $out;
541 }
542
543 #
544 # convert ASCII hex to binary input
545 # $1 ASCII hex
546 # return binary representation
547 sub hex2bin($) {
548         my $in = shift;
549         my $len = length($in);
550         $len = 0 if ($in eq "00");
551         return pack("H$len", "$in");
552 }
553
554 #
555 # convert binary input to ASCII hex
556 # $1 binary value
557 # return ASCII hex representation
558 sub bin2hex($) {
559         my $in = shift;
560         my $len = length($in)*2;
561         return unpack("H$len", "$in");
562 }
563
564 # $1: binary byte (character)
565 # returns: binary byte with odd parity using low bit as parity bit
566 sub odd_par($) {
567         my $in = ord(shift);
568         my $odd_count=0;
569         for(my $i=1; $i<8; $i++) {
570                 $odd_count++ if ($in & (1<<$i));
571         }
572
573         my $out = $in;
574         if ($odd_count & 1) { # check if parity is already odd
575                 $out &= ~1; # clear the low bit
576         } else {
577                 $out |= 1; # set the low bit
578         }
579
580         return chr($out);
581 }
582
583 # DES keys uses only the 7 high bits of a byte, the 8th low bit
584 # is the parity bit
585 # as the new key is calculated from oldkey XOR cipher in the MCT test,
586 # the parity is not really checked and needs to be set to match
587 # expectation (OpenSSL does not really care, but the FIPS
588 # test result is expected that the key has the appropriate parity)
589 # $1: arbitrary binary string
590 # returns: string with odd parity set in low bit of each byte
591 sub fix_key_parity($) {
592         my $in = shift;
593         my $out = "";
594         for (my $i = 0; $i < length($in); $i++) {
595                 $out .= odd_par(substr($in, $i, 1));
596         }
597
598         return $out;
599 }
600
601 ####################################################
602 # DER/PEM utility functions
603 # Cf. http://www.columbia.edu/~ariel/ssleay/layman.html
604
605 # Convert unsigned integer to base256 bigint bytes
606 # $1 integer
607 # returns base256 octet string
608 sub int_base256_unsigned($) {
609         my $n = shift;
610
611         my $out = chr($n & 255);
612         while ($n>>=8) {
613                 $out = chr($n & 255) . $out;
614         }
615
616         return $out;
617 }
618
619 # Convert signed integer to base256 bigint bytes
620 # $1 integer
621 # returns base256 octet string
622 sub int_base256_signed($) {
623         my $n = shift;
624         my $negative = ($n < 0);
625
626         if ($negative) {
627                 $n = -$n-1;
628         }
629
630         my $out = int_base256_unsigned($n);
631
632         if (ord(substr($out, 0, 1)) & 128) {
633                 # it's supposed to be positive but has sign bit set,
634                 # add a leading zero
635                 $out = chr(0) . $out;
636         }
637
638         if ($negative) {
639                 my $neg = chr(255) x length($out);
640                 $out ^= $neg;
641         }
642
643         return $out;
644 }
645
646 # Length header for specified DER object length
647 # $1 length as integer
648 # return octet encoding for length
649 sub der_len($) {
650         my $len = shift;
651
652         if ($len <= 127) {
653                 return chr($len);
654         } else {
655                 my $blen = int_base256_unsigned($len);
656
657                 return chr(128 | length($blen)) . $blen;
658         }
659 }
660
661 # Prepend length header to object
662 # $1 object as octet sequence
663 # return length header for object followed by object as octets
664 sub der_len_obj($) {
665         my $x = shift;
666
667         return der_len(length($x)) . $x;
668 }
669
670 # DER sequence
671 # $* objects
672 # returns DER sequence consisting of the objects passed as arguments
673 sub der_seq {
674         my $seq = join("", @_);
675         return chr(0x30) . der_len_obj($seq);
676 }
677
678 # DER bitstring
679 # $1 input octets (must be full octets, fractional octets not supported)
680 # returns input encapsulated as bitstring
681 sub der_bitstring($) {
682         my $x = shift;
683
684         $x = chr(0) . $x;
685
686         return chr(0x03) . der_len_obj($x);
687 }
688
689 # base-128-encoded integer, used for object numbers.
690 # $1 integer
691 # returns octet sequence
692 sub der_base128($) {
693         my $n = shift;
694
695         my $out = chr($n & 127);
696
697         while ($n>>=7) {
698                 $out = chr(128 | ($n & 127)) . $out;
699         }
700
701         return $out;
702 }
703
704 # Generating the PEM certificate string
705 # (base-64-encoded DER string)
706 # $1 DER string
707 # returns octet sequence
708 sub pem_cert($) {
709         my $n = shift;
710
711         my $out = "-----BEGIN PUBLIC KEY-----\n";
712         $out .= encode_base64($n);
713         $out .= "-----END PUBLIC KEY-----\n";
714
715         return $out;
716 }
717
718 # DER object identifier
719 # $* sequence of id numbers
720 # returns octets
721 sub der_objectid {
722         my $v1 = shift;
723         my $v2 = shift;
724
725         my $out = chr(40*$v1 + $v2) . join("", map { der_base128($_) } @_);
726
727         return chr(0x06) . der_len_obj($out);
728 }
729
730 # DER signed integer
731 # $1 number as octet string (base 256 representation, high byte first)
732 # returns number in DER integer encoding
733 sub der_bigint($) {
734         my $x = shift;
735
736         return chr(0x02) . der_len_obj($x);
737 }
738
739 # DER positive integer with leading zeroes stripped
740 # $1 number as octet string (base 256 representation, high byte first)
741 # returns number in DER integer encoding
742 sub der_pos_bigint($) {
743         my $x = shift;
744
745         # strip leading zero digits
746         $x =~ s/^[\0]+//;
747
748         # need to prepend a zero if high bit set, since it would otherwise be
749         # interpreted as a negative number. Also needed for number 0.
750         if (!length($x) || ord(substr($x, 0, 1)) >= 128) {
751                 $x = chr(0) . $x;
752         }
753
754         return der_bigint($x);
755 }
756
757 # $1 number as signed integer
758 # returns number as signed DER integer encoding
759 sub der_int($) {
760         my $n = shift;
761         
762         return der_bigint(int_base256_signed($n));
763 }
764
765 # the NULL object constant
766 sub der_null() {
767         return chr(0x05) . chr(0x00);
768 }
769
770 # Unit test helper
771 # $1 calculated result
772 # $2 expected result
773 # no return value, dies if results differ, showing caller's line number
774 sub der_test($$) {
775         my $actual = bin2hex(shift);
776         my $expected = shift;
777
778         my @caller = caller;
779         $actual eq $expected or die "Error:line $caller[2]:assertion failed: "
780                 ."$actual != $expected\n";
781 }
782
783 # Unit testing for the DER encoding functions
784 # Examples from http://www.columbia.edu/~ariel/ssleay/layman.html
785 # No input, no output. Dies if unit tests fail.
786 sub der_unit_test {
787         ## uncomment these if you want to test the test framework
788         #print STDERR "Unit test running\n";
789         #der_test chr(0), "42";
790
791         der_test der_null, "0500";
792
793         # length bytes
794         der_test der_len(1), "01";
795         der_test der_len(127), "7f";
796         der_test der_len(128), "8180";
797         der_test der_len(256), "820100";
798         der_test der_len(65536), "83010000";
799
800         # bigint
801         der_test der_bigint(chr(0)), "020100";
802         der_test der_bigint(chr(128)), "020180"; # -128
803         der_test der_pos_bigint(chr(128)), "02020080"; # +128
804         der_test der_pos_bigint(chr(0).chr(0).chr(1)), "020101";
805         der_test der_pos_bigint(chr(0)), "020100";
806
807         # integers (tests base256 conversion)
808         der_test der_int(     0), "020100";
809         der_test der_int(   127), "02017f";
810         der_test der_int(   128), "02020080";
811         der_test der_int(   256), "02020100";
812         der_test der_int(    -1), "0201ff";
813         der_test der_int(  -128), "020180";
814         der_test der_int(  -129), "0202ff7f";
815         der_test der_int(-65536), "0203ff0000";
816         der_test der_int(-65537), "0203feffff";
817
818         # object encoding, "RSA Security"
819         der_test der_base128(840), "8648";
820         der_test der_objectid(1, 2, 840, 113549), "06062a864886f70d";
821
822         # Combinations
823         der_test der_bitstring("ABCD"), "03050041424344";
824         der_test der_bitstring(der_null), "0303000500";
825         der_test der_seq(der_int(0), der_null), "30050201000500";
826
827         # The big picture
828         der_test der_seq(der_seq(der_objectid(1, 2, 840, 113549), der_null),
829                          der_bitstring(der_seq(der_pos_bigint(chr(5)),
830                                                der_pos_bigint(chr(3))))),
831                  "3017300a06062a864886f70d05000309003006020105020103";
832 }
833
834 ####################################################
835 # OpenSSL missing functionality workarounds
836
837 ## Format of an RSA public key:
838 #    0:d=0  hl=3 l= 159 cons: SEQUENCE          
839 #    3:d=1  hl=2 l=  13 cons:  SEQUENCE          
840 #    5:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
841 #   16:d=2  hl=2 l=   0 prim:   NULL              
842 #   18:d=1  hl=3 l= 141 prim:  BIT STRING        
843 #                              [ sequence: INTEGER (n), INTEGER (e) ]
844
845 # generate RSA pub key in PEM format
846 # $1: filename where PEM key is to be stored
847 # $2: n of the RSA key in hex
848 # $3: e of the RSA key in hex
849 # return: nothing, but file created
850 sub gen_pubrsakey($$$) {
851         my $filename=shift;
852         my $n = shift;
853         my $e = shift;
854
855         # make sure the DER encoder works ;-)
856         der_unit_test();
857
858         # generate DER encoding of the public key
859
860         my $rsaEncryption = der_objectid(1, 2, 840, 113549, 1, 1, 1);
861
862         my $der = der_seq(der_seq($rsaEncryption, der_null),
863                           der_bitstring(der_seq(der_pos_bigint(hex2bin($n)),
864                                                 der_pos_bigint(hex2bin($e)))));
865
866         open(FH, ">", $filename) or die;
867         print FH pem_cert($der);
868         close FH;
869
870 }
871
872 # generate RSA pub key in PEM format
873 #
874 # This implementation uses "openssl asn1parse -genconf" which was added
875 # in openssl 0.9.8. It is not available in older openssl versions.
876 #
877 # $1: filename where PEM key is to be stored
878 # $2: n of the RSA key in hex
879 # $3: e of the RSA key in hex
880 # return: nothing, but file created
881 sub gen_pubrsakey_using_openssl($$$) {
882         my $filename=shift;
883         my $n = shift;
884         my $e = shift;
885
886         my $asn1 = "asn1=SEQUENCE:pubkeyinfo
887
888 [pubkeyinfo]
889 algorithm=SEQUENCE:rsa_alg
890 pubkey=BITWRAP,SEQUENCE:rsapubkey
891
892 [rsa_alg]
893 algorithm=OID:rsaEncryption
894 parameter=NULL
895
896 [rsapubkey]
897 n=INTEGER:0x$n
898
899 e=INTEGER:0x$e";
900
901         open(FH, ">$filename.cnf") or die "Cannot create file $filename.cnf: $?";
902         print FH $asn1;
903         close FH;
904         my @args = ("openssl", "asn1parse", "-genconf", "$filename.cnf", "-noout", "-out", "$filename.der");
905         system(@args) == 0 or die "system @args failed: $?";
906         @args = ("openssl", "rsa", "-inform", "DER", "-in", "$filename.der",
907                  "-outform", "PEM", "-pubin", "-pubout", "-out", "$filename");
908         system(@args) == 0 or die "system @args failed: $?";
909         die "RSA PEM formatted key file $filename was not created"
910                 if (! -f $filename);
911
912         unlink("$filename.cnf");
913         unlink("$filename.der");
914 }
915
916 ############################################
917 # Test cases
918
919 # This is the Known Answer Test
920 # $1: the string that we have to put in front of the key
921 #     when printing the key
922 # $2: crypto key1 in hex form
923 # $3: crypto key2 in hex form (TDES, undef otherwise)
924 # $4: crypto key3 in hex form (TDES, undef otherwise)
925 # $5: IV in hex form
926 # $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form
927 # $7: cipher
928 # $8: encrypt=1/decrypt=0
929 # return: string formatted as expected by CAVS
930 sub kat($$$$$$$$) {
931         my $keytype = shift;
932         my $key1 = shift;
933         my $key2 = shift;
934         my $key3 = shift;
935         my $iv = shift;
936         my $pt = shift;
937         my $cipher = shift;
938         my $enc = shift;
939
940         my $out = "";
941
942         $out .= "$keytype = $key1\n";
943
944         # this is the concardination of the keys for 3DES
945         if (defined($key2)) {
946                 $out .= "KEY2 = $key2\n";
947                 $key1 = $key1 . $key2;
948         }
949         if (defined($key3)) {
950                 $out .= "KEY3 = $key3\n";
951                 $key1= $key1 . $key3;
952         }
953         
954         $out .= "IV = $iv\n" if (defined($iv) && $iv ne "");
955         if ($enc) {
956                 $out .= "PLAINTEXT = $pt\n";
957                 $out .= "CIPHERTEXT = " . &$encdec($key1, $iv, $cipher, 1, $pt) . "\n";
958         } else {
959                 $out .= "CIPHERTEXT = $pt\n";
960                 $out .= "PLAINTEXT = " . &$encdec($key1, $iv, $cipher, 0, $pt) . "\n";
961         }
962
963         return $out;
964 }
965
966 # This is the Known Answer Test for Hashes
967 # $1: Plaintext in hex form
968 # $2: hash
969 # $3: hash length (undef if not applicable)
970 # return: string formatted as expected by CAVS
971 sub hash_kat($$$) {
972         my $pt = shift;
973         my $cipher = shift;
974         my $len = shift;
975
976         my $out = "";
977         $out .= "Len = $len\n" if (defined($len));
978         $out .= "Msg = $pt\n";
979
980         $pt = "" if(!$len);
981         $out .= "MD = " . &$hash($pt, $cipher) . "\n";
982         return $out;
983 }
984
985 # Known Answer Test for HMAC hash
986 # $1: key length in bytes
987 # $2: MAC length in bytes
988 # $3: key for HMAC in hex form
989 # $4: message to be hashed
990 # return: string formatted as expected by CAVS
991 sub hmac_kat($$$$) {
992         my $klen = shift;
993         my $tlen = shift;
994         my $key  = shift;
995         my $msg  = shift;
996
997         # XXX this is a hack - we need to decipher the HMAC REQ files in a more
998         # sane way
999         #
1000         # This is a conversion table from the expected hash output size
1001         # to the assumed hash type - we only define here the block size of
1002         # the underlying hashes and do not allow any truncation
1003         my %hashtype = (
1004                 20 => 1,
1005                 28 => 224,
1006                 32 => 256,
1007                 48 => 384,
1008                 64 => 512
1009         );
1010
1011         die "Hash output size $tlen is not supported!"
1012                 if(!defined($hashtype{$tlen}));
1013
1014         my $out = "";
1015         $out .= "Klen = $klen\n";
1016         $out .= "Tlen = $tlen\n";
1017         $out .= "Key = $key\n";
1018         $out .= "Msg = $msg\n";
1019         $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n\n";
1020
1021         return $out;
1022 }
1023
1024
1025 # Cipher Monte Carlo Testing
1026 # $1: the string that we have to put in front of the key
1027 #     when printing the key
1028 # $2: crypto key1 in hex form
1029 # $3: crypto key2 in hex form (TDES, undef otherwise)
1030 # $4: crypto key3 in hex form (TDES, undef otherwise)
1031 # $5: IV in hex form
1032 # $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form
1033 # $7: cipher
1034 # $8: encrypt=1/decrypt=0
1035 # return: string formatted as expected by CAVS
1036 sub crypto_mct($$$$$$$$) {
1037         my $keytype = shift;
1038         my $key1 = hex2bin(shift);
1039         my $key2 = shift;
1040         my $key3 = shift;
1041         my $iv = hex2bin(shift);
1042         my $source_data = hex2bin(shift);
1043         my $cipher = shift;
1044         my $enc = shift;
1045
1046         my $out = "";
1047
1048         $key2 = hex2bin($key2) if (defined($key2));
1049         $key3 = hex2bin($key3) if (defined($key3));
1050         my $bufsize = length($source_data);
1051
1052         # for AES: outer loop 0-99, inner 0-999 based on FIPS compliance tests
1053         # for RC4: outer loop 0-99, inner 0-999 based on atsec compliance tests
1054         # for DES: outer loop 0-399, inner 0-9999 based on FIPS compliance tests
1055         my $ciph = substr($cipher,0,3);
1056         my $oloop=100;
1057         my $iloop=1000;
1058         if ($ciph =~ /des/) {$oloop=400;$iloop=10000;}
1059
1060         for (my $i=0; $i<$oloop; ++$i) {
1061                 $out .= "COUNT = $i\n";
1062                 if (defined($key2)) {
1063                         $out .= "$keytype = ". bin2hex($key1). "\n";
1064                         $out .= "KEY2 = ". bin2hex($key2). "\n";
1065                         $key1 = $key1 . $key2;
1066                 } else {
1067                         $out .= "$keytype = ". bin2hex($key1). "\n";
1068                 }
1069                 if(defined($key3)) {
1070                         $out .= "KEY3 = ". bin2hex($key3). "\n";
1071                         $key1 = $key1 . $key3;
1072                 }
1073                 my $keylen = length($key1);
1074
1075                 $out .= "IV = ". bin2hex($iv) . "\n"
1076                         if (defined($iv) && $iv ne "");
1077
1078                 if ($enc) {
1079                         $out .= "PLAINTEXT = ". bin2hex($source_data). "\n";
1080                 } else {
1081                         $out .= "CIPHERTEXT = ". bin2hex($source_data). "\n";
1082                 }
1083                 my ($CO, $CI);
1084                 my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv);
1085                 $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/);
1086                 my $pid = open2($CO, $CI, $cipher_imp);
1087
1088                 my $calc_data = $iv; # CT[j]
1089                 my $old_calc_data; # CT[j-1]
1090                 my $old_old_calc_data; # CT[j-2]
1091                 my $next_source;
1092
1093                 # TDES inner loop implements logic within driver
1094                 if ($cipher =~ /des/) {
1095                         print $CI "1\n"
1096                                   .$iloop."\n"
1097                                   .bin2hex($key1)."\n"
1098                                   .bin2hex($iv)."\n"
1099                                   .bin2hex($source_data)."\n\n" or die;
1100                         chomp(my $line = <$CO>);
1101                         $calc_data = hex2bin($line);
1102                         chomp($line = <$CO>);
1103                         $old_calc_data = hex2bin($line);
1104                         chomp($line = <$CO>);
1105                         $old_old_calc_data = hex2bin($line);
1106                         chomp($line = <$CO>);
1107                         $iv = hex2bin($line);
1108                         chomp($line = <$CO>);
1109                         $next_source = hex2bin($line);
1110                         # Skip over empty line.
1111                         $line = <$CO>;
1112                 } else {
1113                         for (my $j = 0; $j < $iloop; ++$j) {
1114                                 $old_old_calc_data = $old_calc_data;
1115                                 $old_calc_data = $calc_data;
1116
1117                                 #print STDERR "source_data=", bin2hex($source_data), "\n";
1118                                 syswrite $CI, $source_data or die $!;
1119                                 my $len = sysread $CO, $calc_data, $bufsize;
1120
1121                                 #print STDERR "len=$len, bufsize=$bufsize\n";
1122                                 die if $len ne $bufsize;
1123                                 #print STDERR "calc_data=", bin2hex($calc_data), "\n";
1124
1125                                 if ( (!$enc && $ciph =~ /des/) ||
1126                                      $ciph =~ /rc4/ || 
1127                                      $cipher =~ /ecb/ ) {
1128                                         #TDES in decryption mode, RC4 and ECB mode
1129                                         #have a special rule
1130                                         $source_data = $calc_data;
1131                                 } else {
1132                                         $source_data = $old_calc_data;
1133                                 }
1134                         }
1135                 }
1136                 close $CO;
1137                 close $CI;
1138                 waitpid $pid, 0;
1139
1140                 if ($enc) {
1141                         $out .= "CIPHERTEXT = ". bin2hex($calc_data). "\n\n";
1142                 } else {
1143                         $out .= "PLAINTEXT = ". bin2hex($calc_data). "\n\n";
1144                 }
1145                 
1146                 if ( $ciph =~ /aes/ ) {
1147                         $key1 ^= substr($old_calc_data . $calc_data, -$keylen);
1148                         #print STDERR bin2hex($key1)."\n";
1149                 } elsif ( $ciph =~ /des/ ) {
1150                         die "Wrong keylen $keylen" if ($keylen != 24);
1151
1152                         # $nkey needed as $key holds the concatenation of the
1153                         # old key atm
1154                         my $nkey = fix_key_parity(substr($key1,0,8) ^ $calc_data);
1155                         #print STDERR "KEY1 = ". bin2hex($nkey)."\n";
1156                         if (substr($key1,0,8) ne substr($key1,8,8)) {
1157                                 #print STDERR "KEY2 recalc: KEY1==KEY3, KEY2 indep. or all KEYs are indep.\n";
1158                                 $key2 = fix_key_parity((substr($key1,8,8) ^ $old_calc_data));
1159                         } else {
1160                                 #print STDERR "KEY2 recalc: KEY1==KEY2==KEY3\n";
1161                                 $key2 = fix_key_parity((substr($key1,8,8) ^ $calc_data));
1162                         }
1163                         #print STDERR "KEY2 = ". bin2hex($key2)."\n";
1164                         if ( substr($key1,0,8) eq substr($key1,16)) {
1165                                 #print STDERR "KEY3 recalc: KEY1==KEY2==KEY3 or KEY1==KEY3, KEY2 indep.\n";
1166                                 $key3 = fix_key_parity((substr($key1,16) ^ $calc_data));
1167                         } else {
1168                                 #print STDERR "KEY3 recalc: all KEYs are independent\n";
1169                                 $key3 = fix_key_parity((substr($key1,16) ^ $old_old_calc_data));
1170                         }
1171                         #print STDERR "KEY3 = ". bin2hex($key3)."\n";
1172
1173                         # reset the first key - concardination happens at
1174                         # beginning of loop
1175                         $key1=$nkey;
1176                 } elsif ($ciph =~ /rc4/ ) {
1177                         $key1 ^= substr($calc_data, 0, 16);
1178                         #print STDERR bin2hex($key1)."\n";
1179                 } else {
1180                         die "Test limitation: cipher '$cipher' not supported in Monte Carlo testing";
1181                 }
1182
1183                 if ($cipher =~ /des-ede3-ofb/) {
1184                         $source_data = $source_data ^ $next_source;
1185                 } elsif (!$enc && $cipher =~ /des-ede3-cfb/) {
1186                         #TDES decryption CFB has a special rule
1187                         $source_data = $next_source;
1188                 } elsif (! $enc && $ciph =~ /des/ ) {
1189                         #TDES in decryption mode has a special rule
1190                         $iv = $old_calc_data;
1191                         $source_data = $calc_data;
1192                 } elsif ( $ciph =~ /rc4/ || $cipher =~ /ecb/ ) {
1193                         #No resetting of IV as the IV is all zero set initially (i.e. no IV)
1194                         $source_data = $calc_data;
1195                 } else {
1196                         $iv = $calc_data;
1197                         $source_data = $old_calc_data;
1198                 }
1199         }
1200
1201         return $out;
1202 }
1203
1204 # Hash Monte Carlo Testing
1205 # $1: Plaintext in hex form
1206 # $2: hash
1207 # return: string formatted as expected by CAVS
1208 sub hash_mct($$) {
1209         my $pt = shift;
1210         my $cipher = shift;
1211
1212         my $out = "";
1213
1214         $out .= "Seed = $pt\n\n";
1215
1216         for (my $j=0; $j<100; ++$j) {
1217                 $out .= "COUNT = $j\n";
1218                 my $md0=$pt;
1219                 my $md1=$pt;
1220                 my $md2=$pt;
1221                 for (my $i=0; $i<1000; ++$i) {
1222                         #print STDERR "outer loop $j; inner loop $i\n";
1223                         my $mi= $md0 . $md1 . $md2;
1224                         $md0=$md1;
1225                         $md1=$md2;
1226                         $md2 = &$hash($mi, $cipher);
1227                         $md2 =~ s/\n//;
1228                 }
1229                 $out .= "MD = $md2\n\n";
1230                 $pt=$md2;
1231         }
1232
1233         return $out;
1234 }
1235
1236 # RSA SigGen test
1237 # $1: Message to be signed in hex form
1238 # $2: Hash algorithm
1239 # $3: file name with RSA key in PEM form
1240 # return: string formatted as expected by CAVS
1241 sub rsa_siggen($$$) {
1242         my $data = shift;
1243         my $cipher = shift;
1244         my $keyfile = shift;
1245
1246         my $out = "";
1247
1248         $out .= "SHAAlg = $cipher\n";
1249         $out .= "Msg = $data\n";
1250         $out .= "S = " . &$rsa_sign($data, lc($cipher), $keyfile) . "\n";
1251
1252         return $out;
1253 }
1254
1255 # RSA SigVer test
1256 # $1: Message to be verified in hex form
1257 # $2: Hash algoritm
1258 # $3: Signature of message in hex form
1259 # $4: n of the RSA key in hex in hex form
1260 # $5: e of the RSA key in hex in hex form
1261 # return: string formatted as expected by CAVS
1262 sub rsa_sigver($$$$$) {
1263         my $data = shift;
1264         my $cipher = shift;
1265         my $signature = shift;
1266         my $n = shift;
1267         my $e = shift;
1268
1269         my $out = "";
1270
1271         $out .= "SHAAlg = $cipher\n";
1272         $out .= "e = $e\n";
1273         $out .= "Msg = $data\n";
1274         $out .= "S = $signature\n";
1275
1276         # XXX maybe a secure temp file name is better here
1277         # but since it is not run on a security sensitive
1278         # system, I hope that this is fine
1279         my $keyfile = "rsa_sigver.tmp.$$";
1280         gen_pubrsakey($keyfile, $n, $e);
1281
1282         my $sigfile = "$keyfile.sig";
1283         open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?";
1284         print FH hex2bin($signature);
1285         close FH;
1286
1287         $out .= "Result = " . (&$rsa_verify($data, lc($cipher), $keyfile, $sigfile) ? "P\n" : "F\n");
1288
1289         unlink($keyfile);
1290         unlink($sigfile);
1291
1292         return $out;
1293 }
1294
1295 # X9.31 RNG test
1296 # $1 key for the AES cipher
1297 # $2 DT value
1298 # $3 V value
1299 # $4 type ("VST", "MCT")
1300 # return: string formatted as expected by CAVS
1301 sub rngx931($$$$) {
1302         my $key=shift;
1303         my $dt=shift;
1304         my $v=shift;
1305         my $type=shift;
1306
1307         my $out = "Key = $key\n";
1308         $out   .= "DT = $dt\n";
1309         $out   .= "V = $v\n";
1310
1311         my $count = 1;
1312         $count = 10000 if ($type eq "MCT");
1313
1314         my $rnd_val = "";
1315
1316         # we read 16 bytes from RNG
1317         my $bufsize = 16;
1318
1319         my ($CO, $CI);
1320         my $rng_imp = &$state_rng($key, $dt, $v);
1321         my $pid = open2($CO, $CI, $rng_imp);
1322         for (my $i = 0; $i < $count; ++$i) {
1323                 my $len = sysread $CO, $rnd_val, $bufsize;
1324                 #print STDERR "len=$len, bufsize=$bufsize\n";
1325                 die "len=$len != bufsize=$bufsize" if $len ne $bufsize;
1326                 #print STDERR "calc_data=", bin2hex($rnd_val), "\n";
1327         }
1328         close $CO;
1329         close $CI;
1330         waitpid $pid, 0;
1331
1332         $out .= "R = " . bin2hex($rnd_val) . "\n\n";
1333
1334         return $out;
1335 }
1336
1337 # DSA PQGGen test
1338 # $1 modulus size
1339 # $2 number of rounds to perform the test
1340 # return: string formatted as expected by CAVS
1341 sub dsa_pqggen_driver($$) {
1342         my $mod = shift;
1343         my $rounds = shift;
1344
1345         my $out = "";
1346         for(my $i=0; $i<$rounds; $i++) {
1347                 my $ret = &$dsa_pqggen($mod);
1348                 my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret);
1349                 die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen"
1350                         if (!defined($P) || !defined($Q) || !defined($G) ||
1351                             !defined($Seed) || !defined($c) || !defined($H));
1352                 $out .= "P = $P\n";
1353                 $out .= "Q = $Q\n";
1354                 $out .= "G = $G\n";
1355                 $out .= "Seed = $Seed\n";
1356                 $out .= "c = $c\n";
1357                 $out .= "H = $H\n\n";
1358         }
1359
1360         return $out;
1361 }
1362
1363
1364 # DSA SigGen test
1365 # $1: Message to be signed in hex form
1366 # $2: file name with DSA key in PEM form
1367 # return: string formatted as expected by CAVS
1368 sub dsa_siggen($$) {
1369         my $data = shift;
1370         my $keyfile = shift;
1371
1372         my $out = "";
1373
1374         my %ret = &$dsa_sign($data, $keyfile);
1375
1376         $out .= "Msg = $data\n";
1377         $out .= "Y = " . $ret{'Y'} . "\n";
1378         $out .= "R = " . $ret{'R'} . "\n";
1379         $out .= "S = " . $ret{'S'} . "\n";
1380
1381         return $out;
1382 }
1383
1384
1385 # DSA signature verification
1386 # $1 modulus
1387 # $2 P
1388 # $3 Q
1389 # $4 G
1390 # $5 Y - public key
1391 # $6 r
1392 # $7 s
1393 # $8 message to be verified
1394 # return: string formatted as expected by CAVS
1395 sub dsa_sigver($$$$$$$$) {
1396         my $modulus = shift;
1397         my $p = shift;
1398         my $q = shift;
1399         my $g = shift;
1400         my $y = shift;
1401         my $r = shift;
1402         my $s = shift;
1403         my $msg = shift;
1404
1405         my $out = "";
1406
1407         #PQG are already printed - do not print them here
1408
1409         $out .= "Msg = $msg\n";
1410         $out .= "Y = $y\n";
1411         $out .= "R = $r\n";
1412         $out .= "S = $s\n";
1413
1414         # XXX maybe a secure temp file name is better here
1415         # but since it is not run on a security sensitive
1416         # system, I hope that this is fine
1417         my $keyfile = "dsa_sigver.tmp.$$";
1418         gen_pubdsakey($keyfile, $p, $q, $g, $y);
1419
1420         $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n");
1421
1422         unlink($keyfile);
1423
1424         return $out;
1425 }
1426
1427 ##############################################################
1428 # Parser of input file and generator of result file
1429 #
1430
1431 sub usage() {
1432
1433         print STDERR "Usage:
1434 $0 [-R] [-D] [-I name] <CAVS-test vector file>
1435
1436 -R      execution of ARCFOUR instead of OpenSSL
1437 -I NAME Use interface style NAME:
1438                 openssl     OpenSSL (default)
1439                 libgcrypt   Libgcrypt
1440 -D      SigGen and SigVer are executed with DSA
1441         Please note that the DSA CAVS vectors do not allow distinguishing
1442         them from the RSA vectors. As the RSA test is the default, you have
1443         to supply this option to apply the DSA logic";
1444 }
1445
1446 # Parser of CAVS test vector file
1447 # $1: Test vector file
1448 # $2: Output file for test results
1449 # return: nothing
1450 sub parse($$) {
1451         my $infile = shift;
1452         my $outfile = shift;
1453
1454         my $out = "";
1455
1456         # this is my cipher/hash type
1457         my $cipher = "";
1458
1459         # Test type
1460         # 1 - cipher known answer test
1461         # 2 - cipher Monte Carlo test
1462         # 3 - hash known answer test
1463         # 4 - hash Monte Carlo test
1464         # 5 - RSA signature generation
1465         # 6 - RSA signature verification
1466         my $tt = 0;
1467
1468         # Variables for tests
1469         my $keytype = ""; # we can have "KEY", "KEYs", "KEY1"
1470         my $key1 = "";
1471         my $key2 = undef; #undef needed for allowing
1472         my $key3 = undef; #the use of them as input variables
1473         my $pt = "";
1474         my $enc = 1;
1475         my $iv = "";
1476         my $len = undef; #see key2|3
1477         my $n = "";
1478         my $e = "";
1479         my $signature = "";
1480         my $rsa_keyfile = "";
1481         my $dsa_keyfile = "";
1482         my $dt = "";
1483         my $v = "";
1484         my $klen = "";
1485         my $tlen = "";
1486         my $modulus = "";
1487         my $capital_n = 0;
1488         my $capital_p = "";
1489         my $capital_q = "";
1490         my $capital_g = "";
1491         my $capital_y = "";
1492         my $capital_r = "";
1493         my $capital_s = "";
1494
1495         my $mode = "";
1496
1497         open(IN, "<$infile");
1498         while(<IN>) {
1499
1500                 my $line = $_;
1501                 chomp($line);
1502                 $line =~ s/\r//;
1503
1504                 my $keylen = "";
1505
1506                 # Mode and type check
1507                 # consider the following parsed line
1508                 # '# AESVS MCT test data for CBC'
1509                 # '# TDES Multi block Message Test for CBC'
1510                 # '# INVERSE PERMUTATION - KAT for CBC'
1511                 # '# SUBSTITUTION TABLE - KAT for CBC'
1512                 # '# TDES Monte Carlo (Modes) Test for CBC'
1513                 # '#  "SHA-1 Monte" information for "IBMRHEL5"'
1514                 # '# "SigVer PKCS#1 Ver 1.5" information for "IBMRHEL5"'
1515                 # '# "SigGen PKCS#1 Ver 1.5" information for "IBMRHEL5"'
1516                 # '#RC4VS MCT test data'
1517                 
1518                 # avoid false positives from user specified 'for "PRODUCT"' strings
1519                 my $tmpline = $line;
1520                 $tmpline =~ s/ for ".*"//;
1521
1522                 ##### Extract cipher
1523                 # XXX there may be more - to be added
1524                 if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen)/) {
1525                         if ($tmpline    =~ /CBC/)   { $mode="cbc"; }
1526                         elsif ($tmpline =~ /ECB/)   { $mode="ecb"; }
1527                         elsif ($tmpline =~ /OFB/)   { $mode="ofb"; }
1528                         elsif ($tmpline =~ /CFB/)   { $mode="cfb"; }
1529                         #we do not need mode as the cipher is already clear
1530                         elsif ($tmpline =~ /SHA-1/) { $cipher="sha1"; }
1531                         elsif ($tmpline =~ /SHA-224/) { $cipher="sha224"; }
1532                         elsif ($tmpline =~ /SHA-256/) { $cipher="sha256"; }
1533                         elsif ($tmpline =~ /SHA-384/) { $cipher="sha384"; }
1534                         elsif ($tmpline =~ /SHA-512/) { $cipher="sha512"; }
1535                         #we do not need mode as the cipher is already clear
1536                         elsif ($tmpline =~ /RC4VS/) { $cipher="rc4"; }
1537                         elsif ($tmpline =~ /SigGen|SigVer/) {
1538                                 die "Error: X9.31 is not supported"
1539                                         if ($tmpline =~ /X9/);
1540                                 $cipher="sha1"; #place holder - might be overwritten later
1541                         }
1542
1543                         if ($tmpline =~ /^#.*AESVS/) {
1544                                 # AES cipher (part of it)
1545                                 $cipher="aes";
1546                         }
1547                         if ($tmpline =~ /^#.*(TDES|KAT)/) {
1548                                 # TDES cipher (full definition)
1549                                 # the FIPS-140 test generator tool does not produce
1550                                 # machine readable output!
1551                                 if ($mode eq "cbc") { $cipher="des-ede3-cbc"; }
1552                                 if ($mode eq "ecb") { $cipher="des-ede3"; }
1553                                 if ($mode eq "ofb") { $cipher="des-ede3-ofb"; }
1554                                 if ($mode eq "cfb") { $cipher="des-ede3-cfb"; }
1555                         }
1556
1557                         # check for RNG
1558                         if ($tmpline =~ /ANSI X9\.31/) {
1559                                 # change the tmpline to add the type of the
1560                                 # test which is ONLY visible from the file
1561                                 # name :-(
1562                                 if ($infile =~ /MCT\.req/) {
1563                                         $tmpline .= " MCT";
1564                                 } elsif ($infile =~ /VST\.req/) {
1565                                         $tmpline .= " VST";
1566                                 } else {
1567                                         die "Unexpected cipher type with $infile";
1568                                 }
1569                         }
1570
1571                         if ($tt == 0) {
1572                         ##### Identify the test type
1573                                 if ($tmpline =~ /SigVer/ && $opt{'D'} ) {
1574                                         $tt = 12;
1575                                         die "Interface function dsa_verify for dSA verification not defined for tested library"
1576                                                 if (!defined($dsa_verify));
1577                                 } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) {
1578                                         $tt = 11;
1579                                         die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library"
1580                                                 if (!defined($dsa_sign) || !defined($gen_rsakey));
1581                                 } elsif ($tmpline =~ /PQGGen/) {
1582                                         $tt = 10;
1583                                         die "Interface function for DSA PQGGen testing not defined for tested library"
1584                                                 if (!defined($dsa_pqggen));
1585                                 } elsif ($tmpline =~ /Hash sizes tested/) {
1586                                         $tt = 9;
1587                                         die "Interface function hmac for HMAC testing not defined for tested library"
1588                                                 if (!defined($hmac));
1589                                 } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) {
1590                                         $tt = 8;
1591                                         die "Interface function state_rng for RNG MCT not defined for tested library"
1592                                                 if (!defined($state_rng));
1593                                 } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /VST/) {
1594                                         $tt = 7;
1595                                         die "Interface function state_rng for RNG KAT not defined for tested library"
1596                                                 if (!defined($state_rng));
1597                                 } elsif ($tmpline =~ /SigVer/ ) {
1598                                         $tt = 6;
1599                                         die "Interface function rsa_verify or gen_rsakey for RSA verification not defined for tested library"
1600                                                 if (!defined($rsa_verify) || !defined($gen_rsakey));
1601                                 } elsif ($tmpline =~ /SigGen/ ) {
1602                                         $tt = 5;
1603                                         die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library"
1604                                                 if (!defined($rsa_sign) || !defined($gen_rsakey));
1605                                 } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher =~ /^sha/) {
1606                                         $tt = 4;
1607                                         die "Interface function hash for Hashing not defined for tested library"
1608                                                 if (!defined($hash));
1609                                 } elsif ($tmpline =~ /Monte|MCT|Carlo/) {
1610                                         $tt = 2;
1611                                         die "Interface function state_cipher for Stateful Cipher operation defined for tested library"
1612                                                 if (!defined($state_cipher) || !defined($state_cipher_des));
1613                                 } elsif ($cipher =~ /^sha/) {
1614                                         $tt = 3;
1615                                         die "Interface function hash for Hashing not defined for tested library"
1616                                                 if (!defined($hash));
1617                                 } else {
1618                                         $tt = 1;
1619                                         die "Interface function encdec for Encryption/Decryption not defined for tested library"
1620                                                 if (!defined($encdec));
1621                                 }
1622                         }
1623                 }
1624
1625                 # This is needed as ARCFOUR does not operate with an IV
1626                 $iv = "00000000000000000000000000000000" if ($cipher eq "rc4"
1627                                                              && $iv eq "" );
1628
1629                 # we are now looking for the string
1630                 # '# Key Length : 256'
1631                 # found in AES
1632                 if ($tmpline =~ /^# Key Length.*?(128|192|256)/) {
1633                         if ($cipher eq "aes") {
1634                                 $cipher="$cipher-$1-$mode";
1635                         } else {
1636                                 die "Error: Key length $1 given for cipher $cipher which is unexpected";
1637                         }
1638                 }
1639
1640                 # Get the test data
1641                 if ($line =~ /^(KEY|KEY1|Key)\s*=\s*(.*)/) { # found in ciphers and RNG
1642                         die "KEY seen twice - input file crap" if ($key1 ne "");
1643                         $keytype=$1;
1644                         $key1=$2;
1645                         $key1 =~ s/\s//g; #replace potential white spaces
1646                 }
1647                 elsif ($line =~ /^(KEYs)\s*=\s*(.*)/) { # found in ciphers and RNG
1648                         die "KEY seen twice - input file crap" if ($key1 ne "");
1649                         $keytype=$1;
1650                         $key1=$2;
1651                         $key1 =~ s/\s//g; #replace potential white spaces
1652                         $key2 = $key1;
1653                         $key3 = $key1;
1654                 }
1655                 elsif ($line =~ /^KEY2\s*=\s*(.*)/) { # found in TDES
1656                         die "First key not set, but got already second key - input file crap" if ($key1 eq "");
1657                         die "KEY2 seen twice - input file crap" if (defined($key2));
1658                         $key2=$1;
1659                         $key2 =~ s/\s//g; #replace potential white spaces
1660                 }
1661                 elsif ($line =~ /^KEY3\s*=\s*(.*)/) { # found in TDES
1662                         die "Second key not set, but got already third key - input file crap" if ($key2 eq "");
1663                         die "KEY3 seen twice - input file crap" if (defined($key3));
1664                         $key3=$1;
1665                         $key3 =~ s/\s//g; #replace potential white spaces
1666                 }
1667                 elsif ($line =~ /^IV\s*=\s*(.*)/) { # found in ciphers
1668                         die "IV seen twice - input file crap" if ($iv ne "");
1669                         $iv=$1;
1670                         $iv =~ s/\s//g; #replace potential white spaces
1671                 }
1672                 elsif ($line =~ /^PLAINTEXT\s*=\s*(.*)/) { # found in ciphers
1673                         if ( $1 !~ /\?/ ) { #only use it if there is valid hex data
1674                                 die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne "");
1675                                 $pt=$1;
1676                                 $pt =~ s/\s//g; #replace potential white spaces
1677                                 $enc=1;
1678                         }
1679                 }
1680                 elsif ($line =~ /^CIPHERTEXT\s*=\s*(.*)/) { # found in ciphers
1681                         if ( $1 !~ /\?/ ) { #only use it if there is valid hex data
1682                                 die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne "");
1683                                 $pt=$1;
1684                                 $pt =~ s/\s//g; #replace potential white spaces
1685                                 $enc=0;
1686                         }
1687                 }
1688                 elsif ($line =~ /^Len\s*=\s*(.*)/) { # found in hashs
1689                         $len=$1;
1690                 }
1691                 elsif ($line =~ /^(Msg|Seed)\s*=\s*(.*)/) { # found in hashs
1692                         die "Msg/Seed seen twice - input file crap" if ($pt ne "");
1693                         $pt=$2;
1694                 }
1695                 elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests
1696                         $modulus = $1;
1697                         $out .= $line . "\n\n"; # print it
1698                         # generate the private key with given bit length now
1699                         # as we have the required key length in bit
1700                         if ($tt == 11) {
1701                                 $dsa_keyfile = "dsa_siggen.tmp.$$";
1702                                 my %pqg = &$gen_dsakey($dsa_keyfile);
1703                                 $out .= "P = " . $pqg{'P'} . "\n";
1704                                 $out .= "Q = " . $pqg{'Q'} . "\n";
1705                                 $out .= "G = " . $pqg{'G'} . "\n";
1706                         } elsif ( $tt == 5 ) {
1707                                 # XXX maybe a secure temp file name is better here
1708                                 # but since it is not run on a security sensitive
1709                                 # system, I hope that this is fine
1710                                 $rsa_keyfile = "rsa_siggen.tmp.$$";
1711                                 &$gen_rsakey($modulus, $rsa_keyfile);
1712                                 my $modulus = pipe_through_program("", "openssl rsa -pubout -modulus -in $rsa_keyfile");
1713                                 $modulus =~ s/Modulus=(.*?)\s(.|\s)*/$1/;
1714                                 $out .= "n = $modulus\n";
1715                                 $out .= "\ne = 10001\n"
1716                         }
1717                 }
1718                 elsif ($line =~ /^SHAAlg\s*=\s*(.*)/) { #found in RSA requests
1719                         $cipher=$1;
1720                 }
1721                 elsif($line =~ /^n\s*=\s*(.*)/) { # found in RSA requests
1722                         $out .= $line . "\n";
1723                         $n=$1;
1724                 }
1725                 elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests
1726                         $e=$1;
1727                 }
1728                 elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests
1729                         die "S seen twice - input file crap" if ($signature ne "");
1730                         $signature=$1;
1731                 }
1732                 elsif ($line =~ /^DT\s*=\s*(.*)/) { # X9.31 RNG requests
1733                         die "DT seen twice - check input file"
1734                                 if ($dt ne "");
1735                         $dt=$1;
1736                 }
1737                 elsif ($line =~ /^V\s*=\s*(.*)/) { # X9.31 RNG requests
1738                         die "V seen twice - check input file"
1739                                 if ($v ne "");
1740                         $v=$1;
1741                 }
1742                 elsif ($line =~ /^Klen\s*=\s*(.*)/) { # HMAC requests
1743                         die "Klen seen twice - check input file"
1744                                 if ($klen ne "");
1745                         $klen=$1;
1746                 }
1747                 elsif ($line =~ /^Tlen\s*=\s*(.*)/) { # HMAC RNG requests
1748                         die "Tlen seen twice - check input file"
1749                                 if ($tlen ne "");
1750                         $tlen=$1;
1751                 }
1752                 elsif ($line =~ /^N\s*=\s*(.)/) { #DSA PQGGen
1753                         die "N seen twice - check input file"
1754                                 if ($capital_n);
1755                         $capital_n = $1;
1756                 }
1757                 elsif ($line =~ /^P\s*=\s*(.)/) { #DSA SigVer
1758                         die "P seen twice - check input file"
1759                                 if ($capital_p);
1760                         $capital_p = $1;
1761                         $out .= $line . "\n"; # print it
1762                 }
1763                 elsif ($line =~ /^Q\s*=\s*(.)/) { #DSA SigVer
1764                         die "Q seen twice - check input file"
1765                                 if ($capital_q);
1766                         $capital_q = $1;
1767                         $out .= $line . "\n"; # print it
1768                 }
1769                 elsif ($line =~ /^G\s*=\s*(.)/) { #DSA SigVer
1770                         die "G seen twice - check input file"
1771                                 if ($capital_g);
1772                         $capital_g = $1;
1773                         $out .= $line . "\n"; # print it
1774                 }
1775                 elsif ($line =~ /^Y\s*=\s*(.)/) { #DSA SigVer
1776                         die "Y seen twice - check input file"
1777                                 if ($capital_y);
1778                         $capital_y = $1;
1779                 }
1780                 elsif ($line =~ /^R\s*=\s*(.)/) { #DSA SigVer
1781                         die "R seen twice - check input file"
1782                                 if ($capital_r);
1783                         $capital_r = $1;
1784                 }
1785                 elsif ($line =~ /^S\s*=\s*(.)/) { #DSA SigVer
1786                         die "S seen twice - check input file"
1787                                 if ($capital_s);
1788                         $capital_s = $1;
1789                 }
1790                 else {
1791                         $out .= $line . "\n";
1792                 }
1793
1794                 # call tests if all input data is there
1795                 if ($tt == 1) {
1796                         if ($key1 ne "" && $pt ne "" && $cipher ne "") {
1797                                 $out .= kat($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
1798                                 $keytype = "";
1799                                 $key1 = "";
1800                                 $key2 = undef;
1801                                 $key3 = undef;
1802                                 $iv = "";
1803                                 $pt = "";
1804                         }
1805                 }
1806                 elsif ($tt == 2) {
1807                         if ($key1 ne "" && $pt ne "" && $cipher ne "") {
1808                                 $out .= crypto_mct($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
1809                                 $keytype = "";
1810                                 $key1 = "";
1811                                 $key2 = undef;
1812                                 $key3 = undef;
1813                                 $iv = "";
1814                                 $pt = "";
1815                         }
1816                 }
1817                 elsif ($tt == 3) {
1818                         if ($pt ne "" && $cipher ne "") {
1819                                 $out .= hash_kat($pt, $cipher, $len);
1820                                 $pt = "";
1821                                 $len = undef;
1822                         }
1823                 }
1824                 elsif ($tt == 4) {
1825                         if ($pt ne "" && $cipher ne "") {
1826                                 $out .= hash_mct($pt, $cipher);
1827                                 $pt = "";
1828                         }
1829                 }
1830                 elsif ($tt == 5) {
1831                         if ($pt ne "" && $cipher ne "" && $rsa_keyfile ne "") {
1832                                 $out .= rsa_siggen($pt, $cipher, $rsa_keyfile);
1833                                 $pt = "";
1834                         }
1835                 }
1836                 elsif ($tt == 6) {
1837                         if ($pt ne "" && $cipher ne "" && $signature ne "" && $n ne "" && $e ne "") {
1838                                 $out .= rsa_sigver($pt, $cipher, $signature, $n, $e);
1839                                 $pt = "";
1840                                 $signature = "";
1841                         }
1842                 }
1843                 elsif ($tt == 7 ) {
1844                         if ($key1 ne "" && $dt ne "" && $v ne "") {
1845                                 $out .= rngx931($key1, $dt, $v, "VST");
1846                                 $key1 = "";
1847                                 $dt = "";
1848                                 $v = "";
1849                         }
1850                 }
1851                 elsif ($tt == 8 ) {
1852                         if ($key1 ne "" && $dt ne "" && $v ne "") {
1853                                 $out .= rngx931($key1, $dt, $v, "MCT");
1854                                 $key1 = "";
1855                                 $dt = "";
1856                                 $v = "";
1857                         }
1858                 }
1859                 elsif ($tt == 9) {
1860                         if ($klen ne "" && $tlen ne "" && $key1 ne "" && $pt ne "") {
1861                                 $out .= hmac_kat($klen, $tlen, $key1, $pt);
1862                                 $key1 = "";
1863                                 $tlen = "";
1864                                 $klen = "";
1865                                 $pt = "";
1866                         }
1867                 }
1868                 elsif ($tt == 10) {
1869                         if ($modulus ne "" && $capital_n > 0) {
1870                                 $out .= dsa_pqggen_driver($modulus, $capital_n);
1871                                 #$mod is not resetted
1872                                 $capital_n = 0;
1873                         }
1874                 }
1875                 elsif ($tt == 11) {
1876                         if ($pt ne "" && $dsa_keyfile ne "") {
1877                                 $out .= dsa_siggen($pt, $dsa_keyfile);
1878                                 $pt = "";
1879                         }
1880                 }
1881                 elsif ($tt == 12) {
1882                         if ($modulus ne "" &&
1883                             $capital_p ne "" &&
1884                             $capital_q ne "" &&
1885                             $capital_g ne "" &&
1886                             $capital_y ne "" &&
1887                             $capital_r ne "" &&
1888                             $capital_s ne "" &&
1889                             $pt ne "") {
1890                                 $out .= dsa_sigver($modulus,
1891                                                    $capital_p,
1892                                                    $capital_q,
1893                                                    $capital_g,
1894                                                    $capital_y,
1895                                                    $capital_r,
1896                                                    $capital_s,
1897                                                    $pt);
1898
1899                                 # We do not clear the domain values PQG and
1900                                 # the modulus value as they
1901                                 # are specified only once in a file
1902                                 # and we do not need to print them as they
1903                                 # are already printed above
1904                                 $capital_y = "";
1905                                 $capital_r = "";
1906                                 $capital_s = "";
1907                                 $pt = "";
1908                         }
1909                 }
1910                 elsif ($tt > 0) {
1911                         die "Test case $tt not defined";
1912                 }
1913         }
1914
1915         close IN;
1916         $out =~ s/\n/\r\n/g; # make it a dos file
1917         open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?";
1918         print OUT $out;
1919         close OUT;
1920
1921 }
1922
1923 # Signalhandler
1924 sub cleanup() {
1925         unlink("rsa_siggen.tmp.$$");
1926         unlink("rsa_sigver.tmp.$$");
1927         unlink("rsa_sigver.tmp.$$.sig");
1928         unlink("rsa_sigver.tmp.$$.der");
1929         unlink("rsa_sigver.tmp.$$.cnf");
1930         exit;
1931 }
1932
1933 ############################################################
1934 #
1935 # let us pretend to be C :-)
1936 sub main() {
1937
1938         usage() unless @ARGV;
1939
1940         getopts("DRI:", \%opt) or die "bad option";
1941
1942         ##### Set library
1943
1944         if ( ! defined $opt{'I'} || $opt{'I'} eq 'openssl' ) {
1945                 print STDERR "Using OpenSSL interface functions\n";
1946                 $encdec =       \&openssl_encdec;
1947                 $rsa_sign =     \&openssl_rsa_sign;
1948                 $rsa_verify =   \&openssl_rsa_verify;
1949                 $gen_rsakey =   \&openssl_gen_rsakey;
1950                 $hash =         \&openssl_hash;
1951                 $state_cipher = \&openssl_state_cipher;
1952         } elsif ( $opt{'I'} eq 'libgcrypt' ) {
1953                 print STDERR "Using libgcrypt interface functions\n";
1954                 $encdec =       \&libgcrypt_encdec;
1955                 $rsa_sign =     \&libgcrypt_rsa_sign;
1956                 $rsa_verify =   \&libgcrypt_rsa_verify;
1957                 $gen_rsakey =   \&libgcrypt_gen_rsakey;
1958                 $hash =         \&libgcrypt_hash;
1959                 $state_cipher = \&libgcrypt_state_cipher;
1960                 $state_cipher_des =     \&libgcrypt_state_cipher_des;
1961                 $state_rng =    \&libgcrypt_state_rng;
1962                 $hmac =         \&libgcrypt_hmac;
1963                 $dsa_pqggen =   \&libgcrypt_dsa_pqggen;
1964         } else {
1965                 die "Invalid interface option given";
1966         }
1967
1968         my $infile=$ARGV[0];
1969         die "Error: Test vector file $infile not found" if (! -f $infile);
1970
1971         my $outfile = $infile;
1972         # let us add .rsp regardless whether we could strip .req
1973         $outfile =~ s/\.req$//;
1974         if ($opt{'R'}) {
1975                 $outfile .= ".rc4";
1976         } else {
1977                 $outfile .= ".rsp";
1978         }
1979         if (-f $outfile) {
1980                 die "Output file $outfile could not be removed: $?"
1981                         unless unlink($outfile);
1982         }
1983         print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n";
1984
1985         #Signal handler
1986         $SIG{HUP} = \&cleanup;
1987         $SIG{INT} = \&cleanup;
1988         $SIG{QUIT} = \&cleanup;
1989         $SIG{TERM} = \&cleanup;
1990
1991         # Do the job
1992         parse($infile, $outfile);
1993
1994         unlink("rsa_siggen.tmp.$$");
1995
1996 }
1997
1998 ###########################################
1999 # Call it
2000 main();
2001 1;