+/* Test POST induced failures */
+
+typedef struct
+ {
+ const char *name;
+ int id, subid, keyid;
+ } fail_list;
+
+static fail_list flist[] =
+ {
+ {"Integrity", FIPS_TEST_INTEGRITY, -1, -1},
+ {"AES", FIPS_TEST_CIPHER, NID_aes_128_ecb, -1},
+ {"DES3", FIPS_TEST_CIPHER, NID_des_ede3_ecb, -1},
+ {"AES-GCM", FIPS_TEST_GCM, -1, -1},
+ {"AES-CCM", FIPS_TEST_CCM, -1, -1},
+ {"AES-XTS", FIPS_TEST_XTS, -1, -1},
+ {"Digest", FIPS_TEST_DIGEST, -1, -1},
+ {"HMAC", FIPS_TEST_HMAC, -1, -1},
+ {"CMAC", FIPS_TEST_CMAC, -1, -1},
+ {"DRBG", FIPS_TEST_DRBG, -1, -1},
+ {"X9.31 PRNG", FIPS_TEST_X931, -1, -1},
+ {"RSA", FIPS_TEST_SIGNATURE, -1, EVP_PKEY_RSA},
+ {"DSA", FIPS_TEST_SIGNATURE, -1, EVP_PKEY_DSA},
+ {"ECDSA", FIPS_TEST_SIGNATURE, -1, EVP_PKEY_EC},
+ {"ECDH", FIPS_TEST_ECDH, -1, -1},
+ {NULL, -1, -1, -1}
+ };
+
+static int do_fail_all(int fullpost, int fullerr)
+ {
+ fail_list *ftmp;
+ int rv;
+ size_t i;
+ RSA *rsa = NULL;
+ DSA *dsa = NULL;
+ DRBG_CTX *dctx = NULL, *defctx = NULL;
+ EC_KEY *ec = NULL;
+ BIGNUM *bn = NULL;
+ unsigned char out[10];
+ if (!fullpost)
+ post_quiet = 1;
+ if (!fullerr)
+ no_err = 1;
+ FIPS_module_mode_set(0, NULL);
+ for (ftmp = flist; ftmp->name; ftmp++)
+ {
+ printf(" Testing induced failure of %s test\n", ftmp->name);
+ fail_id = ftmp->id;
+ fail_sub = ftmp->subid;
+ fail_key = ftmp->keyid;
+ rv = FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS);
+ if (rv)
+ {
+ printf("\tFIPS mode incorrectly successful!!\n");
+ st_err++;
+ }
+ }
+ printf(" Testing induced failure of RSA keygen test\n");
+ /* NB POST will succeed with a pairwise test failures as
+ * it is not used during POST.
+ */
+ fail_id = FIPS_TEST_PAIRWISE;
+ fail_key = EVP_PKEY_RSA;
+ /* Now enter FIPS mode successfully */
+ if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+ {
+ printf("\tError entering FIPS mode\n");
+ st_err++;
+ }
+
+ rsa = FIPS_rsa_new();
+ bn = BN_new();
+ if (!rsa || !bn)
+ return 0;
+ BN_set_word(bn, 65537);
+ if (RSA_generate_key_ex(rsa, 2048,bn,NULL))
+ {
+ printf("\tRSA key generated OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tRSA key generation failed as expected.\n");
+
+ /* Leave FIPS mode to clear error */
+ FIPS_module_mode_set(0, NULL);
+
+ printf(" Testing induced failure of DSA keygen test\n");
+ fail_key = EVP_PKEY_DSA;
+ /* Enter FIPS mode successfully */
+ if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+ {
+ printf("\tError entering FIPS mode\n");
+ st_err++;
+ }
+ dsa = FIPS_dsa_new();
+ if (!dsa)
+ return 0;
+ if (!DSA_generate_parameters_ex(dsa, 1024,NULL,0,NULL,NULL,NULL))
+ return 0;
+ if (DSA_generate_key(dsa))
+ {
+ printf("\tDSA key generated OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tDSA key generation failed as expected.\n");
+
+ /* Leave FIPS mode to clear error */
+ FIPS_module_mode_set(0, NULL);
+ /* Enter FIPS mode successfully */
+ if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+ {
+ printf("\tError entering FIPS mode\n");
+ st_err++;
+ }
+
+ printf(" Testing induced failure of ECDSA keygen test\n");
+ fail_key = EVP_PKEY_EC;
+
+ ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+
+ if (!ec)
+ return 0;
+
+ if (EC_KEY_generate_key(ec))
+ {
+ printf("\tECDSA key generated OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tECDSA key generation failed as expected.\n");
+
+ FIPS_ec_key_free(ec);
+ ec = NULL;
+
+ fail_id = -1;
+ fail_sub = -1;
+ fail_key = -1;
+ /* Leave FIPS mode to clear error */
+ FIPS_module_mode_set(0, NULL);
+ /* Enter FIPS mode successfully */
+ if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+ {
+ printf("\tError entering FIPS mode\n");
+ st_err++;
+ }
+ /* Induce continuous PRNG failure for DRBG */
+ printf(" Testing induced failure of DRBG CPRNG test\n");
+ FIPS_drbg_stick(1);
+
+ /* Initialise a DRBG context */
+ dctx = FIPS_drbg_new(NID_sha1, 0);
+ if (!dctx)
+ return 0;
+ for (i = 0; i < sizeof(dummy_drbg_entropy); i++)
+ {
+ dummy_drbg_entropy[i] = i & 0xff;
+ }
+ FIPS_drbg_set_callbacks(dctx, drbg_test_cb, 0, 0x10, drbg_test_cb, 0);
+ if (!FIPS_drbg_instantiate(dctx, dummy_drbg_entropy, 10))
+ {
+ printf("\tDRBG instantiate error!!\n");
+ st_err++;
+ }
+ if (FIPS_drbg_generate(dctx, out, sizeof(out), 0, NULL, 0))
+ {
+ printf("\tDRBG continuous PRNG OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tDRBG continuous PRNG failed as expected\n");
+ FIPS_drbg_stick(0);
+
+ /* Leave FIPS mode to clear error */
+ FIPS_module_mode_set(0, NULL);
+ /* Enter FIPS mode successfully */
+ if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+ {
+ printf("\tError entering FIPS mode\n");
+ st_err++;
+ }
+
+ FIPS_drbg_free(dctx);
+
+ /* Induce continuous PRNG failure for DRBG entropy source*/
+ printf(" Testing induced failure of DRBG entropy CPRNG test\n");
+
+ /* Initialise a DRBG context */
+ dctx = FIPS_drbg_new(NID_sha1, 0);
+ if (!dctx)
+ return 0;
+ for (i = 0; i < sizeof(dummy_drbg_entropy); i++)
+ {
+ dummy_drbg_entropy[i] = i & 0xf;
+ }
+ FIPS_drbg_set_callbacks(dctx, drbg_test_cb, 0, 0x10, drbg_test_cb, 0);
+ if (FIPS_drbg_instantiate(dctx, dummy_drbg_entropy, 10))
+ {
+ printf("\tDRBG continuous PRNG entropy OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tDRBG continuous PRNG entropy failed as expected\n");
+ /* Leave FIPS mode to clear error */
+ FIPS_module_mode_set(0, NULL);
+ /* Enter FIPS mode successfully */
+ if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+ {
+ printf("\tError entering FIPS mode\n");
+ st_err++;
+ }
+ FIPS_drbg_free(dctx);
+
+ /* Leave FIPS mode to clear error */
+ FIPS_module_mode_set(0, NULL);
+ /* Enter FIPS mode successfully */
+ if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+ {
+ printf("\tError entering FIPS mode\n");
+ st_err++;
+ }
+
+ printf(" Testing induced failure of X9.31 CPRNG test\n");
+ FIPS_x931_stick(1);
+ if (!FIPS_x931_set_key(dummy_drbg_entropy, 32))
+ {
+ printf("\tError initialiasing X9.31 PRNG\n");
+ st_err++;
+ }
+ if (!FIPS_x931_seed(dummy_drbg_entropy + 32, 16))
+ {
+ printf("\tError seeding X9.31 PRNG\n");
+ st_err++;
+ }
+ if (FIPS_x931_bytes(out, 10) > 0)
+ {
+ printf("\tX9.31 continuous PRNG failure OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tX9.31 continuous PRNG failed as expected\n");
+ FIPS_x931_stick(0);
+
+ /* Leave FIPS mode to clear error */
+ FIPS_module_mode_set(0, NULL);
+ /* Enter FIPS mode successfully */
+ if (!FIPS_module_mode_set(1, FIPS_AUTH_USER_PASS))
+ {
+ printf("\tError entering FIPS mode\n");
+ st_err++;
+ }
+
+ printf(" Testing operation failure with DRBG entropy failure\n");
+
+ /* Generate DSA key for later use */
+ if (DSA_generate_key(dsa))
+ printf("\tDSA key generated OK as expected.\n");
+ else
+ {
+ printf("\tDSA key generation FAILED!!\n");
+ st_err++;
+ }
+
+ /* Initialise default DRBG context */
+ defctx = FIPS_get_default_drbg();
+ if (!defctx)
+ return 0;
+ if (!FIPS_drbg_init(defctx, NID_sha512, 0))
+ return 0;
+ /* Set entropy failure callback */
+ FIPS_drbg_set_callbacks(defctx, drbg_fail_cb, 0, 0x10, drbg_test_cb, 0);
+ if (FIPS_drbg_instantiate(defctx, dummy_drbg_entropy, 10))
+ {
+ printf("\tDRBG entropy fail OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tDRBG entropy fail failed as expected\n");
+
+ if (FIPS_dsa_sign(dsa, dummy_drbg_entropy, 5, EVP_sha256()))
+ {
+ printf("\tDSA signing OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tDSA signing failed as expected\n");
+
+ ec = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
+
+ if (!ec)
+ return 0;
+
+ if (EC_KEY_generate_key(ec))
+ {
+ printf("\tECDSA key generated OK incorrectly!!\n");
+ st_err++;
+ }
+ else
+ printf("\tECDSA key generation failed as expected.\n");
+
+ printf(" Induced failure test completed with %d errors\n", st_err);
+ post_quiet = 0;
+ no_err = 0;
+ BN_free(bn);
+ FIPS_rsa_free(rsa);
+ FIPS_dsa_free(dsa);
+ FIPS_ec_key_free(ec);
+ if (st_err)
+ return 0;
+ return 1;
+ }
+
+#ifdef FIPS_ALGVS
+int fips_test_suite_main(int argc, char **argv)
+#else
+int main(int argc, char **argv)
+#endif