aboutsummaryrefslogtreecommitdiff
path: root/src/random.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/random.cpp')
-rw-r--r--src/random.cpp24
1 files changed, 11 insertions, 13 deletions
diff --git a/src/random.cpp b/src/random.cpp
index 67efc7d945..b308e8f4a1 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -36,6 +36,10 @@
#include <mutex>
+#if defined(__x86_64__) || defined(__amd64__) || defined(__i386__)
+#include <cpuid.h>
+#endif
+
#include <openssl/err.h>
#include <openssl/rand.h>
@@ -72,18 +76,9 @@ static bool rdrand_supported = false;
static constexpr uint32_t CPUID_F1_ECX_RDRAND = 0x40000000;
static void RDRandInit()
{
- uint32_t eax, ecx, edx;
-#if defined(__i386__) && ( defined(__PIC__) || defined(__PIE__))
- // Avoid clobbering ebx, as that is used for PIC on x86.
- uint32_t tmp;
- __asm__ ("mov %%ebx, %1; cpuid; mov %1, %%ebx": "=a"(eax), "=g"(tmp), "=c"(ecx), "=d"(edx) : "a"(1));
-#else
- uint32_t ebx;
- __asm__ ("cpuid": "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) : "a"(1));
-#endif
- //! When calling cpuid function #1, ecx register will have this set if RDRAND is available.
- if (ecx & CPUID_F1_ECX_RDRAND) {
- LogPrintf("Using RdRand as entropy source\n");
+ uint32_t eax, ebx, ecx, edx;
+ if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx & CPUID_F1_ECX_RDRAND)) {
+ LogPrintf("Using RdRand as an additional entropy source\n");
rdrand_supported = true;
}
hwrand_initialized.store(true);
@@ -191,6 +186,7 @@ void GetDevURandom(unsigned char *ent32)
do {
ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
+ close(f);
RandFailure();
}
have += n;
@@ -231,10 +227,12 @@ void GetOSRand(unsigned char *ent32)
RandFailure();
}
}
-#elif defined(HAVE_GETENTROPY)
+#elif defined(HAVE_GETENTROPY) && defined(__OpenBSD__)
/* On OpenBSD this can return up to 256 bytes of entropy, will return an
* error if more are requested.
* The call cannot return less than the requested number of bytes.
+ getentropy is explicitly limited to openbsd here, as a similar (but not
+ the same) function may exist on other platforms via glibc.
*/
if (getentropy(ent32, NUM_OS_RANDOM_BYTES) != 0) {
RandFailure();