Add "no-fips-post" configure option.

Using this option disables the OpenSSL FIPS provider
self tests.
This is intended for debugging purposes only,
as it breaks FIPS compliance.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/25063)
This commit is contained in:
slontis 2024-08-01 17:52:56 +10:00 committed by Pauli
parent ea3888a397
commit 250a7adbea
7 changed files with 143 additions and 101 deletions

View File

@ -471,6 +471,7 @@ my @disablables = (
"filenames",
"fips",
"fips-securitychecks",
"fips-post",
"fuzz-afl",
"fuzz-libfuzzer",
"gost",
@ -688,7 +689,7 @@ my @disable_cascades = (
"cmp" => [ "crmf" ],
"fips" => [ "fips-securitychecks", "acvp-tests" ],
"fips" => [ "fips-securitychecks", "fips-post", "acvp-tests" ],
"threads" => [ "thread-pool" ],
"thread-pool" => [ "default-thread-pool" ],

View File

@ -834,6 +834,13 @@ Build (and install) the FIPS provider
Don't perform FIPS module run-time checks related to enforcement of security
parameters such as minimum security strength of keys.
### no-fips-post
Don't perform FIPS module Power On Self Tests.
This option MUST be used for debugging only as it makes the FIPS provider
non-compliant. It is useful when setting breakpoints in FIPS algorithms.
### enable-fuzz-libfuzzer, enable-fuzz-afl
Build with support for fuzzing using either libfuzzer or AFL.

View File

@ -28,6 +28,12 @@
#include "crypto/context.h"
#include "internal/core.h"
#if defined(OPENSSL_NO_FIPS_POST)
# define OSSL_FIPS_PROV_NAME "OpenSSL non-compliant FIPS Provider"
#else
# define OSSL_FIPS_PROV_NAME "OpenSSL FIPS Provider"
#endif
static const char FIPS_DEFAULT_PROPERTIES[] = "provider=fips,fips=yes";
static const char FIPS_UNAPPROVED_PROPERTIES[] = "provider=fips,fips=no";
@ -311,7 +317,7 @@ static int fips_get_params(void *provctx, OSSL_PARAM params[])
OSSL_LIB_CTX_FIPS_PROV_INDEX);
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, "OpenSSL FIPS Provider"))
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OSSL_FIPS_PROV_NAME))
return 0;
p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_VERSION);
if (p != NULL && !OSSL_PARAM_set_utf8_ptr(p, OPENSSL_VERSION_STR))

View File

@ -50,9 +50,12 @@
static int FIPS_conditional_error_check = 1;
static CRYPTO_RWLOCK *self_test_lock = NULL;
static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS };
static CRYPTO_ONCE fips_self_test_init = CRYPTO_ONCE_STATIC_INIT;
#if !defined(OPENSSL_NO_FIPS_POST)
static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS };
#endif
DEFINE_RUN_ONCE_STATIC(do_fips_self_test_init)
{
/*
@ -172,6 +175,7 @@ DEP_FINI_ATTRIBUTE void cleanup(void)
}
#endif
#if !defined(OPENSSL_NO_FIPS_POST)
/*
* We need an explicit HMAC-SHA-256 KAT even though it is also
* checked as part of the KDF KATs. Refer IG 10.3.
@ -287,6 +291,7 @@ err:
EVP_MAC_free(mac);
return ret;
}
#endif /* OPENSSL_NO_FIPS_POST */
static void set_fips_state(int state)
{
@ -296,16 +301,18 @@ static void set_fips_state(int state)
/* This API is triggered either on loading of the FIPS module or on demand */
int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
{
int loclstate;
#if !defined(OPENSSL_NO_FIPS_POST)
int ok = 0;
int kats_already_passed = 0;
long checksum_len;
OSSL_CORE_BIO *bio_module = NULL, *bio_indicator = NULL;
unsigned char *module_checksum = NULL;
unsigned char *indicator_checksum = NULL;
int loclstate;
OSSL_SELF_TEST *ev = NULL;
EVP_RAND *testrand = NULL;
EVP_RAND_CTX *rng;
#endif
if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
return 0;
@ -322,6 +329,8 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
if (!CRYPTO_THREAD_write_lock(self_test_lock))
return 0;
#if !defined(OPENSSL_NO_FIPS_POST)
loclstate = tsan_load(&FIPS_state);
if (loclstate == FIPS_STATE_RUNNING) {
if (!on_demand_test) {
@ -434,6 +443,11 @@ end:
CRYPTO_THREAD_unlock(self_test_lock);
return ok;
#else
set_fips_state(FIPS_STATE_RUNNING);
CRYPTO_THREAD_unlock(self_test_lock);
return 1;
#endif /* !defined(OPENSSL_NO_FIPS_POST) */
}
void SELF_TEST_disable_conditional_error_state(void)

View File

@ -134,114 +134,128 @@ ok(run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify");
ok(replace_line_file('module-mac', '', 'fips_no_module_mac.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_no_module_mac.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail no module mac");
# Skip Tests if POST is disabled
SKIP: {
skip "Skipping POST checks", 13
if disabled("fips-post");
ok(replace_line_file('install-mac', '', 'fips_no_install_mac.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_no_install_mac.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail no install indicator mac");
ok(replace_line_file('module-mac', '', 'fips_no_module_mac.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_no_module_mac.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail no module mac");
ok(replace_line_file('module-mac', '00:00:00:00:00:00',
'fips_bad_module_mac.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_bad_module_mac.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail if invalid module integrity value");
ok(replace_line_file('install-mac', '', 'fips_no_install_mac.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_no_install_mac.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail no install indicator mac");
ok(replace_line_file('install-mac', '00:00:00:00:00:00',
'fips_bad_install_mac.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_bad_install_mac.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail if invalid install indicator integrity value");
ok(replace_line_file('module-mac', '00:00:00:00:00:00',
'fips_bad_module_mac.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_bad_module_mac.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail if invalid module integrity value");
ok(replace_line_file('install-status', 'INCORRECT_STATUS_STRING',
'fips_bad_indicator.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_bad_indicator.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail if invalid install indicator status");
ok(replace_line_file('install-mac', '00:00:00:00:00:00',
'fips_bad_install_mac.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_bad_install_mac.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail if invalid install indicator integrity value");
# fail to verify the fips.cnf file if a different key is used
ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail bad key");
ok(replace_line_file('install-status', 'INCORRECT_STATUS_STRING',
'fips_bad_indicator.cnf')
&& !run(app(['openssl', 'fipsinstall',
'-in', 'fips_bad_indicator.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail if invalid install indicator status");
# fail to verify the fips.cnf file if a different mac digest is used
ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA512', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail incorrect digest");
# fail to verify the fips.cnf file if a different key is used
ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:01",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail bad key");
# corrupt the module hmac
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'HMAC'])),
"fipsinstall fails when the module integrity is corrupted");
# fail to verify the fips.cnf file if a different mac digest is used
ok(!run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA512', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-verify'])),
"fipsinstall verify fail incorrect digest");
# corrupt the first digest
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'SHA1'])),
"fipsinstall fails when the digest result is corrupted");
# corrupt the module hmac
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'HMAC'])),
"fipsinstall fails when the module integrity is corrupted");
# corrupt another digest
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'SHA3'])),
"fipsinstall fails when the digest result is corrupted");
# corrupt the first digest
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'SHA1'])),
"fipsinstall fails when the digest result is corrupted");
# corrupt cipher encrypt test
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'AES_GCM'])),
"fipsinstall fails when the AES_GCM result is corrupted");
# corrupt another digest
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'SHA3'])),
"fipsinstall fails when the digest result is corrupted");
# corrupt cipher decrypt test
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'AES_ECB_Decrypt'])),
"fipsinstall fails when the AES_ECB result is corrupted");
# corrupt cipher encrypt test
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'AES_GCM'])),
"fipsinstall fails when the AES_GCM result is corrupted");
# corrupt DRBG
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'CTR'])),
"fipsinstall fails when the DRBG CTR result is corrupted");
# corrupt cipher decrypt test
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'AES_ECB_Decrypt'])),
"fipsinstall fails when the AES_ECB result is corrupted");
# corrupt DRBG
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips_fail.cnf',
'-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
'-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey",
'-section_name', 'fips_sect', '-corrupt_desc', 'CTR'])),
"fipsinstall fails when the DRBG CTR result is corrupted");
}
# corrupt a KAS test
SKIP: {
skip "Skipping KAS DH corruption test because of no dh in this build", 1
if disabled("dh");
if disabled("dh") || disabled("fips-post");
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
'-provider_name', 'fips', '-mac_name', 'HMAC',
@ -255,7 +269,7 @@ SKIP: {
# corrupt a Signature test - 140-3 requires a known answer test
SKIP: {
skip "Skipping Signature DSA corruption test because of no dsa in this build", 1
if disabled("dsa");
if disabled("dsa") || disabled("fips-post");
run(test(["fips_version_test", "-config", $provconf, ">=3.1.0"]),
capture => 1, statusvar => \my $exit);
@ -273,7 +287,7 @@ SKIP: {
# corrupt a Signature test - 140-2 allows a pairwise consistency test
SKIP: {
skip "Skipping Signature DSA corruption test because of no dsa in this build", 1
if disabled("dsa");
if disabled("dsa") || disabled("fips-post");
run(test(["fips_version_test", "-config", $provconf, "<3.1.0"]),
capture => 1, statusvar => \my $exit);
@ -291,7 +305,7 @@ SKIP: {
# corrupt an Asymmetric cipher test
SKIP: {
skip "Skipping Asymmetric RSA corruption test because of no rsa in this build", 1
if disabled("rsa");
if disabled("rsa") || disabled("fips-post");
ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile,
'-corrupt_desc', 'RSA_Encrypt',
'-corrupt_type', 'KAT_AsymmetricCipher'])),

View File

@ -24,7 +24,7 @@ use lib bldtop_dir('.');
plan skip_all => "Configuration loading is turned off"
if disabled("autoload-config");
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
my $no_fips = disabled('fips') || disabled('fips-post') || ($ENV{NO_FIPS} // 0);
plan tests =>
($no_fips ? 1 : 5);

View File

@ -20,7 +20,7 @@ setup("test_provider_status");
use lib srctop_dir('Configurations');
use lib bldtop_dir('.');
my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
my $no_fips = disabled('fips') || disabled('fips-post') || ($ENV{NO_FIPS} // 0);
plan tests => 5;