X-Git-Url: https://git.openssl.org/?a=blobdiff_plain;f=test%2Fdrbgtest.c;h=1aef1fe41a78fb97a297c35764980f2417e3ba2d;hb=1c615e4ce97715ae3af9255bc57be32a49687966;hp=f2054a8ac5e65ab086d23ed373ddc702a5d3fd35;hpb=1b39bc9bcf2c8a0eb1047529feb91ed00c8c6ff7;p=openssl.git diff --git a/test/drbgtest.c b/test/drbgtest.c index f2054a8ac5..1aef1fe41a 100644 --- a/test/drbgtest.c +++ b/test/drbgtest.c @@ -581,6 +581,8 @@ static void reset_drbg_hook_ctx(void) * 1: it is expected that the specified DRBG is reseeded * 0: it is expected that the specified DRBG is not reseeded * -1: don't check whether the specified DRBG was reseeded or not + * |reseed_time|: if nonzero, used instead of time(NULL) to set the + * |before_reseed| time. */ static int test_drbg_reseed(int expect_success, RAND_DRBG *master, @@ -588,7 +590,8 @@ static int test_drbg_reseed(int expect_success, RAND_DRBG *private, int expect_master_reseed, int expect_public_reseed, - int expect_private_reseed + int expect_private_reseed, + time_t reseed_time ) { unsigned char buf[32]; @@ -614,8 +617,11 @@ static int test_drbg_reseed(int expect_success, * step 2: generate random output */ + if (reseed_time == 0) + reseed_time = time(NULL); + /* Generate random output from the public and private DRBG */ - before_reseed = expect_master_reseed == 1 ? time(NULL) : 0; + before_reseed = expect_master_reseed == 1 ? reseed_time : 0; if (!TEST_int_eq(RAND_bytes(buf, sizeof(buf)), expect_success) || !TEST_int_eq(RAND_priv_bytes(buf, sizeof(buf)), expect_success)) return 0; @@ -677,11 +683,12 @@ static int test_drbg_reseed(int expect_success, * setup correctly, in particular whether reseeding works * as designed. */ -static int test_rand_reseed(void) +static int test_rand_drbg_reseed(void) { RAND_DRBG *master, *public, *private; unsigned char rand_add_buf[256]; int rv=0; + time_t before_reseed; /* Check whether RAND_OpenSSL() is the default method */ if (!TEST_ptr_eq(RAND_get_rand_method(), RAND_OpenSSL())) @@ -716,7 +723,7 @@ static int test_rand_reseed(void) /* * Test initial seeding of shared DRBGs */ - if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1))) + if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, 0))) goto error; reset_drbg_hook_ctx(); @@ -724,7 +731,7 @@ static int test_rand_reseed(void) /* * Test initial state of shared DRBGs */ - if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 0))) + if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 0, 0))) goto error; reset_drbg_hook_ctx(); @@ -733,7 +740,7 @@ static int test_rand_reseed(void) * reseed counters differ from the master's reseed counter. */ master->reseed_prop_counter++; - if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 1, 1))) + if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 1, 1, 0))) goto error; reset_drbg_hook_ctx(); @@ -743,7 +750,7 @@ static int test_rand_reseed(void) */ master->reseed_prop_counter++; private->reseed_prop_counter++; - if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 1, 0))) + if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 1, 0, 0))) goto error; reset_drbg_hook_ctx(); @@ -753,7 +760,7 @@ static int test_rand_reseed(void) */ master->reseed_prop_counter++; public->reseed_prop_counter++; - if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 1))) + if (!TEST_true(test_drbg_reseed(1, master, public, private, 0, 0, 1, 0))) goto error; reset_drbg_hook_ctx(); @@ -762,10 +769,17 @@ static int test_rand_reseed(void) memset(rand_add_buf, 'r', sizeof(rand_add_buf)); /* - * Test whether all three DRBGs are reseeded by RAND_add() + * Test whether all three DRBGs are reseeded by RAND_add(). + * The before_reseed time has to be measured here and passed into the + * test_drbg_reseed() test, because the master DRBG gets already reseeded + * in RAND_add(), whence the check for the condition + * before_reseed <= master->reseed_time will fail if the time value happens + * to increase between the RAND_add() and the test_drbg_reseed() call. */ + before_reseed = time(NULL); RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf)); - if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1))) + if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, + before_reseed))) goto error; reset_drbg_hook_ctx(); @@ -776,7 +790,7 @@ static int test_rand_reseed(void) master_ctx.fail = 1; master->reseed_prop_counter++; RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf)); - if (!TEST_true(test_drbg_reseed(0, master, public, private, 0, 0, 0))) + if (!TEST_true(test_drbg_reseed(0, master, public, private, 0, 0, 0, 0))) goto error; reset_drbg_hook_ctx(); @@ -799,12 +813,15 @@ static void run_multi_thread_test(void) { unsigned char buf[256]; time_t start = time(NULL); - RAND_DRBG *public, *private; + RAND_DRBG *public = NULL, *private = NULL; - public = RAND_DRBG_get0_public(); - private = RAND_DRBG_get0_private(); - RAND_DRBG_set_reseed_time_interval(public, 1); + if (!TEST_ptr(public = RAND_DRBG_get0_public()) + || !TEST_ptr(private = RAND_DRBG_get0_private())) { + multi_thread_rand_bytes_succeeded = 0; + return; + } RAND_DRBG_set_reseed_time_interval(private, 1); + RAND_DRBG_set_reseed_time_interval(public, 1); do { if (RAND_bytes(buf, sizeof(buf)) <= 0) @@ -885,64 +902,69 @@ static int test_multi_thread(void) #endif /* - * This function only returns the entropy already added with RAND_add(), - * and does not get entropy from the OS. + * Test that instantiation with RAND_seed() works as expected + * + * If no os entropy source is available then RAND_seed(buffer, bufsize) + * is expected to succeed if and only if the buffer length is at least + * rand_drbg_seedlen(master) bytes. * - * Returns 0 on failure and the size of the buffer on success. + * If an os entropy source is available then RAND_seed(buffer, bufsize) + * is expected to succeed always. */ -static size_t get_pool_entropy(RAND_DRBG *drbg, - unsigned char **pout, - int entropy, size_t min_len, size_t max_len, - int prediction_resistance) +static int test_rand_seed(void) { - if (drbg->pool == NULL) - return 0; + RAND_DRBG *master = NULL; + unsigned char rand_buf[256]; + size_t rand_buflen; + size_t required_seed_buflen = 0; - if (drbg->pool->entropy < (size_t)entropy || drbg->pool->len < min_len - || drbg->pool->len > max_len) + if (!TEST_ptr(master = RAND_DRBG_get0_master())) return 0; - *pout = drbg->pool->buffer; - return drbg->pool->len; -} +#ifdef OPENSSL_RAND_SEED_NONE + required_seed_buflen = rand_drbg_seedlen(master); +#endif -/* - * Clean up the entropy that get_pool_entropy() returned. - */ -static void cleanup_pool_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen) -{ - OPENSSL_secure_clear_free(drbg->pool->buffer, drbg->pool->max_len); - OPENSSL_free(drbg->pool); - drbg->pool = NULL; + memset(rand_buf, 0xCD, sizeof(rand_buf)); + + for ( rand_buflen = 256 ; rand_buflen > 0 ; --rand_buflen ) { + RAND_DRBG_uninstantiate(master); + RAND_seed(rand_buf, rand_buflen); + + if (!TEST_int_eq(RAND_status(), + (rand_buflen >= required_seed_buflen))) + return 0; + } + + return 1; } /* - * Test that instantiating works when OS entropy is not available and that - * RAND_add() is enough to reseed it. + * Test that adding additional data with RAND_add() works as expected + * when the master DRBG is instantiated (and below its reseed limit). + * + * This should succeed regardless of whether an os entropy source is + * available or not. */ static int test_rand_add(void) { - RAND_DRBG *master = RAND_DRBG_get0_master(); - RAND_DRBG_get_entropy_fn old_get_entropy = master->get_entropy; - RAND_DRBG_cleanup_entropy_fn old_cleanup_entropy = master->cleanup_entropy; - int rv = 0; - unsigned char rand_add_buf[256]; + unsigned char rand_buf[256]; + size_t rand_buflen; - master->get_entropy = get_pool_entropy; - master->cleanup_entropy = cleanup_pool_entropy; - master->reseed_prop_counter++; - RAND_DRBG_uninstantiate(master); - memset(rand_add_buf, 0xCD, sizeof(rand_add_buf)); - RAND_add(rand_add_buf, sizeof(rand_add_buf), sizeof(rand_add_buf)); - if (!TEST_true(RAND_DRBG_instantiate(master, NULL, 0))) - goto error; + memset(rand_buf, 0xCD, sizeof(rand_buf)); - rv = 1; + /* make sure it's instantiated */ + RAND_seed(rand_buf, sizeof(rand_buf)); + if (!TEST_true(RAND_status())) + return 0; -error: - master->get_entropy = old_get_entropy; - master->cleanup_entropy = old_cleanup_entropy; - return rv; + for ( rand_buflen = 256 ; rand_buflen > 0 ; --rand_buflen ) { + RAND_add(rand_buf, rand_buflen, 0.0); + if (!TEST_true(RAND_status())) + return 0; + } + + return 1; } static int test_multi_set(void) @@ -983,14 +1005,13 @@ err: static int test_set_defaults(void) { - RAND_DRBG *master, *public, *private; - - master = RAND_DRBG_get0_master(); - public = RAND_DRBG_get0_public(); - private = RAND_DRBG_get0_private(); + RAND_DRBG *master = NULL, *public = NULL, *private = NULL; /* Check the default type and flags for master, public and private */ - return TEST_int_eq(master->type, RAND_DRBG_TYPE) + return TEST_ptr(master = RAND_DRBG_get0_master()) + && TEST_ptr(public = RAND_DRBG_get0_public()) + && TEST_ptr(private = RAND_DRBG_get0_private()) + && TEST_int_eq(master->type, RAND_DRBG_TYPE) && TEST_int_eq(master->flags, RAND_DRBG_FLAGS | RAND_DRBG_FLAG_MASTER) && TEST_int_eq(public->type, RAND_DRBG_TYPE) @@ -1068,7 +1089,8 @@ int setup_tests(void) ADD_ALL_TESTS(test_kats, OSSL_NELEM(drbg_test)); ADD_ALL_TESTS(test_error_checks, OSSL_NELEM(drbg_test)); - ADD_TEST(test_rand_reseed); + ADD_TEST(test_rand_drbg_reseed); + ADD_TEST(test_rand_seed); ADD_TEST(test_rand_add); ADD_TEST(test_multi_set); ADD_TEST(test_set_defaults);