1 1.1 christos #! /usr/bin/env perl 2 1.1 christos # Copyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos # 4 1.1 christos # Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos # this file except in compliance with the License. You can obtain a copy 6 1.1 christos # in the file LICENSE in the source distribution or at 7 1.1 christos # https://www.openssl.org/source/license.html 8 1.1 christos 9 1.1 christos use strict; 10 1.1 christos use warnings; 11 1.1 christos 12 1.1 christos use File::Spec::Functions qw(:DEFAULT abs2rel); 13 1.1 christos use File::Copy; 14 1.1 christos use OpenSSL::Glob; 15 1.1 christos use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file/; 16 1.1 christos use OpenSSL::Test::Utils; 17 1.1 christos 18 1.1 christos BEGIN { 19 1.1 christos setup("test_fipsinstall"); 20 1.1 christos } 21 1.1 christos use lib srctop_dir('Configurations'); 22 1.1 christos use lib bldtop_dir('.'); 23 1.1 christos use platform; 24 1.1 christos 25 1.1 christos plan skip_all => "Test only supported in a fips build" if disabled("fips"); 26 1.1 christos 27 1.1 christos # Compatible options for pedantic FIPS compliance 28 1.1 christos my @pedantic_okay = 29 1.1 christos ( 'ems_check', 'no_drbg_truncated_digests', 'self_test_onload', 30 1.1 christos 'signature_digest_check' 31 1.1 christos ); 32 1.1 christos 33 1.1 christos # Incompatible options for pedantic FIPS compliance 34 1.1 christos my @pedantic_fail = 35 1.1 christos ( 'no_conditional_errors', 'no_security_checks', 'self_test_oninstall', 36 1.1 christos 'no_pbkdf2_lower_bound_check' ); 37 1.1 christos 38 1.1 christos # Command line options 39 1.1 christos my @commandline = 40 1.1 christos ( 41 1.1 christos ( 'ems_check', 'tls1-prf-ems-check' ), 42 1.1 christos ( 'no_short_mac', 'no-short-mac' ), 43 1.1 christos ( 'no_drbg_truncated_digests', 'drbg-no-trunc-md' ), 44 1.1 christos ( 'signature_digest_check', 'signature-digest-check' ), 45 1.1 christos ( 'hkdf_digest_check', 'hkdf-digest-check' ), 46 1.1 christos ( 'tls13_kdf_digest_check', 'tls13-kdf-digest-check' ), 47 1.1 christos ( 'tls1_prf_digest_check', 'tls1-prf-digest-check' ), 48 1.1 christos ( 'sshkdf_digest_check', 'sshkdf-digest-check' ), 49 1.1 christos ( 'sskdf_digest_check', 'sskdf-digest-check' ), 50 1.1 christos ( 'x963kdf_digest_check', 'x963kdf-digest-check' ), 51 1.1 christos ( 'dsa_sign_disabled', 'dsa-sign-disabled' ), 52 1.1 christos ( 'tdes_encrypt_disabled', 'tdes-encrypt-disabled' ), 53 1.1 christos ( 'rsa_pkcs15_pad_disabled', 'rsa-pkcs15-pad-disabled' ), 54 1.1 christos ( 'rsa_pss_saltlen_check', 'rsa-pss-saltlen-check' ), 55 1.1 christos ( 'rsa_sign_x931_disabled', 'rsa-sign-x931-pad-disabled' ), 56 1.1 christos ( 'hkdf_key_check', 'hkdf-key-check' ), 57 1.1 christos ( 'kbkdf_key_check', 'kbkdf-key-check' ), 58 1.1 christos ( 'tls13_kdf_key_check', 'tls13-kdf-key-check' ), 59 1.1 christos ( 'tls1_prf_key_check', 'tls1-prf-key-check' ), 60 1.1 christos ( 'sshkdf_key_check', 'sshkdf-key-check' ), 61 1.1 christos ( 'sskdf_key_check', 'sskdf-key-check' ), 62 1.1 christos ( 'x963kdf_key_check', 'x963kdf-key-check' ), 63 1.1 christos ( 'x942kdf_key_check', 'x942kdf-key-check' ) 64 1.1 christos ); 65 1.1 christos 66 1.1.1.2 christos plan tests => 41 + (scalar @pedantic_okay) + (scalar @pedantic_fail) 67 1.1 christos + 4 * (scalar @commandline); 68 1.1 christos 69 1.1 christos my $infile = bldtop_file('providers', platform->dso('fips')); 70 1.1 christos my $fipskey = $ENV{FIPSKEY} // config('FIPSKEY') // '00'; 71 1.1 christos my $provconf = srctop_file("test", "fips-and-base.cnf"); 72 1.1 christos 73 1.1 christos # Read in a text $infile and replace the regular expression in $srch with the 74 1.1 christos # value in $repl and output to a new file $outfile. 75 1.1 christos sub replace_line_file_internal { 76 1.1 christos 77 1.1 christos my ($infile, $srch, $repl, $outfile) = @_; 78 1.1 christos my $msg; 79 1.1 christos 80 1.1 christos open(my $in, "<", $infile) or return 0; 81 1.1 christos read($in, $msg, 1024); 82 1.1 christos close $in; 83 1.1 christos 84 1.1 christos $msg =~ s/$srch/$repl/; 85 1.1 christos 86 1.1 christos open(my $fh, ">", $outfile) or return 0; 87 1.1 christos print $fh $msg; 88 1.1 christos close $fh; 89 1.1 christos return 1; 90 1.1 christos } 91 1.1 christos 92 1.1 christos # Read in the text input file 'fips.cnf' 93 1.1 christos # and replace a single Key = Value line with a new value in $value. 94 1.1 christos # OR remove the Key = Value line if the passed in $value is empty. 95 1.1 christos # and then output a new file $outfile. 96 1.1 christos # $key is the Key to find 97 1.1 christos sub replace_line_file { 98 1.1 christos my ($key, $value, $outfile) = @_; 99 1.1 christos 100 1.1 christos my $srch = qr/$key\s*=\s*\S*\n/; 101 1.1 christos my $rep; 102 1.1 christos if ($value eq "") { 103 1.1 christos $rep = ""; 104 1.1 christos } else { 105 1.1 christos $rep = "$key = $value\n"; 106 1.1 christos } 107 1.1 christos return replace_line_file_internal('fips.cnf', $srch, $rep, $outfile); 108 1.1 christos } 109 1.1 christos 110 1.1 christos # Read in the text input file 'test/fips.cnf' 111 1.1 christos # and replace the .cnf file used in 112 1.1 christos # .include fipsmodule.cnf with a new value in $value. 113 1.1 christos # and then output a new file $outfile. 114 1.1 christos # $key is the Key to find 115 1.1 christos sub replace_parent_line_file { 116 1.1 christos my ($value, $outfile) = @_; 117 1.1 christos my $srch = qr/fipsmodule.cnf/; 118 1.1 christos my $rep = "$value"; 119 1.1 christos return replace_line_file_internal(srctop_file("test", 'fips.cnf'), 120 1.1 christos $srch, $rep, $outfile); 121 1.1 christos } 122 1.1 christos 123 1.1 christos # Check if the specified pattern occurs in the given file 124 1.1 christos # Returns 1 if the pattern is found and 0 if not 125 1.1 christos sub find_line_file { 126 1.1 christos my ($key, $file) = @_; 127 1.1 christos 128 1.1 christos open(my $in, $file) or return -1; 129 1.1 christos while (my $line = <$in>) { 130 1.1 christos if ($line =~ /$key/) { 131 1.1 christos close($in); 132 1.1 christos return 1; 133 1.1 christos } 134 1.1 christos } 135 1.1 christos close($in); 136 1.1 christos return 0; 137 1.1 christos } 138 1.1 christos 139 1.1 christos # fail if no module name 140 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', 141 1.1 christos '-provider_name', 'fips', 142 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 143 1.1 christos '-section_name', 'fips_sect'])), 144 1.1 christos "fipsinstall fail"); 145 1.1 christos 146 1.1 christos # fail to verify if the configuration file is missing 147 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-in', 'dummy.tmp', '-module', $infile, 148 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 149 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 150 1.1 christos '-section_name', 'fips_sect', '-verify'])), 151 1.1 christos "fipsinstall verify fail"); 152 1.1 christos 153 1.1 christos # output a fips.cnf file containing mac data 154 1.1 christos ok(run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 155 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 156 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 157 1.1 christos '-section_name', 'fips_sect'])), 158 1.1 christos "fipsinstall"); 159 1.1 christos 160 1.1 christos # verify the fips.cnf file 161 1.1 christos ok(run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile, 162 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 163 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 164 1.1 christos '-section_name', 'fips_sect', '-verify'])), 165 1.1 christos "fipsinstall verify"); 166 1.1 christos 167 1.1 christos # Test that default options for fipsinstall output the 'install-status' for 168 1.1 christos # FIPS 140-2 providers. 169 1.1 christos SKIP: { 170 1.1 christos run(test(["fips_version_test", "-config", $provconf, "<3.1.0"]), 171 1.1 christos capture => 1, statusvar => \my $exit); 172 1.1 christos 173 1.1 christos skip "Skipping FIPS 140-3 provider", 2 174 1.1 christos if !$exit; 175 1.1 christos 176 1.1 christos ok(find_line_file('install-mac = ', 'fips.cnf') == 1, 177 1.1 christos 'FIPS 140-2 should output install-mac'); 178 1.1 christos 179 1.1 christos ok(find_line_file('install-status = INSTALL_SELF_TEST_KATS_RUN', 180 1.1 christos 'fips.cnf') == 1, 181 1.1 christos 'FIPS 140-2 should output install-status'); 182 1.1 christos } 183 1.1 christos 184 1.1 christos # Skip Tests if POST is disabled 185 1.1 christos SKIP: { 186 1.1 christos skip "Skipping POST checks", 13 187 1.1 christos if disabled("fips-post"); 188 1.1 christos 189 1.1 christos ok(replace_line_file('module-mac', '', 'fips_no_module_mac.cnf') 190 1.1 christos && !run(app(['openssl', 'fipsinstall', 191 1.1 christos '-in', 'fips_no_module_mac.cnf', 192 1.1 christos '-module', $infile, 193 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 194 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:01", 195 1.1 christos '-section_name', 'fips_sect', '-verify'])), 196 1.1 christos "fipsinstall verify fail no module mac"); 197 1.1 christos 198 1.1 christos ok(replace_line_file('install-mac', '', 'fips_no_install_mac.cnf') 199 1.1 christos && !run(app(['openssl', 'fipsinstall', 200 1.1 christos '-in', 'fips_no_install_mac.cnf', 201 1.1 christos '-module', $infile, 202 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 203 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:01", 204 1.1 christos '-section_name', 'fips_sect', '-verify'])), 205 1.1 christos "fipsinstall verify fail no install indicator mac"); 206 1.1 christos 207 1.1 christos ok(replace_line_file('module-mac', '00:00:00:00:00:00', 208 1.1 christos 'fips_bad_module_mac.cnf') 209 1.1 christos && !run(app(['openssl', 'fipsinstall', 210 1.1 christos '-in', 'fips_bad_module_mac.cnf', 211 1.1 christos '-module', $infile, 212 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 213 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:01", 214 1.1 christos '-section_name', 'fips_sect', '-verify'])), 215 1.1 christos "fipsinstall verify fail if invalid module integrity value"); 216 1.1 christos 217 1.1 christos ok(replace_line_file('install-mac', '00:00:00:00:00:00', 218 1.1 christos 'fips_bad_install_mac.cnf') 219 1.1 christos && !run(app(['openssl', 'fipsinstall', 220 1.1 christos '-in', 'fips_bad_install_mac.cnf', 221 1.1 christos '-module', $infile, 222 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 223 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:01", 224 1.1 christos '-section_name', 'fips_sect', '-verify'])), 225 1.1 christos "fipsinstall verify fail if invalid install indicator integrity value"); 226 1.1 christos 227 1.1 christos ok(replace_line_file('install-status', 'INCORRECT_STATUS_STRING', 228 1.1 christos 'fips_bad_indicator.cnf') 229 1.1 christos && !run(app(['openssl', 'fipsinstall', 230 1.1 christos '-in', 'fips_bad_indicator.cnf', 231 1.1 christos '-module', $infile, 232 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 233 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:01", 234 1.1 christos '-section_name', 'fips_sect', '-verify'])), 235 1.1 christos "fipsinstall verify fail if invalid install indicator status"); 236 1.1 christos 237 1.1 christos # fail to verify the fips.cnf file if a different key is used 238 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', 239 1.1 christos '-module', $infile, 240 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 241 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:01", 242 1.1 christos '-section_name', 'fips_sect', '-verify'])), 243 1.1 christos "fipsinstall verify fail bad key"); 244 1.1 christos 245 1.1 christos # fail to verify the fips.cnf file if a different mac digest is used 246 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', 247 1.1 christos '-module', $infile, 248 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 249 1.1 christos '-macopt', 'digest:SHA512', '-macopt', "hexkey:$fipskey", 250 1.1 christos '-section_name', 'fips_sect', '-verify'])), 251 1.1 christos "fipsinstall verify fail incorrect digest"); 252 1.1 christos 253 1.1 christos # corrupt the module hmac 254 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', 255 1.1 christos '-module', $infile, 256 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 257 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 258 1.1 christos '-section_name', 'fips_sect', '-corrupt_desc', 'HMAC'])), 259 1.1 christos "fipsinstall fails when the module integrity is corrupted"); 260 1.1 christos 261 1.1 christos # corrupt the first digest 262 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', 263 1.1 christos '-module', $infile, 264 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 265 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 266 1.1 christos '-section_name', 'fips_sect', '-corrupt_desc', 'SHA2'])), 267 1.1 christos "fipsinstall fails when the digest result is corrupted"); 268 1.1 christos 269 1.1 christos # corrupt another digest 270 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', 271 1.1 christos '-module', $infile, 272 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 273 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 274 1.1 christos '-section_name', 'fips_sect', '-corrupt_desc', 'SHA3'])), 275 1.1 christos "fipsinstall fails when the digest result is corrupted"); 276 1.1 christos 277 1.1 christos # corrupt cipher encrypt test 278 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', 279 1.1 christos '-module', $infile, 280 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 281 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 282 1.1 christos '-section_name', 'fips_sect', '-corrupt_desc', 'AES_GCM'])), 283 1.1 christos "fipsinstall fails when the AES_GCM result is corrupted"); 284 1.1 christos 285 1.1 christos # corrupt cipher decrypt test 286 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', 287 1.1 christos '-module', $infile, 288 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 289 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 290 1.1 christos '-section_name', 'fips_sect', '-corrupt_desc', 'AES_ECB_Decrypt'])), 291 1.1 christos "fipsinstall fails when the AES_ECB result is corrupted"); 292 1.1 christos 293 1.1 christos # corrupt DRBG 294 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', 295 1.1 christos '-module', $infile, 296 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 297 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 298 1.1 christos '-section_name', 'fips_sect', '-corrupt_desc', 'CTR'])), 299 1.1 christos "fipsinstall fails when the DRBG CTR result is corrupted"); 300 1.1 christos } 301 1.1 christos 302 1.1 christos # corrupt a KAS test 303 1.1 christos SKIP: { 304 1.1 christos skip "Skipping KAS DH corruption test because of no dh in this build", 1 305 1.1 christos if disabled("dh") || disabled("fips-post"); 306 1.1 christos 307 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 308 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 309 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 310 1.1 christos '-section_name', 'fips_sect', 311 1.1 christos '-corrupt_desc', 'DH', 312 1.1 christos '-corrupt_type', 'KAT_KA'])), 313 1.1 christos "fipsinstall fails when the kas result is corrupted"); 314 1.1 christos } 315 1.1 christos 316 1.1 christos # corrupt a Signature test - 140-3 requires a known answer test 317 1.1 christos SKIP: { 318 1.1 christos skip "Skipping Signature DSA corruption test because of no dsa in this build", 1 319 1.1 christos if disabled("dsa") || disabled("fips-post"); 320 1.1 christos 321 1.1 christos run(test(["fips_version_test", "-config", $provconf, ">=3.1.0"]), 322 1.1 christos capture => 1, statusvar => \my $exit); 323 1.1 christos skip "FIPS provider version is too old for KAT DSA signature test", 1 324 1.1 christos if !$exit; 325 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 326 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 327 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 328 1.1 christos '-section_name', 'fips_sect', '-self_test_oninstall', 329 1.1 christos '-corrupt_desc', 'DSA', 330 1.1 christos '-corrupt_type', 'KAT_Signature'])), 331 1.1 christos "fipsinstall fails when the signature result is corrupted"); 332 1.1 christos } 333 1.1 christos 334 1.1 christos # corrupt a Signature test - 140-2 allows a pairwise consistency test 335 1.1 christos SKIP: { 336 1.1 christos skip "Skipping Signature DSA corruption test because of no dsa in this build", 1 337 1.1 christos if disabled("dsa") || disabled("fips-post"); 338 1.1 christos 339 1.1 christos run(test(["fips_version_test", "-config", $provconf, "<3.1.0"]), 340 1.1 christos capture => 1, statusvar => \my $exit); 341 1.1 christos skip "FIPS provider version is too new for PCT DSA signature test", 1 342 1.1 christos if !$exit; 343 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 344 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 345 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 346 1.1 christos '-section_name', 'fips_sect', 347 1.1 christos '-corrupt_desc', 'DSA', 348 1.1 christos '-corrupt_type', 'PCT_Signature'])), 349 1.1 christos "fipsinstall fails when the signature result is corrupted"); 350 1.1 christos } 351 1.1 christos 352 1.1 christos # corrupt ML-KEM tests 353 1.1 christos SKIP: { 354 1.1 christos skip "Skipping ML_KEM corruption tests because of no ML-KEM in this build", 4 355 1.1 christos if disabled("ml-kem") || disabled("fips-post"); 356 1.1 christos 357 1.1 christos run(test(["fips_version_test", "-config", $provconf, ">=3.5.0"]), 358 1.1 christos capture => 1, statusvar => \my $exit); 359 1.1 christos skip "FIPS provider version doesn't support ML-KEM", 4 360 1.1 christos if !$exit; 361 1.1 christos 362 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 363 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 364 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 365 1.1 christos '-section_name', 'fips_sect', 366 1.1 christos '-corrupt_desc', 'ML-KEM', 367 1.1 christos '-corrupt_type', 'KAT_AsymmetricKeyGeneration'])), 368 1.1 christos "fipsinstall fails when the ML-KEM key generation result is corrupted"); 369 1.1 christos 370 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 371 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 372 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 373 1.1 christos '-section_name', 'fips_sect', 374 1.1 christos '-corrupt_desc', 'KEM_Encap', 375 1.1 christos '-corrupt_type', 'KAT_KEM'])), 376 1.1 christos "fipsinstall fails when the ML-KEM encapsulate result is corrupted"); 377 1.1 christos 378 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 379 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 380 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 381 1.1 christos '-section_name', 'fips_sect', 382 1.1 christos '-corrupt_desc', 'KEM_Decap', 383 1.1 christos '-corrupt_type', 'KAT_KEM'])), 384 1.1 christos "fipsinstall fails when the ML-KEM decapsulate result is corrupted"); 385 1.1 christos 386 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 387 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 388 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 389 1.1 christos '-section_name', 'fips_sect', 390 1.1 christos '-corrupt_desc', 'KEM_Decap_Reject', 391 1.1 christos '-corrupt_type', 'KAT_KEM'])), 392 1.1 christos "fipsinstall fails when the ML-KEM decapsulate implicit failure result is corrupted"); 393 1.1 christos } 394 1.1 christos 395 1.1.1.2 christos # corrupt an Asymmetric cipher test 396 1.1.1.2 christos SKIP: { 397 1.1.1.2 christos skip "Skipping Asymmetric RSA corruption test because of no rsa in this build", 1 398 1.1.1.2 christos if disabled("rsa") || disabled("fips-post"); 399 1.1.1.2 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 400 1.1.1.2 christos '-corrupt_desc', 'RSA_Encrypt', 401 1.1.1.2 christos '-corrupt_type', 'KAT_AsymmetricCipher'])), 402 1.1.1.2 christos "fipsinstall fails when the asymmetric cipher result is corrupted"); 403 1.1.1.2 christos } 404 1.1.1.2 christos 405 1.1 christos # 'local' ensures that this change is only done in this file. 406 1.1 christos local $ENV{OPENSSL_CONF_INCLUDE} = abs2rel(curdir()); 407 1.1 christos 408 1.1 christos ok(replace_parent_line_file('fips.cnf', 'fips_parent.cnf') 409 1.1 christos && run(app(['openssl', 'fipsinstall', '-config', 'fips_parent.cnf'])), 410 1.1 christos "verify fips provider loads from a configuration file"); 411 1.1 christos 412 1.1 christos ok(replace_parent_line_file('fips_no_module_mac.cnf', 413 1.1 christos 'fips_parent_no_module_mac.cnf') 414 1.1 christos && !run(app(['openssl', 'fipsinstall', 415 1.1 christos '-config', 'fips_parent_no_module_mac.cnf'])), 416 1.1 christos "verify load config fail no module mac"); 417 1.1 christos 418 1.1 christos SKIP: { 419 1.1 christos run(test(["fips_version_test", "-config", $provconf, "<3.1.0"]), 420 1.1 christos capture => 1, statusvar => \my $exit); 421 1.1 christos skip "FIPS provider version doesn't support self test indicator", 3 422 1.1 christos if !$exit; 423 1.1 christos 424 1.1 christos ok(replace_parent_line_file('fips_no_install_mac.cnf', 425 1.1 christos 'fips_parent_no_install_mac.cnf') 426 1.1 christos && !run(app(['openssl', 'fipsinstall', 427 1.1 christos '-config', 'fips_parent_no_install_mac.cnf'])), 428 1.1 christos "verify load config fail no install mac"); 429 1.1 christos 430 1.1 christos ok(replace_parent_line_file('fips_bad_indicator.cnf', 431 1.1 christos 'fips_parent_bad_indicator.cnf') 432 1.1 christos && !run(app(['openssl', 'fipsinstall', 433 1.1 christos '-config', 'fips_parent_bad_indicator.cnf'])), 434 1.1 christos "verify load config fail bad indicator"); 435 1.1 christos 436 1.1 christos 437 1.1 christos ok(replace_parent_line_file('fips_bad_install_mac.cnf', 438 1.1 christos 'fips_parent_bad_install_mac.cnf') 439 1.1 christos && !run(app(['openssl', 'fipsinstall', 440 1.1 christos '-config', 'fips_parent_bad_install_mac.cnf'])), 441 1.1 christos "verify load config fail bad install mac"); 442 1.1 christos } 443 1.1 christos 444 1.1 christos ok(replace_parent_line_file('fips_bad_module_mac.cnf', 445 1.1 christos 'fips_parent_bad_module_mac.cnf') 446 1.1 christos && !run(app(['openssl', 'fipsinstall', 447 1.1 christos '-config', 'fips_parent_bad_module_mac.cnf'])), 448 1.1 christos "verify load config fail bad module mac"); 449 1.1 christos 450 1.1 christos SKIP: { 451 1.1 christos run(test(["fips_version_test", "-config", $provconf, "<3.1.0"]), 452 1.1 christos capture => 1, statusvar => \my $exit); 453 1.1 christos skip "FIPS provider version doesn't support self test indicator", 3 454 1.1 christos if !$exit; 455 1.1 christos 456 1.1 christos my $stconf = "fipsmodule_selftest.cnf"; 457 1.1 christos 458 1.1 christos ok(run(app(['openssl', 'fipsinstall', '-out', $stconf, 459 1.1 christos '-module', $infile, '-self_test_onload'])), 460 1.1 christos "fipsinstall config saved without self test indicator"); 461 1.1 christos 462 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-in', $stconf, 463 1.1 christos '-module', $infile, '-verify'])), 464 1.1 christos "fipsinstall config verify fails without self test indicator"); 465 1.1 christos 466 1.1 christos ok(run(app(['openssl', 'fipsinstall', '-in', $stconf, 467 1.1 christos '-module', $infile, '-self_test_onload', '-verify'])), 468 1.1 christos "fipsinstall config verify passes when self test indicator is not present"); 469 1.1 christos } 470 1.1 christos 471 1.1 christos SKIP: { 472 1.1 christos run(test(["fips_version_test", "-config", $provconf, ">=3.1.0"]), 473 1.1 christos capture => 1, statusvar => \my $exit); 474 1.1 christos skip "FIPS provider version can run self tests on install", 1 475 1.1 christos if !$exit; 476 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 477 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 478 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 479 1.1 christos '-section_name', 'fips_sect', '-self_test_oninstall', 480 1.1 christos '-ems_check'])), 481 1.1 christos "fipsinstall fails when attempting to run self tests on install"); 482 1.1 christos } 483 1.1 christos 484 1.1 christos ok(find_line_file('drbg-no-trunc-md = 0', 'fips.cnf') == 1, 485 1.1 christos 'fipsinstall defaults to not banning truncated digests with DRBGs'); 486 1.1 christos 487 1.1 christos ok(run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, 488 1.1 christos '-provider_name', 'fips', '-mac_name', 'HMAC', 489 1.1 christos '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", 490 1.1 christos '-section_name', 'fips_sect', '-no_drbg_truncated_digests'])), 491 1.1 christos "fipsinstall knows about allowing truncated digests in DRBGs"); 492 1.1 christos 493 1.1 christos ok(find_line_file('drbg-no-trunc-md = 1', 'fips.cnf') == 1, 494 1.1 christos 'fipsinstall will allow option for truncated digests with DRBGs'); 495 1.1 christos 496 1.1 christos 497 1.1 christos ok(run(app(['openssl', 'fipsinstall', '-out', 'fips-pedantic.cnf', 498 1.1 christos '-module', $infile, '-pedantic'])), 499 1.1 christos "fipsinstall accepts -pedantic option"); 500 1.1 christos 501 1.1 christos foreach my $o (@pedantic_okay) { 502 1.1 christos ok(run(app(['openssl', 'fipsinstall', '-out', "fips-${o}.cnf", 503 1.1 christos '-module', $infile, '-pedantic', "-${o}"])), 504 1.1 christos "fipsinstall accepts -${o} after -pedantic option"); 505 1.1 christos } 506 1.1 christos 507 1.1 christos foreach my $o (@pedantic_fail) { 508 1.1 christos ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', 509 1.1 christos '-module', $infile, '-pedantic', "-${o}"])), 510 1.1 christos "fipsinstall disallows -${o} after -pedantic option"); 511 1.1 christos } 512 1.1 christos 513 1.1 christos foreach my $cp (@commandline) { 514 1.1 christos my $o = $commandline[0]; 515 1.1 christos my $l = $commandline[1]; 516 1.1 christos 517 1.1 christos ok(find_line_file("${l} = 1", 'fips-pedantic.cnf') == 1, 518 1.1 christos "fipsinstall enables ${l} with -pendantic option"); 519 1.1 christos ok(find_line_file("${l} = 0", 'fips.cnf') == 1, 520 1.1 christos "fipsinstall disables ${l} without -pendantic option"); 521 1.1 christos 522 1.1 christos ok(run(app(['openssl', 'fipsinstall', '-out', "fips-${o}.cnf", 523 1.1 christos '-module', $infile, "-${o}"])), 524 1.1 christos "fipsinstall accepts -${o} option"); 525 1.1 christos ok(find_line_file("${l} = 1", "fips-${o}.cnf") == 1, 526 1.1 christos "fipsinstall enables ${l} with -${o} option"); 527 1.1 christos } 528