[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