patch 9.1.0518: initialize the random buffer can be improved

Problem:  initialize the random buffer can be improved
Solution: refactor init_srand() function, move machine-specific parts to
          os_mswin and os_unix, implement a fallback for Windows 10 and
          later (LemonBoy)

closes: #15125

Signed-off-by: LemonBoy <thatlemon@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
LemonBoy
2024-07-04 13:20:49 +02:00
committed by Christian Brabandt
parent 898b3740c7
commit 9987fe8ca0
6 changed files with 91 additions and 47 deletions

View File

@ -9267,69 +9267,47 @@ f_test_srand_seed(typval_T *argvars, typval_T *rettv UNUSED)
static void
init_srand(UINT32_T *x)
{
#ifndef MSWIN
static int dev_urandom_state = NOTDONE; // FAIL or OK once tried
#endif
struct {
union {
UINT32_T number;
char_u bytes[sizeof(UINT32_T)];
} contents;
} buf;
if (srand_seed_for_testing_is_used)
{
*x = srand_seed_for_testing;
return;
}
#ifndef MSWIN
if (dev_urandom_state != FAIL)
{
int fd = open("/dev/urandom", O_RDONLY);
struct {
union {
UINT32_T number;
char bytes[sizeof(UINT32_T)];
} contents;
} buf;
// Attempt reading /dev/urandom.
if (fd == -1)
dev_urandom_state = FAIL;
else
{
buf.contents.number = 0;
if (read(fd, buf.contents.bytes, sizeof(UINT32_T))
!= sizeof(UINT32_T))
dev_urandom_state = FAIL;
else
{
dev_urandom_state = OK;
*x = buf.contents.number;
}
close(fd);
}
if (mch_get_random(buf.contents.bytes, sizeof(buf.contents.bytes)) == OK)
{
*x = buf.contents.number;
return;
}
if (dev_urandom_state != OK)
// The system's random number generator doesn't work, fall back to:
// - randombytes_random()
// - reltime() or time()
// - XOR with process ID
#if defined(FEAT_SODIUM)
if (crypt_sodium_init() >= 0)
*x = crypt_sodium_randombytes_random();
else
#endif
{
// Reading /dev/urandom doesn't work, fall back to:
// - randombytes_random()
// - reltime() or time()
// - XOR with process ID
#if defined(FEAT_SODIUM)
if (crypt_sodium_init() >= 0)
*x = crypt_sodium_randombytes_random();
else
#endif
{
#if defined(FEAT_RELTIME)
proftime_T res;
profile_start(&res);
proftime_T res;
profile_start(&res);
# if defined(MSWIN)
*x = (UINT32_T)res.LowPart;
*x = (UINT32_T)res.LowPart;
# else
*x = (UINT32_T)res.tv_fsec;
*x = (UINT32_T)res.tv_fsec;
# endif
#else
*x = vim_time();
*x = vim_time();
#endif
*x ^= mch_get_pid();
}
*x ^= mch_get_pid();
}
}