]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add option to fipsinstall to disable fips security checks at run time.
authorShane Lontis <shane.lontis@oracle.com>
Sat, 5 Sep 2020 03:08:27 +0000 (13:08 +1000)
committerMatt Caswell <matt@openssl.org>
Fri, 18 Sep 2020 13:20:50 +0000 (14:20 +0100)
Changes merged from a patch by @richsalz.

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/12745)

12 files changed:
INSTALL.md
apps/fipsinstall.c
doc/man1/openssl-fipsinstall.pod.in
doc/man5/fips_config.pod
include/openssl/core_names.h
include/openssl/fips_names.h
providers/common/securitycheck.c
providers/common/securitycheck_fips.c
providers/fips/fipsprov.c
providers/implementations/signature/rsa.c
test/evp_test.c
test/recipes/30-test_evp_data/evppkey_rsa.txt

index 01e255df7e2d3db6c9d0afb849ac2684cec69abf..893049b16e053df560e5595d1a3ed3472ddac312 100644 (file)
@@ -695,6 +695,11 @@ memory allocation).
 
 Don't compile the FIPS provider
 
+### no-fips-securitychecks
+
+Don't perform FIPS module run-time checks related to enforcement of security
+parameters such as minimum security strength of keys.
+
 ### enable-fuzz-libfuzzer, enable-fuzz-afl
 
 Build with support for fuzzing using either libfuzzer or AFL.
index 832f560b5a1867b33b240c3f6e82ed79810053c8..7b206106f3e2d00f409bfd98d90ffbda40b5f6bc 100644 (file)
@@ -37,7 +37,8 @@ typedef enum OPTION_choice {
     OPT_IN, OPT_OUT, OPT_MODULE,
     OPT_PROV_NAME, OPT_SECTION_NAME, OPT_MAC_NAME, OPT_MACOPT, OPT_VERIFY,
     OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG,
-    OPT_NO_CONDITIONAL_ERRORS
+    OPT_NO_CONDITIONAL_ERRORS,
+    OPT_NO_SECURITY_CHECKS
 } OPTION_CHOICE;
 
 const OPTIONS fipsinstall_options[] = {
@@ -52,6 +53,8 @@ const OPTIONS fipsinstall_options[] = {
      {"no_conditional_errors", OPT_NO_CONDITIONAL_ERRORS, '-',
       "Disable the ability of the fips module to enter an error state if"
       " any conditional self tests fail"},
+    {"no_security_checks", OPT_NO_SECURITY_CHECKS, '-',
+     "Disable the run-time FIPS security checks in the module"},
     OPT_SECTION("Input"),
     {"in", OPT_IN, '<', "Input config file, used when verifying"},
 
@@ -133,8 +136,8 @@ static int write_config_header(BIO *out, const char *prov_name,
 
 /*
  * Outputs a fips related config file that contains entries for the fips
- * module checksum, installation indicator checksum and the option
- * conditional_errors.
+ * module checksum, installation indicator checksum and the options
+ * conditional_errors and security_checks.
  *
  * Returns 1 if the config file is written otherwise it returns 0 on error.
  */
@@ -142,6 +145,7 @@ static int write_config_fips_section(BIO *out, const char *section,
                                      unsigned char *module_mac,
                                      size_t module_mac_len,
                                      int conditional_errors,
+                                     int security_checks,
                                      unsigned char *install_mac,
                                      size_t install_mac_len)
 {
@@ -153,16 +157,17 @@ static int write_config_fips_section(BIO *out, const char *section,
                       VERSION_VAL) <= 0
         || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS,
                       conditional_errors ? "1" : "0") <= 0
+        || BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS,
+                      security_checks ? "1" : "0") <= 0
         || !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
                       module_mac_len))
         goto end;
 
     if (install_mac != NULL) {
-        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,
-                            INSTALL_STATUS_VAL) > 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,
+                          INSTALL_STATUS_VAL) <= 0)
         goto end;
     }
     ret = 1;
@@ -174,7 +179,8 @@ static CONF *generate_config_and_load(const char *prov_name,
                                       const char *section,
                                       unsigned char *module_mac,
                                       size_t module_mac_len,
-                                      int conditional_errors)
+                                      int conditional_errors,
+                                      int security_checks)
 {
     BIO *mem_bio = NULL;
     CONF *conf = NULL;
@@ -186,6 +192,7 @@ static CONF *generate_config_and_load(const char *prov_name,
          || !write_config_fips_section(mem_bio, section,
                                        module_mac, module_mac_len,
                                        conditional_errors,
+                                       security_checks,
                                        NULL, 0))
         goto end;
 
@@ -280,7 +287,7 @@ end:
 int fipsinstall_main(int argc, char **argv)
 {
     int ret = 1, verify = 0, gotkey = 0, gotdigest = 0;
-    int enable_conditional_errors = 1;
+    int enable_conditional_errors = 1, enable_security_checks = 1;
     const char *section_name = "fips_sect";
     const char *mac_name = "HMAC";
     const char *prov_name = "fips";
@@ -323,6 +330,9 @@ opthelp:
         case OPT_NO_CONDITIONAL_ERRORS:
             enable_conditional_errors = 0;
             break;
+        case OPT_NO_SECURITY_CHECKS:
+            enable_security_checks = 0;
+            break;
         case OPT_QUIET:
             quiet = 1;
             /* FALLTHROUGH */
@@ -470,7 +480,8 @@ opthelp:
 
         conf = generate_config_and_load(prov_name, section_name, module_mac,
                                         module_mac_len,
-                                        enable_conditional_errors);
+                                        enable_conditional_errors,
+                                        enable_security_checks);
         if (conf == NULL)
             goto end;
         if (!load_fips_prov_and_run_self_test(prov_name))
@@ -484,6 +495,7 @@ opthelp:
         if (!write_config_fips_section(fout, section_name,
                                        module_mac, module_mac_len,
                                        enable_conditional_errors,
+                                       enable_security_checks,
                                        install_mac, install_mac_len))
             goto end;
         if (!quiet)
index 7fb6ad5636659f9c7647971127e7cff4c78f7f0e..b57717f7da4f3a7fe56809966f58fab8a2e7fb61 100644 (file)
@@ -20,6 +20,7 @@ B<openssl fipsinstall>
 [B<-noout>]
 [B<-quiet>]
 [B<-no_conditional_errors>]
+[B<-no_security_checks>]
 [B<-corrupt_desc> I<selftest_description>]
 [B<-corrupt_type> I<selftest_type>]
 [B<-config> I<parent_config>]
@@ -55,6 +56,14 @@ Regardless of whether the error state is entered or not, the current operation
 (e.g. key generation) will return an error. The user is responsible for retrying
 the operation if the module error state is not entered.
 
+=item - A control to indicate whether run-time security checks are done.
+
+This indicates if run-time checks related to enforcement of security parameters
+such as minimum security strength of keys and approved curve names are used.
+The default value of '1' will perform the checks.
+If the value is '0' the checks are not performed and FIPS compliance must
+be done by procedures documented in the relevant Security Policy.
+
 =back
 
 This file is described in L<fips_config(5)>.
@@ -150,6 +159,9 @@ Disable logging of the self tests.
 Configure the module to not enter an error state if a conditional self test
 fails as described above.
 
+=item B<-no_security_checks>
+
+Configure the module to not perform run-time security checks as described above.
 
 =item B<-quiet>
 
@@ -179,21 +191,15 @@ All other options are ignored if '-config' is used.
 Calculate the mac of a FIPS module F<fips.so> and run a FIPS self test
 for the module, and save the F<fips.cnf> configuration file:
 
- openssl fipsinstall -module ./fips.so -out fips.cnf -provider_name fips \
-         -section_name fipsinstall -mac_name HMAC -macopt digest:SHA256 \
-         -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213
+ openssl fipsinstall -module ./fips.so -out fips.cnf -provider_name fips
 
 Verify that the configuration file F<fips.cnf> contains the correct info:
 
- openssl fipsinstall -module ./fips.so -in fips.cnf  -provider_name fips \
-          -section_name fips_install -mac_name HMAC -macopt digest:SHA256 \
-          -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 -verify
+ openssl fipsinstall -module ./fips.so -in fips.cnf  -provider_name fips -verify
 
 Corrupt any self tests which have the description C<SHA1>:
 
  openssl fipsinstall -module ./fips.so -out fips.cnf -provider_name fips \
-         -section_name fipsinstall -mac_name HMAC -macopt digest:SHA256 \
-         -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 \
          -corrupt_desc 'SHA1'
 
 Validate that the fips module can be loaded from a base configuration file:
index ebf6d685cce08ae0924aad954cae469c8e247b46..728386544a3b2dc4f5a24600c1f2347ad41182bf 100644 (file)
@@ -33,17 +33,43 @@ section, as described in L<config(5)/Provider Configuration Module>.
 
 =over 4
 
-=item B<module-mac>
+=item B<activate>
 
-The calculated MAC of the FIPS provider file.
+If present, the module is activated. The value assigned to this name is not
+significant.
 
 =item B<install-version>
 
 A version number for the fips install process. Should be 1.
 
+=item B<conditional-errors>
+
+The FIPS module normally enters an internal error mode if any self test fails.
+Once this error mode is active, no services or cryptographic algorithms are
+accessible from this point on.
+Continuous tests are a subset of the self tests (e.g., a key pair test during key
+generation, or the CRNG output test).
+Setting this value to C<0> allows the error mode to not be triggered if any
+continuous test fails. The default value of C<1> will trigger the error mode.
+Regardless of the value, the operation (e.g., key generation) that called the
+continuous test will return an error code if its continuous test fails. The
+operation may then be retried if the error mode has not been triggered.
+
+=item B<security-checks>
+
+This indicates if run-time checks related to enforcement of security parameters
+such as minimum security strength of keys and approved curve names are used.
+A value of '1' will perform the checks, otherwise if the value is '0' the checks
+are not performed and FIPS compliance must be done by procedures documented in
+the relevant Security Policy.
+
+=item B<module-mac>
+
+The calculated MAC of the FIPS provider file.
+
 =item B<install-status>
 
-An indicator that the self-tests were run.
+An indicator that the self-tests were successfully run.
 This should only be written after the module has
 successfully passed its self tests during installation.
 If this field is not present, then the self tests will run when the module
@@ -60,7 +86,10 @@ It is written-to at the same time as B<install-status> is updated.
 For example:
 
  [fips_sect]
+ activate = 1
  install-version = 1
+ conditional-errors = 1
+ security-checks = 1
  module-mac = 41:D0:FA:C2:5D:41:75:CD:7D:C3:90:55:6F:A4:DC
  install-mac = FE:10:13:5A:D3:B4:C7:82:1B:1E:17:4C:AC:84:0C
  install-status = INSTALL_SELF_TEST_KATS_RUN
@@ -68,6 +97,7 @@ For example:
 =head1 SEE ALSO
 
 L<config(5)>
+L<openssl-fipsinstall(1)>
 
 =head1 COPYRIGHT
 
index 932dae932e83ebed21136fea2e13deb62daabd15..9a6cc2c03dd4341c38968f6b3aedee56b5d7742c 100644 (file)
@@ -24,6 +24,7 @@ extern "C" {
 #define OSSL_PROV_PARAM_VERSION         "version"             /* utf8_string */
 #define OSSL_PROV_PARAM_BUILDINFO       "buildinfo"           /* utf8_string */
 #define OSSL_PROV_PARAM_STATUS          "status"              /* uint */
+#define OSSL_PROV_PARAM_SECURITY_CHECKS "security-checks"     /* uint */
 
 /* Self test callback parameters */
 #define OSSL_PROV_PARAM_SELF_TEST_PHASE  "st-phase" /* utf8_string */
index 7dec75fcea83df9be54b63fa34b62f45c9ce9303..b42fe503f9c6826425b353f7ffcb9aa2c320520f 100644 (file)
@@ -46,6 +46,12 @@ extern "C" {
  */
 # define OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS "conditional-errors"
 
+/*
+ * A boolean that determines if the runtime FIPS security checks are performed.
+ * Type: OSSL_PARAM_UTF8_STRING
+ */
+# define OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS "security-checks"
+
 # ifdef __cplusplus
 }
 # endif
index 624843e3ab31e065d39ec0de6f9978f982f1e26b..9a425fb630a516e0bca5a1caa2fc761f06933727 100644 (file)
@@ -203,7 +203,7 @@ int digest_is_allowed(const EVP_MD *md)
 {
 # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
     if (securitycheck_enabled())
-        return (digest_get_approved_nid(md) != NID_undef);
+        return digest_get_approved_nid(md) != NID_undef;
 # endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
     return 1;
 }
index f73eae95699191d3e4910dbe2ea7ae6988f4bd8d..94457d6ccf1c391bbdbaf31bda116acf92292d64 100644 (file)
 #include "prov/securitycheck.h"
 #include "prov/providercommonerr.h"
 
+extern int FIPS_security_check_enabled(void);
+
 int securitycheck_enabled(void)
 {
 #if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
-    /* TODO(3.0): make this configurable */
-    return 1;
+    return FIPS_security_check_enabled();
 #else
     return 0;
 #endif /* OPENSSL_NO_FIPS_SECURITYCHECKS */
index 4290a87e6e67b1f37fdd0fb5873016bff12702ed..aec262654eb628bc903de7344e1e6441fcc554ca 100644 (file)
@@ -37,6 +37,7 @@ static OSSL_FUNC_provider_query_operation_fn fips_query;
 #define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL)
 
 extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
+int FIPS_security_check_enabled(void);
 
 /*
  * TODO(3.0): Should these be stored in the provider side provctx? Could they
@@ -46,6 +47,8 @@ extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
  */
 
 static SELF_TEST_POST_PARAMS selftest_params;
+static int fips_security_checks = 1;
+static const char *fips_security_check_option = "1";
 
 /* Functions provided by the core */
 static OSSL_FUNC_core_gettable_params_fn *c_gettable_params;
@@ -100,6 +103,7 @@ static const OSSL_PARAM fips_param_types[] = {
     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_VERSION, OSSL_PARAM_UTF8_PTR, NULL, 0),
     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_BUILDINFO, OSSL_PARAM_UTF8_PTR, NULL, 0),
     OSSL_PARAM_DEFN(OSSL_PROV_PARAM_STATUS, OSSL_PARAM_INTEGER, NULL, 0),
+    OSSL_PARAM_DEFN(OSSL_PROV_PARAM_SECURITY_CHECKS, OSSL_PARAM_INTEGER, NULL, 0),
     OSSL_PARAM_END
 };
 
@@ -108,6 +112,7 @@ static const OSSL_PARAM fips_param_types[] = {
  * NOTE: inside core_get_params() these will be loaded from config items
  * stored inside prov->parameters (except for
  * OSSL_PROV_PARAM_CORE_MODULE_FILENAME).
+ * OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS is not a self test parameter.
  */
 static OSSL_PARAM core_params[] =
 {
@@ -129,6 +134,9 @@ static OSSL_PARAM core_params[] =
     OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS,
                         selftest_params.conditional_error_check,
                         sizeof(selftest_params.conditional_error_check)),
+    OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_SECURITY_CHECKS,
+                        fips_security_check_option,
+                        sizeof(fips_security_check_option)),
     OSSL_PARAM_END
 };
 
@@ -153,6 +161,9 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
     p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS);
     if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running()))
         return 0;
+    p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_SECURITY_CHECKS);
+    if (p != NULL && !OSSL_PARAM_set_int(p, fips_security_checks))
+        return 0;
     return 1;
 }
 
@@ -653,6 +664,11 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
         && strcmp(selftest_params.conditional_error_check, "0") == 0)
         SELF_TEST_disable_conditional_error_state();
 
+    /* Disable the security check if is disabled in the fips config file*/
+    if (fips_security_check_option != NULL
+        && strcmp(fips_security_check_option, "0") == 0)
+        fips_security_checks = 0;
+
     /*  Create a context. */
     if ((*provctx = PROV_CTX_new()) == NULL
         || (libctx = OPENSSL_CTX_new()) == NULL) {
@@ -858,3 +874,8 @@ int BIO_snprintf(char *buf, size_t n, const char *format, ...)
     va_end(args);
     return ret;
 }
+
+int FIPS_security_check_enabled(void)
+{
+    return fips_security_checks;
+}
index 5209ac992b200c3bac4285b0a916956a283ee44f..f2a02a75421a4bb1ad2ec625c573acd85a9394a3 100644 (file)
@@ -1244,7 +1244,7 @@ static const OSSL_PARAM known_settable_ctx_params[] = {
     OSSL_PARAM_END
 };
 
-static const OSSL_PARAM *rsa_settable_ctx_params(void *provctx)
+static const OSSL_PARAM *rsa_settable_ctx_params(ossl_unused void *provctx)
 {
     /*
      * TODO(3.0): Should this function return a different set of settable ctx
index 14ea4a84966d2f912d9b021dfdb05ff4eac6fee9..a146f4726f9040bad951afabe0f7a44b5374d99c 100644 (file)
@@ -21,6 +21,7 @@
 #include <openssl/kdf.h>
 #include <openssl/params.h>
 #include <openssl/core_names.h>
+#include <openssl/fips_names.h>
 #include "internal/numbers.h"
 #include "internal/nelem.h"
 #include "crypto/evp.h"
@@ -3286,6 +3287,33 @@ static char *take_value(PAIR *pp)
     return p;
 }
 
+static int securitycheck_enabled(void)
+{
+    static int enabled = -1;
+
+    if (enabled == -1) {
+        if (OSSL_PROVIDER_available(libctx, "fips")) {
+            OSSL_PARAM params[2];
+            OSSL_PROVIDER *prov = NULL;
+            int check = 1;
+
+            prov = OSSL_PROVIDER_load(libctx, "fips");
+            if (prov != NULL) {
+                params[0] =
+                    OSSL_PARAM_construct_int(OSSL_PROV_PARAM_SECURITY_CHECKS,
+                                             &check);
+                params[1] = OSSL_PARAM_construct_end();
+                OSSL_PROVIDER_get_params(prov, params);
+                OSSL_PROVIDER_unload(prov);
+            }
+            enabled = check;
+            return enabled;
+        }
+        enabled = 0;
+    }
+    return enabled;
+}
+
 /*
  * Return 1 if one of the providers named in the string is available.
  * The provider names are separated with whitespace.
@@ -3445,11 +3473,15 @@ start:
     for (pp++, i = 1; i < (t->s.numpairs - skip_availablein); pp++, i++) {
         if (strcmp(pp->key, "Securitycheck") == 0) {
 #if defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
-            TEST_info("skipping, securitycheck is not available: %s:%d",
-                      t->s.test_file, t->s.start);
-            t->skip = 1;
-            return 0;
+#else
+            if (!securitycheck_enabled())
 #endif
+            {
+                TEST_info("skipping, Securitycheck is disabled: %s:%d",
+                          t->s.test_file, t->s.start);
+                t->skip = 1;
+                return 0;
+            }
         } else if (strcmp(pp->key, "Availablein") == 0) {
             TEST_info("Line %d: 'Availablein' should be the first option",
                       t->s.curr);
index 15065cee77981131f940f23abcf2230bccf6e8e9..4354bd649a9288d68a23b54533801e0a63b0c646 100644 (file)
@@ -14,7 +14,7 @@
 
 # Private keys used for PKEY operations.
 
-# Any Tests that keys <2048 bits OR sign with SHA1 are in this file.
+# Any Tests that have keys < 2048 bits OR sign with SHA1 are in this file.
 
 # RSA 2048 bit key.