Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hw rng attempt to read value from arm64 devices. #3228

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/lib/rng/processor_rng/info.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ brief -> "Directly invokes a CPU specific instruction to generate random numbers
x86_32
x86_64
ppc64
arm64
</arch>

<header:public>
Expand Down
27 changes: 27 additions & 0 deletions src/lib/rng/processor_rng/processor_rng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ const size_t HWRNG_RETRIES = 10;
*/
const size_t HWRNG_RETRIES = 10;

#elif(BOTAN_COMPILER_HAS_BUILTIN(__builtin_arm_rndrrs) || BOTAN_COMPILER_HAS_BUILTIN(__builtin_aarch64_rndrrs)) && \
__GNUC__ > 11
/**
* Does not seem to have an official number
* but 512 seems a bit much
*/
const size_t HWRNG_RETRIES = 10;

#else
/*
* Lacking specific guidance we give the CPU quite a bit of leeway
Expand Down Expand Up @@ -63,6 +71,21 @@ hwrng_output read_hwrng(bool& success) {
#endif
success = (1 == cf);

#elif(BOTAN_COMPILER_HAS_BUILTIN(__builtin_arm_rndrrs) || BOTAN_COMPILER_HAS_BUILTIN(__builtin_aarch64_rndrrs)) && \
__GNUC__ > 11
/**
* apple devices do not seem to allow direct access to
* hardware random device on arm64 (aka TRNG).
* Here, fetching the value and status in one shot
*/
hwrng_output status = 0;
#if BOTAN_COMPILER_HAS_BUILTIN(__builtin_arm_rndrrs) && defined(__ARM_32BIT_STATE) && __ARM_32BIT_STATE
status = __builtin_arm_rndrrs(&output);
#elif BOTAN_COMPILER_HAS_BUILTIN(__builtin_aarch64_rndrrs) && defined(__ARM_64BIT_STATE) && __ARM_64BIT_STATE
status = __builtin_aarch64_rndrrs(&output);
#endif
success = (status == 0xb0000);

#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)

/*
Expand Down Expand Up @@ -108,6 +131,8 @@ hwrng_output read_hwrng() {
bool Processor_RNG::available() {
#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
return CPUID::has_rdrand();
#elif defined(BOTAN_TARGET_ARCH_IS_ARM64)
return CPUID::has_arm_rndrrs();
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
return CPUID::has_darn_rng();
#else
Expand All @@ -120,6 +145,8 @@ std::string Processor_RNG::name() const {
return "rdrand";
#elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY)
return "darn";
#elif defined(BOTAN_TARGET_ARCH_IS_ARM64)
return "rng";
#else
return "hwrng";
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/lib/utils/cpuid/cpuid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ std::vector<CPUID::CPUID_bits> CPUID::bit_from_string(std::string_view tok) {
return {CPUID::CPUID_ARM_SM3_BIT};
if(tok == "armv8sm4" || tok == "arm_sm4")
return {CPUID::CPUID_ARM_SM4_BIT};
if(tok == "rng")
return {CPUID::CPUID_ARM_RND_BIT};

#else
BOTAN_UNUSED(tok);
Expand Down
5 changes: 5 additions & 0 deletions src/lib/utils/cpuid/cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class BOTAN_TEST_API CPUID final {
CPUID_ARM_SHA2_512_BIT = (1U << 21),
CPUID_ARM_SM3_BIT = (1U << 22),
CPUID_ARM_SM4_BIT = (1U << 23),
CPUID_ARM_RND_BIT = (1ULL << 24),
#endif

CPUID_IS_BIG_ENDIAN_BIT = (1U << 30),
Expand Down Expand Up @@ -193,6 +194,10 @@ class BOTAN_TEST_API CPUID final {
*/
static bool has_arm_sm4() { return has_neon() && has_cpuid_bit(CPUID_ARM_SM4_BIT); }

/**
* Check if the processor supports ARMv8 RNDRRS
*/
static bool has_arm_rndrrs() { return has_cpuid_bit(CPUID_ARM_RND_BIT); }
#endif

#if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY)
Expand Down
9 changes: 9 additions & 0 deletions src/lib/utils/cpuid/cpuid_aarch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ uint32_t CPUID::CPUID_Data::detect_cpu_features() {
ARCH_hwcap = 16, // AT_HWCAP
};

enum ARM_hwcap_crypto_bit {
RND_bit = (1 << 16),

ARCH_hwcap_crypto = 26 // AT_HWCAP2
};

const unsigned long hwcap = OS::get_auxval(ARM_hwcap_bit::ARCH_hwcap);
if(hwcap & ARM_hwcap_bit::NEON_bit) {
detected_features |= CPUID::CPUID_ARM_NEON_BIT;
Expand All @@ -70,6 +76,9 @@ uint32_t CPUID::CPUID_Data::detect_cpu_features() {
if(hwcap & ARM_hwcap_bit::SVE_bit)
detected_features |= CPUID::CPUID_ARM_SVE_BIT;
}
const unsigned long hwcap_crypto = OS::get_auxval(ARM_hwcap_crypto_bit::ARCH_hwcap_crypto);
if(hwcap_crypto & ARM_hwcap_crypto_bit::RND_bit)
detected_features |= CPUID::CPUID_ARM_RND_BIT;

#elif defined(BOTAN_TARGET_OS_IS_IOS) || defined(BOTAN_TARGET_OS_IS_MACOS)

Expand Down
Loading