mirror of
https://github.com/openssl/openssl.git
synced 2025-03-25 20:00:44 +08:00
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)
This commit is contained in:
parent
7a810fac86
commit
991a6bb581
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user