From faf8fd252785ee8b181d11c3aea7e0b2b0ed3f56 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Mattias=20R=C3=B6nnblom?= Date: Fri, 28 Jun 2019 11:01:22 +0200 Subject: [PATCH] eal: improve entropy for initial PRNG seed MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Replace the use of rte_get_timer_cycles() with getentropy() for seeding the pseudo-random number generator. getentropy() provides a more truly random value. getentropy() requires glibc 2.25 and Linux kernel 3.17. In case getentropy() is not found at compile time, or the relevant syscall fails in runtime, the rdseed machine instruction will be used as a fallback. rdseed is only available on x86 (Broadwell or later). In case it is not present, rte_get_timer_cycles() will be used as a second fallback. On non-Meson builds, getentropy() will not be used. Suggested-by: Bruce Richardson Suggested-by: Stephen Hemminger Signed-off-by: Mattias Rönnblom Acked-by: Bruce Richardson --- lib/librte_eal/common/rte_random.c | 36 +++++++++++++++++++++++++++++- lib/librte_eal/meson.build | 3 +++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/librte_eal/common/rte_random.c b/lib/librte_eal/common/rte_random.c index 4d3cf52260..e53d96d180 100644 --- a/lib/librte_eal/common/rte_random.c +++ b/lib/librte_eal/common/rte_random.c @@ -2,7 +2,11 @@ * Copyright(c) 2019 Ericsson AB */ +#ifdef RTE_MACHINE_CPUFLAG_RDSEED +#include +#endif #include +#include #include #include @@ -133,7 +137,37 @@ rte_rand(void) return __rte_rand_lfsr258(state); } +static uint64_t +__rte_random_initial_seed(void) +{ +#ifdef RTE_LIBEAL_USE_GETENTROPY + int ge_rc; + uint64_t ge_seed; + + ge_rc = getentropy(&ge_seed, sizeof(ge_seed)); + + if (ge_rc == 0) + return ge_seed; +#endif +#ifdef RTE_MACHINE_CPUFLAG_RDSEED + unsigned int rdseed_rc; + unsigned long long rdseed_seed; + + /* first fallback: rdseed instruction, if available */ + rdseed_rc = _rdseed64_step(&rdseed_seed); + + if (rdseed_rc == 1) + return (uint64_t)rdseed_seed; +#endif + /* second fallback: seed using rdtsc */ + return rte_get_timer_cycles(); +} + RTE_INIT(rte_rand_init) { - rte_srand(rte_get_timer_cycles()); + uint64_t seed; + + seed = __rte_random_initial_seed(); + + rte_srand(seed); } diff --git a/lib/librte_eal/meson.build b/lib/librte_eal/meson.build index fa36b20e09..ccd5b85b82 100644 --- a/lib/librte_eal/meson.build +++ b/lib/librte_eal/meson.build @@ -18,6 +18,9 @@ deps += 'kvargs' if dpdk_conf.has('RTE_USE_LIBBSD') ext_deps += libbsd endif +if cc.has_function('getentropy', prefix : '#include ') + cflags += '-DRTE_LIBEAL_USE_GETENTROPY' +endif sources = common_sources + env_sources objs = common_objs + env_objs headers = common_headers + env_headers -- 2.20.1