specific data, which can subsequently be retrieved by the entropy and nonce
callbacks using RAND_DRBG_get_callback_data().
The ownership of the context data remains with the caller, i.e., it is the
-caller's responsibility to keep it available as long as it is need by the
+caller's responsibility to keep it available as long as it is needed by the
callbacks and free it after use.
For more information about the the callback data see the NOTES section.
utilize for the nonce, following the recommendations of [NIST SP 800-90A Rev. 1],
section 8.6.7.
-The callback data a rather specialized feature, because in general the
+The callback data is a rather specialized feature, because in general the
random sources don't (and in fact, they must not) depend on any state provided
by the DRBG.
There are however exceptional cases where this feature is useful, most notably
make_drbg_test_data_hash(NID_sha512, sha512, 0),
};
-static int app_data_index;
-
/*
* Test context data, attached as EXDATA to the RAND_DRBG
*/
int entropy, size_t min_len, size_t max_len,
int prediction_resistance)
{
- TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
+ TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_callback_data(drbg);
t->entropycnt++;
*pout = (unsigned char *)t->entropy;
static size_t kat_nonce(RAND_DRBG *drbg, unsigned char **pout,
int entropy, size_t min_len, size_t max_len)
{
- TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
+ TEST_CTX *t = (TEST_CTX *)RAND_DRBG_get_callback_data(drbg);
t->noncecnt++;
*pout = (unsigned char *)t->nonce;
return 0;
if (!TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
kat_nonce, NULL))
+ || !TEST_true(RAND_DRBG_set_callback_data(drbg, &t))
|| !TEST_true(disable_crngt(drbg))) {
failures++;
goto err;
t.entropylen = td->entropylen;
t.nonce = td->nonce;
t.noncelen = td->noncelen;
- RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
if (!TEST_true(RAND_DRBG_instantiate(drbg, td->pers, td->perslen))
|| !TEST_true(RAND_DRBG_generate(drbg, buff, td->exlen, 0,
*/
if (!TEST_true(RAND_DRBG_set(drbg, td->nid, td->flags))
|| !TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
- kat_nonce, NULL)))
+ kat_nonce, NULL))
+ || !TEST_true(RAND_DRBG_set_callback_data(drbg, &t)))
failures++;
- RAND_DRBG_set_ex_data(drbg, app_data_index, &t);
t.entropy = td->entropy_pr;
t.entropylen = td->entropylen_pr;
t.nonce = td->nonce_pr;
|| !TEST_true(RAND_DRBG_set_callbacks(drbg, kat_entropy, NULL,
kat_nonce, NULL)))
return 0;
- RAND_DRBG_set_ex_data(drbg, app_data_index, t);
+ RAND_DRBG_set_callback_data(drbg, t);
t->entropy = td->entropy;
t->entropylen = td->entropylen;
t->nonce = td->nonce;
static HOOK_CTX *get_hook_ctx(RAND_DRBG *drbg)
{
- return (HOOK_CTX *)RAND_DRBG_get_ex_data(drbg, app_data_index);
+ return (HOOK_CTX *)RAND_DRBG_get_callback_data(drbg);
}
/* Intercepts and counts calls to the get_entropy() callback */
memset(ctx, 0, sizeof(*ctx));
ctx->drbg = drbg;
ctx->get_entropy = drbg->get_entropy;
+
+ /*
+ * We can't use the public API here, since it prohibits modifying
+ * the callbacks or the callback data of chained DRBGs.
+ */
drbg->get_entropy = get_entropy_hook;
- RAND_DRBG_set_ex_data(drbg, app_data_index, ctx);
+ drbg->callback_data = ctx;
}
/* Installs the hook for the get_entropy() callback of the given drbg */
static void unhook_drbg(RAND_DRBG *drbg)
{
- HOOK_CTX *ctx = get_hook_ctx(drbg);
+ HOOK_CTX *ctx = drbg->callback_data;
- drbg->get_entropy = ctx->get_entropy;
- CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RAND_DRBG, drbg, &drbg->ex_data);
+ if (ctx != NULL)
+ drbg->get_entropy = ctx->get_entropy;
}
/* Resets the given hook context */
int setup_tests(void)
{
- app_data_index = RAND_DRBG_get_ex_new_index(0L, NULL, NULL, NULL, NULL);
-
ADD_ALL_TESTS(test_kats, OSSL_NELEM(drbg_test));
ADD_ALL_TESTS(test_error_checks, OSSL_NELEM(drbg_test));
ADD_TEST(test_rand_drbg_reseed);