aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/entropy
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/entropy')
-rw-r--r--src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp6
-rw-r--r--src/lib/entropy/darwin_secrandom/darwin_secrandom.h2
-rw-r--r--src/lib/entropy/dev_random/dev_random.cpp75
-rw-r--r--src/lib/entropy/dev_random/dev_random.h6
4 files changed, 61 insertions, 28 deletions
diff --git a/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp b/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp
index 0a6b85955..7dde17155 100644
--- a/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp
+++ b/src/lib/entropy/darwin_secrandom/darwin_secrandom.cpp
@@ -16,11 +16,11 @@ namespace Botan {
*/
void Darwin_SecRandom::poll(Entropy_Accumulator& accum)
{
- secure_vector<byte>& buf = accum.get_io_buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);
+ m_io_buf.resize(BOTAN_SYSTEM_RNG_POLL_REQUEST);
- if(0 == SecRandomCopyBytes(kSecRandomDefault, buf.size(), buf.data()))
+ if(0 == SecRandomCopyBytes(kSecRandomDefault, m_io_buf.size(), m_io_buf.data()))
{
- accum.add(buf.data(), buf.size(), BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
+ accum.add(m_io_buf.data(), m_io_buf.size(), BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
}
}
diff --git a/src/lib/entropy/darwin_secrandom/darwin_secrandom.h b/src/lib/entropy/darwin_secrandom/darwin_secrandom.h
index 09cdc208d..267d177f0 100644
--- a/src/lib/entropy/darwin_secrandom/darwin_secrandom.h
+++ b/src/lib/entropy/darwin_secrandom/darwin_secrandom.h
@@ -21,6 +21,8 @@ class Darwin_SecRandom final : public Entropy_Source
std::string name() const override { return "darwin_secrandom"; }
void poll(Entropy_Accumulator& accum) override;
+ private:
+ secure_vector<uint8_t> m_io_buf;
};
}
diff --git a/src/lib/entropy/dev_random/dev_random.cpp b/src/lib/entropy/dev_random/dev_random.cpp
index aca161d64..ff746f34e 100644
--- a/src/lib/entropy/dev_random/dev_random.cpp
+++ b/src/lib/entropy/dev_random/dev_random.cpp
@@ -6,6 +6,7 @@
*/
#include <botan/internal/dev_random.h>
+#include <botan/exceptn.h>
#include <sys/types.h>
#include <sys/select.h>
@@ -31,15 +32,39 @@ Device_EntropySource::Device_EntropySource(const std::vector<std::string>& fsnam
const int flags = O_RDONLY | O_NONBLOCK | O_NOCTTY;
+ m_max_fd = 0;
+
for(auto fsname : fsnames)
{
- fd_type fd = ::open(fsname.c_str(), flags);
+ int fd = ::open(fsname.c_str(), flags);
- if(fd >= 0 && fd < FD_SETSIZE)
- m_devices.push_back(fd);
- else if(fd >= 0)
- ::close(fd);
+ if(fd > 0)
+ {
+ if(fd > FD_SETSIZE)
+ {
+ ::close(fd);
+ throw Exception("Open of OS RNG succeeded but fd is too large for fd_set");
+ }
+
+ m_dev_fds.push_back(fd);
+ m_max_fd = std::max(m_max_fd, fd);
+ }
+ else
+ {
+ /*
+ ENOENT or EACCES is normal as some of the named devices may not exist
+ on this system. But any other errno value probably indicates
+ either a bug in the application or file descriptor exhaustion.
+ */
+ if(errno != ENOENT && errno != EACCES)
+ {
+ throw Exception("Opening OS RNG device failed with errno " +
+ std::to_string(errno));
+ }
+ }
}
+
+ m_io_buf.resize(BOTAN_SYSTEM_RNG_POLL_REQUEST);
}
/**
@@ -47,8 +72,11 @@ Device_EntropySource destructor: close all open devices
*/
Device_EntropySource::~Device_EntropySource()
{
- for(size_t i = 0; i != m_devices.size(); ++i)
- ::close(m_devices[i]);
+ for(int fd : m_dev_fds)
+ {
+ // ignoring return value here, can't throw in destructor anyway
+ ::close(fd);
+ }
}
/**
@@ -56,35 +84,36 @@ Device_EntropySource::~Device_EntropySource()
*/
void Device_EntropySource::poll(Entropy_Accumulator& accum)
{
- if(m_devices.empty())
+ if(m_dev_fds.empty())
return;
- fd_type max_fd = m_devices[0];
fd_set read_set;
FD_ZERO(&read_set);
- for(size_t i = 0; i != m_devices.size(); ++i)
+
+ for(int dev_fd : m_dev_fds)
{
- FD_SET(m_devices[i], &read_set);
- max_fd = std::max(m_devices[i], max_fd);
+ FD_SET(dev_fd, &read_set);
}
struct ::timeval timeout;
-
timeout.tv_sec = (BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS / 1000);
timeout.tv_usec = (BOTAN_SYSTEM_RNG_POLL_TIMEOUT_MS % 1000) * 1000;
- if(::select(max_fd + 1, &read_set, nullptr, nullptr, &timeout) < 0)
- return;
-
- secure_vector<byte>& buf = accum.get_io_buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);
-
- for(size_t i = 0; i != m_devices.size(); ++i)
+ if(::select(m_max_fd + 1, &read_set, nullptr, nullptr, &timeout) > 0)
{
- if(FD_ISSET(m_devices[i], &read_set))
+ for(int dev_fd : m_dev_fds)
{
- const ssize_t got = ::read(m_devices[i], buf.data(), buf.size());
- if(got > 0)
- accum.add(buf.data(), got, BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
+ if(FD_ISSET(dev_fd, &read_set))
+ {
+ const ssize_t got = ::read(dev_fd, m_io_buf.data(), m_io_buf.size());
+
+ if(got > 0)
+ {
+ accum.add(m_io_buf.data(),
+ static_cast<size_t>(got),
+ BOTAN_ENTROPY_ESTIMATE_STRONG_RNG);
+ }
+ }
}
}
}
diff --git a/src/lib/entropy/dev_random/dev_random.h b/src/lib/entropy/dev_random/dev_random.h
index 1f29b2f64..05b36f3eb 100644
--- a/src/lib/entropy/dev_random/dev_random.h
+++ b/src/lib/entropy/dev_random/dev_random.h
@@ -25,10 +25,12 @@ class Device_EntropySource final : public Entropy_Source
void poll(Entropy_Accumulator& accum) override;
Device_EntropySource(const std::vector<std::string>& fsnames);
+
~Device_EntropySource();
private:
- typedef int fd_type;
- std::vector<fd_type> m_devices;
+ secure_vector<uint8_t> m_io_buf;
+ std::vector<int> m_dev_fds;
+ int m_max_fd;
};
}