Change: use a stronger hash and actual random information to generate Uids

This commit is contained in:
Patric Stout
2024-01-18 23:52:53 +01:00
committed by Patric Stout
parent 37244bc8c5
commit bd85f61a40
4 changed files with 78 additions and 16 deletions

View File

@@ -10,6 +10,7 @@
#include "../stdafx.h"
#include "random_func.hpp"
#include "bitmath_func.hpp"
#include "../debug.h"
#ifdef RANDOM_DEBUG
#include "../network/network.h"
@@ -20,6 +21,15 @@
#include "../timer/timer_game_calendar.h"
#endif /* RANDOM_DEBUG */
#if defined(_WIN32)
# include <windows.h>
# include <bcrypt.h>
#elif defined(__EMSCRIPTEN__)
# include <emscripten.h>
#elif !defined(__APPLE__) && !defined(__NetBSD__) && !defined(__FreeBSD__)
# include <sys/random.h>
#endif
#include "../safeguards.h"
Randomizer _random, _interactive_random;
@@ -83,3 +93,53 @@ uint32_t DoRandomRange(uint32_t limit, int line, const char *file)
return ((uint64_t)DoRandom(line, file) * (uint64_t)limit) >> 32;
}
#endif /* RANDOM_DEBUG */
/**
* Fill the given buffer with random bytes.
*
* This function will attempt to use a cryptographically-strong random
* generator, but will fall back to a weaker random generator if none is
* available.
*
* In the end, the buffer will always be filled with some form of random
* bytes when this function returns.
*
* @param buf The buffer to fill with random bytes.
*/
void RandomBytesWithFallback(std::span<uint8_t> buf)
{
#if defined(_WIN32)
auto res = BCryptGenRandom(nullptr, static_cast<PUCHAR>(buf.data()), static_cast<ULONG>(buf.size()), BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (res >= 0) return;
#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
arc4random_buf(buf.data(), buf.size());
return;
#elif defined(__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 25)))
auto res = getrandom(buf.data(), buf.size(), 0);
if (res > 0 && static_cast<size_t>(res) == buf.size()) return;
#elif defined(__EMSCRIPTEN__)
auto res = EM_ASM_INT({
var buf = $0;
var bytes = $1;
var crypto = window.crypto;
if (crypto === undefined || crypto.getRandomValues === undefined) {
return -1;
}
crypto.getRandomValues(Module.HEAPU8.subarray(buf, buf + bytes));
return 1;
}, buf.data(), buf.size());
if (res > 0) return;
#else
# warning "No cryptographically-strong random generator available; using a fallback instead"
#endif
static bool warned_once = false;
Debug(misc, warned_once ? 1 : 0, "Cryptographically-strong random generator unavailable; using fallback");
warned_once = true;
for (uint i = 0; i < buf.size(); i++) {
buf[i] = static_cast<uint8_t>(InteractiveRandom());
}
}

View File

@@ -159,4 +159,6 @@ inline bool Chance16R(const uint a, const uint b, uint32_t &r)
}
#endif /* RANDOM_DEBUG */
void RandomBytesWithFallback(std::span<uint8_t> buf);
#endif /* RANDOM_FUNC_HPP */