-/*
- * Hook context data, attached as EXDATA to the RAND_DRBG
- */
-typedef struct hook_ctx_st {
- RAND_DRBG *drbg;
- /*
- * Currently, all DRBGs use the same get_entropy() callback.
- * The tests however, don't assume this and store
- * the original callback for every DRBG separately.
- */
- RAND_DRBG_get_entropy_fn get_entropy;
- /* forces a failure of the get_entropy() call if nonzero */
- int fail;
- /* counts successful reseeds */
- int reseed_count;
-} HOOK_CTX;
-
-static HOOK_CTX master_ctx, public_ctx, private_ctx;
-
-static HOOK_CTX *get_hook_ctx(RAND_DRBG *drbg)
-{
- return (HOOK_CTX *)RAND_DRBG_get_callback_data(drbg);
-}
-
-/* Intercepts and counts calls to the get_entropy() callback */
-static size_t get_entropy_hook(RAND_DRBG *drbg, unsigned char **pout,
- int entropy, size_t min_len, size_t max_len,
- int prediction_resistance)
-{
- size_t ret;
- HOOK_CTX *ctx = get_hook_ctx(drbg);
-
- if (ctx->fail != 0)
- return 0;
-
- ret = ctx->get_entropy(drbg, pout, entropy, min_len, max_len,
- prediction_resistance);
-
- if (ret != 0)
- ctx->reseed_count++;
- return ret;
-}
-
-/* Installs a hook for the get_entropy() callback of the given drbg */
-static void hook_drbg(RAND_DRBG *drbg, HOOK_CTX *ctx)
-{
- 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;
- 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 = drbg->callback_data;
-
- if (ctx != NULL)
- drbg->get_entropy = ctx->get_entropy;
-}
-
-/* Resets the given hook context */
-static void reset_hook_ctx(HOOK_CTX *ctx)
-{
- ctx->fail = 0;
- ctx->reseed_count = 0;
-}
-
-/* Resets all drbg hook contexts */
-static void reset_drbg_hook_ctx(void)
-{
- reset_hook_ctx(&master_ctx);
- reset_hook_ctx(&public_ctx);
- reset_hook_ctx(&private_ctx);
-}
-