diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c index 203f397a48..0daa55a1b8 100644 --- a/apps/fipsinstall.c +++ b/apps/fipsinstall.c @@ -284,7 +284,8 @@ err: return ret; } -static int load_fips_prov_and_run_self_test(const char *prov_name) +static int load_fips_prov_and_run_self_test(const char *prov_name, + int *is_fips_140_2_prov) { int ret = 0; OSSL_PROVIDER *prov = NULL; @@ -314,7 +315,16 @@ static int load_fips_prov_and_run_self_test(const char *prov_name) BIO_printf(bio_err, "\t%-10s\t%s\n", "version:", vers); if (OSSL_PARAM_modified(params + 2)) BIO_printf(bio_err, "\t%-10s\t%s\n", "build:", build); + } else { + *p++ = OSSL_PARAM_construct_utf8_ptr(OSSL_PROV_PARAM_VERSION, + &vers, sizeof(vers)); + *p = OSSL_PARAM_construct_end(); + if (!OSSL_PROVIDER_get_params(prov, params)) { + BIO_printf(bio_err, "Failed to query FIPS module parameters\n"); + goto end; + } } + *is_fips_140_2_prov = (strncmp("3.0.", vers, 4) == 0); ret = 1; end: OSSL_PROVIDER_unload(prov); @@ -436,7 +446,9 @@ static int write_config_fips_section(BIO *out, const char *section, module_mac_len)) goto end; - if (install_mac != NULL && install_mac_len > 0) { + if (install_mac != NULL + && install_mac_len > 0 + && opts->self_test_onload == 0) { if (!print_mac(out, OSSL_PROV_FIPS_PARAM_INSTALL_MAC, install_mac, install_mac_len) || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_STATUS, @@ -559,6 +571,7 @@ end: int fipsinstall_main(int argc, char **argv) { int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, pedantic = 0; + int is_fips_140_2_prov = 0, set_selftest_onload_option = 0; const char *section_name = "fips_sect"; const char *mac_name = "HMAC"; const char *prov_name = "fips"; @@ -734,11 +747,13 @@ int fipsinstall_main(int argc, char **argv) verify = 1; break; case OPT_SELF_TEST_ONLOAD: + set_selftest_onload_option = 1; fips_opts.self_test_onload = 1; break; case OPT_SELF_TEST_ONINSTALL: if (!check_non_pedantic_fips(pedantic, "self_test_oninstall")) goto end; + set_selftest_onload_option = 1; fips_opts.self_test_onload = 0; break; } @@ -836,34 +851,43 @@ int fipsinstall_main(int argc, char **argv) if (!do_mac(ctx, read_buffer, module_bio, module_mac, &module_mac_len)) goto end; - if (fips_opts.self_test_onload == 0) { - mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL, - strlen(INSTALL_STATUS_VAL)); - if (mem_bio == NULL) { - BIO_printf(bio_err, "Unable to create memory BIO\n"); - goto end; - } - if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len)) - goto end; - } else { - install_mac_len = 0; + /* Calculate the MAC for the indicator status - it may not be used */ + mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL, + strlen(INSTALL_STATUS_VAL)); + if (mem_bio == NULL) { + BIO_printf(bio_err, "Unable to create memory BIO\n"); + goto end; } + if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len)) + goto end; if (verify) { + if (fips_opts.self_test_onload == 1) + install_mac_len = 0; if (!verify_config(in_fname, section_name, module_mac, module_mac_len, install_mac, install_mac_len)) goto end; if (!quiet) BIO_printf(bio_err, "VERIFY PASSED\n"); } else { - conf = generate_config_and_load(prov_name, section_name, module_mac, module_mac_len, &fips_opts); if (conf == NULL) goto end; - if (!load_fips_prov_and_run_self_test(prov_name)) + if (!load_fips_prov_and_run_self_test(prov_name, &is_fips_140_2_prov)) goto end; + /* + * In OpenSSL 3.1 the code was changed so that the status indicator is + * not written out by default since this is a FIPS 140-3 requirement. + * For backwards compatibility - if the detected FIPS provider is 3.0.X + * (Which was a FIPS 140-2 validation), then the indicator status will + * be written to the config file unless 'self_test_onload' is set on the + * command line. + */ + if (set_selftest_onload_option == 0 && is_fips_140_2_prov) + fips_opts.self_test_onload = 0; + fout = out_fname == NULL ? dup_bio_out(FORMAT_TEXT) : bio_open_default(out_fname, 'w', FORMAT_TEXT); @@ -871,6 +895,7 @@ int fipsinstall_main(int argc, char **argv) BIO_printf(bio_err, "Failed to open file\n"); goto end; } + if (!write_config_fips_section(fout, section_name, module_mac, module_mac_len, &fips_opts, install_mac, install_mac_len)) diff --git a/doc/man1/openssl-fipsinstall.pod.in b/doc/man1/openssl-fipsinstall.pod.in index 165179395b..9dd4f5a49f 100644 --- a/doc/man1/openssl-fipsinstall.pod.in +++ b/doc/man1/openssl-fipsinstall.pod.in @@ -367,14 +367,17 @@ used for cross compiling, since the self tests need to run at least once on each target machine. Once the self tests have run on the target machine the user could possibly then add the 2 fields into the configuration using some other mechanism. - -This is the default. +This option defaults to 0 for any OpenSSL FIPS 140-2 provider (OpenSSL 3.0.X). +and is not relevant for an OpenSSL FIPS 140-3 provider, since this is no +longer allowed. =item B<-self_test_oninstall> The converse of B<-self_test_oninstall>. The two fields related to the "test status indicator" and "MAC status indicator" are written to the output configuration file. +This field is not relevant for an OpenSSL FIPS 140-3 provider, since this is no +longer allowed. =item B<-quiet> diff --git a/test/recipes/03-test_fipsinstall.t b/test/recipes/03-test_fipsinstall.t index 4965b9e63d..07c5d6cd70 100644 --- a/test/recipes/03-test_fipsinstall.t +++ b/test/recipes/03-test_fipsinstall.t @@ -63,7 +63,7 @@ my @commandline = ( 'x942kdf_key_check', 'x942kdf-key-check' ) ); -plan tests => 35 + (scalar @pedantic_okay) + (scalar @pedantic_fail) +plan tests => 37 + (scalar @pedantic_okay) + (scalar @pedantic_fail) + 4 * (scalar @commandline); my $infile = bldtop_file('providers', platform->dso('fips')); @@ -150,7 +150,6 @@ ok(!run(app(['openssl', 'fipsinstall', '-in', 'dummy.tmp', '-module', $infile, '-section_name', 'fips_sect', '-verify'])), "fipsinstall verify fail"); - # output a fips.cnf file containing mac data ok(run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, '-provider_name', 'fips', '-mac_name', 'HMAC', @@ -165,6 +164,23 @@ ok(run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile, '-section_name', 'fips_sect', '-verify'])), "fipsinstall verify"); +# Test that default options for fipsinstall output the 'install-status' for +# FIPS 140-2 providers. +SKIP: { + run(test(["fips_version_test", "-config", $provconf, "<3.1.0"]), + capture => 1, statusvar => \my $exit); + + skip "Skipping FIPS 140-3 provider", 2 + if !$exit; + + ok(find_line_file('install-mac = ', 'fips.cnf') == 1, + 'FIPS 140-2 should output install-mac'); + + ok(find_line_file('install-status = INSTALL_SELF_TEST_KATS_RUN', + 'fips.cnf') == 1, + 'FIPS 140-2 should output install-status'); +} + # Skip Tests if POST is disabled SKIP: { skip "Skipping POST checks", 13 @@ -466,4 +482,3 @@ foreach my $cp (@commandline) { ok(find_line_file("${l} = 1", "fips-${o}.cnf") == 1, "fipsinstall enables ${l} with -${o} option"); } -