X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=test%2Fdrbgtest.c;h=882fef82d4ddc522a624ac1d9ca1abe5020e0601;hp=bb51e0121036a67249553329033aee89307cc2c9;hb=c89d9cdab1727553e3cfa964e9f082cbc5a194c2;hpb=3064b55134434a0b2850f07eff57120f35bb269a diff --git a/test/drbgtest.c b/test/drbgtest.c index bb51e01210..882fef82d4 100644 --- a/test/drbgtest.c +++ b/test/drbgtest.c @@ -677,7 +677,7 @@ 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]; @@ -884,64 +884,107 @@ static int test_multi_thread(void) } #endif +#ifdef OPENSSL_RAND_SEED_NONE /* - * This function only returns the entropy already added with RAND_add(), - * and does not get entropy from the OS. + * Calculates the minimum buffer length which needs to be + * provided to RAND_seed() in order to successfully + * instantiate the DRBG. * - * Returns 0 on failure and the size of the buffer on success. + * Copied from rand_drbg_seedlen() in rand_drbg.c */ -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 size_t rand_drbg_seedlen(RAND_DRBG *drbg) { - if (drbg->pool == NULL) - return 0; + /* + * If no os entropy source is available then RAND_seed(buffer, bufsize) + * is expected to succeed if and only if the buffer length satisfies + * the following requirements, which follow from the calculations + * in RAND_DRBG_instantiate(). + */ + size_t min_entropy = drbg->strength; + size_t min_entropylen = drbg->min_entropylen; - if (drbg->pool->entropy < (size_t)entropy || drbg->pool->len < min_len - || drbg->pool->len > max_len) - return 0; + /* + * Extra entropy for the random nonce in the absence of a + * get_nonce callback, see comment in RAND_DRBG_instantiate(). + */ + if (drbg->min_noncelen > 0 && drbg->get_nonce == NULL) { + min_entropy += drbg->strength / 2; + min_entropylen += drbg->min_noncelen; + } + + /* + * Convert entropy requirement from bits to bytes + * (dividing by 8 without rounding upwards, because + * all entropy requirements are divisible by 8). + */ + min_entropy >>= 3; - *pout = drbg->pool->buffer; - return drbg->pool->len; + /* Return a value that satisfies both requirements */ + return min_entropy > min_entropylen ? min_entropy : min_entropylen; } +#endif /*OPENSSL_RAND_SEED_NONE*/ /* - * Clean up the entropy that get_pool_entropy() returned. + * 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. + * + * If an os entropy source is available then RAND_seed(buffer, bufsize) + * is expected to succeed always. */ -static void cleanup_pool_entropy(RAND_DRBG *drbg, unsigned char *out, size_t outlen) +static int test_rand_seed(void) { - OPENSSL_free(drbg->pool); - drbg->pool = NULL; + RAND_DRBG *master = RAND_DRBG_get0_master(); + unsigned char rand_buf[256]; + size_t rand_buflen; +#ifdef OPENSSL_RAND_SEED_NONE + size_t required_seed_buflen = rand_drbg_seedlen(master); +#else + size_t required_seed_buflen = 0; +#endif + + 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) @@ -1067,7 +1110,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);