summaryrefslogtreecommitdiff
path: root/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl')
-rw-r--r--plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl2243
1 files changed, 0 insertions, 2243 deletions
diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl b/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl
deleted file mode 100644
index 7111f0f47c..0000000000
--- a/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl
+++ /dev/null
@@ -1,2243 +0,0 @@
-#!/usr/bin/env perl
-#
-# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $
-#
-# CAVS test driver (based on the OpenSSL driver)
-# Written by: Stephan Müller <sm@atsec.com>
-# Copyright (c) atsec information security corporation
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# NO WARRANTY
-#
-# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-# REPAIR OR CORRECTION.
-#
-# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-# POSSIBILITY OF SUCH DAMAGES.
-#
-#
-# test execution instruction:
-# 1. get the request files from the lab
-# 2. call each request file from 1. with this program:
-# $0 <FILE>.rep
-# 3. send the resulting file <FILE>.rsp to the lab
-#
-#
-# Test should be easily adoptable to other implementations
-# See the first functions for this task
-#
-# Following tests are covered (others may also be covered
-# but have not been tested)
-#
-# AES
-# [CBC|CFB128|ECB|OFB]GFSbox[128|192|256]
-# [CBC|CFB128|ECB|OFB]MCT[128|192|256]
-# [CBC|CFB128|ECB|OFB]VarKey[128|192|256]
-# [CBC|CFB128|ECB|OFB]KeySbox[128|192|256]
-# [CBC|CFB128|ECB|OFB]MMT[128|192|256]
-# [CBC|CFB128|ECB|OFB]VarTxt[128|192|256]
-#
-# RSA
-# SigGen[15|RSA]
-# SigVer15
-# (SigVerRSA is not applicable for OpenSSL as X9.31 padding
-# is not done through openssl dgst)
-# KeyGen RSA X9.31
-#
-# SHA
-# SHA[1|224|256|384|512]ShortMsg
-# SHA[1|224|256|384|512]LongMsg
-# SHA[1|224|256|384|512]Monte
-#
-# HMAC (SHA - caveat: we only support hash output equal to the block size of
-# of the hash - we do not support truncation of the hash; to support
-# that, we first need to decipher the HMAC.req file - see hmac_kat() )
-# HMAC
-#
-# TDES
-# T[CBC|CFB??|ECB|OFB]Monte[1|2|3]
-# T[CBC|CFB??|ECB|OFB]permop
-# T[CBC|CFB??|ECB|OFB]MMT[1|2|3]
-# T[CBC|CFB??|ECB|OFB]subtab
-# T[CBC|CFB??|ECB|OFB]varkey
-# T[CBC|CFB??|ECB|OFB]invperm
-# T[CBC|CFB??|ECB|OFB]vartext
-#
-# ANSI X9.31 RNG
-# ANSI931_AES128MCT
-# ANSI931_AES128VST
-#
-# DSA
-# PQGGen
-# SigGen
-# SigVer
-#
-# RC4 (atsec developed tests)
-# RC4KeyBD
-# RC4MCT
-# RC4PltBD
-# RC4REGT
-#
-
-use strict;
-use warnings;
-use IPC::Open2;
-use Getopt::Std;
-use MIME::Base64;
-
-# Contains the command line options
-my %opt;
-
-#################################################################
-##### Central interface functions to the external ciphers #######
-#################################################################
-# Only these interface routines should be changed in case of
-# porting to a new cipher library
-#
-# For porting to a new library, create implementation of these functions
-# and then add pointers to the respective implementation of each
-# function to the given variables.
-
-# common encryption/decryption routine
-# $1 key in hex form (please note for 3DES: even when ede3 for three
-# independent ciphers is given with the cipher specification, we hand in
-# either one key for k1 = k2 = k3, two keys which are concatinated for
-# k1 = k3, k2 independent, or three keys which are concatinated for
-# k1, k2, k3 independent)
-# $2 iv in hex form
-# $3 cipher - the cipher string is defined as specified in the openssl
-# enc(1ssl) specification for the option "-ciphername"
-# (e.g. aes-128-cbc or des-ede3-cbc)
-# $4 encrypt=1/decrypt=0
-# $5 de/encrypted data in hex form
-# return en/decrypted data in hex form
-my $encdec;
-
-#
-# Derive an RSA key from the given X9.31 parameters.
-# $1: modulus size
-# $2: E in hex form
-# $3: Xp1 in hex form
-# $4: Xp2 in hex form
-# $5: Xp in hex form
-# $6: Xq1 in hex form
-# $7: Xq2 in hex form
-# $8: Xq in hex form
-# return: string with the calculated values in hex format, where each value
-# is separated from the previous with a \n in the following order:
-# P\n
-# Q\n
-# N\n
-# D\n
-my $rsa_derive;
-
-# Sign a message with RSA
-# $1: data to be signed in hex form
-# $2: Hash algo
-# $3: Key file in PEM format with the private key
-# return: digest in hex format
-my $rsa_sign;
-
-# Verify a message with RSA
-# $1: data to be verified in hex form
-# $2: hash algo
-# $3: file holding the public RSA key in PEM format
-# $4: file holding the signature in binary form
-# return: 1 == verified / 0 == not verified
-my $rsa_verify;
-
-# generate a new private RSA key with the following properties:
-# exponent is 65537
-# PEM format
-# $1 key size in bit
-# $2 keyfile name
-# return: nothing, but file created
-my $gen_rsakey;
-
-# Creating a hash
-# $1: Plaintext in hex form
-# $2: hash type in the form documented in openssl's dgst(1ssl) - e.g.
-# sha1, sha224, sha256, sha384, sha512
-# return: hash in hex form
-my $hash;
-
-# supplying the call to the external cipher implementation
-# that is being used to keep STDIN and STDOUT open
-# to maintain the state of the block chaining
-# $1: cipher
-# $2: 1=encryption, 0=decryption
-# $3: buffersize needed for openssl
-# $4: encryption key in binary form
-# $5: IV in binary form
-# return: command line to execute the application
-my $state_cipher;
-# the only difference of the DES version is that it implements the inner loop
-# of the TDES tests
-my $state_cipher_des;
-
-# supplying the call to the external cipher implementation
-# that is being used to keep STDIN and STDOUT open
-# to maintain the state of the RNG with its seed
-#
-# input holds seed values
-# $1: cipher key in hex format
-# $2: DT value in hex format
-# $3: V value in hex format
-#
-# return: command line to execute the application
-#
-# the application is expected to deliver random values on STDOUT - the script
-# reads 128 bits repeatedly where the state of the RNG must be retained
-# between the reads. The output of the RNG on STDOUT is assumed to be binary.
-my $state_rng;
-
-# Generate an HMAC based on SHAx
-# $1: Key to be used for the HMAC in hex format
-# $2: length of the hash to be calculated in bits
-# $3: Message for which the HMAC shall be calculated in hex format
-# $4: hash type (1 - SHA1, 224 - SHA224, and so on)
-# return: calculated HMAC in hex format
-my $hmac;
-
-#
-# Generate the P, Q, G, Seed, counter, h (value used to generate g) values
-# for DSA
-# $1: modulus size
-# return: string with the calculated values in hex format, where each value
-# is separated from the previous with a \n in the following order:
-# P\n
-# Q\n
-# G\n
-# Seed\n
-# counter\n
-# h
-my $dsa_pqggen;
-
-#
-# Generate an DSA public key from the provided parameters:
-# $1: Name of file to create
-# $2: P in hex form
-# $3: Q in hex form
-# $4: G in hex form
-# $5: Y in hex form
-my $dsa_genpubkey;
-
-# Verify a message with DSA
-# $1: data to be verified in hex form
-# $2: file holding the public DSA key in PEM format
-# $3: R value of the signature
-# $4: S value of the signature
-# return: 1 == verified / 0 == not verified
-my $dsa_verify;
-
-# generate a new DSA key with the following properties:
-# PEM format
-# $1 keyfile name
-# return: file created, hash with keys of P, Q, G in hex format
-my $gen_dsakey;
-
-# Sign a message with DSA
-# $1: data to be signed in hex form
-# $2: Key file in PEM format with the private key
-# return: hash of digest information in hex format with Y, R, S as keys
-my $dsa_sign;
-
-################################################################
-##### OpenSSL interface functions
-################################################################
-sub openssl_encdec($$$$$) {
- my $key=shift;
- my $iv=shift;
- my $cipher=shift;
- my $enc = (shift) ? "-e" : "-d";
- my $data=shift;
-
- # We only invoke the driver with the IV parameter, if we have
- # an IV, otherwise, we skip it
- $iv = "-iv $iv" if ($iv);
-
- $data=hex2bin($data);
- my $program="openssl enc -$cipher -nopad -nosalt -K $key $enc $iv";
- $program = "rc4 -k $key" if $opt{'R'}; #for ARCFOUR, no IV must be given
- $data=pipe_through_program($data,$program);
- return bin2hex($data);
-}
-
-sub openssl_rsa_sign($$$) {
- my $data = shift;
- my $cipher = shift;
- my $keyfile = shift;
-
- $data=hex2bin($data);
- die "ARCFOUR not available for RSA" if $opt{'R'};
- $data=pipe_through_program($data,
- "openssl dgst -$cipher -binary -sign $keyfile");
- return bin2hex($data);
-}
-
-sub openssl_rsa_verify($$$$) {
- my $data = shift;
- my $cipher = shift;
- my $keyfile = shift;
- my $sigfile = shift;
-
- $data = hex2bin($data);
- die "ARCFOUR not available for RSA" if $opt{'R'};
- $data = pipe_through_program($data,
- "openssl dgst -$cipher -binary -verify $keyfile -signature $sigfile");
-
- # Parse through the OpenSSL output information
- return ($data =~ /OK/);
-}
-
-sub openssl_gen_rsakey($$) {
- my $keylen = shift;
- my $file = shift;
-
- die "ARCFOUR not available for RSA" if $opt{'R'};
- # generating of a key with exponent 0x10001
- my @args = ("openssl", "genrsa", "-F4", "-out", "$file", "$keylen");
- system(@args) == 0
- or die "system @args failed: $?";
- die "system @args failed: file $file not created" if (! -f $file);
-}
-
-sub openssl_hash($$) {
- my $pt = shift;
- my $cipher = shift;
-
- die "ARCFOUR not available for hashes" if $opt{'R'};
- my $hash = hex2bin($pt);
- #bin2hex not needed as the '-hex' already converts it
- return pipe_through_program($hash, "openssl dgst -$cipher -hex");
-}
-
-sub openssl_state_cipher($$$$$) {
- my $cipher = shift;
- my $encdec = shift;
- my $bufsize = shift;
- my $key = shift;
- my $iv = shift;
-
- my $enc = $encdec ? "-e": "-d";
-
- # We only invoke the driver with the IV parameter, if we have
- # an IV, otherwise, we skip it
- $iv = "-iv ".bin2hex($iv) if ($iv);
-
- my $out = "openssl enc -'$cipher' $enc -nopad -nosalt -bufsize $bufsize -K ".bin2hex($key)." $iv";
- #for ARCFOUR, no IV must be given
- $out = "rc4 -k " . bin2hex($key) if $opt{'R'};
- return $out;
-}
-
-###### End of OpenSSL interface implementation ############
-
-###########################################################
-###### libgcrypt implementation
-###########################################################
-sub libgcrypt_encdec($$$$$) {
- my $key=shift;
- my $iv=shift;
- my $cipher=shift;
- my $enc = (shift) ? "encrypt" : "decrypt";
- my $data=shift;
-
- # We only invoke the driver with the IV parameter, if we have
- # an IV, otherwise, we skip it
- $iv = "--iv $iv" if ($iv);
-
- my $program="fipsdrv --key $key $iv --algo $cipher $enc";
-
- return pipe_through_program($data,$program);
-
-}
-
-sub libgcrypt_rsa_derive($$$$$$$$) {
- my $n = shift;
- my $e = shift;
- my $xp1 = shift;
- my $xp2 = shift;
- my $xp = shift;
- my $xq1 = shift;
- my $xq2 = shift;
- my $xq = shift;
- my $sexp;
- my @tmp;
-
- $n = sprintf ("%u", $n);
- $e = sprintf ("%u", hex($e));
- $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")"
- . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")"
- . "(derive-parms"
- . "(Xp1 #$xp1#)"
- . "(Xp2 #$xp2#)"
- . "(Xp #$xp#)"
- . "(Xq1 #$xq1#)"
- . "(Xq2 #$xq2#)"
- . "(Xq #$xq#))))\n";
-
- return pipe_through_program($sexp, "fipsdrv rsa-derive");
-}
-
-
-sub libgcrypt_rsa_sign($$$) {
- my $data = shift;
- my $hashalgo = shift;
- my $keyfile = shift;
-
- die "ARCFOUR not available for RSA" if $opt{'R'};
-
- return pipe_through_program($data,
- "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile rsa-sign");
-}
-
-sub libgcrypt_rsa_verify($$$$) {
- my $data = shift;
- my $hashalgo = shift;
- my $keyfile = shift;
- my $sigfile = shift;
-
- die "ARCFOUR not available for RSA" if $opt{'R'};
- $data = pipe_through_program($data,
- "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify");
-
- # Parse through the output information
- return ($data =~ /GOOD signature/);
-}
-
-sub libgcrypt_gen_rsakey($$) {
- my $keylen = shift;
- my $file = shift;
-
- die "ARCFOUR not available for RSA" if $opt{'R'};
- my @args = ("fipsdrv --keysize $keylen rsa-gen > $file");
- system(@args) == 0
- or die "system @args failed: $?";
- die "system @args failed: file $file not created" if (! -f $file);
-}
-
-sub libgcrypt_hash($$) {
- my $pt = shift;
- my $hashalgo = shift;
-
- my $program = "fipsdrv --algo $hashalgo digest";
- die "ARCFOUR not available for hashes" if $opt{'R'};
-
- return pipe_through_program($pt, $program);
-}
-
-sub libgcrypt_state_cipher($$$$$) {
- my $cipher = shift;
- my $enc = (shift) ? "encrypt": "decrypt";
- my $bufsize = shift;
- my $key = shift;
- my $iv = shift;
-
- # We only invoke the driver with the IV parameter, if we have
- # an IV, otherwise, we skip it
- $iv = "--iv ".bin2hex($iv) if ($iv);
-
- my $program="fipsdrv --binary --key ".bin2hex($key)." $iv --algo '$cipher' --chunk '$bufsize' $enc";
-
- return $program;
-}
-
-sub libgcrypt_state_cipher_des($$$$$) {
- my $cipher = shift;
- my $enc = (shift) ? "encrypt": "decrypt";
- my $bufsize = shift;
- my $key = shift;
- my $iv = shift;
-
- # We only invoke the driver with the IV parameter, if we have
- # an IV, otherwise, we skip it
- $iv = "--iv ".bin2hex($iv) if ($iv);
-
- my $program="fipsdrv --algo '$cipher' --mct-server $enc";
-
- return $program;
-}
-
-sub libgcrypt_state_rng($$$) {
- my $key = shift;
- my $dt = shift;
- my $v = shift;
-
- return "fipsdrv --binary --loop --key $key --iv $v --dt $dt random";
-}
-
-sub libgcrypt_hmac($$$$) {
- my $key = shift;
- my $maclen = shift;
- my $msg = shift;
- my $hashtype = shift;
-
- my $program = "fipsdrv --key $key --algo $hashtype hmac-sha";
- return pipe_through_program($msg, $program);
-}
-
-sub libgcrypt_dsa_pqggen($) {
- my $mod = shift;
-
- my $program = "fipsdrv --keysize $mod dsa-pqg-gen";
- return pipe_through_program("", $program);
-}
-
-sub libgcrypt_gen_dsakey($) {
- my $file = shift;
-
- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen";
- my $tmp;
- my %ret;
-
- die "ARCFOUR not available for DSA" if $opt{'R'};
-
- $tmp = pipe_through_program("", $program);
- die "dsa key gen failed: file $file not created" if (! -f $file);
-
- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp);
- return %ret;
-}
-
-sub libgcrypt_dsa_genpubkey($$$$$) {
- my $filename = shift;
- my $p = shift;
- my $q = shift;
- my $g = shift;
- my $y = shift;
-
- my $sexp;
-
- $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))";
-
- open(FH, ">", $filename) or die;
- print FH $sexp;
- close FH;
-}
-
-sub libgcrypt_dsa_sign($$) {
- my $data = shift;
- my $keyfile = shift;
- my $tmp;
- my %ret;
-
- die "ARCFOUR not available for DSA" if $opt{'R'};
-
- $tmp = pipe_through_program($data, "fipsdrv --key $keyfile dsa-sign");
- @ret{'Y', 'R', 'S'} = split(/\n/, $tmp);
- return %ret;
-}
-
-sub libgcrypt_dsa_verify($$$$) {
- my $data = shift;
- my $keyfile = shift;
- my $r = shift;
- my $s = shift;
-
- my $ret;
-
- die "ARCFOUR not available for DSA" if $opt{'R'};
-
- my $sigfile = "$keyfile.sig";
- open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?";
- print FH "(sig-val(dsa(r #$r#)(s #$s#)))";
- close FH;
-
- $ret = pipe_through_program($data,
- "fipsdrv --key $keyfile --signature $sigfile dsa-verify");
- unlink ($sigfile);
- # Parse through the output information
- return ($ret =~ /GOOD signature/);
-}
-
-######### End of libgcrypt implementation ################
-
-################################################################
-###### Vendor1 interface functions
-################################################################
-
-sub vendor1_encdec($$$$$) {
- my $key=shift;
- my $iv=shift;
- my $cipher=shift;
- my $enc = (shift) ? "encrypt" : "decrypt";
- my $data=shift;
-
- $data=hex2bin($data);
- my $program = "./aes $enc $key";
- $data=pipe_through_program($data,$program);
- return bin2hex($data);
-}
-
-sub vendor1_state_cipher($$$$$) {
- my $cipher = shift;
- my $encdec = shift;
- my $bufsize = shift;
- my $key = shift;
- my $iv = shift;
-
- $key = bin2hex($key);
- my $enc = $encdec ? "encrypt": "decrypt";
- my $out = "./aes $enc $key $bufsize";
- return $out;
-}
-
-##### No other interface functions below this point ######
-##########################################################
-
-##########################################################
-# General helper routines
-
-# Executing a program by feeding STDIN and retrieving
-# STDOUT
-# $1: data string to be piped to the app on STDIN
-# rest: program and args
-# returns: STDOUT of program as string
-sub pipe_through_program($@) {
- my $in = shift;
- my @args = @_;
-
- my ($CO, $CI);
- my $pid = open2($CO, $CI, @args);
-
- my $out = "";
- my $len = length($in);
- my $first = 1;
- while (1) {
- my $rin = "";
- my $win = "";
- # Output of prog is FD that we read
- vec($rin,fileno($CO),1) = 1;
- # Input of prog is FD that we write
- # check for $first is needed because we can have NULL input
- # that is to be written to the app
- if ( $len > 0 || $first) {
- (vec($win,fileno($CI),1) = 1);
- $first=0;
- }
- # Let us wait for 100ms
- my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1);
- if ( $wout ) {
- my $written = syswrite($CI, $in, $len);
- die "broken pipe" if !defined $written;
- $len -= $written;
- substr($in, 0, $written) = "";
- if ($len <= 0) {
- close $CI or die "broken pipe: $!";
- }
- }
- if ( $rout ) {
- my $tmp_out = "";
- my $bytes_read = sysread($CO, $tmp_out, 4096);
- $out .= $tmp_out;
- last if ($bytes_read == 0);
- }
- }
- close $CO or die "broken pipe: $!";
- waitpid $pid, 0;
-
- return $out;
-}
-
-#
-# convert ASCII hex to binary input
-# $1 ASCII hex
-# return binary representation
-sub hex2bin($) {
- my $in = shift;
- my $len = length($in);
- $len = 0 if ($in eq "00");
- return pack("H$len", "$in");
-}
-
-#
-# convert binary input to ASCII hex
-# $1 binary value
-# return ASCII hex representation
-sub bin2hex($) {
- my $in = shift;
- my $len = length($in)*2;
- return unpack("H$len", "$in");
-}
-
-# $1: binary byte (character)
-# returns: binary byte with odd parity using low bit as parity bit
-sub odd_par($) {
- my $in = ord(shift);
- my $odd_count=0;
- for(my $i=1; $i<8; $i++) {
- $odd_count++ if ($in & (1<<$i));
- }
-
- my $out = $in;
- if ($odd_count & 1) { # check if parity is already odd
- $out &= ~1; # clear the low bit
- } else {
- $out |= 1; # set the low bit
- }
-
- return chr($out);
-}
-
-# DES keys uses only the 7 high bits of a byte, the 8th low bit
-# is the parity bit
-# as the new key is calculated from oldkey XOR cipher in the MCT test,
-# the parity is not really checked and needs to be set to match
-# expectation (OpenSSL does not really care, but the FIPS
-# test result is expected that the key has the appropriate parity)
-# $1: arbitrary binary string
-# returns: string with odd parity set in low bit of each byte
-sub fix_key_parity($) {
- my $in = shift;
- my $out = "";
- for (my $i = 0; $i < length($in); $i++) {
- $out .= odd_par(substr($in, $i, 1));
- }
-
- return $out;
-}
-
-####################################################
-# DER/PEM utility functions
-# Cf. http://www.columbia.edu/~ariel/ssleay/layman.html
-
-# Convert unsigned integer to base256 bigint bytes
-# $1 integer
-# returns base256 octet string
-sub int_base256_unsigned($) {
- my $n = shift;
-
- my $out = chr($n & 255);
- while ($n>>=8) {
- $out = chr($n & 255) . $out;
- }
-
- return $out;
-}
-
-# Convert signed integer to base256 bigint bytes
-# $1 integer
-# returns base256 octet string
-sub int_base256_signed($) {
- my $n = shift;
- my $negative = ($n < 0);
-
- if ($negative) {
- $n = -$n-1;
- }
-
- my $out = int_base256_unsigned($n);
-
- if (ord(substr($out, 0, 1)) & 128) {
- # it's supposed to be positive but has sign bit set,
- # add a leading zero
- $out = chr(0) . $out;
- }
-
- if ($negative) {
- my $neg = chr(255) x length($out);
- $out ^= $neg;
- }
-
- return $out;
-}
-
-# Length header for specified DER object length
-# $1 length as integer
-# return octet encoding for length
-sub der_len($) {
- my $len = shift;
-
- if ($len <= 127) {
- return chr($len);
- } else {
- my $blen = int_base256_unsigned($len);
-
- return chr(128 | length($blen)) . $blen;
- }
-}
-
-# Prepend length header to object
-# $1 object as octet sequence
-# return length header for object followed by object as octets
-sub der_len_obj($) {
- my $x = shift;
-
- return der_len(length($x)) . $x;
-}
-
-# DER sequence
-# $* objects
-# returns DER sequence consisting of the objects passed as arguments
-sub der_seq {
- my $seq = join("", @_);
- return chr(0x30) . der_len_obj($seq);
-}
-
-# DER bitstring
-# $1 input octets (must be full octets, fractional octets not supported)
-# returns input encapsulated as bitstring
-sub der_bitstring($) {
- my $x = shift;
-
- $x = chr(0) . $x;
-
- return chr(0x03) . der_len_obj($x);
-}
-
-# base-128-encoded integer, used for object numbers.
-# $1 integer
-# returns octet sequence
-sub der_base128($) {
- my $n = shift;
-
- my $out = chr($n & 127);
-
- while ($n>>=7) {
- $out = chr(128 | ($n & 127)) . $out;
- }
-
- return $out;
-}
-
-# Generating the PEM certificate string
-# (base-64-encoded DER string)
-# $1 DER string
-# returns octet sequence
-sub pem_cert($) {
- my $n = shift;
-
- my $out = "-----BEGIN PUBLIC KEY-----\n";
- $out .= encode_base64($n);
- $out .= "-----END PUBLIC KEY-----\n";
-
- return $out;
-}
-
-# DER object identifier
-# $* sequence of id numbers
-# returns octets
-sub der_objectid {
- my $v1 = shift;
- my $v2 = shift;
-
- my $out = chr(40*$v1 + $v2) . join("", map { der_base128($_) } @_);
-
- return chr(0x06) . der_len_obj($out);
-}
-
-# DER signed integer
-# $1 number as octet string (base 256 representation, high byte first)
-# returns number in DER integer encoding
-sub der_bigint($) {
- my $x = shift;
-
- return chr(0x02) . der_len_obj($x);
-}
-
-# DER positive integer with leading zeroes stripped
-# $1 number as octet string (base 256 representation, high byte first)
-# returns number in DER integer encoding
-sub der_pos_bigint($) {
- my $x = shift;
-
- # strip leading zero digits
- $x =~ s/^[\0]+//;
-
- # need to prepend a zero if high bit set, since it would otherwise be
- # interpreted as a negative number. Also needed for number 0.
- if (!length($x) || ord(substr($x, 0, 1)) >= 128) {
- $x = chr(0) . $x;
- }
-
- return der_bigint($x);
-}
-
-# $1 number as signed integer
-# returns number as signed DER integer encoding
-sub der_int($) {
- my $n = shift;
-
- return der_bigint(int_base256_signed($n));
-}
-
-# the NULL object constant
-sub der_null() {
- return chr(0x05) . chr(0x00);
-}
-
-# Unit test helper
-# $1 calculated result
-# $2 expected result
-# no return value, dies if results differ, showing caller's line number
-sub der_test($$) {
- my $actual = bin2hex(shift);
- my $expected = shift;
-
- my @caller = caller;
- $actual eq $expected or die "Error:line $caller[2]:assertion failed: "
- ."$actual != $expected\n";
-}
-
-# Unit testing for the DER encoding functions
-# Examples from http://www.columbia.edu/~ariel/ssleay/layman.html
-# No input, no output. Dies if unit tests fail.
-sub der_unit_test {
- ## uncomment these if you want to test the test framework
- #print STDERR "Unit test running\n";
- #der_test chr(0), "42";
-
- der_test der_null, "0500";
-
- # length bytes
- der_test der_len(1), "01";
- der_test der_len(127), "7f";
- der_test der_len(128), "8180";
- der_test der_len(256), "820100";
- der_test der_len(65536), "83010000";
-
- # bigint
- der_test der_bigint(chr(0)), "020100";
- der_test der_bigint(chr(128)), "020180"; # -128
- der_test der_pos_bigint(chr(128)), "02020080"; # +128
- der_test der_pos_bigint(chr(0).chr(0).chr(1)), "020101";
- der_test der_pos_bigint(chr(0)), "020100";
-
- # integers (tests base256 conversion)
- der_test der_int( 0), "020100";
- der_test der_int( 127), "02017f";
- der_test der_int( 128), "02020080";
- der_test der_int( 256), "02020100";
- der_test der_int( -1), "0201ff";
- der_test der_int( -128), "020180";
- der_test der_int( -129), "0202ff7f";
- der_test der_int(-65536), "0203ff0000";
- der_test der_int(-65537), "0203feffff";
-
- # object encoding, "RSA Security"
- der_test der_base128(840), "8648";
- der_test der_objectid(1, 2, 840, 113549), "06062a864886f70d";
-
- # Combinations
- der_test der_bitstring("ABCD"), "03050041424344";
- der_test der_bitstring(der_null), "0303000500";
- der_test der_seq(der_int(0), der_null), "30050201000500";
-
- # The big picture
- der_test der_seq(der_seq(der_objectid(1, 2, 840, 113549), der_null),
- der_bitstring(der_seq(der_pos_bigint(chr(5)),
- der_pos_bigint(chr(3))))),
- "3017300a06062a864886f70d05000309003006020105020103";
-}
-
-####################################################
-# OpenSSL missing functionality workarounds
-
-## Format of an RSA public key:
-# 0:d=0 hl=3 l= 159 cons: SEQUENCE
-# 3:d=1 hl=2 l= 13 cons: SEQUENCE
-# 5:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption
-# 16:d=2 hl=2 l= 0 prim: NULL
-# 18:d=1 hl=3 l= 141 prim: BIT STRING
-# [ sequence: INTEGER (n), INTEGER (e) ]
-
-# generate RSA pub key in PEM format
-# $1: filename where PEM key is to be stored
-# $2: n of the RSA key in hex
-# $3: e of the RSA key in hex
-# return: nothing, but file created
-sub gen_pubrsakey($$$) {
- my $filename=shift;
- my $n = shift;
- my $e = shift;
-
- # make sure the DER encoder works ;-)
- der_unit_test();
-
- # generate DER encoding of the public key
-
- my $rsaEncryption = der_objectid(1, 2, 840, 113549, 1, 1, 1);
-
- my $der = der_seq(der_seq($rsaEncryption, der_null),
- der_bitstring(der_seq(der_pos_bigint(hex2bin($n)),
- der_pos_bigint(hex2bin($e)))));
-
- open(FH, ">", $filename) or die;
- print FH pem_cert($der);
- close FH;
-
-}
-
-# generate RSA pub key in PEM format
-#
-# This implementation uses "openssl asn1parse -genconf" which was added
-# in openssl 0.9.8. It is not available in older openssl versions.
-#
-# $1: filename where PEM key is to be stored
-# $2: n of the RSA key in hex
-# $3: e of the RSA key in hex
-# return: nothing, but file created
-sub gen_pubrsakey_using_openssl($$$) {
- my $filename=shift;
- my $n = shift;
- my $e = shift;
-
- my $asn1 = "asn1=SEQUENCE:pubkeyinfo
-
-[pubkeyinfo]
-algorithm=SEQUENCE:rsa_alg
-pubkey=BITWRAP,SEQUENCE:rsapubkey
-
-[rsa_alg]
-algorithm=OID:rsaEncryption
-parameter=NULL
-
-[rsapubkey]
-n=INTEGER:0x$n
-
-e=INTEGER:0x$e";
-
- open(FH, ">$filename.cnf") or die "Cannot create file $filename.cnf: $?";
- print FH $asn1;
- close FH;
- my @args = ("openssl", "asn1parse", "-genconf", "$filename.cnf", "-noout", "-out", "$filename.der");
- system(@args) == 0 or die "system @args failed: $?";
- @args = ("openssl", "rsa", "-inform", "DER", "-in", "$filename.der",
- "-outform", "PEM", "-pubin", "-pubout", "-out", "$filename");
- system(@args) == 0 or die "system @args failed: $?";
- die "RSA PEM formatted key file $filename was not created"
- if (! -f $filename);
-
- unlink("$filename.cnf");
- unlink("$filename.der");
-}
-
-############################################
-# Test cases
-
-# This is the Known Answer Test
-# $1: the string that we have to put in front of the key
-# when printing the key
-# $2: crypto key1 in hex form
-# $3: crypto key2 in hex form (TDES, undef otherwise)
-# $4: crypto key3 in hex form (TDES, undef otherwise)
-# $5: IV in hex form
-# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form
-# $7: cipher
-# $8: encrypt=1/decrypt=0
-# return: string formatted as expected by CAVS
-sub kat($$$$$$$$) {
- my $keytype = shift;
- my $key1 = shift;
- my $key2 = shift;
- my $key3 = shift;
- my $iv = shift;
- my $pt = shift;
- my $cipher = shift;
- my $enc = shift;
-
- my $out = "";
-
- $out .= "$keytype = $key1\n";
-
- # this is the concardination of the keys for 3DES
- if (defined($key2)) {
- $out .= "KEY2 = $key2\n";
- $key1 = $key1 . $key2;
- }
- if (defined($key3)) {
- $out .= "KEY3 = $key3\n";
- $key1= $key1 . $key3;
- }
-
- $out .= "IV = $iv\n" if (defined($iv) && $iv ne "");
- if ($enc) {
- $out .= "PLAINTEXT = $pt\n";
- $out .= "CIPHERTEXT = " . &$encdec($key1, $iv, $cipher, 1, $pt) . "\n";
- } else {
- $out .= "CIPHERTEXT = $pt\n";
- $out .= "PLAINTEXT = " . &$encdec($key1, $iv, $cipher, 0, $pt) . "\n";
- }
-
- return $out;
-}
-
-# This is the Known Answer Test for Hashes
-# $1: Plaintext in hex form
-# $2: hash
-# $3: hash length (undef if not applicable)
-# return: string formatted as expected by CAVS
-sub hash_kat($$$) {
- my $pt = shift;
- my $cipher = shift;
- my $len = shift;
-
- my $out = "";
- $out .= "Len = $len\n" if (defined($len));
- $out .= "Msg = $pt\n";
-
- $pt = "" if(!$len);
- $out .= "MD = " . &$hash($pt, $cipher) . "\n";
- return $out;
-}
-
-# Known Answer Test for HMAC hash
-# $1: key length in bytes
-# $2: MAC length in bytes
-# $3: key for HMAC in hex form
-# $4: message to be hashed
-# return: string formatted as expected by CAVS
-sub hmac_kat($$$$) {
- my $klen = shift;
- my $tlen = shift;
- my $key = shift;
- my $msg = shift;
-
- # XXX this is a hack - we need to decipher the HMAC REQ files in a more
- # sane way
- #
- # This is a conversion table from the expected hash output size
- # to the assumed hash type - we only define here the block size of
- # the underlying hashes and do not allow any truncation
- my %hashtype = (
- 20 => 1,
- 28 => 224,
- 32 => 256,
- 48 => 384,
- 64 => 512
- );
-
- die "Hash output size $tlen is not supported!"
- if(!defined($hashtype{$tlen}));
-
- my $out = "";
- $out .= "Klen = $klen\n";
- $out .= "Tlen = $tlen\n";
- $out .= "Key = $key\n";
- $out .= "Msg = $msg\n";
- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n";
-
- return $out;
-}
-
-
-# Cipher Monte Carlo Testing
-# $1: the string that we have to put in front of the key
-# when printing the key
-# $2: crypto key1 in hex form
-# $3: crypto key2 in hex form (TDES, undef otherwise)
-# $4: crypto key3 in hex form (TDES, undef otherwise)
-# $5: IV in hex form
-# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form
-# $7: cipher
-# $8: encrypt=1/decrypt=0
-# return: string formatted as expected by CAVS
-sub crypto_mct($$$$$$$$) {
- my $keytype = shift;
- my $key1 = hex2bin(shift);
- my $key2 = shift;
- my $key3 = shift;
- my $iv = hex2bin(shift);
- my $source_data = hex2bin(shift);
- my $cipher = shift;
- my $enc = shift;
-
- my $out = "";
-
- $key2 = hex2bin($key2) if (defined($key2));
- $key3 = hex2bin($key3) if (defined($key3));
- my $bufsize = length($source_data);
-
- # for AES: outer loop 0-99, inner 0-999 based on FIPS compliance tests
- # for RC4: outer loop 0-99, inner 0-999 based on atsec compliance tests
- # for DES: outer loop 0-399, inner 0-9999 based on FIPS compliance tests
- my $ciph = substr($cipher,0,3);
- my $oloop=100;
- my $iloop=1000;
- if ($ciph =~ /des/) {$oloop=400;$iloop=10000;}
-
- for (my $i=0; $i<$oloop; ++$i) {
- $out .= "COUNT = $i\n";
- if (defined($key2)) {
- $out .= "$keytype = ". bin2hex($key1). "\n";
- $out .= "KEY2 = ". bin2hex($key2). "\n";
- $key1 = $key1 . $key2;
- } else {
- $out .= "$keytype = ". bin2hex($key1). "\n";
- }
- if(defined($key3)) {
- $out .= "KEY3 = ". bin2hex($key3). "\n";
- $key1 = $key1 . $key3;
- }
- my $keylen = length($key1);
-
- $out .= "IV = ". bin2hex($iv) . "\n"
- if (defined($iv) && $iv ne "");
-
- if ($enc) {
- $out .= "PLAINTEXT = ". bin2hex($source_data). "\n";
- } else {
- $out .= "CIPHERTEXT = ". bin2hex($source_data). "\n";
- }
- my ($CO, $CI);
- my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv);
- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/);
- my $pid = open2($CO, $CI, $cipher_imp);
-
- my $calc_data = $iv; # CT[j]
- my $old_calc_data; # CT[j-1]
- my $old_old_calc_data; # CT[j-2]
- my $next_source;
-
- # TDES inner loop implements logic within driver
- if ($cipher =~ /des/) {
- # Need to provide a dummy IV in case of ECB mode.
- my $iv_arg = (defined($iv) && $iv ne "")
- ? bin2hex($iv)
- : "00"x(length($source_data));
- print $CI "1\n"
- .$iloop."\n"
- .bin2hex($key1)."\n"
- .$iv_arg."\n"
- .bin2hex($source_data)."\n\n" or die;
- chomp(my $line = <$CO>);
- $calc_data = hex2bin($line);
- chomp($line = <$CO>);
- $old_calc_data = hex2bin($line);
- chomp($line = <$CO>);
- $old_old_calc_data = hex2bin($line);
- chomp($line = <$CO>);
- $iv = hex2bin($line) if (defined($iv) && $iv ne "");
- chomp($line = <$CO>);
- $next_source = hex2bin($line);
- # Skip over empty line.
- $line = <$CO>;
- } else {
- for (my $j = 0; $j < $iloop; ++$j) {
- $old_old_calc_data = $old_calc_data;
- $old_calc_data = $calc_data;
-
- #print STDERR "source_data=", bin2hex($source_data), "\n";
- syswrite $CI, $source_data or die $!;
- my $len = sysread $CO, $calc_data, $bufsize;
-
- #print STDERR "len=$len, bufsize=$bufsize\n";
- die if $len ne $bufsize;
- #print STDERR "calc_data=", bin2hex($calc_data), "\n";
-
- if ( (!$enc && $ciph =~ /des/) ||
- $ciph =~ /rc4/ ||
- $cipher =~ /ecb/ ) {
- #TDES in decryption mode, RC4 and ECB mode
- #have a special rule
- $source_data = $calc_data;
- } else {
- $source_data = $old_calc_data;
- }
- }
- }
- close $CO;
- close $CI;
- waitpid $pid, 0;
-
- if ($enc) {
- $out .= "CIPHERTEXT = ". bin2hex($calc_data). "\n\n";
- } else {
- $out .= "PLAINTEXT = ". bin2hex($calc_data). "\n\n";
- }
-
- if ( $ciph =~ /aes/ ) {
- $key1 ^= substr($old_calc_data . $calc_data, -$keylen);
- #print STDERR bin2hex($key1)."\n";
- } elsif ( $ciph =~ /des/ ) {
- die "Wrong keylen $keylen" if ($keylen != 24);
-
- # $nkey needed as $key holds the concatenation of the
- # old key atm
- my $nkey = fix_key_parity(substr($key1,0,8) ^ $calc_data);
- #print STDERR "KEY1 = ". bin2hex($nkey)."\n";
- if (substr($key1,0,8) ne substr($key1,8,8)) {
- #print STDERR "KEY2 recalc: KEY1==KEY3, KEY2 indep. or all KEYs are indep.\n";
- $key2 = fix_key_parity((substr($key1,8,8) ^ $old_calc_data));
- } else {
- #print STDERR "KEY2 recalc: KEY1==KEY2==KEY3\n";
- $key2 = fix_key_parity((substr($key1,8,8) ^ $calc_data));
- }
- #print STDERR "KEY2 = ". bin2hex($key2)."\n";
- if ( substr($key1,0,8) eq substr($key1,16)) {
- #print STDERR "KEY3 recalc: KEY1==KEY2==KEY3 or KEY1==KEY3, KEY2 indep.\n";
- $key3 = fix_key_parity((substr($key1,16) ^ $calc_data));
- } else {
- #print STDERR "KEY3 recalc: all KEYs are independent\n";
- $key3 = fix_key_parity((substr($key1,16) ^ $old_old_calc_data));
- }
- #print STDERR "KEY3 = ". bin2hex($key3)."\n";
-
- # reset the first key - concardination happens at
- # beginning of loop
- $key1=$nkey;
- } elsif ($ciph =~ /rc4/ ) {
- $key1 ^= substr($calc_data, 0, 16);
- #print STDERR bin2hex($key1)."\n";
- } else {
- die "Test limitation: cipher '$cipher' not supported in Monte Carlo testing";
- }
-
- if ($cipher =~ /des-ede3-ofb/) {
- $source_data = $source_data ^ $next_source;
- } elsif (!$enc && $cipher =~ /des-ede3-cfb/) {
- #TDES decryption CFB has a special rule
- $source_data = $next_source;
- } elsif ( $ciph =~ /rc4/ || $cipher eq "des-ede3" || $cipher =~ /ecb/) {
- #No resetting of IV as the IV is all zero set initially (i.e. no IV)
- $source_data = $calc_data;
- } elsif (! $enc && $ciph =~ /des/ ) {
- #TDES in decryption mode has a special rule
- $iv = $old_calc_data;
- $source_data = $calc_data;
- } else {
- $iv = $calc_data;
- $source_data = $old_calc_data;
- }
- }
-
- return $out;
-}
-
-# Hash Monte Carlo Testing
-# $1: Plaintext in hex form
-# $2: hash
-# return: string formatted as expected by CAVS
-sub hash_mct($$) {
- my $pt = shift;
- my $cipher = shift;
-
- my $out = "";
-
- $out .= "Seed = $pt\n\n";
-
- for (my $j=0; $j<100; ++$j) {
- $out .= "COUNT = $j\n";
- my $md0=$pt;
- my $md1=$pt;
- my $md2=$pt;
- for (my $i=0; $i<1000; ++$i) {
- #print STDERR "outer loop $j; inner loop $i\n";
- my $mi= $md0 . $md1 . $md2;
- $md0=$md1;
- $md1=$md2;
- $md2 = &$hash($mi, $cipher);
- $md2 =~ s/\n//;
- }
- $out .= "MD = $md2\n\n";
- $pt=$md2;
- }
-
- return $out;
-}
-
-# RSA SigGen test
-# $1: Message to be signed in hex form
-# $2: Hash algorithm
-# $3: file name with RSA key in PEM form
-# return: string formatted as expected by CAVS
-sub rsa_siggen($$$) {
- my $data = shift;
- my $cipher = shift;
- my $keyfile = shift;
-
- my $out = "";
-
- $out .= "SHAAlg = $cipher\n";
- $out .= "Msg = $data\n";
- $out .= "S = " . &$rsa_sign($data, lc($cipher), $keyfile) . "\n";
-
- return $out;
-}
-
-# RSA SigVer test
-# $1: Message to be verified in hex form
-# $2: Hash algoritm
-# $3: Signature of message in hex form
-# $4: n of the RSA key in hex in hex form
-# $5: e of the RSA key in hex in hex form
-# return: string formatted as expected by CAVS
-sub rsa_sigver($$$$$) {
- my $data = shift;
- my $cipher = shift;
- my $signature = shift;
- my $n = shift;
- my $e = shift;
-
- my $out = "";
-
- $out .= "SHAAlg = $cipher\n";
- $out .= "e = $e\n";
- $out .= "Msg = $data\n";
- $out .= "S = $signature\n";
-
- # XXX maybe a secure temp file name is better here
- # but since it is not run on a security sensitive
- # system, I hope that this is fine
- my $keyfile = "rsa_sigver.tmp.$$";
- gen_pubrsakey($keyfile, $n, $e);
-
- my $sigfile = "$keyfile.sig";
- open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?";
- print FH hex2bin($signature);
- close FH;
-
- $out .= "Result = " . (&$rsa_verify($data, lc($cipher), $keyfile, $sigfile) ? "P\n" : "F\n");
-
- unlink($keyfile);
- unlink($sigfile);
-
- return $out;
-}
-
-# RSA X9.31 key generation test
-# $1 modulus size
-# $2 e
-# $3 xp1
-# $4 xp2
-# $5 Xp
-# $6 xq1
-# $7 xq2
-# $8 Xq
-# return: string formatted as expected by CAVS
-sub rsa_keygen($$$$$$$$) {
- my $modulus = shift;
- my $e = shift;
- my $xp1 = shift;
- my $xp2 = shift;
- my $Xp = shift;
- my $xq1 = shift;
- my $xq2 = shift;
- my $Xq = shift;
-
- my $out = "";
-
- my $ret = &$rsa_derive($modulus, $e, $xp1, $xp2, $Xp, $xq1, $xq2, $Xq);
-
- my ($P, $Q, $N, $D) = split(/\n/, $ret);
-
- $out .= "e = $e\n";
- $out .= "xp1 = $xp1\n";
- $out .= "xp2 = $xp2\n";
- $out .= "Xp = $Xp\n";
- $out .= "p = $P\n";
- $out .= "xq1 = $xq1\n";
- $out .= "xq2 = $xq2\n";
- $out .= "Xq = $Xq\n";
- $out .= "q = $Q\n";
- $out .= "n = $N\n";
- $out .= "d = $D\n\n";
-
- return $out;
-
-}
-
-# X9.31 RNG test
-# $1 key for the AES cipher
-# $2 DT value
-# $3 V value
-# $4 type ("VST", "MCT")
-# return: string formatted as expected by CAVS
-sub rngx931($$$$) {
- my $key=shift;
- my $dt=shift;
- my $v=shift;
- my $type=shift;
-
- my $out = "Key = $key\n";
- $out .= "DT = $dt\n";
- $out .= "V = $v\n";
-
- my $count = 1;
- $count = 10000 if ($type eq "MCT");
-
- my $rnd_val = "";
-
- # we read 16 bytes from RNG
- my $bufsize = 16;
-
- my ($CO, $CI);
- my $rng_imp = &$state_rng($key, $dt, $v);
- my $pid = open2($CO, $CI, $rng_imp);
- for (my $i = 0; $i < $count; ++$i) {
- my $len = sysread $CO, $rnd_val, $bufsize;
- #print STDERR "len=$len, bufsize=$bufsize\n";
- die "len=$len != bufsize=$bufsize" if $len ne $bufsize;
- #print STDERR "calc_data=", bin2hex($rnd_val), "\n";
- }
- close $CO;
- close $CI;
- waitpid $pid, 0;
-
- $out .= "R = " . bin2hex($rnd_val) . "\n\n";
-
- return $out;
-}
-
-# DSA PQGGen test
-# $1 modulus size
-# $2 number of rounds to perform the test
-# return: string formatted as expected by CAVS
-sub dsa_pqggen_driver($$) {
- my $mod = shift;
- my $rounds = shift;
-
- my $out = "";
- for(my $i=0; $i<$rounds; $i++) {
- my $ret = &$dsa_pqggen($mod);
- my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret);
- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen"
- if (!defined($P) || !defined($Q) || !defined($G) ||
- !defined($Seed) || !defined($c) || !defined($H));
-
- # now change the counter to decimal as CAVS wants decimal
- # counter value although all other is HEX
- $c = hex($c);
-
- $out .= "P = $P\n";
- $out .= "Q = $Q\n";
- $out .= "G = $G\n";
- $out .= "Seed = $Seed\n";
- $out .= "c = $c\n";
- $out .= "H = $H\n\n";
- }
-
- return $out;
-}
-
-
-# DSA SigGen test
-# $1: Message to be signed in hex form
-# $2: file name with DSA key in PEM form
-# return: string formatted as expected by CAVS
-sub dsa_siggen($$) {
- my $data = shift;
- my $keyfile = shift;
-
- my $out = "";
-
- my %ret = &$dsa_sign($data, $keyfile);
-
- $out .= "Msg = $data\n";
- $out .= "Y = " . $ret{'Y'} . "\n";
- $out .= "R = " . $ret{'R'} . "\n";
- $out .= "S = " . $ret{'S'} . "\n";
-
- return $out;
-}
-
-
-# DSA signature verification
-# $1 modulus
-# $2 P
-# $3 Q
-# $4 G
-# $5 Y - public key
-# $6 r
-# $7 s
-# $8 message to be verified
-# return: string formatted as expected by CAVS
-sub dsa_sigver($$$$$$$$) {
- my $modulus = shift;
- my $p = shift;
- my $q = shift;
- my $g = shift;
- my $y = shift;
- my $r = shift;
- my $s = shift;
- my $msg = shift;
-
- my $out = "";
-
- #PQG are already printed - do not print them here
-
- $out .= "Msg = $msg\n";
- $out .= "Y = $y\n";
- $out .= "R = $r\n";
- $out .= "S = $s\n";
-
- # XXX maybe a secure temp file name is better here
- # but since it is not run on a security sensitive
- # system, I hope that this is fine
- my $keyfile = "dsa_sigver.tmp.$$";
- &$dsa_genpubkey($keyfile, $p, $q, $g, $y);
-
- $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n");
-
- unlink($keyfile);
-
- return $out;
-}
-
-##############################################################
-# Parser of input file and generator of result file
-#
-
-sub usage() {
-
- print STDERR "Usage:
-$0 [-R] [-D] [-I name] <CAVS-test vector file>
-
--R execution of ARCFOUR instead of OpenSSL
--I NAME Use interface style NAME:
- openssl OpenSSL (default)
- libgcrypt Libgcrypt
--D SigGen and SigVer are executed with DSA
- Please note that the DSA CAVS vectors do not allow distinguishing
- them from the RSA vectors. As the RSA test is the default, you have
- to supply this option to apply the DSA logic";
-}
-
-# Parser of CAVS test vector file
-# $1: Test vector file
-# $2: Output file for test results
-# return: nothing
-sub parse($$) {
- my $infile = shift;
- my $outfile = shift;
-
- my $out = "";
-
- # this is my cipher/hash type
- my $cipher = "";
-
- # Test type
- # 1 - cipher known answer test
- # 2 - cipher Monte Carlo test
- # 3 - hash known answer test
- # 4 - hash Monte Carlo test
- # 5 - RSA signature generation
- # 6 - RSA signature verification
- my $tt = 0;
-
- # Variables for tests
- my $keytype = ""; # we can have "KEY", "KEYs", "KEY1"
- my $key1 = "";
- my $key2 = undef; #undef needed for allowing
- my $key3 = undef; #the use of them as input variables
- my $pt = "";
- my $enc = 1;
- my $iv = "";
- my $len = undef; #see key2|3
- my $n = "";
- my $e = "";
- my $signature = "";
- my $rsa_keyfile = "";
- my $dsa_keyfile = "";
- my $dt = "";
- my $v = "";
- my $klen = "";
- my $tlen = "";
- my $modulus = "";
- my $capital_n = 0;
- my $capital_p = "";
- my $capital_q = "";
- my $capital_g = "";
- my $capital_y = "";
- my $capital_r = "";
- my $xp1 = "";
- my $xp2 = "";
- my $Xp = "";
- my $xq1 = "";
- my $xq2 = "";
- my $Xq = "";
-
- my $mode = "";
-
- open(IN, "<$infile");
- while(<IN>) {
-
- my $line = $_;
- chomp($line);
- $line =~ s/\r//;
-
- my $keylen = "";
-
- # Mode and type check
- # consider the following parsed line
- # '# AESVS MCT test data for CBC'
- # '# TDES Multi block Message Test for CBC'
- # '# INVERSE PERMUTATION - KAT for CBC'
- # '# SUBSTITUTION TABLE - KAT for CBC'
- # '# TDES Monte Carlo (Modes) Test for CBC'
- # '# "SHA-1 Monte" information for "IBMRHEL5"'
- # '# "SigVer PKCS#1 Ver 1.5" information for "IBMRHEL5"'
- # '# "SigGen PKCS#1 Ver 1.5" information for "IBMRHEL5"'
- # '#RC4VS MCT test data'
-
- # avoid false positives from user specified 'for "PRODUCT"' strings
- my $tmpline = $line;
- $tmpline =~ s/ for ".*"//;
-
- ##### Extract cipher
- # XXX there may be more - to be added
- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) {
- if ($tmpline =~ /CBC/) { $mode="cbc"; }
- elsif ($tmpline =~ /ECB/) { $mode="ecb"; }
- elsif ($tmpline =~ /OFB/) { $mode="ofb"; }
- elsif ($tmpline =~ /CFB/) { $mode="cfb"; }
- #we do not need mode as the cipher is already clear
- elsif ($tmpline =~ /SHA-1/) { $cipher="sha1"; }
- elsif ($tmpline =~ /SHA-224/) { $cipher="sha224"; }
- elsif ($tmpline =~ /SHA-256/) { $cipher="sha256"; }
- elsif ($tmpline =~ /SHA-384/) { $cipher="sha384"; }
- elsif ($tmpline =~ /SHA-512/) { $cipher="sha512"; }
- #we do not need mode as the cipher is already clear
- elsif ($tmpline =~ /RC4VS/) { $cipher="rc4"; }
- elsif ($tmpline =~ /SigGen|SigVer/) {
- die "Error: X9.31 is not supported"
- if ($tmpline =~ /X9/);
- $cipher="sha1"; #place holder - might be overwritten later
- }
-
- if ($tmpline =~ /^#.*AESVS/) {
- # AES cipher (part of it)
- $cipher="aes";
- }
- if ($tmpline =~ /^#.*(TDES|KAT)/) {
- # TDES cipher (full definition)
- # the FIPS-140 test generator tool does not produce
- # machine readable output!
- if ($mode eq "cbc") { $cipher="des-ede3-cbc"; }
- if ($mode eq "ecb") { $cipher="des-ede3"; }
- if ($mode eq "ofb") { $cipher="des-ede3-ofb"; }
- if ($mode eq "cfb") { $cipher="des-ede3-cfb"; }
- }
-
- # check for RNG
- if ($tmpline =~ /ANSI X9\.31/) {
- # change the tmpline to add the type of the
- # test which is ONLY visible from the file
- # name :-(
- if ($infile =~ /MCT\.req/) {
- $tmpline .= " MCT";
- } elsif ($infile =~ /VST\.req/) {
- $tmpline .= " VST";
- } else {
- die "Unexpected cipher type with $infile";
- }
- }
-
- if ($tt == 0) {
- ##### Identify the test type
- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) {
- $tt = 13;
- die "Interface function rsa_derive for RSA key generation not defined for tested library"
- if (!defined($rsa_derive));
- } elsif ($tmpline =~ /SigVer/ && $opt{'D'} ) {
- $tt = 12;
- die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library"
- if (!defined($dsa_verify) || !defined($dsa_genpubkey));
- } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) {
- $tt = 11;
- die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library"
- if (!defined($dsa_sign) || !defined($gen_rsakey));
- } elsif ($tmpline =~ /PQGGen/) {
- $tt = 10;
- die "Interface function for DSA PQGGen testing not defined for tested library"
- if (!defined($dsa_pqggen));
- } elsif ($tmpline =~ /Hash sizes tested/) {
- $tt = 9;
- die "Interface function hmac for HMAC testing not defined for tested library"
- if (!defined($hmac));
- } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) {
- $tt = 8;
- die "Interface function state_rng for RNG MCT not defined for tested library"
- if (!defined($state_rng));
- } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /VST/) {
- $tt = 7;
- die "Interface function state_rng for RNG KAT not defined for tested library"
- if (!defined($state_rng));
- } elsif ($tmpline =~ /SigVer/ ) {
- $tt = 6;
- die "Interface function rsa_verify or gen_rsakey for RSA verification not defined for tested library"
- if (!defined($rsa_verify) || !defined($gen_rsakey));
- } elsif ($tmpline =~ /SigGen/ ) {
- $tt = 5;
- die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library"
- if (!defined($rsa_sign) || !defined($gen_rsakey));
- } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher =~ /^sha/) {
- $tt = 4;
- die "Interface function hash for Hashing not defined for tested library"
- if (!defined($hash));
- } elsif ($tmpline =~ /Monte|MCT|Carlo/) {
- $tt = 2;
- die "Interface function state_cipher for Stateful Cipher operation defined for tested library"
- if (!defined($state_cipher) || !defined($state_cipher_des));
- } elsif ($cipher =~ /^sha/) {
- $tt = 3;
- die "Interface function hash for Hashing not defined for tested library"
- if (!defined($hash));
- } else {
- $tt = 1;
- die "Interface function encdec for Encryption/Decryption not defined for tested library"
- if (!defined($encdec));
- }
- }
- }
-
- # This is needed as ARCFOUR does not operate with an IV
- $iv = "00000000000000000000000000000000" if ($cipher eq "rc4"
- && $iv eq "" );
-
- # we are now looking for the string
- # '# Key Length : 256'
- # found in AES
- if ($tmpline =~ /^# Key Length.*?(128|192|256)/) {
- if ($cipher eq "aes") {
- $cipher="$cipher-$1-$mode";
- } else {
- die "Error: Key length $1 given for cipher $cipher which is unexpected";
- }
- }
-
- # Get the test data
- if ($line =~ /^(KEY|KEY1|Key)\s*=\s*(.*)/) { # found in ciphers and RNG
- die "KEY seen twice - input file crap" if ($key1 ne "");
- $keytype=$1;
- $key1=$2;
- $key1 =~ s/\s//g; #replace potential white spaces
- }
- elsif ($line =~ /^(KEYs)\s*=\s*(.*)/) { # found in ciphers and RNG
- die "KEY seen twice - input file crap" if ($key1 ne "");
- $keytype=$1;
- $key1=$2;
- $key1 =~ s/\s//g; #replace potential white spaces
- $key2 = $key1;
- $key3 = $key1;
- }
- elsif ($line =~ /^KEY2\s*=\s*(.*)/) { # found in TDES
- die "First key not set, but got already second key - input file crap" if ($key1 eq "");
- die "KEY2 seen twice - input file crap" if (defined($key2));
- $key2=$1;
- $key2 =~ s/\s//g; #replace potential white spaces
- }
- elsif ($line =~ /^KEY3\s*=\s*(.*)/) { # found in TDES
- die "Second key not set, but got already third key - input file crap" if ($key2 eq "");
- die "KEY3 seen twice - input file crap" if (defined($key3));
- $key3=$1;
- $key3 =~ s/\s//g; #replace potential white spaces
- }
- elsif ($line =~ /^IV\s*=\s*(.*)/) { # found in ciphers
- die "IV seen twice - input file crap" if ($iv ne "");
- $iv=$1;
- $iv =~ s/\s//g; #replace potential white spaces
- }
- elsif ($line =~ /^PLAINTEXT\s*=\s*(.*)/) { # found in ciphers
- if ( $1 !~ /\?/ ) { #only use it if there is valid hex data
- die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne "");
- $pt=$1;
- $pt =~ s/\s//g; #replace potential white spaces
- $enc=1;
- }
- }
- elsif ($line =~ /^CIPHERTEXT\s*=\s*(.*)/) { # found in ciphers
- if ( $1 !~ /\?/ ) { #only use it if there is valid hex data
- die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne "");
- $pt=$1;
- $pt =~ s/\s//g; #replace potential white spaces
- $enc=0;
- }
- }
- elsif ($line =~ /^Len\s*=\s*(.*)/) { # found in hashs
- $len=$1;
- }
- elsif ($line =~ /^(Msg|Seed)\s*=\s*(.*)/) { # found in hashs
- die "Msg/Seed seen twice - input file crap" if ($pt ne "");
- $pt=$2;
- }
- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests
- $modulus = $1;
- $out .= $line . "\n\n"; # print it
- # generate the private key with given bit length now
- # as we have the required key length in bit
- if ($tt == 11) {
- $dsa_keyfile = "dsa_siggen.tmp.$$";
- my %pqg = &$gen_dsakey($dsa_keyfile);
- $out .= "P = " . $pqg{'P'} . "\n";
- $out .= "Q = " . $pqg{'Q'} . "\n";
- $out .= "G = " . $pqg{'G'} . "\n";
- } elsif ( $tt == 5 ) {
- # XXX maybe a secure temp file name is better here
- # but since it is not run on a security sensitive
- # system, I hope that this is fine
- $rsa_keyfile = "rsa_siggen.tmp.$$";
- &$gen_rsakey($modulus, $rsa_keyfile);
- my $modulus = pipe_through_program("", "openssl rsa -pubout -modulus -in $rsa_keyfile");
- $modulus =~ s/Modulus=(.*?)\s(.|\s)*/$1/;
- $out .= "n = $modulus\n";
- $out .= "\ne = 10001\n"
- }
- }
- elsif ($line =~ /^SHAAlg\s*=\s*(.*)/) { #found in RSA requests
- $cipher=$1;
- }
- elsif($line =~ /^n\s*=\s*(.*)/) { # found in RSA requests
- $out .= $line . "\n";
- $n=$1;
- }
- elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests
- $e=$1;
- }
- elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests
- die "S seen twice - input file crap" if ($signature ne "");
- $signature=$1;
- }
- elsif ($line =~ /^DT\s*=\s*(.*)/) { # X9.31 RNG requests
- die "DT seen twice - check input file"
- if ($dt ne "");
- $dt=$1;
- }
- elsif ($line =~ /^V\s*=\s*(.*)/) { # X9.31 RNG requests
- die "V seen twice - check input file"
- if ($v ne "");
- $v=$1;
- }
- elsif ($line =~ /^Klen\s*=\s*(.*)/) { # HMAC requests
- die "Klen seen twice - check input file"
- if ($klen ne "");
- $klen=$1;
- }
- elsif ($line =~ /^Tlen\s*=\s*(.*)/) { # HMAC RNG requests
- die "Tlen seen twice - check input file"
- if ($tlen ne "");
- $tlen=$1;
- }
- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen
- die "N seen twice - check input file"
- if ($capital_n);
- $capital_n = $1;
- }
- elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer
- die "P seen twice - check input file"
- if ($capital_p);
- $capital_p = $1;
- $out .= $line . "\n"; # print it
- }
- elsif ($line =~ /^Q\s*=\s*(.*)/) { #DSA SigVer
- die "Q seen twice - check input file"
- if ($capital_q);
- $capital_q = $1;
- $out .= $line . "\n"; # print it
- }
- elsif ($line =~ /^G\s*=\s*(.*)/) { #DSA SigVer
- die "G seen twice - check input file"
- if ($capital_g);
- $capital_g = $1;
- $out .= $line . "\n"; # print it
- }
- elsif ($line =~ /^Y\s*=\s*(.*)/) { #DSA SigVer
- die "Y seen twice - check input file"
- if ($capital_y);
- $capital_y = $1;
- }
- elsif ($line =~ /^R\s*=\s*(.*)/) { #DSA SigVer
- die "R seen twice - check input file"
- if ($capital_r);
- $capital_r = $1;
- }
- elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen
- die "xp1 seen twice - check input file"
- if ($xp1);
- $xp1 = $1;
- }
- elsif ($line =~ /^xp2\s*=\s*(.*)/) { #RSA key gen
- die "xp2 seen twice - check input file"
- if ($xp2);
- $xp2 = $1;
- }
- elsif ($line =~ /^Xp\s*=\s*(.*)/) { #RSA key gen
- die "Xp seen twice - check input file"
- if ($Xp);
- $Xp = $1;
- }
- elsif ($line =~ /^xq1\s*=\s*(.*)/) { #RSA key gen
- die "xq1 seen twice - check input file"
- if ($xq1);
- $xq1 = $1;
- }
- elsif ($line =~ /^xq2\s*=\s*(.*)/) { #RSA key gen
- die "xq2 seen twice - check input file"
- if ($xq2);
- $xq2 = $1;
- }
- elsif ($line =~ /^Xq\s*=\s*(.*)/) { #RSA key gen
- die "Xq seen twice - check input file"
- if ($Xq);
- $Xq = $1;
- }
- else {
- $out .= $line . "\n";
- }
-
- # call tests if all input data is there
- if ($tt == 1) {
- if ($key1 ne "" && $pt ne "" && $cipher ne "") {
- $out .= kat($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
- $keytype = "";
- $key1 = "";
- $key2 = undef;
- $key3 = undef;
- $iv = "";
- $pt = "";
- }
- }
- elsif ($tt == 2) {
- if ($key1 ne "" && $pt ne "" && $cipher ne "") {
- $out .= crypto_mct($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc);
- $keytype = "";
- $key1 = "";
- $key2 = undef;
- $key3 = undef;
- $iv = "";
- $pt = "";
- }
- }
- elsif ($tt == 3) {
- if ($pt ne "" && $cipher ne "") {
- $out .= hash_kat($pt, $cipher, $len);
- $pt = "";
- $len = undef;
- }
- }
- elsif ($tt == 4) {
- if ($pt ne "" && $cipher ne "") {
- $out .= hash_mct($pt, $cipher);
- $pt = "";
- }
- }
- elsif ($tt == 5) {
- if ($pt ne "" && $cipher ne "" && $rsa_keyfile ne "") {
- $out .= rsa_siggen($pt, $cipher, $rsa_keyfile);
- $pt = "";
- }
- }
- elsif ($tt == 6) {
- if ($pt ne "" && $cipher ne "" && $signature ne "" && $n ne "" && $e ne "") {
- $out .= rsa_sigver($pt, $cipher, $signature, $n, $e);
- $pt = "";
- $signature = "";
- }
- }
- elsif ($tt == 7 ) {
- if ($key1 ne "" && $dt ne "" && $v ne "") {
- $out .= rngx931($key1, $dt, $v, "VST");
- $key1 = "";
- $dt = "";
- $v = "";
- }
- }
- elsif ($tt == 8 ) {
- if ($key1 ne "" && $dt ne "" && $v ne "") {
- $out .= rngx931($key1, $dt, $v, "MCT");
- $key1 = "";
- $dt = "";
- $v = "";
- }
- }
- elsif ($tt == 9) {
- if ($klen ne "" && $tlen ne "" && $key1 ne "" && $pt ne "") {
- $out .= hmac_kat($klen, $tlen, $key1, $pt);
- $key1 = "";
- $tlen = "";
- $klen = "";
- $pt = "";
- }
- }
- elsif ($tt == 10) {
- if ($modulus ne "" && $capital_n > 0) {
- $out .= dsa_pqggen_driver($modulus, $capital_n);
- #$mod is not resetted
- $capital_n = 0;
- }
- }
- elsif ($tt == 11) {
- if ($pt ne "" && $dsa_keyfile ne "") {
- $out .= dsa_siggen($pt, $dsa_keyfile);
- $pt = "";
- }
- }
- elsif ($tt == 12) {
- if ($modulus ne "" &&
- $capital_p ne "" &&
- $capital_q ne "" &&
- $capital_g ne "" &&
- $capital_y ne "" &&
- $capital_r ne "" &&
- $signature ne "" &&
- $pt ne "") {
- $out .= dsa_sigver($modulus,
- $capital_p,
- $capital_q,
- $capital_g,
- $capital_y,
- $capital_r,
- $signature,
- $pt);
-
- # We do not clear the domain values PQG and
- # the modulus value as they
- # are specified only once in a file
- # and we do not need to print them as they
- # are already printed above
- $capital_y = "";
- $capital_r = "";
- $signature = "";
- $pt = "";
- }
- }
- elsif ($tt == 13) {
- if($modulus ne "" &&
- $e ne "" &&
- $xp1 ne "" &&
- $xp2 ne "" &&
- $Xp ne "" &&
- $xq1 ne "" &&
- $xq2 ne "" &&
- $Xq ne "") {
- $out .= rsa_keygen($modulus,
- $e,
- $xp1,
- $xp2,
- $Xp,
- $xq1,
- $xq2,
- $Xq);
- $e = "";
- $xp1 = "";
- $xp2 = "";
- $Xp = "";
- $xq1 = "";
- $xq2 = "";
- $Xq = "";
- }
- }
- elsif ($tt > 0) {
- die "Test case $tt not defined";
- }
- }
-
- close IN;
- $out =~ s/\n/\r\n/g; # make it a dos file
- open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?";
- print OUT $out;
- close OUT;
-
-}
-
-# Signalhandler
-sub cleanup() {
- unlink("rsa_siggen.tmp.$$");
- unlink("rsa_sigver.tmp.$$");
- unlink("rsa_sigver.tmp.$$.sig");
- unlink("rsa_sigver.tmp.$$.der");
- unlink("rsa_sigver.tmp.$$.cnf");
- unlink("dsa_siggen.tmp.$$");
- unlink("dsa_sigver.tmp.$$");
- unlink("dsa_sigver.tmp.$$.sig");
- exit;
-}
-
-############################################################
-#
-# let us pretend to be C :-)
-sub main() {
-
- usage() unless @ARGV;
-
- getopts("DRI:", \%opt) or die "bad option";
-
- ##### Set library
-
- if ( ! defined $opt{'I'} || $opt{'I'} eq 'openssl' ) {
- print STDERR "Using OpenSSL interface functions\n";
- $encdec = \&openssl_encdec;
- $rsa_sign = \&openssl_rsa_sign;
- $rsa_verify = \&openssl_rsa_verify;
- $gen_rsakey = \&openssl_gen_rsakey;
- $hash = \&openssl_hash;
- $state_cipher = \&openssl_state_cipher;
- } elsif ( $opt{'I'} eq 'libgcrypt' ) {
- print STDERR "Using libgcrypt interface functions\n";
- $encdec = \&libgcrypt_encdec;
- $rsa_sign = \&libgcrypt_rsa_sign;
- $rsa_verify = \&libgcrypt_rsa_verify;
- $gen_rsakey = \&libgcrypt_gen_rsakey;
- $rsa_derive = \&libgcrypt_rsa_derive;
- $hash = \&libgcrypt_hash;
- $state_cipher = \&libgcrypt_state_cipher;
- $state_cipher_des = \&libgcrypt_state_cipher_des;
- $state_rng = \&libgcrypt_state_rng;
- $hmac = \&libgcrypt_hmac;
- $dsa_pqggen = \&libgcrypt_dsa_pqggen;
- $gen_dsakey = \&libgcrypt_gen_dsakey;
- $dsa_sign = \&libgcrypt_dsa_sign;
- $dsa_verify = \&libgcrypt_dsa_verify;
- $dsa_genpubkey = \&libgcrypt_dsa_genpubkey;
- } else {
- die "Invalid interface option given";
- }
-
- my $infile=$ARGV[0];
- die "Error: Test vector file $infile not found" if (! -f $infile);
-
- my $outfile = $infile;
- # let us add .rsp regardless whether we could strip .req
- $outfile =~ s/\.req$//;
- if ($opt{'R'}) {
- $outfile .= ".rc4";
- } else {
- $outfile .= ".rsp";
- }
- if (-f $outfile) {
- die "Output file $outfile could not be removed: $?"
- unless unlink($outfile);
- }
- print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n";
-
- #Signal handler
- $SIG{HUP} = \&cleanup;
- $SIG{INT} = \&cleanup;
- $SIG{QUIT} = \&cleanup;
- $SIG{TERM} = \&cleanup;
-
- # Do the job
- parse($infile, $outfile);
-
- cleanup();
-
-}
-
-###########################################
-# Call it
-main();
-1;