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