summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShane Lontis <shane.lontis@oracle.com>2020-09-05 13:08:27 +1000
committerMatt Caswell <matt@openssl.org>2020-09-18 14:20:50 +0100
commit991a6bb58182d4d2077a68eb813c897b7de73462 (patch)
tree738fc724534be090323181dc445cf19e442b827c
parent7a810fac866c6c1d93015999633ee2a29f17b3d2 (diff)
downloadopenssl-new-991a6bb58182d4d2077a68eb813c897b7de73462.tar.gz
Add option to fipsinstall to disable fips security checks at run time.
Changes merged from a patch by @richsalz. Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org> (Merged from https://github.com/openssl/openssl/pull/12745)
-rw-r--r--INSTALL.md5
-rw-r--r--apps/fipsinstall.c34
-rw-r--r--doc/man1/openssl-fipsinstall.pod.in22
-rw-r--r--doc/man5/fips_config.pod36
-rw-r--r--include/openssl/core_names.h1
-rw-r--r--include/openssl/fips_names.h6
-rw-r--r--providers/common/securitycheck.c2
-rw-r--r--providers/common/securitycheck_fips.c5
-rw-r--r--providers/fips/fipsprov.c21
-rw-r--r--providers/implementations/signature/rsa.c2
-rw-r--r--test/evp_test.c40
-rw-r--r--test/recipes/30-test_evp_data/evppkey_rsa.txt2
12 files changed, 145 insertions, 31 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 01e255df7e..893049b16e 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -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.
diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c
index 832f560b5a..7b206106f3 100644
--- a/apps/fipsinstall.c
+++ b/apps/fipsinstall.c
@@ -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)
diff --git a/doc/man1/openssl-fipsinstall.pod.in b/doc/man1/openssl-fipsinstall.pod.in
index 7fb6ad5636..b57717f7da 100644
--- a/doc/man1/openssl-fipsinstall.pod.in
+++ b/doc/man1/openssl-fipsinstall.pod.in
@@ -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:
diff --git a/doc/man5/fips_config.pod b/doc/man5/fips_config.pod
index ebf6d685cc..728386544a 100644
--- a/doc/man5/fips_config.pod
+++ b/doc/man5/fips_config.pod
@@ -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
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 932dae932e..9a6cc2c03d 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -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 */
diff --git a/include/openssl/fips_names.h b/include/openssl/fips_names.h
index 7dec75fcea..b42fe503f9 100644
--- a/include/openssl/fips_names.h
+++ b/include/openssl/fips_names.h
@@ -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
diff --git a/providers/common/securitycheck.c b/providers/common/securitycheck.c
index 624843e3ab..9a425fb630 100644
--- a/providers/common/securitycheck.c
+++ b/providers/common/securitycheck.c
@@ -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;
}
diff --git a/providers/common/securitycheck_fips.c b/providers/common/securitycheck_fips.c
index f73eae9569..94457d6ccf 100644
--- a/providers/common/securitycheck_fips.c
+++ b/providers/common/securitycheck_fips.c
@@ -19,11 +19,12 @@
#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 */
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 4290a87e6e..aec262654e 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -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;
+}
diff --git a/providers/implementations/signature/rsa.c b/providers/implementations/signature/rsa.c
index 5209ac992b..f2a02a7542 100644
--- a/providers/implementations/signature/rsa.c
+++ b/providers/implementations/signature/rsa.c
@@ -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
diff --git a/test/evp_test.c b/test/evp_test.c
index 14ea4a8496..a146f4726f 100644
--- a/test/evp_test.c
+++ b/test/evp_test.c
@@ -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);
diff --git a/test/recipes/30-test_evp_data/evppkey_rsa.txt b/test/recipes/30-test_evp_data/evppkey_rsa.txt
index 15065cee77..4354bd649a 100644
--- a/test/recipes/30-test_evp_data/evppkey_rsa.txt
+++ b/test/recipes/30-test_evp_data/evppkey_rsa.txt
@@ -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.