summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/fipsinstall.c48
-rw-r--r--crypto/dsa/dsa_key.c2
-rw-r--r--crypto/ec/ec_key.c2
-rw-r--r--crypto/err/openssl.txt3
-rw-r--r--crypto/rsa/rsa_gen.c2
-rw-r--r--doc/man1/openssl-fipsinstall.pod.in18
-rw-r--r--include/openssl/fips_names.h7
-rw-r--r--include/openssl/self_test.h1
-rw-r--r--providers/common/include/prov/providercommon.h2
-rw-r--r--providers/common/include/prov/providercommonerr.h3
-rw-r--r--providers/common/provider_err.c2
-rw-r--r--providers/fips/fipsprov.c7
-rw-r--r--providers/fips/self_test.c20
-rw-r--r--providers/fips/self_test.h5
-rw-r--r--providers/implementations/rands/crngt.c3
-rw-r--r--providers/prov_running.c4
16 files changed, 103 insertions, 26 deletions
diff --git a/apps/fipsinstall.c b/apps/fipsinstall.c
index 104806c1b7..2df7d0f024 100644
--- a/apps/fipsinstall.c
+++ b/apps/fipsinstall.c
@@ -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");
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index b537ec0b3c..bf9d8a269c 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -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;
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 84ce095693..84e1b96c48 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -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);
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 6c2e81efb9..35c1dd6bdc 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -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
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index b7a37b77a2..dc4ec0a8d3 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -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);
diff --git a/doc/man1/openssl-fipsinstall.pod.in b/doc/man1/openssl-fipsinstall.pod.in
index 451e8a775d..7fb6ad5636 100644
--- a/doc/man1/openssl-fipsinstall.pod.in
+++ b/doc/man1/openssl-fipsinstall.pod.in
@@ -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>.
diff --git a/include/openssl/fips_names.h b/include/openssl/fips_names.h
index 493ddb046d..7dec75fcea 100644
--- a/include/openssl/fips_names.h
+++ b/include/openssl/fips_names.h
@@ -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
diff --git a/include/openssl/self_test.h b/include/openssl/self_test.h
index ff6e1b8e08..aa153581fa 100644
--- a/include/openssl/self_test.h
+++ b/include/openssl/self_test.h
@@ -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"
diff --git a/providers/common/include/prov/providercommon.h b/providers/common/include/prov/providercommon.h
index 280d2d2072..44e9c812aa 100644
--- a/providers/common/include/prov/providercommon.h
+++ b/providers/common/include/prov/providercommon.h
@@ -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);
diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h
index d4d3c7e8e8..d972a819e2 100644
--- a/providers/common/include/prov/providercommonerr.h
+++ b/providers/common/include/prov/providercommonerr.h
@@ -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
diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c
index 329bb279eb..606d78cc57 100644
--- a/providers/common/provider_err.c
+++ b/providers/common/provider_err.c
@@ -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),
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 0f1c979efe..4290a87e6e 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -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
diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c
index b0df0863e2..9d95f0ccf1 100644
--- a/providers/fips/self_test.c
+++ b/providers/fips/self_test.c
@@ -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)
diff --git a/providers/fips/self_test.h b/providers/fips/self_test.h
index 20f8a12472..205623cc3d 100644
--- a/providers/fips/self_test.h
+++ b/providers/fips/self_test.h
@@ -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);
diff --git a/providers/implementations/rands/crngt.c b/providers/implementations/rands/crngt.c
index 9a9e9c703b..e23485291b 100644
--- a/providers/implementations/rands/crngt.c
+++ b/providers/implementations/rands/crngt.c
@@ -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;
}
diff --git a/providers/prov_running.c b/providers/prov_running.c
index 7e62dedf4d..379fd5d25c 100644
--- a/providers/prov_running.c
+++ b/providers/prov_running.c
@@ -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;