mirror of
https://github.com/openssl/openssl.git
synced 2024-11-21 01:15:20 +08:00
keygen: add FIPS error state management to conditional self tests
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from https://github.com/openssl/openssl/pull/12801)
This commit is contained in:
parent
801ed9edba
commit
35e6ea3bdc
@ -38,7 +38,8 @@ 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_CONFIG
|
||||
OPT_NO_LOG, OPT_CORRUPT_DESC, OPT_CORRUPT_TYPE, OPT_QUIET, OPT_CONFIG,
|
||||
OPT_NO_CONDITIONAL_ERRORS
|
||||
} OPTION_CHOICE;
|
||||
|
||||
const OPTIONS fipsinstall_options[] = {
|
||||
@ -50,7 +51,9 @@ const OPTIONS fipsinstall_options[] = {
|
||||
{"provider_name", OPT_PROV_NAME, 's', "FIPS provider name"},
|
||||
{"section_name", OPT_SECTION_NAME, 's',
|
||||
"FIPS Provider config section name (optional)"},
|
||||
|
||||
{"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"},
|
||||
OPT_SECTION("Input"),
|
||||
{"in", OPT_IN, '<', "Input config file, used when verifying"},
|
||||
|
||||
@ -132,24 +135,28 @@ 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 and the installation indicator checksum.
|
||||
* module checksum, installation indicator checksum and the option
|
||||
* conditional_errors.
|
||||
*
|
||||
* Returns 1 if the config file is written otherwise it returns 0 on error.
|
||||
*/
|
||||
static int write_config_fips_section(BIO *out, const char *section,
|
||||
unsigned char *module_mac,
|
||||
size_t module_mac_len,
|
||||
int conditional_errors,
|
||||
unsigned char *install_mac,
|
||||
size_t install_mac_len)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!(BIO_printf(out, "[%s]\n", section) > 0
|
||||
&& BIO_printf(out, "activate = 1\n") > 0
|
||||
&& BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
|
||||
VERSION_VAL) > 0
|
||||
&& print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
|
||||
module_mac_len)))
|
||||
if (BIO_printf(out, "[%s]\n", section) <= 0
|
||||
|| BIO_printf(out, "activate = 1\n") <= 0
|
||||
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
|
||||
VERSION_VAL) <= 0
|
||||
|| BIO_printf(out, "%s = %s\n", OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS,
|
||||
conditional_errors ? "1" : "0") <= 0
|
||||
|| !print_mac(out, OSSL_PROV_FIPS_PARAM_MODULE_MAC, module_mac,
|
||||
module_mac_len))
|
||||
goto end;
|
||||
|
||||
if (install_mac != NULL) {
|
||||
@ -168,7 +175,8 @@ end:
|
||||
static CONF *generate_config_and_load(const char *prov_name,
|
||||
const char *section,
|
||||
unsigned char *module_mac,
|
||||
size_t module_mac_len)
|
||||
size_t module_mac_len,
|
||||
int conditional_errors)
|
||||
{
|
||||
BIO *mem_bio = NULL;
|
||||
CONF *conf = NULL;
|
||||
@ -177,8 +185,10 @@ static CONF *generate_config_and_load(const char *prov_name,
|
||||
if (mem_bio == NULL)
|
||||
return 0;
|
||||
if (!write_config_header(mem_bio, prov_name, section)
|
||||
|| !write_config_fips_section(mem_bio, section, module_mac,
|
||||
module_mac_len, NULL, 0))
|
||||
|| !write_config_fips_section(mem_bio, section,
|
||||
module_mac, module_mac_len,
|
||||
conditional_errors,
|
||||
NULL, 0))
|
||||
goto end;
|
||||
|
||||
conf = app_load_config_bio(mem_bio, NULL);
|
||||
@ -272,6 +282,7 @@ end:
|
||||
int fipsinstall_main(int argc, char **argv)
|
||||
{
|
||||
int ret = 1, verify = 0, gotkey = 0, gotdigest = 0;
|
||||
int enable_conditional_errors = 1;
|
||||
const char *section_name = "fips_sect";
|
||||
const char *mac_name = "HMAC";
|
||||
const char *prov_name = "fips";
|
||||
@ -311,6 +322,9 @@ opthelp:
|
||||
case OPT_OUT:
|
||||
out_fname = opt_arg();
|
||||
break;
|
||||
case OPT_NO_CONDITIONAL_ERRORS:
|
||||
enable_conditional_errors = 0;
|
||||
break;
|
||||
case OPT_QUIET:
|
||||
quiet = 1;
|
||||
/* FALLTHROUGH */
|
||||
@ -457,7 +471,8 @@ opthelp:
|
||||
} else {
|
||||
|
||||
conf = generate_config_and_load(prov_name, section_name, module_mac,
|
||||
module_mac_len);
|
||||
module_mac_len,
|
||||
enable_conditional_errors);
|
||||
if (conf == NULL)
|
||||
goto end;
|
||||
if (!load_fips_prov_and_run_self_test(prov_name))
|
||||
@ -468,9 +483,10 @@ opthelp:
|
||||
BIO_printf(bio_err, "Failed to open file\n");
|
||||
goto end;
|
||||
}
|
||||
if (!write_config_fips_section(fout, section_name, module_mac,
|
||||
module_mac_len, install_mac,
|
||||
install_mac_len))
|
||||
if (!write_config_fips_section(fout, section_name,
|
||||
module_mac, module_mac_len,
|
||||
enable_conditional_errors,
|
||||
install_mac, install_mac_len))
|
||||
goto end;
|
||||
if (!quiet)
|
||||
BIO_printf(bio_out, "INSTALL PASSED\n");
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "prov/providercommon.h"
|
||||
#include "crypto/dsa.h"
|
||||
#include "dsa_local.h"
|
||||
|
||||
@ -113,6 +114,7 @@ static int dsa_keygen(DSA *dsa, int pairwise_test)
|
||||
OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg);
|
||||
ok = dsa_keygen_pairwise_test(dsa, cb, cbarg);
|
||||
if (!ok) {
|
||||
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
|
||||
BN_free(dsa->pub_key);
|
||||
BN_clear_free(dsa->priv_key);
|
||||
dsa->pub_key = NULL;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "prov/providercommon.h"
|
||||
#include "crypto/bn.h"
|
||||
|
||||
static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
|
||||
@ -330,6 +331,7 @@ int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test)
|
||||
err:
|
||||
/* Step (9): If there is an error return an invalid keypair. */
|
||||
if (!ok) {
|
||||
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
|
||||
BN_clear(eckey->priv_key);
|
||||
if (eckey->pub_key != NULL)
|
||||
EC_POINT_set_to_infinity(group, eckey->pub_key);
|
||||
|
@ -2877,6 +2877,7 @@ PROV_R_FAILED_TO_GENERATE_KEY:121:failed to generate key
|
||||
PROV_R_FAILED_TO_GET_PARAMETER:103:failed to get parameter
|
||||
PROV_R_FAILED_TO_SET_PARAMETER:104:failed to set parameter
|
||||
PROV_R_FAILED_TO_SIGN:175:failed to sign
|
||||
PROV_R_FIPS_MODULE_CONDITIONAL_ERROR:227:fips module conditional error
|
||||
PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE:224:fips module entering error state
|
||||
PROV_R_FIPS_MODULE_IN_ERROR_STATE:225:fips module in error state
|
||||
PROV_R_GENERATE_ERROR:191:generate error
|
||||
@ -2936,7 +2937,7 @@ PROV_R_MODULE_INTEGRITY_FAILURE:214:module integrity failure
|
||||
PROV_R_NOT_A_PRIVATE_KEY:221:not a private key
|
||||
PROV_R_NOT_A_PUBLIC_KEY:220:not a public key
|
||||
PROV_R_NOT_INSTANTIATED:193:not instantiated
|
||||
PROV_R_NOT_PARAMETERS:224:not parameters
|
||||
PROV_R_NOT_PARAMETERS:226:not parameters
|
||||
PROV_R_NOT_SUPPORTED:136:not supported
|
||||
PROV_R_NOT_XOF_OR_INVALID_LENGTH:113:not xof or invalid length
|
||||
PROV_R_NO_KEY_SET:114:no key set
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "prov/providercommon.h"
|
||||
#include "rsa_local.h"
|
||||
|
||||
static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg);
|
||||
@ -444,6 +445,7 @@ static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes,
|
||||
OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg);
|
||||
ok = rsa_keygen_pairwise_test(rsa, stcb, stcbarg);
|
||||
if (!ok) {
|
||||
ossl_set_error_state(OSSL_SELF_TEST_TYPE_PCT);
|
||||
/* Clear intermediate results */
|
||||
BN_clear_free(rsa->d);
|
||||
BN_clear_free(rsa->p);
|
||||
|
@ -19,6 +19,7 @@ B<openssl fipsinstall>
|
||||
[B<-macopt> I<nm>:I<v>]
|
||||
[B<-noout>]
|
||||
[B<-quiet>]
|
||||
[B<-no_conditional_errors>]
|
||||
[B<-corrupt_desc> I<selftest_description>]
|
||||
[B<-corrupt_type> I<selftest_type>]
|
||||
[B<-config> I<parent_config>]
|
||||
@ -43,6 +44,17 @@ This indicates if the Known Answer Self Tests (KAT's) have successfully run.
|
||||
|
||||
=item - A MAC of the status indicator.
|
||||
|
||||
=item - A control for conditional self tests errors.
|
||||
|
||||
By default if a continuous test (e.g a key pair test) fails then the FIPS module
|
||||
will enter an error state, and no services or cryptographic algorithms will be
|
||||
able to be accessed after this point.
|
||||
The default value of '1' will cause the fips module error state to be entered.
|
||||
If the value is '0' then the module error state will not be entered.
|
||||
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.
|
||||
|
||||
=back
|
||||
|
||||
This file is described in L<fips_config(5)>.
|
||||
@ -133,6 +145,12 @@ The default digest is SHA-256.
|
||||
|
||||
Disable logging of the self tests.
|
||||
|
||||
=item B<-no_conditional_errors>
|
||||
|
||||
Configure the module to not enter an error state if a conditional self test
|
||||
fails as described above.
|
||||
|
||||
|
||||
=item B<-quiet>
|
||||
|
||||
Do not output pass/fail messages. Implies B<-noout>.
|
||||
|
@ -39,6 +39,13 @@ extern "C" {
|
||||
*/
|
||||
# define OSSL_PROV_FIPS_PARAM_INSTALL_STATUS "install-status"
|
||||
|
||||
/*
|
||||
* A boolean that determines if the FIPS conditional test errors result in
|
||||
* the module entering an error state.
|
||||
* Type: OSSL_PARAM_UTF8_STRING
|
||||
*/
|
||||
# define OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS "conditional-errors"
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif
|
||||
|
@ -27,6 +27,7 @@ extern "C" {
|
||||
# define OSSL_SELF_TEST_TYPE_NONE "None"
|
||||
# define OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY "Module_Integrity"
|
||||
# define OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY "Install_Integrity"
|
||||
# define OSSL_SELF_TEST_TYPE_CRNG "Continuous_RNG_Test"
|
||||
# define OSSL_SELF_TEST_TYPE_PCT "Pairwise_Consistency_Test"
|
||||
# define OSSL_SELF_TEST_TYPE_KAT_CIPHER "KAT_Cipher"
|
||||
# define OSSL_SELF_TEST_TYPE_KAT_DIGEST "KAT_Digest"
|
||||
|
@ -20,7 +20,7 @@ int cipher_capable_aes_cbc_hmac_sha256(void);
|
||||
OSSL_FUNC_provider_get_capabilities_fn provider_get_capabilities;
|
||||
|
||||
/* Set the error state if this is a FIPS module */
|
||||
void ossl_set_error_state(void);
|
||||
void ossl_set_error_state(const char *type);
|
||||
|
||||
/* Return true if the module is in a usable condition */
|
||||
int ossl_prov_is_running(void);
|
||||
|
@ -75,6 +75,7 @@ int ERR_load_PROV_strings(void);
|
||||
# define PROV_R_FAILED_TO_GET_PARAMETER 103
|
||||
# define PROV_R_FAILED_TO_SET_PARAMETER 104
|
||||
# define PROV_R_FAILED_TO_SIGN 175
|
||||
# define PROV_R_FIPS_MODULE_CONDITIONAL_ERROR 227
|
||||
# define PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE 224
|
||||
# define PROV_R_FIPS_MODULE_IN_ERROR_STATE 225
|
||||
# define PROV_R_GENERATE_ERROR 191
|
||||
@ -133,7 +134,7 @@ int ERR_load_PROV_strings(void);
|
||||
# define PROV_R_NOT_A_PRIVATE_KEY 221
|
||||
# define PROV_R_NOT_A_PUBLIC_KEY 220
|
||||
# define PROV_R_NOT_INSTANTIATED 193
|
||||
# define PROV_R_NOT_PARAMETERS 224
|
||||
# define PROV_R_NOT_PARAMETERS 226
|
||||
# define PROV_R_NOT_SUPPORTED 136
|
||||
# define PROV_R_NOT_XOF_OR_INVALID_LENGTH 113
|
||||
# define PROV_R_NO_KEY_SET 114
|
||||
|
@ -58,6 +58,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER),
|
||||
"failed to set parameter"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SIGN), "failed to sign"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR),
|
||||
"fips module conditional error"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE),
|
||||
"fips module entering error state"},
|
||||
{ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FIPS_MODULE_IN_ERROR_STATE),
|
||||
|
@ -126,6 +126,9 @@ static OSSL_PARAM core_params[] =
|
||||
OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_INSTALL_VERSION,
|
||||
selftest_params.indicator_version,
|
||||
sizeof(selftest_params.indicator_version)),
|
||||
OSSL_PARAM_utf8_ptr(OSSL_PROV_FIPS_PARAM_CONDITIONAL_ERRORS,
|
||||
selftest_params.conditional_error_check,
|
||||
sizeof(selftest_params.conditional_error_check)),
|
||||
OSSL_PARAM_END
|
||||
};
|
||||
|
||||
@ -645,6 +648,10 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle,
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
/* Disable the conditional error check if is disabled in the fips config file*/
|
||||
if (selftest_params.conditional_error_check != NULL
|
||||
&& strcmp(selftest_params.conditional_error_check, "0") == 0)
|
||||
SELF_TEST_disable_conditional_error_state();
|
||||
|
||||
/* Create a context. */
|
||||
if ((*provctx = PROV_CTX_new()) == NULL
|
||||
|
@ -44,6 +44,7 @@
|
||||
#define MAC_NAME "HMAC"
|
||||
#define DIGEST_NAME "SHA256"
|
||||
|
||||
static int FIPS_conditional_error_check = 1;
|
||||
static int FIPS_state = FIPS_STATE_INIT;
|
||||
static CRYPTO_RWLOCK *self_test_lock = NULL;
|
||||
static unsigned char fixed_key[32] = { FIPS_KEY_ELEMENTS };
|
||||
@ -311,16 +312,27 @@ end:
|
||||
if (ok)
|
||||
FIPS_state = FIPS_STATE_RUNNING;
|
||||
else
|
||||
ossl_set_error_state();
|
||||
ossl_set_error_state(OSSL_SELF_TEST_TYPE_NONE);
|
||||
CRYPTO_THREAD_unlock(self_test_lock);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
void ossl_set_error_state(void)
|
||||
void SELF_TEST_disable_conditional_error_state(void)
|
||||
{
|
||||
FIPS_state = FIPS_STATE_ERROR;
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE);
|
||||
FIPS_conditional_error_check = 0;
|
||||
}
|
||||
|
||||
void ossl_set_error_state(const char *type)
|
||||
{
|
||||
int cond_test = (type != NULL && strcmp(type, OSSL_SELF_TEST_TYPE_PCT) == 0);
|
||||
|
||||
if (!cond_test || (FIPS_conditional_error_check == 1)) {
|
||||
FIPS_state = FIPS_STATE_ERROR;
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_ENTERING_ERROR_STATE);
|
||||
} else {
|
||||
ERR_raise(ERR_LIB_PROV, PROV_R_FIPS_MODULE_CONDITIONAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
int ossl_prov_is_running(void)
|
||||
|
@ -21,6 +21,9 @@ typedef struct self_test_post_params_st {
|
||||
const char *indicator_data; /* data to perform MAC on */
|
||||
const char *indicator_checksum_data; /* Expected MAC integrity value */
|
||||
|
||||
/* Used for continuous tests */
|
||||
const char *conditional_error_check;
|
||||
|
||||
/* BIO callbacks supplied to the FIPS provider */
|
||||
OSSL_FUNC_BIO_new_file_fn *bio_new_file_cb;
|
||||
OSSL_FUNC_BIO_new_membuf_fn *bio_new_buffer_cb;
|
||||
@ -34,3 +37,5 @@ typedef struct self_test_post_params_st {
|
||||
|
||||
int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test);
|
||||
int SELF_TEST_kats(OSSL_SELF_TEST *event, OPENSSL_CTX *libctx);
|
||||
|
||||
void SELF_TEST_disable_conditional_error_state(void);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/core_dispatch.h>
|
||||
#include <openssl/params.h>
|
||||
#include <openssl/self_test.h>
|
||||
#include "prov/providercommon.h"
|
||||
#include "prov/provider_ctx.h"
|
||||
#include "internal/cryptlib.h"
|
||||
@ -99,7 +100,7 @@ static int prov_crngt_compare_previous(const unsigned char *prev,
|
||||
const int res = memcmp(prev, cur, sz) != 0;
|
||||
|
||||
if (!res)
|
||||
ossl_set_error_state();
|
||||
ossl_set_error_state(OSSL_SELF_TEST_TYPE_CRNG);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,11 @@
|
||||
#include "prov/providercommon.h"
|
||||
|
||||
/* By default, our providers don't have an error state */
|
||||
void ossl_set_error_state(void)
|
||||
void ossl_set_error_state(const char *type)
|
||||
{
|
||||
}
|
||||
|
||||
/* By default, out providers are always in a happy state */
|
||||
/* By default, our providers are always in a happy state */
|
||||
int ossl_prov_is_running(void)
|
||||
{
|
||||
return 1;
|
||||
|
Loading…
Reference in New Issue
Block a user