mirror of
https://github.com/vim/vim.git
synced 2025-07-25 10:54:51 -04:00
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:
parent
898b3740c7
commit
9987fe8ca0
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -830,6 +830,40 @@ mch_icon_load(HANDLE *iconp)
|
||||
0, mch_icon_load_cb, iconp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Fill the buffer 'buf' with 'len' random bytes.
|
||||
* Returns FAIL if the OS PRNG is not available or something went wrong.
|
||||
*/
|
||||
int
|
||||
mch_get_random(char_u *buf, int len)
|
||||
{
|
||||
static int initialized = NOTDONE;
|
||||
static HINSTANCE hInstLib;
|
||||
static BOOL (WINAPI *pProcessPrng)(PUCHAR, ULONG);
|
||||
|
||||
if (initialized == NOTDONE)
|
||||
{
|
||||
hInstLib = vimLoadLib("bcryptprimitives.dll");
|
||||
if (hInstLib != NULL)
|
||||
pProcessPrng = (void *)GetProcAddress(hInstLib, "ProcessPrng");
|
||||
if (hInstLib == NULL || pProcessPrng == NULL)
|
||||
{
|
||||
FreeLibrary(hInstLib);
|
||||
initialized = FAIL;
|
||||
}
|
||||
else
|
||||
initialized = OK;
|
||||
}
|
||||
|
||||
if (initialized == FAIL)
|
||||
return FAIL;
|
||||
|
||||
// According to the documentation this call cannot fail.
|
||||
pProcessPrng(buf, len);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
mch_libcall(
|
||||
char_u *libname,
|
||||
|
@ -7722,6 +7722,34 @@ sig_sysmouse SIGDEFARG(sigarg)
|
||||
}
|
||||
#endif // FEAT_SYSMOUSE
|
||||
|
||||
/*
|
||||
* Fill the buffer 'buf' with 'len' random bytes.
|
||||
* Returns FAIL if the OS PRNG is not available or something went wrong.
|
||||
*/
|
||||
int
|
||||
mch_get_random(char_u *buf, int len)
|
||||
{
|
||||
static int dev_urandom_state = NOTDONE;
|
||||
|
||||
if (dev_urandom_state == FAIL)
|
||||
return FAIL;
|
||||
|
||||
int fd = open("/dev/urandom", O_RDONLY);
|
||||
|
||||
// Attempt reading /dev/urandom.
|
||||
if (fd == -1)
|
||||
dev_urandom_state = FAIL;
|
||||
else if (read(fd, buf, len) == len)
|
||||
dev_urandom_state = OK;
|
||||
else
|
||||
{
|
||||
dev_urandom_state = FAIL;
|
||||
close(fd);
|
||||
}
|
||||
|
||||
return dev_urandom_state;
|
||||
}
|
||||
|
||||
#if defined(FEAT_LIBCALL) || defined(PROTO)
|
||||
typedef char_u * (*STRPROCSTR)(char_u *);
|
||||
typedef char_u * (*INTPROCSTR)(int);
|
||||
|
@ -23,6 +23,7 @@ int mch_has_wildcard(char_u *p);
|
||||
int mch_chdir(char *path);
|
||||
int mch_icon_load(HANDLE *iconp);
|
||||
int mch_libcall(char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result);
|
||||
int mch_get_random(char_u *buf, int len);
|
||||
void DumpPutS(const char *psz);
|
||||
int mch_get_winpos(int *x, int *y);
|
||||
void mch_set_winpos(int x, int y);
|
||||
|
@ -76,6 +76,7 @@ int mch_rename(const char *src, const char *dest);
|
||||
int gpm_available(void);
|
||||
int gpm_enabled(void);
|
||||
int mch_libcall(char_u *libname, char_u *funcname, char_u *argstring, int argint, char_u **string_result, int *number_result);
|
||||
int mch_get_random(char_u *buf, int len);
|
||||
void setup_term_clip(void);
|
||||
void start_xterm_trace(int button);
|
||||
void stop_xterm_trace(void);
|
||||
|
@ -704,6 +704,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
518,
|
||||
/**/
|
||||
517,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user