1#!/usr/bin/perl -w 2# Perl utility to run or verify FIPS 140-2 CMVP algorithm tests based on the 3# pathnames of input algorithm test files actually present (the unqualified 4# file names are consistent but the pathnames are not). 5# 6 7# FIPS test definitions 8# List of all the unqualified file names we expect and command lines to run 9 10# DSA tests 11my @fips_dsa_test_list = ( 12 13 "DSA", 14 15 [ "PQGGen", "fips_dssvs pqg" ], 16 [ "KeyPair", "fips_dssvs keypair" ], 17 [ "SigGen", "fips_dssvs siggen" ], 18 [ "SigVer", "fips_dssvs sigver" ] 19 20); 21 22my @fips_dsa_pqgver_test_list = ( 23 24 [ "PQGVer", "fips_dssvs pqgver" ] 25 26); 27 28# RSA tests 29 30my @fips_rsa_test_list = ( 31 32 "RSA", 33 34 [ "SigGen15", "fips_rsastest" ], 35 [ "SigVer15", "fips_rsavtest" ], 36 [ "SigVerRSA", "fips_rsavtest -x931" ], 37 [ "KeyGenRSA", "fips_rsagtest" ], 38 [ "SigGenRSA", "fips_rsastest -x931" ] 39 40); 41 42# Special cases for PSS. The filename itself is 43# not sufficient to determine the test. Addditionally we 44# need to examine the file contents to determine the salt length 45# In these cases the test filename has (saltlen) appended. 46 47# RSA PSS salt length 0 tests 48 49my @fips_rsa_pss0_test_list = ( 50 51 [ "SigGenPSS(0)", "fips_rsastest -saltlen 0" ], 52 [ "SigVerPSS(0)", "fips_rsavtest -saltlen 0" ] 53 54); 55 56# RSA PSS salt length 62 tests 57 58my @fips_rsa_pss62_test_list = ( 59 [ "SigGenPSS(62)", "fips_rsastest -saltlen 62" ], 60 [ "SigVerPSS(62)", "fips_rsavtest -saltlen 62" ] 61 62); 63 64# SHA tests 65 66my @fips_sha_test_list = ( 67 68 "SHA", 69 70 [ "SHA1LongMsg", "fips_shatest" ], 71 [ "SHA1Monte", "fips_shatest" ], 72 [ "SHA1ShortMsg", "fips_shatest" ], 73 [ "SHA224LongMsg", "fips_shatest" ], 74 [ "SHA224Monte", "fips_shatest" ], 75 [ "SHA224ShortMsg", "fips_shatest" ], 76 [ "SHA256LongMsg", "fips_shatest" ], 77 [ "SHA256Monte", "fips_shatest" ], 78 [ "SHA256ShortMsg", "fips_shatest" ], 79 [ "SHA384LongMsg", "fips_shatest" ], 80 [ "SHA384Monte", "fips_shatest" ], 81 [ "SHA384ShortMsg", "fips_shatest" ], 82 [ "SHA512LongMsg", "fips_shatest" ], 83 [ "SHA512Monte", "fips_shatest" ], 84 [ "SHA512ShortMsg", "fips_shatest" ] 85 86); 87 88# HMAC 89 90my @fips_hmac_test_list = ( 91 92 "HMAC", 93 94 [ "HMAC", "fips_hmactest" ] 95 96); 97 98# RAND tests, AES version 99 100my @fips_rand_aes_test_list = ( 101 102 "RAND (AES)", 103 104 [ "ANSI931_AES128MCT", "fips_rngvs mct" ], 105 [ "ANSI931_AES192MCT", "fips_rngvs mct" ], 106 [ "ANSI931_AES256MCT", "fips_rngvs mct" ], 107 [ "ANSI931_AES128VST", "fips_rngvs vst" ], 108 [ "ANSI931_AES192VST", "fips_rngvs vst" ], 109 [ "ANSI931_AES256VST", "fips_rngvs vst" ] 110 111); 112 113# RAND tests, DES2 version 114 115my @fips_rand_des2_test_list = ( 116 117 "RAND (DES2)", 118 119 [ "ANSI931_TDES2MCT", "fips_rngvs mct" ], 120 [ "ANSI931_TDES2VST", "fips_rngvs vst" ] 121 122); 123 124# AES tests 125 126my @fips_aes_test_list = ( 127 128 "AES", 129 130 [ "CBCGFSbox128", "fips_aesavs -f" ], 131 [ "CBCGFSbox192", "fips_aesavs -f" ], 132 [ "CBCGFSbox256", "fips_aesavs -f" ], 133 [ "CBCKeySbox128", "fips_aesavs -f" ], 134 [ "CBCKeySbox192", "fips_aesavs -f" ], 135 [ "CBCKeySbox256", "fips_aesavs -f" ], 136 [ "CBCMCT128", "fips_aesavs -f" ], 137 [ "CBCMCT192", "fips_aesavs -f" ], 138 [ "CBCMCT256", "fips_aesavs -f" ], 139 [ "CBCMMT128", "fips_aesavs -f" ], 140 [ "CBCMMT192", "fips_aesavs -f" ], 141 [ "CBCMMT256", "fips_aesavs -f" ], 142 [ "CBCVarKey128", "fips_aesavs -f" ], 143 [ "CBCVarKey192", "fips_aesavs -f" ], 144 [ "CBCVarKey256", "fips_aesavs -f" ], 145 [ "CBCVarTxt128", "fips_aesavs -f" ], 146 [ "CBCVarTxt192", "fips_aesavs -f" ], 147 [ "CBCVarTxt256", "fips_aesavs -f" ], 148 [ "CFB128GFSbox128", "fips_aesavs -f" ], 149 [ "CFB128GFSbox192", "fips_aesavs -f" ], 150 [ "CFB128GFSbox256", "fips_aesavs -f" ], 151 [ "CFB128KeySbox128", "fips_aesavs -f" ], 152 [ "CFB128KeySbox192", "fips_aesavs -f" ], 153 [ "CFB128KeySbox256", "fips_aesavs -f" ], 154 [ "CFB128MCT128", "fips_aesavs -f" ], 155 [ "CFB128MCT192", "fips_aesavs -f" ], 156 [ "CFB128MCT256", "fips_aesavs -f" ], 157 [ "CFB128MMT128", "fips_aesavs -f" ], 158 [ "CFB128MMT192", "fips_aesavs -f" ], 159 [ "CFB128MMT256", "fips_aesavs -f" ], 160 [ "CFB128VarKey128", "fips_aesavs -f" ], 161 [ "CFB128VarKey192", "fips_aesavs -f" ], 162 [ "CFB128VarKey256", "fips_aesavs -f" ], 163 [ "CFB128VarTxt128", "fips_aesavs -f" ], 164 [ "CFB128VarTxt192", "fips_aesavs -f" ], 165 [ "CFB128VarTxt256", "fips_aesavs -f" ], 166 [ "CFB8GFSbox128", "fips_aesavs -f" ], 167 [ "CFB8GFSbox192", "fips_aesavs -f" ], 168 [ "CFB8GFSbox256", "fips_aesavs -f" ], 169 [ "CFB8KeySbox128", "fips_aesavs -f" ], 170 [ "CFB8KeySbox192", "fips_aesavs -f" ], 171 [ "CFB8KeySbox256", "fips_aesavs -f" ], 172 [ "CFB8MCT128", "fips_aesavs -f" ], 173 [ "CFB8MCT192", "fips_aesavs -f" ], 174 [ "CFB8MCT256", "fips_aesavs -f" ], 175 [ "CFB8MMT128", "fips_aesavs -f" ], 176 [ "CFB8MMT192", "fips_aesavs -f" ], 177 [ "CFB8MMT256", "fips_aesavs -f" ], 178 [ "CFB8VarKey128", "fips_aesavs -f" ], 179 [ "CFB8VarKey192", "fips_aesavs -f" ], 180 [ "CFB8VarKey256", "fips_aesavs -f" ], 181 [ "CFB8VarTxt128", "fips_aesavs -f" ], 182 [ "CFB8VarTxt192", "fips_aesavs -f" ], 183 [ "CFB8VarTxt256", "fips_aesavs -f" ], 184 185 [ "ECBGFSbox128", "fips_aesavs -f" ], 186 [ "ECBGFSbox192", "fips_aesavs -f" ], 187 [ "ECBGFSbox256", "fips_aesavs -f" ], 188 [ "ECBKeySbox128", "fips_aesavs -f" ], 189 [ "ECBKeySbox192", "fips_aesavs -f" ], 190 [ "ECBKeySbox256", "fips_aesavs -f" ], 191 [ "ECBMCT128", "fips_aesavs -f" ], 192 [ "ECBMCT192", "fips_aesavs -f" ], 193 [ "ECBMCT256", "fips_aesavs -f" ], 194 [ "ECBMMT128", "fips_aesavs -f" ], 195 [ "ECBMMT192", "fips_aesavs -f" ], 196 [ "ECBMMT256", "fips_aesavs -f" ], 197 [ "ECBVarKey128", "fips_aesavs -f" ], 198 [ "ECBVarKey192", "fips_aesavs -f" ], 199 [ "ECBVarKey256", "fips_aesavs -f" ], 200 [ "ECBVarTxt128", "fips_aesavs -f" ], 201 [ "ECBVarTxt192", "fips_aesavs -f" ], 202 [ "ECBVarTxt256", "fips_aesavs -f" ], 203 [ "OFBGFSbox128", "fips_aesavs -f" ], 204 [ "OFBGFSbox192", "fips_aesavs -f" ], 205 [ "OFBGFSbox256", "fips_aesavs -f" ], 206 [ "OFBKeySbox128", "fips_aesavs -f" ], 207 [ "OFBKeySbox192", "fips_aesavs -f" ], 208 [ "OFBKeySbox256", "fips_aesavs -f" ], 209 [ "OFBMCT128", "fips_aesavs -f" ], 210 [ "OFBMCT192", "fips_aesavs -f" ], 211 [ "OFBMCT256", "fips_aesavs -f" ], 212 [ "OFBMMT128", "fips_aesavs -f" ], 213 [ "OFBMMT192", "fips_aesavs -f" ], 214 [ "OFBMMT256", "fips_aesavs -f" ], 215 [ "OFBVarKey128", "fips_aesavs -f" ], 216 [ "OFBVarKey192", "fips_aesavs -f" ], 217 [ "OFBVarKey256", "fips_aesavs -f" ], 218 [ "OFBVarTxt128", "fips_aesavs -f" ], 219 [ "OFBVarTxt192", "fips_aesavs -f" ], 220 [ "OFBVarTxt256", "fips_aesavs -f" ] 221 222); 223 224my @fips_aes_cfb1_test_list = ( 225 226 # AES CFB1 tests 227 228 [ "CFB1GFSbox128", "fips_aesavs -f" ], 229 [ "CFB1GFSbox192", "fips_aesavs -f" ], 230 [ "CFB1GFSbox256", "fips_aesavs -f" ], 231 [ "CFB1KeySbox128", "fips_aesavs -f" ], 232 [ "CFB1KeySbox192", "fips_aesavs -f" ], 233 [ "CFB1KeySbox256", "fips_aesavs -f" ], 234 [ "CFB1MCT128", "fips_aesavs -f" ], 235 [ "CFB1MCT192", "fips_aesavs -f" ], 236 [ "CFB1MCT256", "fips_aesavs -f" ], 237 [ "CFB1MMT128", "fips_aesavs -f" ], 238 [ "CFB1MMT192", "fips_aesavs -f" ], 239 [ "CFB1MMT256", "fips_aesavs -f" ], 240 [ "CFB1VarKey128", "fips_aesavs -f" ], 241 [ "CFB1VarKey192", "fips_aesavs -f" ], 242 [ "CFB1VarKey256", "fips_aesavs -f" ], 243 [ "CFB1VarTxt128", "fips_aesavs -f" ], 244 [ "CFB1VarTxt192", "fips_aesavs -f" ], 245 [ "CFB1VarTxt256", "fips_aesavs -f" ] 246 247); 248 249# Triple DES tests 250 251my @fips_des3_test_list = ( 252 253 "Triple DES", 254 255 [ "TCBCinvperm", "fips_desmovs -f" ], 256 [ "TCBCMMT1", "fips_desmovs -f" ], 257 [ "TCBCMMT2", "fips_desmovs -f" ], 258 [ "TCBCMMT3", "fips_desmovs -f" ], 259 [ "TCBCMonte1", "fips_desmovs -f" ], 260 [ "TCBCMonte2", "fips_desmovs -f" ], 261 [ "TCBCMonte3", "fips_desmovs -f" ], 262 [ "TCBCpermop", "fips_desmovs -f" ], 263 [ "TCBCsubtab", "fips_desmovs -f" ], 264 [ "TCBCvarkey", "fips_desmovs -f" ], 265 [ "TCBCvartext", "fips_desmovs -f" ], 266 [ "TCFB64invperm", "fips_desmovs -f" ], 267 [ "TCFB64MMT1", "fips_desmovs -f" ], 268 [ "TCFB64MMT2", "fips_desmovs -f" ], 269 [ "TCFB64MMT3", "fips_desmovs -f" ], 270 [ "TCFB64Monte1", "fips_desmovs -f" ], 271 [ "TCFB64Monte2", "fips_desmovs -f" ], 272 [ "TCFB64Monte3", "fips_desmovs -f" ], 273 [ "TCFB64permop", "fips_desmovs -f" ], 274 [ "TCFB64subtab", "fips_desmovs -f" ], 275 [ "TCFB64varkey", "fips_desmovs -f" ], 276 [ "TCFB64vartext", "fips_desmovs -f" ], 277 [ "TCFB8invperm", "fips_desmovs -f" ], 278 [ "TCFB8MMT1", "fips_desmovs -f" ], 279 [ "TCFB8MMT2", "fips_desmovs -f" ], 280 [ "TCFB8MMT3", "fips_desmovs -f" ], 281 [ "TCFB8Monte1", "fips_desmovs -f" ], 282 [ "TCFB8Monte2", "fips_desmovs -f" ], 283 [ "TCFB8Monte3", "fips_desmovs -f" ], 284 [ "TCFB8permop", "fips_desmovs -f" ], 285 [ "TCFB8subtab", "fips_desmovs -f" ], 286 [ "TCFB8varkey", "fips_desmovs -f" ], 287 [ "TCFB8vartext", "fips_desmovs -f" ], 288 [ "TECBinvperm", "fips_desmovs -f" ], 289 [ "TECBMMT1", "fips_desmovs -f" ], 290 [ "TECBMMT2", "fips_desmovs -f" ], 291 [ "TECBMMT3", "fips_desmovs -f" ], 292 [ "TECBMonte1", "fips_desmovs -f" ], 293 [ "TECBMonte2", "fips_desmovs -f" ], 294 [ "TECBMonte3", "fips_desmovs -f" ], 295 [ "TECBpermop", "fips_desmovs -f" ], 296 [ "TECBsubtab", "fips_desmovs -f" ], 297 [ "TECBvarkey", "fips_desmovs -f" ], 298 [ "TECBvartext", "fips_desmovs -f" ], 299 [ "TOFBinvperm", "fips_desmovs -f" ], 300 [ "TOFBMMT1", "fips_desmovs -f" ], 301 [ "TOFBMMT2", "fips_desmovs -f" ], 302 [ "TOFBMMT3", "fips_desmovs -f" ], 303 [ "TOFBMonte1", "fips_desmovs -f" ], 304 [ "TOFBMonte2", "fips_desmovs -f" ], 305 [ "TOFBMonte3", "fips_desmovs -f" ], 306 [ "TOFBpermop", "fips_desmovs -f" ], 307 [ "TOFBsubtab", "fips_desmovs -f" ], 308 [ "TOFBvarkey", "fips_desmovs -f" ], 309 [ "TOFBvartext", "fips_desmovs -f" ] 310 311); 312 313my @fips_des3_cfb1_test_list = ( 314 315 # DES3 CFB1 tests 316 317 [ "TCFB1invperm", "fips_desmovs -f" ], 318 [ "TCFB1MMT1", "fips_desmovs -f" ], 319 [ "TCFB1MMT2", "fips_desmovs -f" ], 320 [ "TCFB1MMT3", "fips_desmovs -f" ], 321 [ "TCFB1Monte1", "fips_desmovs -f" ], 322 [ "TCFB1Monte2", "fips_desmovs -f" ], 323 [ "TCFB1Monte3", "fips_desmovs -f" ], 324 [ "TCFB1permop", "fips_desmovs -f" ], 325 [ "TCFB1subtab", "fips_desmovs -f" ], 326 [ "TCFB1varkey", "fips_desmovs -f" ], 327 [ "TCFB1vartext", "fips_desmovs -f" ], 328 329); 330 331# Verification special cases. 332# In most cases the output of a test is deterministic and 333# it can be compared to a known good result. A few involve 334# the genration and use of random keys and the output will 335# be different each time. In thoses cases we perform special tests 336# to simply check their consistency. For example signature generation 337# output will be run through signature verification to see if all outputs 338# show as valid. 339# 340 341my %verify_special = ( 342 "PQGGen" => "fips_dssvs pqgver", 343 "KeyPair" => "fips_dssvs keyver", 344 "SigGen" => "fips_dssvs sigver", 345 "SigGen15" => "fips_rsavtest", 346 "SigGenRSA" => "fips_rsavtest -x931", 347 "SigGenPSS(0)" => "fips_rsavtest -saltlen 0", 348 "SigGenPSS(62)" => "fips_rsavtest -saltlen 62", 349); 350 351my $win32 = $^O =~ m/mswin/i; 352my $onedir = 0; 353my $filter = ""; 354my $tvdir; 355my $tprefix; 356my $shwrap_prefix; 357my $debug = 0; 358my $quiet = 0; 359my $notest = 0; 360my $verify = 1; 361my $rspdir = "rsp"; 362my $ignore_missing = 0; 363my $ignore_bogus = 0; 364my $bufout = ''; 365my $list_tests = 0; 366 367my %fips_enabled = ( 368 dsa => 1, 369 "dsa-pqgver" => 0, 370 rsa => 1, 371 "rsa-pss0" => 0, 372 "rsa-pss62" => 1, 373 sha => 1, 374 hmac => 1, 375 "rand-aes" => 1, 376 "rand-des2" => 0, 377 aes => 1, 378 "aes-cfb1" => 0, 379 des3 => 1, 380 "des3-cfb1" => 0 381); 382 383foreach (@ARGV) { 384 if ( $_ eq "--win32" ) { 385 $win32 = 1; 386 } 387 elsif ( $_ eq "--onedir" ) { 388 $onedir = 1; 389 } 390 elsif ( $_ eq "--debug" ) { 391 $debug = 1; 392 } 393 elsif ( $_ eq "--ignore-missing" ) { 394 $ignore_missing = 1; 395 } 396 elsif ( $_ eq "--ignore-bogus" ) { 397 $ignore_bogus = 1; 398 } 399 elsif ( $_ eq "--generate" ) { 400 $verify = 0; 401 } 402 elsif ( $_ eq "--notest" ) { 403 $notest = 1; 404 } 405 elsif ( $_ eq "--quiet" ) { 406 $quiet = 1; 407 } 408 elsif (/--dir=(.*)$/) { 409 $tvdir = $1; 410 } 411 elsif (/--rspdir=(.*)$/) { 412 $rspdir = $1; 413 } 414 elsif (/--tprefix=(.*)$/) { 415 $tprefix = $1; 416 } 417 elsif (/--shwrap_prefix=(.*)$/) { 418 $shwrap_prefix = $1; 419 } 420 elsif (/^--(enable|disable)-(.*)$/) { 421 if ( !exists $fips_enabled{$2} ) { 422 print STDERR "Unknown test $2\n"; 423 } 424 if ( $1 eq "enable" ) { 425 $fips_enabled{$2} = 1; 426 } 427 else { 428 $fips_enabled{$2} = 0; 429 } 430 } 431 elsif (/--filter=(.*)$/) { 432 $filter = $1; 433 } 434 elsif (/^--list-tests$/) { 435 $list_tests = 1; 436 } 437 else { 438 Help(); 439 exit(1); 440 } 441} 442 443my @fips_test_list; 444 445push @fips_test_list, @fips_dsa_test_list if $fips_enabled{"dsa"}; 446push @fips_test_list, @fips_dsa_pqgver_test_list if $fips_enabled{"dsa-pqgver"}; 447push @fips_test_list, @fips_rsa_test_list if $fips_enabled{"rsa"}; 448push @fips_test_list, @fips_rsa_pss0_test_list if $fips_enabled{"rsa-pss0"}; 449push @fips_test_list, @fips_rsa_pss62_test_list if $fips_enabled{"rsa-pss62"}; 450push @fips_test_list, @fips_sha_test_list if $fips_enabled{"sha"}; 451push @fips_test_list, @fips_hmac_test_list if $fips_enabled{"hmac"}; 452push @fips_test_list, @fips_rand_aes_test_list if $fips_enabled{"rand-aes"}; 453push @fips_test_list, @fips_rand_des2_test_list if $fips_enabled{"rand-des2"}; 454push @fips_test_list, @fips_aes_test_list if $fips_enabled{"aes"}; 455push @fips_test_list, @fips_aes_cfb1_test_list if $fips_enabled{"aes-cfb1"}; 456push @fips_test_list, @fips_des3_test_list if $fips_enabled{"des3"}; 457push @fips_test_list, @fips_des3_cfb1_test_list if $fips_enabled{"des3-cfb1"}; 458 459if ($list_tests) { 460 my ( $test, $en ); 461 print "=====TEST LIST=====\n"; 462 foreach $test ( sort keys %fips_enabled ) { 463 $en = $fips_enabled{$test}; 464 $test =~ tr/[a-z]/[A-Z]/; 465 printf "%-10s %s\n", $test, $en ? "enabled" : "disabled"; 466 } 467 exit(0); 468} 469 470foreach (@fips_test_list) { 471 next unless ref($_); 472 my $nm = $_->[0]; 473 $_->[2] = ""; 474 $_->[3] = ""; 475 print STDERR "Duplicate test $nm\n" if exists $fips_tests{$nm}; 476 $fips_tests{$nm} = $_; 477} 478 479$tvdir = "." unless defined $tvdir; 480 481if ($win32) { 482 if ( !defined $tprefix ) { 483 if ($onedir) { 484 $tprefix = ".\\"; 485 } 486 else { 487 $tprefix = "..\\out32dll\\"; 488 } 489 } 490} 491else { 492 if ($onedir) { 493 $tprefix = "./" unless defined $tprefix; 494 $shwrap_prefix = "./" unless defined $shwrap_prefix; 495 } 496 else { 497 $tprefix = "../test/" unless defined $tprefix; 498 $shwrap_prefix = "../util/" unless defined $shwrap_prefix; 499 } 500} 501 502sanity_check_exe( $win32, $tprefix, $shwrap_prefix ); 503 504my $cmd_prefix = $win32 ? "" : "${shwrap_prefix}shlib_wrap.sh "; 505 506find_files( $filter, $tvdir ); 507 508sanity_check_files(); 509 510my ( $runerr, $cmperr, $cmpok, $scheckrunerr, $scheckerr, $scheckok, $skipcnt ) 511 = ( 0, 0, 0, 0, 0, 0, 0 ); 512 513exit(0) if $notest; 514 515run_tests( $verify, $win32, $tprefix, $filter, $tvdir ); 516 517if ($verify) { 518 print "ALGORITHM TEST VERIFY SUMMARY REPORT:\n"; 519 print "Tests skipped due to missing files: $skipcnt\n"; 520 print "Algorithm test program execution failures: $runerr\n"; 521 print "Test comparisons successful: $cmpok\n"; 522 print "Test comparisons failed: $cmperr\n"; 523 print "Test sanity checks successful: $scheckok\n"; 524 print "Test sanity checks failed: $scheckerr\n"; 525 print "Sanity check program execution failures: $scheckrunerr\n"; 526 527 if ( $runerr || $cmperr || $scheckrunerr || $scheckerr ) { 528 print "***TEST FAILURE***\n"; 529 } 530 else { 531 print "***ALL TESTS SUCCESSFUL***\n"; 532 } 533} 534else { 535 print "ALGORITHM TEST SUMMARY REPORT:\n"; 536 print "Tests skipped due to missing files: $skipcnt\n"; 537 print "Algorithm test program execution failures: $runerr\n"; 538 539 if ($runerr) { 540 print "***TEST FAILURE***\n"; 541 } 542 else { 543 print "***ALL TESTS SUCCESSFUL***\n"; 544 } 545} 546 547#-------------------------------- 548sub Help { 549 ( my $cmd ) = ( $0 =~ m#([^/]+)$# ); 550 print <<EOF; 551$cmd: generate run CMVP algorithm tests 552 --debug Enable debug output 553 --dir=<dirname> Optional root for *.req file search 554 --filter=<regexp> 555 --onedir <dirname> Assume all components in current directory 556 --rspdir=<dirname> Name of subdirectories containing *.rsp files, default "rsp" 557 --shwrap_prefix=<prefix> 558 --tprefix=<prefix> 559 --ignore-bogus Ignore duplicate or bogus files 560 --ignore-missing Ignore missing test files 561 --quiet Shhh.... 562 --generate Generate algorithm test output 563 --win32 Win32 environment 564 --enable-<alg> Enable algorithm set <alg>. 565 --disable-<alg> Disable algorithm set <alg>. 566 Where <alg> can be one of: 567EOF 568 569while (my ($key, $value) = each %fips_enabled) 570 { 571 printf "\t\t%-20s(%s by default)\n", $key , 572 $value ? "enabled" : "disabled"; 573 } 574} 575 576# Sanity check to see if all necessary executables exist 577 578sub sanity_check_exe { 579 my ( $win32, $tprefix, $shwrap_prefix ) = @_; 580 my %exe_list; 581 my $bad = 0; 582 $exe_list{ $shwrap_prefix . "shlib_wrap.sh" } = 1 unless $win32; 583 foreach (@fips_test_list) { 584 next unless ref($_); 585 my $cmd = $_->[1]; 586 $cmd =~ s/ .*$//; 587 $cmd = $tprefix . $cmd; 588 $cmd .= ".exe" if $win32; 589 $exe_list{$cmd} = 1; 590 } 591 592 foreach ( sort keys %exe_list ) { 593 if ( !-f $_ ) { 594 print STDERR "ERROR: can't find executable $_\n"; 595 $bad = 1; 596 } 597 } 598 if ($bad) { 599 print STDERR "FATAL ERROR: executables missing\n"; 600 exit(1); 601 } 602 elsif ($debug) { 603 print STDERR "Executable sanity check passed OK\n"; 604 } 605} 606 607# Search for all request and response files 608 609sub find_files { 610 my ( $filter, $dir ) = @_; 611 my ( $dirh, $testname ); 612 opendir( $dirh, $dir ); 613 while ( $_ = readdir($dirh) ) { 614 next if ( $_ eq "." || $_ eq ".." ); 615 $_ = "$dir/$_"; 616 if ( -f "$_" ) { 617 if (/\/([^\/]*)\.rsp$/) { 618 $testname = fix_pss( $1, $_ ); 619 if ( exists $fips_tests{$testname} ) { 620 if ( $fips_tests{$testname}->[3] eq "" ) { 621 $fips_tests{$testname}->[3] = $_; 622 } 623 else { 624 print STDERR 625"WARNING: duplicate response file $_ for test $testname\n"; 626 $nbogus++; 627 } 628 } 629 else { 630 print STDERR "WARNING: bogus file $_\n"; 631 $nbogus++; 632 } 633 } 634 next unless /$filter.*\.req$/i; 635 if (/\/([^\/]*)\.req$/) { 636 $testname = fix_pss( $1, $_ ); 637 if ( exists $fips_tests{$testname} ) { 638 if ( $fips_tests{$testname}->[2] eq "" ) { 639 $fips_tests{$testname}->[2] = $_; 640 } 641 else { 642 print STDERR 643"WARNING: duplicate request file $_ for test $testname\n"; 644 $nbogus++; 645 } 646 647 } 648 elsif ( !/SHAmix\.req$/ ) { 649 print STDERR "WARNING: unrecognized filename $_\n"; 650 $nbogus++; 651 } 652 } 653 } 654 elsif ( -d "$_" ) { 655 find_files( $filter, $_ ); 656 } 657 } 658 closedir($dirh); 659} 660 661sub fix_pss { 662 my ( $test, $path ) = @_; 663 my $sl = ""; 664 local $_; 665 if ( $test =~ /PSS/ ) { 666 open( IN, $path ) || die "Can't Open File $path"; 667 while (<IN>) { 668 if (/^\s*#\s*salt\s+len:\s+(\d+)\s*$/i) { 669 $sl = $1; 670 last; 671 } 672 } 673 close IN; 674 if ( $sl eq "" ) { 675 print STDERR "WARNING: No Salt length detected for file $path\n"; 676 } 677 else { 678 return $test . "($sl)"; 679 } 680 } 681 return $test; 682} 683 684sub sanity_check_files { 685 my $bad = 0; 686 foreach (@fips_test_list) { 687 next unless ref($_); 688 my ( $tst, $cmd, $req, $resp ) = @$_; 689 690 #print STDERR "FILES $tst, $cmd, $req, $resp\n"; 691 if ( $req eq "" ) { 692 print STDERR "WARNING: missing request file for $tst\n"; 693 $bad = 1; 694 next; 695 } 696 if ( $verify && $resp eq "" ) { 697 print STDERR "WARNING: no response file for test $tst\n"; 698 $bad = 1; 699 } 700 elsif ( !$verify && $resp ne "" ) { 701 print STDERR "WARNING: response file $resp will be overwritten\n"; 702 } 703 } 704 if ($bad) { 705 print STDERR "ERROR: test vector file set not complete\n"; 706 exit(1) unless $ignore_missing; 707 } 708 if ($nbogus) { 709 print STDERR 710 "ERROR: $nbogus bogus or duplicate request and response files\n"; 711 exit(1) unless $ignore_bogus; 712 } 713 if ( $debug && !$nbogus && !$bad ) { 714 print STDERR "test vector file set complete\n"; 715 } 716} 717 718sub run_tests { 719 my ( $verify, $win32, $tprefix, $filter, $tvdir ) = @_; 720 my ( $tname, $tref ); 721 my $bad = 0; 722 foreach (@fips_test_list) { 723 if ( !ref($_) ) { 724 print "Running $_ tests\n" unless $quiet; 725 next; 726 } 727 my ( $tname, $tcmd, $req, $rsp ) = @$_; 728 my $out = $rsp; 729 if ($verify) { 730 $out =~ s/\.rsp$/.tst/; 731 } 732 if ( $req eq "" ) { 733 print STDERR 734 "WARNING: Request file for $tname missing: test skipped\n"; 735 $skipcnt++; 736 next; 737 } 738 if ( $verify && $rsp eq "" ) { 739 print STDERR 740 "WARNING: Response file for $tname missing: test skipped\n"; 741 $skipcnt++; 742 next; 743 } 744 elsif ( !$verify ) { 745 if ( $rsp ne "" ) { 746 print STDERR "WARNING: Response file for $tname deleted\n"; 747 unlink $rsp; 748 } 749 $out = $req; 750 $out =~ s|/req/(\S+)\.req|/$rspdir/$1.rsp|; 751 my $outdir = $out; 752 $outdir =~ s|/[^/]*$||; 753 if ( !-d $outdir ) { 754 print STDERR "DEBUG: Creating directory $outdir\n" if $debug; 755 mkdir($outdir) || die "Can't create directory $outdir"; 756 } 757 } 758 my $cmd = "$cmd_prefix$tprefix$tcmd "; 759 if ( $tcmd =~ /-f$/ ) { 760 $cmd .= "\"$req\" \"$out\""; 761 } 762 else { 763 $cmd .= "<\"$req\" >\"$out\""; 764 } 765 print STDERR "DEBUG: running test $tname\n" if ( $debug && !$verify ); 766 system($cmd); 767 if ( $? != 0 ) { 768 print STDERR 769 "WARNING: error executing test $tname for command: $cmd\n"; 770 $runerr++; 771 next; 772 } 773 if ($verify) { 774 if ( exists $verify_special{$tname} ) { 775 my $vout = $rsp; 776 $vout =~ s/\.rsp$/.ver/; 777 $tcmd = $verify_special{$tname}; 778 $cmd = "$cmd_prefix$tprefix$tcmd "; 779 $cmd .= "<\"$out\" >\"$vout\""; 780 system($cmd); 781 if ( $? != 0 ) { 782 print STDERR 783 "WARNING: error executing verify test $tname $cmd\n"; 784 $scheckrunerr++; 785 next; 786 } 787 my ( $fcount, $pcount ) = ( 0, 0 ); 788 open VER, "$vout"; 789 while (<VER>) { 790 if (/^Result\s*=\s*(\S*)\s*$/i) 791 792 { 793 if ( $1 eq "F" ) { 794 $fcount++; 795 } 796 else { 797 $pcount++; 798 } 799 } 800 } 801 close VER; 802 803 unlink $vout; 804 if ( $fcount || $debug ) { 805 print STDERR "DEBUG: $tname, Pass=$pcount, Fail=$fcount\n"; 806 } 807 if ( $fcount || !$pcount ) { 808 $scheckerr++; 809 } 810 else { 811 $scheckok++; 812 } 813 814 } 815 elsif ( !cmp_file( $tname, $rsp, $out ) ) { 816 $cmperr++; 817 } 818 else { 819 $cmpok++; 820 } 821 unlink $out; 822 } 823 } 824} 825 826sub cmp_file { 827 my ( $tname, $rsp, $tst ) = @_; 828 my ( $rspf, $tstf ); 829 my ( $rspline, $tstline ); 830 if ( !open( $rspf, $rsp ) ) { 831 print STDERR "ERROR: can't open request file $rsp\n"; 832 return 0; 833 } 834 if ( !open( $tstf, $tst ) ) { 835 print STDERR "ERROR: can't open output file $tst\n"; 836 return 0; 837 } 838 for ( ; ; ) { 839 $rspline = next_line($rspf); 840 $tstline = next_line($tstf); 841 if ( !defined($rspline) && !defined($tstline) ) { 842 print STDERR "DEBUG: $tname file comparison OK\n" if $debug; 843 return 1; 844 } 845 if ( !defined($rspline) ) { 846 print STDERR "ERROR: $tname EOF on $rsp\n"; 847 return 0; 848 } 849 if ( !defined($tstline) ) { 850 print STDERR "ERROR: $tname EOF on $tst\n"; 851 return 0; 852 } 853 854 # Workaround for bug in RAND des2 test output */ 855 if ( $tstline =~ /^Key2 =/ && $rspline =~ /^Key1 =/ ) { 856 $rspline =~ s/^Key1/Key2/; 857 } 858 859 if ( $tstline ne $rspline ) { 860 print STDERR "ERROR: $tname mismatch:\n"; 861 print STDERR "\t \"$tstline\" != \"$rspline\"\n"; 862 return 0; 863 } 864 } 865 return 1; 866} 867 868sub next_line { 869 my ($in) = @_; 870 871 while (<$in>) { 872 chomp; 873 874 # Delete comments 875 s/#.*$//; 876 877 # Ignore blank lines 878 next if (/^\s*$/); 879 880 # Translate multiple space into one 881 s/\s+/ /g; 882 # Delete trailing whitespace 883 s/\s+$//; 884 return $_; 885 } 886 return undef; 887} 888