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[] = {
{"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"},
/*
* 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) {
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;
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);
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";
case OPT_OUT:
out_fname = opt_arg();
break;
+ case OPT_NO_CONDITIONAL_ERRORS:
+ enable_conditional_errors = 0;
+ break;
case OPT_QUIET:
quiet = 1;
/* FALLTHROUGH */
} 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))
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");
#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"
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;
#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,
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);
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
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
#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);
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);
[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>]
=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)>.
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>.
*/
# 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
# 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"
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);
# 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
# 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
{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),
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
};
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
#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 };
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)
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;
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);
#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"
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;
}
#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;