aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/entropy
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-06-30 13:15:30 -0400
committerJack Lloyd <[email protected]>2016-07-17 10:43:40 -0400
commit93922f20f04058ec624f7db3c74d8aa5a3d06440 (patch)
tree81144cfacced43c68c4385683ee0c123a1987042 /src/lib/entropy
parent4c5847412d41756aab738a3746666cfaffe5d4af (diff)
Add Stateful_RNG
Handles fork checking for HMAC_RNG and HMAC_DRBG AutoSeeded_RNG change - switch to HMAC_DRBG as default. Start removing the io buffer from entropy poller. Update default RNG poll bits to 256. Fix McEliece test, was using wrong RNG API. Update docs.
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;
};
}