mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-17 21:32:00 +01:00
Merge 2498dd8dbd5acdede03e1a57c5873ca022903023 into 5f4422d68dc3530c353af1f87499de1c864b60ad
This commit is contained in:
commit
b3ad2a34da
@ -192,11 +192,38 @@ uint64_t GetRdSeed() noexcept
|
|||||||
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
|
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
|
||||||
|
|
||||||
bool g_rndr_supported = false;
|
bool g_rndr_supported = false;
|
||||||
|
bool g_rndrrs_supported = false;
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 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;
|
||||||
|
}
|
||||||
|
|
||||||
void InitHardwareRand()
|
void InitHardwareRand()
|
||||||
{
|
{
|
||||||
if (getauxval(AT_HWCAP2) & HWCAP2_RNG) {
|
if (getauxval(AT_HWCAP2) & HWCAP2_RNG) {
|
||||||
g_rndr_supported = true;
|
g_rndr_supported = true;
|
||||||
|
g_rndrrs_supported = VerifyRNDRRS();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,8 +231,10 @@ void ReportHardwareRand()
|
|||||||
{
|
{
|
||||||
// This must be done in a separate function, as InitHardwareRand() may be indirectly called
|
// This must be done in a separate function, as InitHardwareRand() may be indirectly called
|
||||||
// from global constructors, before logging is initialized.
|
// from global constructors, before logging is initialized.
|
||||||
if (g_rndr_supported) {
|
if (g_rndr_supported && g_rndrrs_supported) {
|
||||||
LogPrintf("Using RNDR and RNDRRS as additional entropy sources\n");
|
LogPrintf("Using RNDR and RNDRRS as additional entropy sources\n");
|
||||||
|
} else if (g_rndr_supported) {
|
||||||
|
LogPrintf("Using RNDR as an additional entropy source\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,20 +257,14 @@ uint64_t GetRNDR() noexcept
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Read 64 bits of entropy using rndrrs.
|
/** Read 64 bits of entropy using rndrrs.
|
||||||
*
|
|
||||||
* Must only be called when RNDRRS is supported.
|
* Must only be called when RNDRRS is supported.
|
||||||
*/
|
*/
|
||||||
uint64_t GetRNDRRS() noexcept
|
uint64_t GetRNDRRS() noexcept
|
||||||
{
|
{
|
||||||
uint8_t ok = 0;
|
|
||||||
uint64_t r1;
|
uint64_t r1;
|
||||||
do {
|
while (!GetRNDRRSInternal(r1)) {
|
||||||
// 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");
|
__asm__ volatile("yield");
|
||||||
} while (true);
|
}
|
||||||
return r1;
|
return r1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +318,7 @@ void SeedHardwareSlow(CSHA512& hasher) noexcept {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
|
#elif defined(__aarch64__) && defined(HWCAP2_RNG)
|
||||||
if (g_rndr_supported) {
|
if (g_rndrrs_supported) {
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
uint64_t out = GetRNDRRS();
|
uint64_t out = GetRNDRRS();
|
||||||
hasher.Write((const unsigned char*)&out, sizeof(out));
|
hasher.Write((const unsigned char*)&out, sizeof(out));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user