aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/entropy/dev_random/es_dev.cpp51
-rw-r--r--src/entropy/dev_random/es_dev.h8
2 files changed, 40 insertions, 19 deletions
diff --git a/src/entropy/dev_random/es_dev.cpp b/src/entropy/dev_random/es_dev.cpp
index b185eae75..ca456b28c 100644
--- a/src/entropy/dev_random/es_dev.cpp
+++ b/src/entropy/dev_random/es_dev.cpp
@@ -15,15 +15,16 @@ namespace Botan {
/**
Close the device, if open
*/
-Device_EntropySource::Device_Reader::~Device_Reader()
+void Device_EntropySource::Device_Reader::close()
{
- if(fd > 0) { ::close(fd); }
+ if(fd > 0) { ::close(fd); fd = -1; }
}
/**
Read bytes from a device file
*/
-u32bit Device_EntropySource::Device_Reader::get(byte out[], u32bit length)
+u32bit Device_EntropySource::Device_Reader::get(byte out[], u32bit length,
+ u32bit ms_wait_time)
{
if(fd < 0)
return 0;
@@ -31,15 +32,13 @@ u32bit Device_EntropySource::Device_Reader::get(byte out[], u32bit length)
if(fd >= FD_SETSIZE)
return 0;
- const u32bit READ_WAIT_MS = 3;
-
fd_set read_set;
FD_ZERO(&read_set);
FD_SET(fd, &read_set);
struct ::timeval timeout;
timeout.tv_sec = 0;
- timeout.tv_usec = READ_WAIT_MS * 1000;
+ timeout.tv_usec = ms_wait_time * 1000;
if(::select(fd + 1, &read_set, 0, 0, &timeout) < 0)
return 0;
@@ -62,7 +61,8 @@ u32bit Device_EntropySource::Device_Reader::get(byte out[], u32bit length)
/**
Attempt to open a device
*/
-int Device_EntropySource::Device_Reader::open(const std::string& pathname)
+Device_EntropySource::Device_Reader::fd_type
+Device_EntropySource::Device_Reader::open(const std::string& pathname)
{
#ifndef O_NONBLOCK
#define O_NONBLOCK 0
@@ -79,10 +79,15 @@ int Device_EntropySource::Device_Reader::open(const std::string& pathname)
/**
Device_EntropySource constructor
*/
-Device_EntropySource::Device_EntropySource(const std::vector<std::string>& fsnames)
+Device_EntropySource::Device_EntropySource(
+ const std::vector<std::string>& fsnames)
{
for(u32bit i = 0; i != fsnames.size(); ++i)
- devices.push_back(Device_Reader(Device_Reader::open(fsnames[i])));
+ {
+ Device_Reader::fd_type fd = Device_Reader::open(fsnames[i]);
+ if(fd > 0)
+ devices.push_back(Device_Reader(fd));
+ }
}
/**
@@ -90,25 +95,37 @@ Device_EntropySource::Device_EntropySource(const std::vector<std::string>& fsnam
*/
u32bit Device_EntropySource::slow_poll(byte output[], u32bit length)
{
- u32bit read = 0;
-
for(size_t i = 0; i != devices.size(); ++i)
{
- read += devices[i].get(output + read, length - read);
+ const u32bit got = devices[i].get(output, length, 100);
- if(read == length)
- break;
+ if(got)
+ return got;
}
- return read;
+ return 0;
}
/**
-* Fast /dev/random and co poll: limit output to 64 bytes
+* Fast poll: try limit to 10 ms wait
*/
u32bit Device_EntropySource::fast_poll(byte output[], u32bit length)
{
- return slow_poll(output, std::min<u32bit>(length, 64));
+ for(size_t i = 0; i != devices.size(); ++i)
+ {
+ const u32bit got = devices[i].get(output, length, 10);
+
+ if(got)
+ return got;
+ }
+
+ return 0;
+ }
+
+Device_EntropySource::~Device_EntropySource()
+ {
+ for(size_t i = 0; i != devices.size(); ++i)
+ devices[i].close();
}
}
diff --git a/src/entropy/dev_random/es_dev.h b/src/entropy/dev_random/es_dev.h
index ff6a14f2c..db64b75fa 100644
--- a/src/entropy/dev_random/es_dev.h
+++ b/src/entropy/dev_random/es_dev.h
@@ -21,6 +21,7 @@ class BOTAN_DLL Device_EntropySource : public EntropySource
std::string name() const { return "RNG Device Reader"; }
Device_EntropySource(const std::vector<std::string>& fsnames);
+ ~Device_EntropySource();
u32bit slow_poll(byte[], u32bit);
u32bit fast_poll(byte[], u32bit);
@@ -34,9 +35,12 @@ class BOTAN_DLL Device_EntropySource : public EntropySource
public:
typedef int fd_type;
+ // Does not own fd, a transient class
Device_Reader(fd_type device_fd) : fd(device_fd) {}
- ~Device_Reader();
- u32bit get(byte out[], u32bit length);
+
+ void close();
+
+ u32bit get(byte out[], u32bit length, u32bit ms_wait_time);
static fd_type open(const std::string& pathname);
private: