Merge bitcoin/bitcoin#31908: Revert merge of PR #31826

3e9b12b3e0 Revert "Merge bitcoin/bitcoin#31826: random: Check `GetRNDRRS` is supported in `InitHardwareRand` to avoid infinite loop" (Antoine Poinsot)

Pull request description:

  PR #31826 was merged [despite the code not compiling](https://github.com/bitcoin/bitcoin/pull/31826#discussion_r1961315638).

  #31902 was opened to fix the code but since this code is only targeting a not officially supported platform, we don't have a CI in place to compile and run tests on this platform, neither apparently reviewers do (nor does the author?), don't take more risk right before 29 and revert the original broken PR.

ACKs for top commit:
  sipa:
    ACK 3e9b12b3e0
  achow101:
    ACK 3e9b12b3e0
  TheCharlatan:
    ACK 3e9b12b3e0
  eval-exec:
    ACK 3e9b12b3e0
  laanwj:
    ACK 3e9b12b3e0

Tree-SHA512: e90f8ffb2eebe77e5b6f1c273fbeb29dd5bd6a76698d9a6048c33f3349033c56ea984dd9b64704698da01ecad4c47f98acac1a30312bf2499dbdd1931596953f
This commit is contained in:
Ava Chow 2025-02-19 10:03:26 -08:00
commit fd14995b6a
No known key found for this signature in database
GPG key ID: 17565732E08E5E41

View file

@ -192,13 +192,11 @@ uint64_t GetRdSeed() noexcept
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
bool g_rndr_supported = false;
bool g_rndrrs_supported = false;
void InitHardwareRand()
{
if (getauxval(AT_HWCAP2) & HWCAP2_RNG) {
g_rndr_supported = true;
g_rndrrs_supported = VerifyRNDRRS();
}
}
@ -206,10 +204,8 @@ 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 && g_rndrrs_supported) {
if (g_rndr_supported) {
LogPrintf("Using RNDR and RNDRRS as additional entropy sources\n");
} else if (g_rndr_supported) {
LogPrintf("Using RNDR as an additional entropy source\n");
}
}
@ -231,43 +227,24 @@ uint64_t GetRNDR() noexcept
return r1;
}
// Helper function to retrieve random value using RNDRRS
bool GetRNDRRSInternal(uint64_t &r1) noexcept
{
uint8_t ok = 0;
__asm__ volatile("mrs %0, s3_3_c2_c4_1; cset %w1, ne;"
: "=r"(r1), "=r"(ok)::"cc");
return ok != 0;
}
/** Read 64 bits of entropy using RNDRRS.
/** Read 64 bits of entropy using rndrrs.
*
* Must only be called when RNDRRS is supported.
*/
uint64_t GetRNDRRS() noexcept
{
uint8_t ok = 0;
uint64_t r1;
while (!GetRNDRRSInternal(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;
}
/** Verify if RNDRRS is supported and functional.
* Return true if it works within the retry limit.
*/
bool VerifyRNDRRS() noexcept
{
uint64_t test;
for (int retry = 0; retry < 10; ++retry) {
if (GetRNDRRSInternal(test)) {
return true;
}
__asm__ volatile("yield");
}
return false;
}
#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).
@ -318,7 +295,7 @@ void SeedHardwareSlow(CSHA512& hasher) noexcept {
return;
}
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
if (g_rndrrs_supported) {
if (g_rndr_supported) {
for (int i = 0; i < 4; ++i) {
uint64_t out = GetRNDRRS();
hasher.Write((const unsigned char*)&out, sizeof(out));