Skip to content

Commit

Permalink
Add "no-fips-post" configure option.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Reviewed-by: Paul Dale <[email protected]>
(Merged from openssl#25063)
  • Loading branch information
slontis authored and paulidale committed Aug 8, 2024
1 parent ea3888a commit 250a7ad
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 108 deletions.
3 changes: 2 additions & 1 deletion Configure
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ my @disablables = (
"filenames",
"fips",
"fips-securitychecks",
"fips-post",
"fuzz-afl",
"fuzz-libfuzzer",
"gost",
Expand Down Expand Up @@ -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" ],
Expand Down
7 changes: 7 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 7 additions & 1 deletion providers/fips/fipsprov.c
Original file line number Diff line number Diff line change
Expand Up @@ -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";

Expand Down Expand Up @@ -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))
Expand Down
18 changes: 16 additions & 2 deletions providers/fips/self_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
/*
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -287,6 +291,7 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex
EVP_MAC_free(mac);
return ret;
}
#endif /* OPENSSL_NO_FIPS_POST */

static void set_fips_state(int state)
{
Expand All @@ -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;
Expand All @@ -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) {
Expand Down Expand Up @@ -434,6 +443,11 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
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)
Expand Down
218 changes: 116 additions & 102 deletions test/recipes/03-test_fipsinstall.t
Original file line number Diff line number Diff line change
Expand Up @@ -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");

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', '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', '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('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 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");

# 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 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");
# Skip Tests if POST is disabled
SKIP: {
skip "Skipping POST checks", 13
if disabled("fips-post");

# 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");
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('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', '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', '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('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 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");

# 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 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 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 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 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 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 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 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 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 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',
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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'])),
Expand Down
2 changes: 1 addition & 1 deletion test/recipes/30-test_defltfips.t
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion test/recipes/30-test_provider_status.t
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down

0 comments on commit 250a7ad

Please sign in to comment.