diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c index c8687bec8f..bd1cd68477 100644 --- a/apps/fipsinstall.c +++ b/apps/fipsinstall.c @@ -38,7 +38,7 @@ typedef enum OPTION_choice { OPT_ERR = -1, OPT_EOF = 0, OPT_HELP, 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_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG } OPTION_CHOICE; const OPTIONS fipsinstall_options[] = { @@ -62,6 +62,7 @@ const OPTIONS fipsinstall_options[] = { {"noout", OPT_NO_LOG, '-', "Disable logging of self test events"}, {"corrupt_desc", OPT_CORRUPT_DESC, 's', "Corrupt a self test by description"}, {"corrupt_type", OPT_CORRUPT_TYPE, 's', "Corrupt a self test by type"}, + {"config", OPT_CONFIG, '<', "The parent config to verify"}, {"quiet", OPT_QUIET, '-', "No messages, just exit status"}, {NULL} }; @@ -202,6 +203,11 @@ static void free_config_and_unload(CONF *conf) } } +static int verify_module_load(const char *parent_config_file) +{ + return OPENSSL_CTX_load_config(NULL, parent_config_file); +} + /* * Returns 1 if the config file entries match the passed in module_mac and * install_mac values, otherwise it returns 0. @@ -271,7 +277,7 @@ int fipsinstall_main(int argc, char **argv) const char *prov_name = "fips"; BIO *module_bio = NULL, *mem_bio = NULL, *fout = NULL; char *in_fname = NULL, *out_fname = NULL, *prog; - char *module_fname = NULL; + char *module_fname = NULL, *parent_config = NULL; EVP_MAC_CTX *ctx = NULL, *ctx2 = NULL; STACK_OF(OPENSSL_STRING) *opts = NULL; OPTION_CHOICE o; @@ -328,6 +334,9 @@ opthelp: case OPT_MAC_NAME: mac_name = opt_arg(); break; + case OPT_CONFIG: + parent_config = opt_arg(); + break; case OPT_MACOPT: if (!sk_OPENSSL_STRING_push(opts, opt_arg())) goto opthelp; @@ -342,6 +351,17 @@ opthelp: } } argc = opt_num_rest(); + + if (parent_config != NULL) { + /* Test that a parent config can load the module */ + if (verify_module_load(parent_config)) { + ret = OSSL_PROVIDER_available(NULL, prov_name) ? 0 : 1; + if (!quiet) + BIO_printf(bio_out, "FIPS provider is %s\n", + ret == 0 ? "available" : " not available"); + } + goto end; + } if (module_fname == NULL || (verify && in_fname == NULL) || (!verify && out_fname == NULL) diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index fe937e6139..fcc4fb5c1c 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -2854,8 +2854,10 @@ PROV_R_GENERATE_ERROR:191:generate error PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE:165:\ illegal or unsupported padding mode PROV_R_INAVLID_UKM_LENGTH:146:inavlid ukm length +PROV_R_INDICATOR_INTEGRITY_FAILURE:210:indicator integrity failure PROV_R_INSUFFICIENT_DRBG_STRENGTH:181:insufficient drbg strength PROV_R_INVALID_AAD:108:invalid aad +PROV_R_INVALID_CONFIG_DATA:211:invalid config data PROV_R_INVALID_CONSTANT_LENGTH:157:invalid constant length PROV_R_INVALID_CURVE:176:invalid curve PROV_R_INVALID_CUSTOM_LENGTH:111:invalid custom length @@ -2878,6 +2880,7 @@ PROV_R_INVALID_PSS_SALTLEN:169:invalid pss saltlen PROV_R_INVALID_SALT_LENGTH:112:invalid salt length PROV_R_INVALID_SEED_LENGTH:154:invalid seed length PROV_R_INVALID_SIGNATURE_SIZE:179:invalid signature size +PROV_R_INVALID_STATE:212:invalid state PROV_R_INVALID_TAG:110:invalid tag PROV_R_INVALID_TAGLEN:118:invalid taglen PROV_R_INVALID_X931_DIGEST:170:invalid x931 digest @@ -2885,6 +2888,7 @@ PROV_R_IN_ERROR_STATE:192:in error state PROV_R_KEY_SIZE_TOO_SMALL:171:key size too small PROV_R_MISSING_CEK_ALG:144:missing cek alg PROV_R_MISSING_CIPHER:155:missing cipher +PROV_R_MISSING_CONFIG_DATA:213:missing config data PROV_R_MISSING_CONSTANT:156:missing constant PROV_R_MISSING_KEY:128:missing key PROV_R_MISSING_MAC:150:missing mac @@ -2897,6 +2901,7 @@ PROV_R_MISSING_SEED:140:missing seed PROV_R_MISSING_SESSION_ID:133:missing session id PROV_R_MISSING_TYPE:134:missing type PROV_R_MISSING_XCGHASH:135:missing xcghash +PROV_R_MODULE_INTEGRITY_FAILURE:214:module integrity failure PROV_R_NOT_INSTANTIATED:193:not instantiated PROV_R_NOT_SUPPORTED:136:not supported PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length @@ -2913,6 +2918,8 @@ PROV_R_READ_KEY:159:read key PROV_R_REQUEST_TOO_LARGE_FOR_DRBG:196:request too large for drbg PROV_R_REQUIRE_CTR_MODE_CIPHER:206:require ctr mode cipher PROV_R_RESEED_ERROR:197:reseed error +PROV_R_SELF_TEST_KAT_FAILURE:215:self test kat failure +PROV_R_SELF_TEST_POST_FAILURE:216:self test post failure PROV_R_TAG_NOTSET:119:tag notset PROV_R_TAG_NOT_NEEDED:120:tag not needed PROV_R_UNABLE_TO_FIND_CIPHERS:207:unable to find ciphers diff --git a/crypto/provider_core.c b/crypto/provider_core.c index f68fd8f0f9..b6586f904e 100644 --- a/crypto/provider_core.c +++ b/crypto/provider_core.c @@ -611,7 +611,6 @@ static int provider_activate(OSSL_PROVIDER *prov) /* With this flag set, this provider has become fully "loaded". */ prov->flag_initialized = 1; - return 1; } diff --git a/doc/man1/openssl-fipsinstall.pod.in b/doc/man1/openssl-fipsinstall.pod.in index 30df7bf3e9..ec83e0950f 100644 --- a/doc/man1/openssl-fipsinstall.pod.in +++ b/doc/man1/openssl-fipsinstall.pod.in @@ -21,6 +21,7 @@ B [B<-quiet>] [B<-corrupt_desc> I] [B<-corrupt_type> I] +[B<-config> I] =head1 DESCRIPTION @@ -143,6 +144,14 @@ Either option or both may be used to select the tests to corrupt. Refer to the entries for B and B in L for values that can be used. +=item B<-config> I + +Test that a FIPS provider can be loaded from the specified configuration file. +A previous call to this application needs to generate the extra configuration +data that is included by the base C configuration file. +See L for further information on how to set up a provider section. +All other options are ignored if '-config' is used. + =back =head1 EXAMPLES @@ -167,8 +176,16 @@ Corrupt any self tests which have the description C: -macopt hexkey:000102030405060708090A0B0C0D0E0F10111213 \ -corrupt_desc 'SHA1' +Validate that the fips module can be loaded from a base configuration file: + + export OPENSSL_CONF_INCLUDE= + export OPENSSL_MODULES= + openssl fipsinstall -config' 'default.cnf' + + =head1 SEE ALSO +L, L, L, L diff --git a/doc/man5/fips_config.pod b/doc/man5/fips_config.pod index 5077f30ecd..ebf6d685cc 100644 --- a/doc/man5/fips_config.pod +++ b/doc/man5/fips_config.pod @@ -59,7 +59,7 @@ It is written-to at the same time as B is updated. For example: - [fips_install] + [fips_sect] install-version = 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 diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index c21537fd4f..f5fd37d9cc 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -78,8 +78,10 @@ int ERR_load_PROV_strings(void); # define PROV_R_GENERATE_ERROR 191 # define PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 165 # define PROV_R_INAVLID_UKM_LENGTH 146 +# define PROV_R_INDICATOR_INTEGRITY_FAILURE 210 # define PROV_R_INSUFFICIENT_DRBG_STRENGTH 181 # define PROV_R_INVALID_AAD 108 +# define PROV_R_INVALID_CONFIG_DATA 211 # define PROV_R_INVALID_CONSTANT_LENGTH 157 # define PROV_R_INVALID_CURVE 176 # define PROV_R_INVALID_CUSTOM_LENGTH 111 @@ -102,6 +104,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_INVALID_SALT_LENGTH 112 # define PROV_R_INVALID_SEED_LENGTH 154 # define PROV_R_INVALID_SIGNATURE_SIZE 179 +# define PROV_R_INVALID_STATE 212 # define PROV_R_INVALID_TAG 110 # define PROV_R_INVALID_TAGLEN 118 # define PROV_R_INVALID_X931_DIGEST 170 @@ -109,6 +112,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_KEY_SIZE_TOO_SMALL 171 # define PROV_R_MISSING_CEK_ALG 144 # define PROV_R_MISSING_CIPHER 155 +# define PROV_R_MISSING_CONFIG_DATA 213 # define PROV_R_MISSING_CONSTANT 156 # define PROV_R_MISSING_KEY 128 # define PROV_R_MISSING_MAC 150 @@ -121,6 +125,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_MISSING_SESSION_ID 133 # define PROV_R_MISSING_TYPE 134 # define PROV_R_MISSING_XCGHASH 135 +# define PROV_R_MODULE_INTEGRITY_FAILURE 214 # define PROV_R_NOT_INSTANTIATED 193 # define PROV_R_NOT_SUPPORTED 136 # define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113 @@ -136,6 +141,8 @@ int ERR_load_PROV_strings(void); # define PROV_R_REQUEST_TOO_LARGE_FOR_DRBG 196 # define PROV_R_REQUIRE_CTR_MODE_CIPHER 206 # define PROV_R_RESEED_ERROR 197 +# define PROV_R_SELF_TEST_KAT_FAILURE 215 +# define PROV_R_SELF_TEST_POST_FAILURE 216 # define PROV_R_TAG_NOTSET 119 # define PROV_R_TAG_NOT_NEEDED 120 # define PROV_R_UNABLE_TO_FIND_CIPHERS 207 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index 7a0e0c595d..7a5c41bfda 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -63,9 +63,13 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "illegal or unsupported padding mode"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INAVLID_UKM_LENGTH), "inavlid ukm length"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INDICATOR_INTEGRITY_FAILURE), + "indicator integrity failure"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INSUFFICIENT_DRBG_STRENGTH), "insufficient drbg strength"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_AAD), "invalid aad"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONFIG_DATA), + "invalid config data"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CONSTANT_LENGTH), "invalid constant length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_CURVE), "invalid curve"}, @@ -98,6 +102,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "invalid seed length"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SIGNATURE_SIZE), "invalid signature size"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_STATE), "invalid state"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAG), "invalid tag"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAGLEN), "invalid taglen"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_X931_DIGEST), @@ -107,6 +112,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "key size too small"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CEK_ALG), "missing cek alg"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CIPHER), "missing cipher"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONFIG_DATA), + "missing config data"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CONSTANT), "missing constant"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_KEY), "missing key"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MAC), "missing mac"}, @@ -121,6 +128,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "missing session id"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_TYPE), "missing type"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_XCGHASH), "missing xcghash"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MODULE_INTEGRITY_FAILURE), + "module integrity failure"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_INSTANTIATED), "not instantiated"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_SUPPORTED), "not supported"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_NOT_XOF_OR_INVALID_LENGTH), @@ -145,6 +154,10 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_REQUIRE_CTR_MODE_CIPHER), "require ctr mode cipher"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_RESEED_ERROR), "reseed error"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_KAT_FAILURE), + "self test kat failure"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_SELF_TEST_POST_FAILURE), + "self test post failure"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOTSET), "tag notset"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_TAG_NOT_NEEDED), "tag not needed"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_FIND_CIPHERS), diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c index a998e392d7..c91ad1c6d7 100644 --- a/providers/fips/fipsprov.c +++ b/providers/fips/fipsprov.c @@ -31,6 +31,7 @@ #include "prov/implementations.h" #include "prov/provider_ctx.h" #include "prov/providercommon.h" +#include "prov/providercommonerr.h" #include "prov/provider_util.h" #include "self_test.h" @@ -700,8 +701,10 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, selftest_params.cb_arg = NULL; } - if (!c_get_params(handle, core_params)) + if (!c_get_params(handle, core_params)) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; + } /* Create a context. */ if ((*provctx = PROV_CTX_new()) == NULL @@ -724,8 +727,10 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, fgbl->handle = handle; selftest_params.libctx = libctx; - if (!SELF_TEST_post(&selftest_params, 0)) + if (!SELF_TEST_post(&selftest_params, 0)) { + ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_POST_FAILURE); goto err; + } /* * TODO(3.0): Remove me. This is just a dummy call to demonstrate making @@ -735,7 +740,6 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, goto err; *out = fips_dispatch_table; - return 1; err: fips_teardown(*provctx); diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c index 58aa42eed8..8902510b44 100644 --- a/providers/fips/self_test.c +++ b/providers/fips/self_test.c @@ -12,7 +12,9 @@ #include #include #include +#include #include "e_os.h" +#include "prov/providercommonerr.h" /* * We're cheating here. Normally we don't allow RUN_ONCE usage inside the FIPS * module because all such initialisation should be associated with an @@ -206,6 +208,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) if (!on_demand_test) return 1; } else if (loclstate != FIPS_STATE_SELFTEST) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE); return 0; } @@ -218,11 +221,14 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) FIPS_state = FIPS_STATE_SELFTEST; } else if (FIPS_state != FIPS_STATE_SELFTEST) { CRYPTO_THREAD_unlock(self_test_lock); + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_STATE); return 0; } if (st == NULL - || st->module_checksum_data == NULL) + || st->module_checksum_data == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); goto end; + } ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg); if (ev == NULL) @@ -230,16 +236,20 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data, &checksum_len); - if (module_checksum == NULL) + if (module_checksum == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); goto end; + } bio_module = (*st->bio_new_file_cb)(st->module_filename, "rb"); /* Always check the integrity of the fips module */ if (bio_module == NULL || !verify_integrity(bio_module, st->bio_read_ex_cb, module_checksum, checksum_len, st->libctx, - ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) + ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY)) { + ERR_raise(ERR_LIB_PROV, PROV_R_MODULE_INTEGRITY_FAILURE); goto end; + } /* This will be NULL during installation - so the self test KATS will run */ if (st->indicator_data != NULL) { @@ -247,12 +257,16 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) * If the kats have already passed indicator is set - then check the * integrity of the indicator. */ - if (st->indicator_checksum_data == NULL) + if (st->indicator_checksum_data == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA); goto end; + } indicator_checksum = OPENSSL_hexstr2buf(st->indicator_checksum_data, &checksum_len); - if (indicator_checksum == NULL) + if (indicator_checksum == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA); goto end; + } bio_indicator = (*st->bio_new_buffer_cb)(st->indicator_data, @@ -261,16 +275,20 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test) || !verify_integrity(bio_indicator, st->bio_read_ex_cb, indicator_checksum, checksum_len, st->libctx, ev, - OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY)) + OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INDICATOR_INTEGRITY_FAILURE); goto end; - else + } else { kats_already_passed = 1; + } } /* Only runs the KAT's during installation OR on_demand() */ if (on_demand_test || kats_already_passed == 0) { - if (!SELF_TEST_kats(ev, st->libctx)) + if (!SELF_TEST_kats(ev, st->libctx)) { + ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE); goto end; + } } ok = 1; end: diff --git a/test/recipes/03-test_fipsinstall.t b/test/recipes/03-test_fipsinstall.t index 64970bea5a..1d7a1ff6ae 100644 --- a/test/recipes/03-test_fipsinstall.t +++ b/test/recipes/03-test_fipsinstall.t @@ -12,7 +12,7 @@ use warnings; use File::Spec; use File::Copy; use OpenSSL::Glob; -use OpenSSL::Test qw/:DEFAULT srctop_dir bldtop_dir bldtop_file/; +use OpenSSL::Test qw/:DEFAULT srctop_dir srctop_file bldtop_dir bldtop_file/; use OpenSSL::Test::Utils; BEGIN { @@ -24,23 +24,73 @@ use platform; plan skip_all => "Test only supported in a fips build" if disabled("fips"); -plan tests => 12; +plan tests => 23; my $infile = bldtop_file('providers', platform->dso('fips')); my $fipskey = $ENV{FIPSKEY} // '00'; +# Read in a text $infile and replace the regular expression in $srch with the +# value in $repl and output to a new file $outfile. +sub replace_line_file_internal { + + my ($infile, $srch, $repl, $outfile) = @_; + my $msg; + + open(my $in, "<", $infile) or return 0; + read($in, $msg, 1024); + close $in; + + $msg =~ s/$srch/$repl/; + + open(my $fh, ">", $outfile) or return 0; + print $fh $msg; + close $fh; + return 1; +} + +# Read in the text input file 'fips.cnf' +# and replace a single Key = Value line with a new value in $value. +# OR remove the Key = Value line if the passed in $value is empty. +# and then output a new file $outfile. +# $key is the Key to find +sub replace_line_file { + my ($key, $value, $outfile) = @_; + + my $srch = qr/$key\s*=\s*\S*\n/; + my $rep; + if ($value eq "") { + $rep = ""; + } else { + $rep = "$key = $value\n"; + } + return replace_line_file_internal('fips.cnf', $srch, $rep, $outfile); +} + +# Read in the text input file 'test/fips.cnf' +# and replace the .cnf file used in +# .include fipsmodule.cnf with a new value in $value. +# and then output a new file $outfile. +# $key is the Key to find +sub replace_parent_line_file { + my ($value, $outfile) = @_; + my $srch = qr/fipsmodule.cnf/; + my $rep = "$value"; + return replace_line_file_internal(srctop_file("test", 'fips.cnf'), + $srch, $rep, $outfile); +} + # fail if no module name ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', '-provider_name', 'fips', '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", - '-section_name', 'fips_install'])), + '-section_name', 'fips_sect'])), "fipsinstall fail"); # fail to verify if the configuration file is missing ok(!run(app(['openssl', 'fipsinstall', '-in', 'dummy.tmp', '-module', $infile, '-provider_name', 'fips', '-mac_name', 'HMAC', '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", - '-section_name', 'fips_install', '-verify'])), + '-section_name', 'fips_sect', '-verify'])), "fipsinstall verify fail"); @@ -48,56 +98,104 @@ ok(!run(app(['openssl', 'fipsinstall', '-in', 'dummy.tmp', '-module', $infile, 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_install'])), + '-section_name', 'fips_sect'])), "fipsinstall"); # verify the fips.cnf file ok(run(app(['openssl', 'fipsinstall', '-in', 'fips.cnf', '-module', $infile, '-provider_name', 'fips', '-mac_name', 'HMAC', '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", - '-section_name', 'fips_install', '-verify'])), + '-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_install', '-verify'])), + '-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_install', '-verify'])), + '-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_install', '-corrupt_desc', 'HMAC'])), + '-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.cnf', '-module', $infile, +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_install', '-corrupt_desc', 'SHA1'])), + '-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.cnf', '-module', $infile, +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_install', '-corrupt_desc', 'SHA3'])), + '-section_name', 'fips_sect', '-corrupt_desc', 'SHA3'])), "fipsinstall fails when the digest result is corrupted"); # corrupt DRBG -ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.cnf', '-module', $infile, +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_install', '-corrupt_desc', 'CTR'])), + '-section_name', 'fips_sect', '-corrupt_desc', 'CTR'])), "fipsinstall fails when the DRBG CTR result is corrupted"); # corrupt a KAS test @@ -108,7 +206,7 @@ SKIP: { ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.conf', '-module', $infile, '-provider_name', 'fips', '-mac_name', 'HMAC', '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", - '-section_name', 'fips_install', + '-section_name', 'fips_sect', '-corrupt_desc', 'DH', '-corrupt_type', 'KAT_KA'])), "fipsinstall fails when the kas result is corrupted"); @@ -121,8 +219,47 @@ SKIP: { ok(!run(app(['openssl', 'fipsinstall', '-out', 'fips.conf', '-module', $infile, '-provider_name', 'fips', '-mac_name', 'HMAC', '-macopt', 'digest:SHA256', '-macopt', "hexkey:$fipskey", - '-section_name', 'fips_install', + '-section_name', 'fips_sect', '-corrupt_desc', 'DSA', '-corrupt_type', 'KAT_Signature'])), "fipsinstall fails when the signature result is corrupted"); } + +$ENV{OPENSSL_CONF_INCLUDE} = "."; + +ok(replace_parent_line_file('fips.cnf', 'fips_parent.cnf') + && run(app(['openssl', 'fipsinstall', '-config', 'fips_parent.cnf'])), + "verify fips provider loads from a configuration file"); + +ok(replace_parent_line_file('fips_no_module_mac.cnf', + 'fips_parent_no_module_mac.cnf') + && !run(app(['openssl', 'fipsinstall', + '-config', 'fips_parent_no_module_mac.cnf'])), + "verify load config fail no module mac"); + +ok(replace_parent_line_file('fips_no_install_mac.cnf', + 'fips_parent_no_install_mac.cnf') + && !run(app(['openssl', 'fipsinstall', + '-config', 'fips_parent_no_install_mac.cnf'])), + "verify load config fail no install mac"); + +ok(replace_parent_line_file('fips_bad_indicator.cnf', + 'fips_parent_bad_indicator.cnf') + && !run(app(['openssl', 'fipsinstall', + '-config', 'fips_parent_bad_indicator.cnf'])), + "verify load config fail bad indicator"); + + +ok(replace_parent_line_file('fips_bad_install_mac.cnf', + 'fips_parent_bad_install_mac.cnf') + && !run(app(['openssl', 'fipsinstall', + '-config', 'fips_parent_bad_install_mac.cnf'])), + "verify load config fail bad install mac"); + +ok(replace_parent_line_file('fips_bad_module_mac.cnf', + 'fips_parent_bad_module_mac.cnf') + && !run(app(['openssl', 'fipsinstall', + '-config', 'fips_parent_bad_module_mac.cnf'])), + "verify load config fail bad module mac"); + +delete $ENV{OPENSSL_CONF_INCLUDE};