8#include <botan/internal/dev_random.h>
9#include <botan/exceptn.h>
12#include <sys/select.h>
38 for(
auto fsname : fsnames)
40 int fd = ::open(fsname.c_str(),
flags);
49 if(errno != ENOENT && errno != EACCES)
50 throw System_Error(
"Opening OS RNG device failed", errno);
57 throw Invalid_State(
"Open of OS RNG succeeded but returned fd is too large for fd_set");
60 m_dev_fds.push_back(fd);
61 m_max_fd = std::max(m_max_fd, fd);
71 for(
int fd : m_dev_fds)
85 if(m_dev_fds.size() > 0)
90 for(
int dev_fd : m_dev_fds)
92 FD_SET(dev_fd, &read_set);
97 struct ::timeval timeout;
98 timeout.tv_sec = (BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS / 1000);
99 timeout.tv_usec = (BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS % 1000) * 1000;
101 if(::select(m_max_fd + 1, &read_set,
nullptr,
nullptr, &timeout) > 0)
103 for(
int dev_fd : m_dev_fds)
105 if(FD_ISSET(dev_fd, &read_set))
107 const ssize_t got = ::read(dev_fd, io_buf.data(), io_buf.size());
111 rng.
add_entropy(io_buf.data(),
static_cast<size_t>(got));
size_t poll(RandomNumberGenerator &rng) override
Device_EntropySource(const std::vector< std::string > &fsnames)
virtual void add_entropy(const uint8_t input[], size_t length)=0
std::vector< T, secure_allocator< T > > secure_vector