Skip to content

Commit

Permalink
hw rng attempt to read value from arm64 devices.
Browse files Browse the repository at this point in the history
  • Loading branch information
devnexen authored and randombit committed Jul 21, 2024
1 parent 1a8a90b commit 5568ea8
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 0 deletions.
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

0 comments on commit 5568ea8

Please sign in to comment.