Merge c8a883a412 into merged_master (Bitcoin PR bitcoin/bitcoin#26839)

This commit is contained in:
Byron Hambly 2025-11-06 09:44:37 +02:00
commit 94b14e65a8
No known key found for this signature in database
GPG key ID: DE8F6EA20A661697

View file

@ -38,6 +38,9 @@
#ifdef HAVE_SYSCTL_ARND
#include <sys/sysctl.h>
#endif
#if defined(HAVE_STRONG_GETAUXVAL) && defined(__aarch64__)
#include <sys/auxv.h>
#endif
[[noreturn]] static void RandFailure()
{
@ -173,6 +176,62 @@ static uint64_t GetRdSeed() noexcept
#endif
}
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
static bool g_rndr_supported = false;
static void InitHardwareRand()
{
if (getauxval(AT_HWCAP2) & HWCAP2_RNG) {
g_rndr_supported = true;
}
}
static void ReportHardwareRand()
{
// This must be done in a separate function, as InitHardwareRand() may be indirectly called
// from global constructors, before logging is initialized.
if (g_rndr_supported) {
LogPrintf("Using RNDR and RNDRRS as additional entropy sources\n");
}
}
/** Read 64 bits of entropy using rndr.
*
* Must only be called when RNDR is supported.
*/
static uint64_t GetRNDR() noexcept
{
uint8_t ok;
uint64_t r1;
do {
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/RNDR--Random-Number
__asm__ volatile("mrs %0, s3_3_c2_c4_0; cset %w1, ne;"
: "=r"(r1), "=r"(ok)::"cc");
if (ok) break;
__asm__ volatile("yield");
} while (true);
return r1;
}
/** Read 64 bits of entropy using rndrrs.
*
* Must only be called when RNDRRS is supported.
*/
static uint64_t GetRNDRRS() noexcept
{
uint8_t ok;
uint64_t r1;
do {
// https://developer.arm.com/documentation/ddi0601/2022-12/AArch64-Registers/RNDRRS--Reseeded-Random-Number
__asm__ volatile("mrs %0, s3_3_c2_c4_1; cset %w1, ne;"
: "=r"(r1), "=r"(ok)::"cc");
if (ok) break;
__asm__ volatile("yield");
} while (true);
return r1;
}
#else
/* Access to other hardware random number generators could be added here later,
* assuming it is sufficiently fast (in the order of a few hundred CPU cycles).
@ -191,6 +250,12 @@ static void SeedHardwareFast(CSHA512& hasher) noexcept {
hasher.Write((const unsigned char*)&out, sizeof(out));
return;
}
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
if (g_rndr_supported) {
uint64_t out = GetRNDR();
hasher.Write((const unsigned char*)&out, sizeof(out));
return;
}
#endif
}
@ -216,6 +281,14 @@ static void SeedHardwareSlow(CSHA512& hasher) noexcept {
}
return;
}
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
if (g_rndr_supported) {
for (int i = 0; i < 4; ++i) {
uint64_t out = GetRNDRRS();
hasher.Write((const unsigned char*)&out, sizeof(out));
}
return;
}
#endif
}