]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
fipsinstall: Save the 'status indicator' if the FIPS provider is 3.0.X.
authorslontis <shane.lontis@oracle.com>
Tue, 27 Feb 2024 04:57:14 +0000 (15:57 +1100)
committerTomas Mraz <tomas@openssl.org>
Fri, 11 Oct 2024 12:52:37 +0000 (14:52 +0200)
Fixes #23400

The 3.1 FIPS provider no longer writes out the 'status indicator' by
default due to changes related to FIPS 140-3 requirements. For Backwards
compatability if the fipsinstall detects it is loading a 3.0.X FIPS
provider then it will save the 'status indicator' by default.

Disclaimer: Using a fipsinstall command line utility that is not supplied
with the FIPS provider tarball source is not recommended.

This PR deliberately does not attempt to exclude any additional options
that were added after 3.0.X. These additional options will be ignored by older
providers.

Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Hugo Landau <hlandau@devever.net>
(Merged from https://github.com/openssl/openssl/pull/23689)

apps/fipsinstall.c
doc/man1/openssl-fipsinstall.pod.in
test/recipes/03-test_fipsinstall.t

index 203f397a481dac8bd9377834c7bd5be7012ef45a..0daa55a1b8aefddfe88d4d2690f573b31f815d81 100644 (file)
@@ -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))
index 165179395b85bf362bb730ce0b1f921217c2b1d6..9dd4f5a49ffe181534ec02be2ec5e8b60decbc7b 100644 (file)
@@ -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>
 
index 4965b9e63dbbd26f5703ce17ff7eadf8e39f98b1..07c5d6cd70b2d3025294c3b44f67c95a967e5f0e 100644 (file)
@@ -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");
 }
-