Files
AnyPS5/core/libs/prx/libc/src/HostEntropy.cpp
T
winstrexandClaude Opus 5.5 8f9efc25f2 fix(libs): take guest entropy from the host OS instead of std::random_device
std::random_device in libstdc++ reads RDSEED on x86 Linux. On an AMD
EPYC 9V45 (Zen 5) CI runner its 32-bit results repeat about 130 times
in 65536 draws, so guest_posix_random fails. libc now exports
HostEntropy_nid_no_patch, which uses getentropy (rand_s on Windows) and
throws when the OS cannot provide entropy. arc4random, arc4random_buf,
sceRandomGetRandomNumber, /dev/random and /dev/urandom reads,
std::_Random_device and sceKernelUuidCreate use it, and the arc4random
and random device TechnicalDebt entries say so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 22:07:49 -03:00

34 lines
1.1 KiB
C++

#ifdef _WIN32
#define _CRT_RAND_S
#endif
#include "prx/libc/include/HostEntropy.hpp"
#include <algorithm>
#include <cerrno>
#include <cstdlib>
#include <cstring>
#include <system_error>
#ifdef __APPLE__
#include <sys/random.h>
#elif !defined(_WIN32)
#include <unistd.h>
#endif
void HostEntropy_nid_no_patch(void* buffer, std::size_t size) {
auto* bytes = static_cast<unsigned char*>(buffer);
#ifdef _WIN32
for (std::size_t offset = 0; offset < size; offset += sizeof(unsigned int)) {
unsigned int value = 0;
if (const errno_t error = rand_s(&value); error != 0)
throw std::system_error(error, std::generic_category(), "HostEntropy: rand_s failed");
std::memcpy(bytes + offset, &value, std::min(sizeof(value), size - offset));
}
#else
constexpr std::size_t MaxChunk = 256;
for (std::size_t offset = 0; offset < size; offset += MaxChunk) {
if (getentropy(bytes + offset, std::min(MaxChunk, size - offset)) != 0)
throw std::system_error(errno, std::generic_category(), "HostEntropy: getentropy failed");
}
#endif
}