[PATCH] eal: add support for TRNG with Arm RNG feature
Mattias Rönnblom
hofors at lysator.liu.se
Wed Jul 24 08:40:39 CEST 2024
On 2024-07-23 23:27, Shunzhi Wen wrote:> True Random Number Generator
(TRNG) is capable of
> generating random numbers from a physical entropy source.
> TRNG is enabled when compiled on Arm arch that supports
> FEAT_RNG introduced in Armv8.5-A flagged by __ARM_FEATURE_RNG.
>
I'm missing a rationale here. Why is this useful?
> Signed-off-by: Shunzhi Wen <shunzhi.wen at arm.com>
> Reviewed-by: Wathsala Vithanage <wathsala.vithanage at arm.com>
> Reviewed-by: Jack Bond-Preston <jack.bond-preston at arm.com>
> Reviewed-by: Dhruv Tripathi <dhruv.tripathi at arm.com>
> ---
> .mailmap | 2 ++
> app/test/test_rand_perf.c | 25 +++++++++++++++++--
> config/arm/meson.build | 2 +-
> lib/eal/arm/include/rte_cpuflags_64.h | 3 +++
> lib/eal/arm/meson.build | 1 +
> lib/eal/arm/rte_cpuflags.c | 1 +
> lib/eal/arm/rte_random.c | 20 +++++++++++++++
> .../{rte_random.c => eal_common_random.c} | 0
> lib/eal/common/meson.build | 2 +-
> lib/eal/include/rte_random.h | 17 +++++++++++++
> lib/eal/loongarch/meson.build | 1 +
> lib/eal/loongarch/rte_random.c | 14 +++++++++++
> lib/eal/ppc/meson.build | 1 +
> lib/eal/ppc/rte_random.c | 14 +++++++++++
> lib/eal/riscv/meson.build | 1 +
> lib/eal/riscv/rte_random.c | 14 +++++++++++
> lib/eal/version.map | 1 +
> lib/eal/x86/meson.build | 1 +
> lib/eal/x86/rte_random.c | 14 +++++++++++
> 19 files changed, 130 insertions(+), 4 deletions(-)
> create mode 100644 lib/eal/arm/rte_random.c
> rename lib/eal/common/{rte_random.c => eal_common_random.c} (100%)
> create mode 100644 lib/eal/loongarch/rte_random.c
> create mode 100644 lib/eal/ppc/rte_random.c
> create mode 100644 lib/eal/riscv/rte_random.c
> create mode 100644 lib/eal/x86/rte_random.c
>
> diff --git a/.mailmap b/.mailmap
> index ac06962e82..23209edfd2 100644
> --- a/.mailmap
> +++ b/.mailmap
> @@ -338,6 +338,7 @@ Dexia Li <dexia.li at jaguarmicro.com>
> Dexuan Cui <decui at microsoft.com>
> Dharmik Thakkar <dharmikjayesh.thakkar at arm.com>
<dharmik.thakkar at arm.com>
> Dheemanth Mallikarjun <dheemanthm at vmware.com>
> +Dhruv Tripathi <dhruv.tripathi at arm.com>
> Diana Wang <na.wang at corigine.com>
> Didier Pallard <didier.pallard at 6wind.com>
> Dilshod Urazov <dilshod.urazov at oktetlabs.ru>
> @@ -1353,6 +1354,7 @@ Shuki Katzenelson <shuki at lightbitslabs.com>
> Shun Hao <shunh at nvidia.com>
> Shu Shen <shu.shen at radisys.com>
> Shujing Dong <shujing.dong at corigine.com>
> +Shunzhi Wen <shunzhi.wen at arm.com>
> Shweta Choudaha <shweta.choudaha at att.com>
> Shyam Kumar Shrivastav <shrivastav.shyam at gmail.com>
> Shy Shyman <shys at nvidia.com> <shys at mellanox.com>
> diff --git a/app/test/test_rand_perf.c b/app/test/test_rand_perf.c
> index 30204e12c0..b61cc75014 100644
> --- a/app/test/test_rand_perf.c
> +++ b/app/test/test_rand_perf.c
> @@ -20,6 +20,7 @@ static volatile uint64_t vsum;
>
> enum rand_type {
> rand_type_64,
> + rand_type_true_rand_64,
> rand_type_float,
> rand_type_bounded_best_case,
> rand_type_bounded_worst_case
> @@ -31,6 +32,8 @@ rand_type_desc(enum rand_type rand_type)
> switch (rand_type) {
> case rand_type_64:
> return "Full 64-bit [rte_rand()]";
> + case rand_type_true_rand_64:
> + return "Full 64-bit True Random [rte_trand()]";
> case rand_type_float:
> return "Floating point [rte_drand()]";
> case rand_type_bounded_best_case:
> @@ -50,6 +53,9 @@ test_rand_perf_type(enum rand_type rand_type)
> uint64_t end;
> uint64_t sum = 0;
> uint64_t op_latency;
> + int ret;
> + uint64_t val;
> + uint32_t fail_count = 0;
>
> start = rte_rdtsc();
>
> @@ -58,6 +64,13 @@ test_rand_perf_type(enum rand_type rand_type)
> case rand_type_64:
> sum += rte_rand();
> break;
> + case rand_type_true_rand_64:
> + ret = rte_trand(&val);
> + if (ret == 0)
> + sum += val;
> + else
> + fail_count++;
> + break;
> case rand_type_float:
> sum += 1000. * rte_drand();
> break;
> @@ -77,8 +90,15 @@ test_rand_perf_type(enum rand_type rand_type)
>
> op_latency = (end - start) / ITERATIONS;
>
> - printf("%s: %"PRId64" TSC cycles/op\n", rand_type_desc(rand_type),
> - op_latency);
> + if (!fail_count)
> + printf("%s: %"PRId64" TSC cycles/op\n",
> + rand_type_desc(rand_type),
> + op_latency);
> + else
> + printf("%s: %"PRId64" TSC cycles/op (failed %d time(s))\n",
> + rand_type_desc(rand_type),
> + op_latency,
> + fail_count);
> }
>
> static int
> @@ -89,6 +109,7 @@ test_rand_perf(void)
> printf("Pseudo-random number generation latencies:\n");
>
> test_rand_perf_type(rand_type_64);
> + test_rand_perf_type(rand_type_true_rand_64);
> test_rand_perf_type(rand_type_float);
> test_rand_perf_type(rand_type_bounded_best_case);
> test_rand_perf_type(rand_type_bounded_worst_case);
> diff --git a/config/arm/meson.build b/config/arm/meson.build
> index 012935d5d7..13be94254e 100644
> --- a/config/arm/meson.build
> +++ b/config/arm/meson.build
> @@ -95,7 +95,7 @@ part_number_config_arm = {
> },
> '0xd49': {
> 'march': 'armv9-a',
> - 'march_features': ['sve2'],
> + 'march_features': ['sve2', 'rng'],
> 'fallback_march': 'armv8.5-a',
> 'mcpu': 'neoverse-n2',
> 'flags': [
> diff --git a/lib/eal/arm/include/rte_cpuflags_64.h
b/lib/eal/arm/include/rte_cpuflags_64.h
> index afe70209c3..6aa067339f 100644
> --- a/lib/eal/arm/include/rte_cpuflags_64.h
> +++ b/lib/eal/arm/include/rte_cpuflags_64.h
> @@ -36,6 +36,9 @@ enum rte_cpu_flag_t {
> RTE_CPUFLAG_SVEF64MM,
> RTE_CPUFLAG_SVEBF16,
> RTE_CPUFLAG_AARCH64,
> +
> + /* RNDR, RNDRRS instructions */
> + RTE_CPUFLAG_RNG,
> };
>
> #include "generic/rte_cpuflags.h"
> diff --git a/lib/eal/arm/meson.build b/lib/eal/arm/meson.build
> index 6fba3d6ba7..e9e468cbf0 100644
> --- a/lib/eal/arm/meson.build
> +++ b/lib/eal/arm/meson.build
> @@ -9,4 +9,5 @@ sources += files(
> 'rte_hypervisor.c',
> 'rte_mmu.c',
> 'rte_power_intrinsics.c',
> + 'rte_random.c',
> )
> diff --git a/lib/eal/arm/rte_cpuflags.c b/lib/eal/arm/rte_cpuflags.c
> index 7ba4f8ba97..56074f0c6a 100644
> --- a/lib/eal/arm/rte_cpuflags.c
> +++ b/lib/eal/arm/rte_cpuflags.c
> @@ -116,6 +116,7 @@ const struct feature_entry
rte_cpu_feature_table[] = {
> FEAT_DEF(SVEF64MM, REG_HWCAP2, 11)
> FEAT_DEF(SVEBF16, REG_HWCAP2, 12)
> FEAT_DEF(AARCH64, REG_PLATFORM, 0)
> + FEAT_DEF(RNG, REG_HWCAP2, 16)
> };
> #endif /* RTE_ARCH */
>
> diff --git a/lib/eal/arm/rte_random.c b/lib/eal/arm/rte_random.c
> new file mode 100644
> index 0000000000..74c8fa733b
> --- /dev/null
> +++ b/lib/eal/arm/rte_random.c
> @@ -0,0 +1,20 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2024 Arm Limited
> + */
> +
> +#include "arm_acle.h"
> +#include "rte_common.h"
> +#include "rte_random.h"
> +#include <errno.h>
> +
> +int
> +rte_trand(uint64_t *val)
> +{
> +#if defined __ARM_FEATURE_RNG
> + int ret = __rndr(val);
> + return (ret == 0) ? 0 : -ENODATA;
> +#else
> + RTE_SET_USED(val);
> + return -ENOTSUP;
> +#endif
> +}
> diff --git a/lib/eal/common/rte_random.c
b/lib/eal/common/eal_common_random.c
> similarity index 100%
> rename from lib/eal/common/rte_random.c
> rename to lib/eal/common/eal_common_random.c
> diff --git a/lib/eal/common/meson.build b/lib/eal/common/meson.build
> index 22a626ba6f..c4405aa48b 100644
> --- a/lib/eal/common/meson.build
> +++ b/lib/eal/common/meson.build
> @@ -32,7 +32,6 @@ sources += files(
> 'malloc_elem.c',
> 'malloc_heap.c',
> 'rte_malloc.c',
> - 'rte_random.c',
> 'rte_reciprocal.c',
> 'rte_service.c',
> 'rte_version.c',
> @@ -48,6 +47,7 @@ if not is_windows
> 'eal_common_trace.c',
> 'eal_common_trace_ctf.c',
> 'eal_common_trace_utils.c',
> + 'eal_common_random.c',
> 'hotplug_mp.c',
> 'malloc_mp.c',
> 'rte_keepalive.c',
> diff --git a/lib/eal/include/rte_random.h b/lib/eal/include/rte_random.h
> index 5031c6fe5f..e6b5ac46ed 100644
> --- a/lib/eal/include/rte_random.h
> +++ b/lib/eal/include/rte_random.h
> @@ -15,6 +15,7 @@
> extern "C" {
> #endif
>
> +#include <rte_compat.h>
> #include <stdint.h>
>
> /**
> @@ -84,6 +85,22 @@ rte_rand_max(uint64_t upper_bound);
> */
> double rte_drand(void);
>
> +/**
> + * Get a true random value.
> + *
> + * The generator is cryptographically secure.
If you want to extend <rte_random.h> with a cryptographically secure
random number generator, that's fine.
To have an API that's only available on certain ARM CPUs is not.
NAK
A new function should be called something with "secure", rather than
"true" (which is a bit silly, since we might well live in a completely
deterministic universe). "secure" would more clearly communicate the
intent, and also doesn't imply any particular implementation.
> + *
> + * @param val
> + * A pointer to store a true random value between 0 and (1<<64)-1.
> + * @return
> + * 0 on success
> + * -ENODATA on failure
> + * -ENOTSUP if unsupported
> + */
> +__rte_experimental
> +int
> +rte_trand(uint64_t *val);
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/lib/eal/loongarch/meson.build
b/lib/eal/loongarch/meson.build
> index 3acfe6c3bd..f1dc741598 100644
> --- a/lib/eal/loongarch/meson.build
> +++ b/lib/eal/loongarch/meson.build
> @@ -9,4 +9,5 @@ sources += files(
> 'rte_hypervisor.c',
> 'rte_mmu.c',
> 'rte_power_intrinsics.c',
> + 'rte_random.c',
> )
> diff --git a/lib/eal/loongarch/rte_random.c
b/lib/eal/loongarch/rte_random.c
> new file mode 100644
> index 0000000000..d033c47ea1
> --- /dev/null
> +++ b/lib/eal/loongarch/rte_random.c
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2024 Arm Limited
> + */
> +
> +#include "rte_common.h"
> +#include "rte_random.h"
> +#include <errno.h>
> +
> +int
> +rte_trand(uint64_t *val)
> +{
> + RTE_SET_USED(val);
> + return -ENOTSUP;
> +}
> diff --git a/lib/eal/ppc/meson.build b/lib/eal/ppc/meson.build
> index eeeaeee240..4bf3add6f3 100644
> --- a/lib/eal/ppc/meson.build
> +++ b/lib/eal/ppc/meson.build
> @@ -9,4 +9,5 @@ sources += files(
> 'rte_hypervisor.c',
> 'rte_mmu.c',
> 'rte_power_intrinsics.c',
> + 'rte_random.c',
> )
> diff --git a/lib/eal/ppc/rte_random.c b/lib/eal/ppc/rte_random.c
> new file mode 100644
> index 0000000000..d033c47ea1
> --- /dev/null
> +++ b/lib/eal/ppc/rte_random.c
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2024 Arm Limited
> + */
> +
> +#include "rte_common.h"
> +#include "rte_random.h"
> +#include <errno.h>
> +
> +int
> +rte_trand(uint64_t *val)
> +{
> + RTE_SET_USED(val);
> + return -ENOTSUP;
> +}
> diff --git a/lib/eal/riscv/meson.build b/lib/eal/riscv/meson.build
> index 6fba3d6ba7..e9e468cbf0 100644
> --- a/lib/eal/riscv/meson.build
> +++ b/lib/eal/riscv/meson.build
> @@ -9,4 +9,5 @@ sources += files(
> 'rte_hypervisor.c',
> 'rte_mmu.c',
> 'rte_power_intrinsics.c',
> + 'rte_random.c',
> )
> diff --git a/lib/eal/riscv/rte_random.c b/lib/eal/riscv/rte_random.c
> new file mode 100644
> index 0000000000..d033c47ea1
> --- /dev/null
> +++ b/lib/eal/riscv/rte_random.c
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2024 Arm Limited
> + */
> +
> +#include "rte_common.h"
> +#include "rte_random.h"
> +#include <errno.h>
> +
> +int
> +rte_trand(uint64_t *val)
> +{
> + RTE_SET_USED(val);
> + return -ENOTSUP;
> +}
> diff --git a/lib/eal/version.map b/lib/eal/version.map
> index 3df50c3fbb..d8b69ea609 100644
> --- a/lib/eal/version.map
> +++ b/lib/eal/version.map
> @@ -396,6 +396,7 @@ EXPERIMENTAL {
>
> # added in 24.03
> rte_vfio_get_device_info; # WINDOWS_NO_EXPORT
> + rte_trand;
> };
>
> INTERNAL {
> diff --git a/lib/eal/x86/meson.build b/lib/eal/x86/meson.build
> index e08dffa13d..b67bdb3238 100644
> --- a/lib/eal/x86/meson.build
> +++ b/lib/eal/x86/meson.build
> @@ -10,4 +10,5 @@ sources += files(
> 'rte_mmu.c',
> 'rte_spinlock.c',
> 'rte_power_intrinsics.c',
> + 'rte_random.c',
> )
> diff --git a/lib/eal/x86/rte_random.c b/lib/eal/x86/rte_random.c
> new file mode 100644
> index 0000000000..d033c47ea1
> --- /dev/null
> +++ b/lib/eal/x86/rte_random.c
> @@ -0,0 +1,14 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2024 Arm Limited
> + */
> +
> +#include "rte_common.h"
> +#include "rte_random.h"
> +#include <errno.h>
> +
> +int
> +rte_trand(uint64_t *val)
> +{
> + RTE_SET_USED(val);
> + return -ENOTSUP;
> +}
More information about the dev
mailing list