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