diff options
author | Jack Lloyd <[email protected]> | 2016-06-30 13:15:30 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2016-07-17 10:43:40 -0400 |
commit | 93922f20f04058ec624f7db3c74d8aa5a3d06440 (patch) | |
tree | 81144cfacced43c68c4385683ee0c123a1987042 /src/lib/entropy | |
parent | 4c5847412d41756aab738a3746666cfaffe5d4af (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.cpp | 6 | ||||
-rw-r--r-- | src/lib/entropy/darwin_secrandom/darwin_secrandom.h | 2 | ||||
-rw-r--r-- | src/lib/entropy/dev_random/dev_random.cpp | 75 | ||||
-rw-r--r-- | src/lib/entropy/dev_random/dev_random.h | 6 |
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; }; } |