Skip to content

Commit

Permalink
Merge bitcoin/bitcoin#31908: Revert merge of PR #31826
Browse files Browse the repository at this point in the history
3e9b12b 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](bitcoin/bitcoin#31826 (comment)).

  #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 3e9b12b
  achow101:
    ACK 3e9b12b
  TheCharlatan:
    ACK 3e9b12b
  eval-exec:
    ACK bitcoin/bitcoin@3e9b12b
  laanwj:
    ACK 3e9b12b

Tree-SHA512: e90f8ffb2eebe77e5b6f1c273fbeb29dd5bd6a76698d9a6048c33f3349033c56ea984dd9b64704698da01ecad4c47f98acac1a30312bf2499dbdd1931596953f
  • Loading branch information
achow101 committed Feb 19, 2025
2 parents 785649f + 3e9b12b commit fd14995
Showing 1 changed file with 11 additions and 34 deletions.
45 changes: 11 additions & 34 deletions src/random.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,24 +192,20 @@ 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();
}
}

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");
}
}

Expand All @@ -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).
Expand Down Expand Up @@ -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));
Expand Down

0 comments on commit fd14995

Please sign in to comment.