mirror of
https://github.com/kvazar-network/kevacoin.git
synced 2025-01-17 18:40:09 +00:00
random: Add fallback if getrandom syscall not available
If the code was compiled with newer (>=3.17) kernel headers but executed on a system without the system call, every use of random would crash the program. Add a fallback for that case.
This commit is contained in:
parent
7cad849299
commit
7e6dcd9995
@ -102,6 +102,28 @@ static void RandAddSeedPerfmon()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
/** Fallback: get 32 bytes of system entropy from /dev/urandom. The most
|
||||||
|
* compatible way to get cryptographic randomness on UNIX-ish platforms.
|
||||||
|
*/
|
||||||
|
void GetDevURandom(unsigned char *ent32)
|
||||||
|
{
|
||||||
|
int f = open("/dev/urandom", O_RDONLY);
|
||||||
|
if (f == -1) {
|
||||||
|
RandFailure();
|
||||||
|
}
|
||||||
|
int have = 0;
|
||||||
|
do {
|
||||||
|
ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
|
||||||
|
if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
|
||||||
|
RandFailure();
|
||||||
|
}
|
||||||
|
have += n;
|
||||||
|
} while (have < NUM_OS_RANDOM_BYTES);
|
||||||
|
close(f);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/** Get 32 bytes of system entropy. */
|
/** Get 32 bytes of system entropy. */
|
||||||
void GetOSRand(unsigned char *ent32)
|
void GetOSRand(unsigned char *ent32)
|
||||||
{
|
{
|
||||||
@ -122,8 +144,17 @@ void GetOSRand(unsigned char *ent32)
|
|||||||
* will always return as many bytes as requested and will not be
|
* will always return as many bytes as requested and will not be
|
||||||
* interrupted by signals."
|
* interrupted by signals."
|
||||||
*/
|
*/
|
||||||
if (syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0) != NUM_OS_RANDOM_BYTES) {
|
int rv = syscall(SYS_getrandom, ent32, NUM_OS_RANDOM_BYTES, 0);
|
||||||
RandFailure();
|
if (rv != NUM_OS_RANDOM_BYTES) {
|
||||||
|
if (rv < 0 && errno == ENOSYS) {
|
||||||
|
/* Fallback for kernel <3.17: the return value will be -1 and errno
|
||||||
|
* ENOSYS if the syscall is not available, in that case fall back
|
||||||
|
* to /dev/urandom.
|
||||||
|
*/
|
||||||
|
GetDevURandom(ent32);
|
||||||
|
} else {
|
||||||
|
RandFailure();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#elif defined(HAVE_GETENTROPY)
|
#elif defined(HAVE_GETENTROPY)
|
||||||
/* On OpenBSD this can return up to 256 bytes of entropy, will return an
|
/* On OpenBSD this can return up to 256 bytes of entropy, will return an
|
||||||
@ -150,19 +181,7 @@ void GetOSRand(unsigned char *ent32)
|
|||||||
/* Fall back to /dev/urandom if there is no specific method implemented to
|
/* Fall back to /dev/urandom if there is no specific method implemented to
|
||||||
* get system entropy for this OS.
|
* get system entropy for this OS.
|
||||||
*/
|
*/
|
||||||
int f = open("/dev/urandom", O_RDONLY);
|
GetDevURandom(ent32);
|
||||||
if (f == -1) {
|
|
||||||
RandFailure();
|
|
||||||
}
|
|
||||||
int have = 0;
|
|
||||||
do {
|
|
||||||
ssize_t n = read(f, ent32 + have, NUM_OS_RANDOM_BYTES - have);
|
|
||||||
if (n <= 0 || n + have > NUM_OS_RANDOM_BYTES) {
|
|
||||||
RandFailure();
|
|
||||||
}
|
|
||||||
have += n;
|
|
||||||
} while (have < NUM_OS_RANDOM_BYTES);
|
|
||||||
close(f);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user