Skip to content

Commit

Permalink
URandom: replace /dev/urandom file with getrandom syscall
Browse files Browse the repository at this point in the history
  • Loading branch information
jonathanpoelen committed Oct 24, 2023
1 parent ddcde55 commit 9eef9d7
Showing 1 changed file with 13 additions and 32 deletions.
45 changes: 13 additions & 32 deletions src/system/linux/system/urandom.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,55 +9,36 @@ SPDX-License-Identifier: GPL-2.0-or-later
#include "core/error.hpp"
#include "utils/log.hpp"
#include "utils/random.hpp"
#include "utils/sugar/unique_fd.hpp"

#include <cerrno>
#include <cstring>

#include <unistd.h>
#include <sys/random.h>


class URandom final : public Random
{
unique_fd ufd;

public:
URandom()
: ufd(open("/dev/urandom", O_RDONLY))
{
if (ufd.is_open()) {
LOG(LOG_INFO, "using /dev/urandom as random source");
}
else {
LOG(LOG_INFO, "access to /dev/urandom failed: %s", strerror(errno));

ufd.reset(open("/dev/random", O_RDONLY));
if (ufd.is_open()) {
LOG(LOG_INFO, "using /dev/random as random source");
}
else {
LOG(LOG_ERR, "random source failed to provide random data : couldn't open device");
throw Error(ERR_RANDOM_SOURCE_FAILED);
}
}
}

void random(writable_bytes_view buf) override
{
// TODO This is basically a blocking read, we should provide timeout management and behaviour
uint8_t* data = buf.data();
size_t len = buf.size();
while (len) {
ssize_t ret = ::read(ufd.fd(), data, len);
if (REDEMPTION_UNLIKELY(ret <= 0)) {
#if defined(__sun) && defined(__SVR4)
/* On Solaris, getrandom() is limited to returning up to 1024 bytes. */
size_t len_max = 1024;
#else
size_t len_max = LONG_MAX;
#endif
// TODO This is basically a blocking read, we should provide timeout management and behaviour
ssize_t n = getrandom(data, len < len_max ? len : len_max, 0);
if (REDEMPTION_UNLIKELY(n < 0)) {
if (errno == EINTR) {
continue;
}
// ignore errno == EAGAIN because GRND_NONBLOCK flag is not used
LOG(LOG_ERR, "random source failed to provide random data [%s]", strerror(errno));
throw Error(ERR_RANDOM_SOURCE_FAILED);
}
data += ret;
len -= ret;
data += n;
len -= n;
}
}
};

0 comments on commit 9eef9d7

Please sign in to comment.