1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

Use secure randomness to seed internal RNG

This commit is contained in:
sfan5 2025-03-30 16:42:26 +02:00
parent 785c042f1f
commit 1281173e50
4 changed files with 18 additions and 18 deletions

View file

@ -16,14 +16,13 @@
#include "porting.h" #include "porting.h"
#include "util/container.h" #include "util/container.h"
#include "util/thread.h" #include "util/thread.h"
#include "util/numeric.h"
#include "version.h" #include "version.h"
#include "settings.h" #include "settings.h"
#include "noise.h"
static std::mutex g_httpfetch_mutex; static std::mutex g_httpfetch_mutex;
static std::unordered_map<u64, std::queue<HTTPFetchResult>> static std::unordered_map<u64, std::queue<HTTPFetchResult>>
g_httpfetch_results; g_httpfetch_results;
static PcgRandom g_callerid_randomness;
static std::string default_user_agent() static std::string default_user_agent()
{ {
@ -78,18 +77,18 @@ u64 httpfetch_caller_alloc_secure()
// Generate random caller IDs and make sure they're not // Generate random caller IDs and make sure they're not
// already used or reserved. // already used or reserved.
// Give up after 100 tries to prevent infinite loop // Give up after 100 tries to prevent infinite loop
size_t tries = 100; int tries = 100;
u64 caller; u64 caller;
do { do {
caller = (((u64) g_callerid_randomness.next()) << 32) | // Global RNG is seeded securely, so we can use it.
g_callerid_randomness.next(); myrand_bytes(&caller, sizeof(caller));
if (--tries < 1) { if (--tries < 1) {
FATAL_ERROR("httpfetch_caller_alloc_secure: ran out of caller IDs"); FATAL_ERROR("httpfetch_caller_alloc_secure: ran out of caller IDs");
return HTTPFETCH_DISCARD; return HTTPFETCH_DISCARD;
} }
} while (caller >= HTTPFETCH_CID_START && } while (caller < HTTPFETCH_CID_START ||
g_httpfetch_results.find(caller) != g_httpfetch_results.end()); g_httpfetch_results.find(caller) != g_httpfetch_results.end());
verbosestream << "httpfetch_caller_alloc_secure: allocating " verbosestream << "httpfetch_caller_alloc_secure: allocating "
@ -702,11 +701,6 @@ void httpfetch_init(int parallel_limit)
FATAL_ERROR_IF(res != CURLE_OK, "cURL init failed"); FATAL_ERROR_IF(res != CURLE_OK, "cURL init failed");
g_httpfetch_thread = std::make_unique<CurlFetchThread>(parallel_limit); g_httpfetch_thread = std::make_unique<CurlFetchThread>(parallel_limit);
// Initialize g_callerid_randomness for httpfetch_caller_alloc_secure
u64 randbuf[2];
porting::secure_rand_fill_buf(randbuf, sizeof(u64) * 2);
g_callerid_randomness = PcgRandom(randbuf[0], randbuf[1]);
} }
void httpfetch_cleanup() void httpfetch_cleanup()

View file

@ -700,12 +700,18 @@ static bool init_common(const Settings &cmd_args, int argc, char *argv[])
init_log_streams(cmd_args); init_log_streams(cmd_args);
// Initialize random seed // Initialize random seed
{ u64 seed;
u32 seed = static_cast<u32>(time(nullptr)) << 16; if (!porting::secure_rand_fill_buf(&seed, sizeof(seed))) {
seed |= porting::getTimeUs() & 0xffff; verbosestream << "Secure randomness not available to seed global RNG." << std::endl;
std::ostringstream oss;
// some stuff that's hard to predict:
oss << time(nullptr) << porting::getTimeUs() << argc << g_settings_path;
print_version(oss);
std::string data = oss.str();
seed = murmur_hash_64_ua(data.c_str(), data.size(), 0xc0ffee);
}
srand(seed); srand(seed);
mysrand(seed); mysrand(seed);
}
// Initialize HTTP fetcher // Initialize HTTP fetcher
httpfetch_init(g_settings->getS32("curl_parallel_limit")); httpfetch_init(g_settings->getS32("curl_parallel_limit"));

View file

@ -20,7 +20,7 @@ u32 myrand()
return g_pcgrand.next(); return g_pcgrand.next();
} }
void mysrand(unsigned int seed) void mysrand(u64 seed)
{ {
g_pcgrand.seed(seed); g_pcgrand.seed(seed);
} }

View file

@ -244,7 +244,7 @@ inline float wrapDegrees_180(float f)
*/ */
#define MYRAND_RANGE 0xffffffff #define MYRAND_RANGE 0xffffffff
u32 myrand(); u32 myrand();
void mysrand(unsigned int seed); void mysrand(u64 seed);
void myrand_bytes(void *out, size_t len); void myrand_bytes(void *out, size_t len);
int myrand_range(int min, int max); int myrand_range(int min, int max);
float myrand_range(float min, float max); float myrand_range(float min, float max);