From 4cfb8820e4124a5348fe4f46ac72cc84562cbe7e Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Tue, 4 Jun 2019 10:51:53 -0400 Subject: [PATCH] rngd: prioritize faster sources of entropy We have two broad categories of entropy sources in rngd. Fast sources and slow sources. Slow sources (like jitterentropy) provided entropy to systems that have no other entropy source, but can actually hinder performance when large amounts of entropy are requested (consider a case where the entropy pool is empty, and the rdrand source can provide twice the entropy in half the time that jitterentropy can). Its still valuable to have jitterentropy enabled, but we shouldn't be extracting entropy from it, if a faster source can provide it. So lets prioritize our fast sources over the slow ones. in the do_loop, lets by default not collect entropy from sources marked as slow. If we pass through an interation of the do_loop with no entropy collected, then lets include the slow sources on the next pass to give us a better chance at collection. Then, when entropy is gathered, we can go back to only using the fast sources. Signed-off-by: Neil Horman --- rngd.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/rngd.c b/rngd.c index 1b3d73d..a086949 100644 --- a/rngd.c +++ b/rngd.c @@ -577,6 +577,7 @@ static void do_loop(int random_step) int i; int retval; struct rng *iter; + bool try_slow_sources = false; int (*random_add_fn)(struct rng *rng, int random_step, unsigned char *buf, fips_ctx_t *fipsctx_in); @@ -587,11 +588,29 @@ static void do_loop(int random_step) for (no_work = 0; no_work < 100; no_work = (work_done ? 0 : no_work+1)) { work_done = false; + + /* + * Exclude slow sources when faster sources are working well + * sources like jitterentropy can provide some entropy when needed + * but can actually hinder performance when large amounts of entropy are needed + * owing to the fact that they may block while generating said entropy + * So, lets prioritize the faster sources. Start by only trying to collect + * entropy from the fast sources, then iff that fails, start including the slower + * sources as well. Once we get some entropy, return to only using fast sources + */ + if (no_work) + try_slow_sources = true; + else + try_slow_sources = false; + for (i = 0; i < ENT_MAX; ++i) { int rc; /*message(LOG_CONS|LOG_INFO, "I is %d\n", i);*/ iter = &entropy_sources[i]; + if (!try_slow_sources && iter->flags.slow_source) + continue; + retry_same: if (!server_running) return;