Browse Source

Add fipsinstall option to run self test KATS on module load

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15149)
master
Shane Lontis 1 year ago
parent
commit
2abffec0f0
5 changed files with 73 additions and 30 deletions
  1. +38
    -26
      apps/fipsinstall.c
  2. +12
    -1
      doc/man1/openssl-fipsinstall.pod.in
  3. +2
    -1
      doc/man5/fips_config.pod
  4. +5
    -1
      providers/fips/self_test.c
  5. +16
    -1
      test/recipes/03-test_fipsinstall.t

+ 38
- 26
apps/fipsinstall.c View File

@ -38,7 +38,8 @@ typedef enum OPTION_choice {
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_SECURITY_CHECKS
OPT_NO_SECURITY_CHECKS,
OPT_SELF_TEST_ONLOAD
} OPTION_CHOICE;
const OPTIONS fipsinstall_options[] = {
@ -55,6 +56,8 @@ const OPTIONS fipsinstall_options[] = {
" any conditional self tests fail"},
{"no_security_checks", OPT_NO_SECURITY_CHECKS, '-',
"Disable the run-time FIPS security checks in the module"},
{"self_test_onload", OPT_SELF_TEST_ONLOAD, '-',
"Forces self tests to always run on module load"},
OPT_SECTION("Input"),
{"in", OPT_IN, '<', "Input config file, used when verifying"},
@ -163,7 +166,7 @@ static int write_config_fips_section(BIO *out, const char *section,
module_mac_len))
goto end;
if (install_mac != NULL) {
if (install_mac != NULL && install_mac_len > 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,
@ -247,11 +250,6 @@ static int verify_config(const char *infile, const char *section,
BIO_printf(bio_err, "version not found\n");
goto end;
}
s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_STATUS);
if (s == NULL || strcmp(s, INSTALL_STATUS_VAL) != 0) {
BIO_printf(bio_err, "install status not found\n");
goto end;
}
s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_MODULE_MAC);
if (s == NULL) {
BIO_printf(bio_err, "Module integrity MAC not found\n");
@ -264,17 +262,24 @@ static int verify_config(const char *infile, const char *section,
BIO_printf(bio_err, "Module integrity mismatch\n");
goto end;
}
s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_MAC);
if (s == NULL) {
BIO_printf(bio_err, "Install indicator MAC not found\n");
goto end;
}
buf2 = OPENSSL_hexstr2buf(s, &len);
if (buf2 == NULL
|| (size_t)len != install_mac_len
|| memcmp(install_mac, buf2, install_mac_len) != 0) {
BIO_printf(bio_err, "Install indicator status mismatch\n");
goto end;
if (install_mac != NULL && install_mac_len > 0) {
s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_STATUS);
if (s == NULL || strcmp(s, INSTALL_STATUS_VAL) != 0) {
BIO_printf(bio_err, "install status not found\n");
goto end;
}
s = NCONF_get_string(conf, section, OSSL_PROV_FIPS_PARAM_INSTALL_MAC);
if (s == NULL) {
BIO_printf(bio_err, "Install indicator MAC not found\n");
goto end;
}
buf2 = OPENSSL_hexstr2buf(s, &len);
if (buf2 == NULL
|| (size_t)len != install_mac_len
|| memcmp(install_mac, buf2, install_mac_len) != 0) {
BIO_printf(bio_err, "Install indicator status mismatch\n");
goto end;
}
}
ret = 1;
end:
@ -286,7 +291,7 @@ end:
int fipsinstall_main(int argc, char **argv)
{
int ret = 1, verify = 0, gotkey = 0, gotdigest = 0;
int ret = 1, verify = 0, gotkey = 0, gotdigest = 0, self_test_onload = 0;
int enable_conditional_errors = 1, enable_security_checks = 1;
const char *section_name = "fips_sect";
const char *mac_name = "HMAC";
@ -371,6 +376,9 @@ opthelp:
case OPT_VERIFY:
verify = 1;
break;
case OPT_SELF_TEST_ONLOAD:
self_test_onload = 1;
break;
}
}
@ -462,14 +470,18 @@ opthelp:
if (!do_mac(ctx, read_buffer, module_bio, module_mac, &module_mac_len))
goto end;
mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL,
strlen(INSTALL_STATUS_VAL));
if (mem_bio == NULL) {
BIO_printf(bio_err, "Unable to create memory BIO\n");
goto end;
if (self_test_onload == 0) {
mem_bio = BIO_new_mem_buf((const void *)INSTALL_STATUS_VAL,
strlen(INSTALL_STATUS_VAL));
if (mem_bio == NULL) {
BIO_printf(bio_err, "Unable to create memory BIO\n");
goto end;
}
if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len))
goto end;
} else {
install_mac_len = 0;
}
if (!do_mac(ctx2, read_buffer, mem_bio, install_mac, &install_mac_len))
goto end;
if (verify) {
if (!verify_config(in_fname, section_name, module_mac, module_mac_len,


+ 12
- 1
doc/man1/openssl-fipsinstall.pod.in View File

@ -21,6 +21,7 @@ B<openssl fipsinstall>
[B<-quiet>]
[B<-no_conditional_errors>]
[B<-no_security_checks>]
[B<-self_test_onload>]
[B<-corrupt_desc> I<selftest_description>]
[B<-corrupt_type> I<selftest_type>]
[B<-config> I<parent_config>]
@ -30,7 +31,7 @@ B<openssl fipsinstall>
This command is used to generate a FIPS module configuration file.
This configuration file can be used each time a FIPS module is loaded
in order to pass data to the FIPS module self tests. The FIPS module always
verifies its MAC, but only needs to run the KAT's once,
verifies its MAC, but optionally only needs to run the KAT's once,
at installation.
The generated configuration file consists of:
@ -163,6 +164,16 @@ fails as described above.
Configure the module to not perform run-time security checks as described above.
=item B<-self_test_onload>
Do not write the two fields related to the "test status indicator" and
"MAC status indicator" to the output configuration file. Without these fields
the self tests KATS will run each time the module is loaded. This option could be
used for cross compiling, since the self tests need to run at least once on each
target machine. Once the self tests have run on the target machine the user
could possibly then add the 2 fields into the configuration using some other
mechanism.
=item B<-quiet>
Do not output pass/fail messages. Implies B<-noout>.


+ 2
- 1
doc/man5/fips_config.pod View File

@ -16,7 +16,8 @@ purposes:
=item - Run the startup FIPS self-test known answer tests (KATS).
This is done once, at installation time.
This is normally done once, at installation time, but may also be set up to
run each time the module is used.
=item - Verify the module's checksum.


+ 5
- 1
providers/fips/self_test.c View File

@ -331,7 +331,11 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
}
}
/* Only runs the KAT's during installation OR on_demand() */
/*
* Only runs the KAT's during installation OR on_demand().
* NOTE: If the installation option 'self_test_onload' is chosen then this
* path will always be run, since kats_already_passed will always be 0.
*/
if (on_demand_test || kats_already_passed == 0) {
if (!SELF_TEST_kats(ev, st->libctx)) {
ERR_raise(ERR_LIB_PROV, PROV_R_SELF_TEST_KAT_FAILURE);


+ 16
- 1
test/recipes/03-test_fipsinstall.t View File

@ -24,7 +24,7 @@ use platform;
plan skip_all => "Test only supported in a fips build" if disabled("fips");
plan tests => 26;
plan tests => 29;
my $infile = bldtop_file('providers', platform->dso('fips'));
my $fipskey = $ENV{FIPSKEY} // '00';
@ -286,3 +286,18 @@ ok(replace_parent_line_file('fips_bad_module_mac.cnf',
&& !run(app(['openssl', 'fipsinstall',
'-config', 'fips_parent_bad_module_mac.cnf'])),
"verify load config fail bad module mac");
my $stconf = "fipsmodule_selftest.cnf";
ok(run(app(['openssl', 'fipsinstall', '-out', $stconf,
'-module', $infile, '-self_test_onload'])),
"fipsinstall config saved without self test indicator");
ok(!run(app(['openssl', 'fipsinstall', '-in', $stconf,
'-module', $infile, '-verify'])),
"fipsinstall config verify fails without self test indicator");
ok(run(app(['openssl', 'fipsinstall', '-in', $stconf,
'-module', $infile, '-self_test_onload', '-verify'])),
"fipsinstall config verify passes when self test indicator is not present");

Loading…
Cancel
Save