mirror of
https://github.com/jedisct1/libsodium.git
synced 2026-08-25 08:37:13 +09:00
Add getrandom(2) support for FreeBSD 12
This commit is contained in:
@@ -19,9 +19,26 @@
|
||||
#ifdef __linux__
|
||||
# ifdef __dietlibc__
|
||||
# define _LINUX_SOURCE
|
||||
# else
|
||||
# include <sys/random.h>
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# else /* __dietlibc__ */
|
||||
# include <sys/syscall.h>
|
||||
# if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F))
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# endif
|
||||
# endif /* __dietlibc__ */
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <sys/param.h>
|
||||
# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000
|
||||
# include <sys/random.h>
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__)
|
||||
# define BLOCK_ON_DEV_RANDOM
|
||||
#endif
|
||||
#ifdef BLOCK_ON_DEV_RANDOM
|
||||
# include <poll.h>
|
||||
#endif
|
||||
#ifdef HAVE_RDRAND
|
||||
@@ -177,7 +194,7 @@ safe_read(const int fd, void * const buf_, size_t size)
|
||||
return (ssize_t) (buf - (unsigned char *) buf_);
|
||||
}
|
||||
|
||||
# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
|
||||
# ifdef BLOCK_ON_DEV_RANDOM
|
||||
static int
|
||||
randombytes_block_on_dev_random(void)
|
||||
{
|
||||
@@ -219,11 +236,11 @@ randombytes_salsa20_random_random_dev_open(void)
|
||||
const char **device = devices;
|
||||
int fd;
|
||||
|
||||
# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
|
||||
# ifdef BLOCK_ON_DEV_RANDOM
|
||||
if (randombytes_block_on_dev_random() != 0) {
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
do {
|
||||
fd = open(*device, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
@@ -246,7 +263,7 @@ randombytes_salsa20_random_random_dev_open(void)
|
||||
}
|
||||
# endif
|
||||
|
||||
# if defined(__dietlibc__) || (defined(SYS_getrandom) && defined(__NR_getrandom))
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
static int
|
||||
_randombytes_linux_getrandom(void * const buf, const size_t size)
|
||||
{
|
||||
@@ -254,11 +271,7 @@ _randombytes_linux_getrandom(void * const buf, const size_t size)
|
||||
|
||||
assert(size <= 256U);
|
||||
do {
|
||||
# ifdef __dietlibc__
|
||||
readnb = getrandom(buf, size, 0);
|
||||
# else
|
||||
readnb = syscall(SYS_getrandom, buf, (int) size, 0);
|
||||
# endif
|
||||
} while (readnb < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
|
||||
return (readnb == (int) size) - 1;
|
||||
@@ -299,7 +312,7 @@ randombytes_salsa20_random_init(void)
|
||||
errno = errno_save;
|
||||
# else
|
||||
|
||||
# if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
{
|
||||
unsigned char fodder[16];
|
||||
|
||||
@@ -310,7 +323,7 @@ randombytes_salsa20_random_init(void)
|
||||
}
|
||||
global.getrandom_available = 0;
|
||||
}
|
||||
# endif /* SYS_getrandom */
|
||||
# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */
|
||||
|
||||
if ((global.random_data_source_fd =
|
||||
randombytes_salsa20_random_random_dev_open()) == -1) {
|
||||
@@ -343,7 +356,7 @@ randombytes_salsa20_random_stir(void)
|
||||
|
||||
# ifdef HAVE_SAFE_ARC4RANDOM
|
||||
arc4random_buf(stream.key, sizeof stream.key);
|
||||
# elif defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# elif defined(HAVE_LINUX_COMPATIBLE_GETRANDOM)
|
||||
if (global.getrandom_available != 0) {
|
||||
if (randombytes_linux_getrandom(stream.key, sizeof stream.key) != 0) {
|
||||
sodium_misuse(); /* LCOV_EXCL_LINE */
|
||||
@@ -428,7 +441,7 @@ randombytes_salsa20_random_close(void)
|
||||
ret = 0;
|
||||
# endif
|
||||
|
||||
# if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
if (global.getrandom_available != 0) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
@@ -18,9 +18,26 @@
|
||||
#ifdef __linux__
|
||||
# ifdef __dietlibc__
|
||||
# define _LINUX_SOURCE
|
||||
# else
|
||||
# include <sys/random.h>
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# else /* __dietlibc__ */
|
||||
# include <sys/syscall.h>
|
||||
# if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# define getrandom(B, S, F) syscall(SYS_getrandom, (B), (int) (S), (F))
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# endif
|
||||
# endif /* __dietlibc */
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <sys/param.h>
|
||||
# if defined(__FreeBSD_version) && __FreeBSD_version >= 1200000
|
||||
# include <sys/random.h>
|
||||
# define HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(NO_BLOCKING_RANDOM_POLL) && defined(__linux__)
|
||||
# define BLOCK_ON_DEV_RANDOM
|
||||
#endif
|
||||
#ifdef BLOCK_ON_DEV_RANDOM
|
||||
# include <poll.h>
|
||||
#endif
|
||||
|
||||
@@ -102,7 +119,7 @@ static SysRandom stream = {
|
||||
SODIUM_C99(.getrandom_available =) 0
|
||||
};
|
||||
|
||||
#ifndef _WIN32
|
||||
# ifndef _WIN32
|
||||
static ssize_t
|
||||
safe_read(const int fd, void * const buf_, size_t size)
|
||||
{
|
||||
@@ -126,10 +143,8 @@ safe_read(const int fd, void * const buf_, size_t size)
|
||||
|
||||
return (ssize_t) (buf - (unsigned char *) buf_);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
|
||||
# ifdef BLOCK_ON_DEV_RANDOM
|
||||
static int
|
||||
randombytes_block_on_dev_random(void)
|
||||
{
|
||||
@@ -154,7 +169,7 @@ randombytes_block_on_dev_random(void)
|
||||
}
|
||||
return close(fd);
|
||||
}
|
||||
# endif
|
||||
# endif /* BLOCK_ON_DEV_RANDOM */
|
||||
|
||||
static int
|
||||
randombytes_sysrandom_random_dev_open(void)
|
||||
@@ -162,34 +177,34 @@ randombytes_sysrandom_random_dev_open(void)
|
||||
/* LCOV_EXCL_START */
|
||||
struct stat st;
|
||||
static const char *devices[] = {
|
||||
# ifndef USE_BLOCKING_RANDOM
|
||||
# ifndef USE_BLOCKING_RANDOM
|
||||
"/dev/urandom",
|
||||
# endif
|
||||
# endif
|
||||
"/dev/random", NULL
|
||||
};
|
||||
const char **device = devices;
|
||||
int fd;
|
||||
|
||||
# if defined(__linux__) && !defined(USE_BLOCKING_RANDOM) && !defined(NO_BLOCKING_RANDOM_POLL)
|
||||
# ifdef BLOCK_ON_DEV_RANDOM
|
||||
if (randombytes_block_on_dev_random() != 0) {
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
do {
|
||||
fd = open(*device, O_RDONLY);
|
||||
if (fd != -1) {
|
||||
if (fstat(fd, &st) == 0 &&
|
||||
# ifdef __COMPCERT__
|
||||
# ifdef __COMPCERT__
|
||||
1
|
||||
# elif defined(S_ISNAM)
|
||||
# elif defined(S_ISNAM)
|
||||
(S_ISNAM(st.st_mode) || S_ISCHR(st.st_mode))
|
||||
# else
|
||||
# else
|
||||
S_ISCHR(st.st_mode)
|
||||
# endif
|
||||
# endif
|
||||
) {
|
||||
# if defined(F_SETFD) && defined(FD_CLOEXEC)
|
||||
# if defined(F_SETFD) && defined(FD_CLOEXEC)
|
||||
(void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
|
||||
# endif
|
||||
# endif
|
||||
return fd;
|
||||
}
|
||||
(void) close(fd);
|
||||
@@ -204,7 +219,7 @@ randombytes_sysrandom_random_dev_open(void)
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
# if defined(__dietlibc__) || (defined(SYS_getrandom) && defined(__NR_getrandom))
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
static int
|
||||
_randombytes_linux_getrandom(void * const buf, const size_t size)
|
||||
{
|
||||
@@ -212,11 +227,7 @@ _randombytes_linux_getrandom(void * const buf, const size_t size)
|
||||
|
||||
assert(size <= 256U);
|
||||
do {
|
||||
# ifdef __dietlibc__
|
||||
readnb = getrandom(buf, size, 0);
|
||||
# else
|
||||
readnb = syscall(SYS_getrandom, buf, (int) size, 0);
|
||||
# endif
|
||||
} while (readnb < 0 && (errno == EINTR || errno == EAGAIN));
|
||||
|
||||
return (readnb == (int) size) - 1;
|
||||
@@ -242,14 +253,14 @@ randombytes_linux_getrandom(void * const buf_, size_t size)
|
||||
|
||||
return 0;
|
||||
}
|
||||
# endif
|
||||
# endif /* HAVE_LINUX_COMPATIBLE_GETRANDOM */
|
||||
|
||||
static void
|
||||
randombytes_sysrandom_init(void)
|
||||
{
|
||||
const int errno_save = errno;
|
||||
|
||||
# if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
{
|
||||
unsigned char fodder[16];
|
||||
|
||||
@@ -260,7 +271,7 @@ randombytes_sysrandom_init(void)
|
||||
}
|
||||
stream.getrandom_available = 0;
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
|
||||
if ((stream.random_data_source_fd =
|
||||
randombytes_sysrandom_random_dev_open()) == -1) {
|
||||
@@ -269,13 +280,13 @@ randombytes_sysrandom_init(void)
|
||||
errno = errno_save;
|
||||
}
|
||||
|
||||
#else /* _WIN32 */
|
||||
# else /* _WIN32 */
|
||||
|
||||
static void
|
||||
randombytes_sysrandom_init(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
# endif /* _WIN32 */
|
||||
|
||||
static void
|
||||
randombytes_sysrandom_stir(void)
|
||||
@@ -299,24 +310,24 @@ randombytes_sysrandom_close(void)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
#ifndef _WIN32
|
||||
# ifndef _WIN32
|
||||
if (stream.random_data_source_fd != -1 &&
|
||||
close(stream.random_data_source_fd) == 0) {
|
||||
stream.random_data_source_fd = -1;
|
||||
stream.initialized = 0;
|
||||
ret = 0;
|
||||
}
|
||||
# if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
if (stream.getrandom_available != 0) {
|
||||
ret = 0;
|
||||
}
|
||||
# endif
|
||||
#else /* _WIN32 */
|
||||
# endif
|
||||
# else /* _WIN32 */
|
||||
if (stream.initialized != 0) {
|
||||
stream.initialized = 0;
|
||||
ret = 0;
|
||||
}
|
||||
#endif
|
||||
# endif /* _WIN32 */
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -324,26 +335,26 @@ static void
|
||||
randombytes_sysrandom_buf(void * const buf, const size_t size)
|
||||
{
|
||||
randombytes_sysrandom_stir_if_needed();
|
||||
#if defined(ULONG_LONG_MAX) && defined(SIZE_MAX)
|
||||
# if SIZE_MAX > ULONG_LONG_MAX
|
||||
# if defined(ULONG_LONG_MAX) && defined(SIZE_MAX)
|
||||
# if SIZE_MAX > ULONG_LONG_MAX
|
||||
/* coverity[result_independent_of_operands] */
|
||||
assert(size <= ULONG_LONG_MAX);
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#ifndef _WIN32
|
||||
# if defined(SYS_getrandom) && defined(__NR_getrandom)
|
||||
# ifndef _WIN32
|
||||
# ifdef HAVE_LINUX_COMPATIBLE_GETRANDOM
|
||||
if (stream.getrandom_available != 0) {
|
||||
if (randombytes_linux_getrandom(buf, size) != 0) {
|
||||
sodium_misuse(); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
# endif
|
||||
if (stream.random_data_source_fd == -1 ||
|
||||
safe_read(stream.random_data_source_fd, buf, size) != (ssize_t) size) {
|
||||
sodium_misuse(); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
#else
|
||||
# else /* _WIN32 */
|
||||
COMPILER_ASSERT(randombytes_BYTES_MAX <= 0xffffffffUL);
|
||||
if (size > (size_t) 0xffffffffUL) {
|
||||
sodium_misuse(); /* LCOV_EXCL_LINE */
|
||||
@@ -351,7 +362,7 @@ randombytes_sysrandom_buf(void * const buf, const size_t size)
|
||||
if (! RtlGenRandom((PVOID) buf, (ULONG) size)) {
|
||||
sodium_misuse(); /* LCOV_EXCL_LINE */
|
||||
}
|
||||
#endif
|
||||
# endif /* _WIN32 */
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
|
||||
Reference in New Issue
Block a user