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