From 0c0a18ea9ea67a47c48c37b344745af44877e218 Mon Sep 17 00:00:00 2001 From: lloyd Date: Sat, 17 Nov 2007 02:29:00 +0000 Subject: Add a new module, es_dev, that will replace es_file. Instead of using C++ iostreams, it uses unbuffered Unix I/O syscalls and is careful to avoid blocking for more than short amounts of time. --- modules/es_dev/es_dev.cpp | 118 +++++++++++++++++++++++++++++++++++++++++++++ modules/es_dev/es_dev.h | 24 +++++++++ modules/es_dev/modinfo.txt | 11 +++++ 3 files changed, 153 insertions(+) create mode 100644 modules/es_dev/es_dev.cpp create mode 100644 modules/es_dev/es_dev.h create mode 100644 modules/es_dev/modinfo.txt diff --git a/modules/es_dev/es_dev.cpp b/modules/es_dev/es_dev.cpp new file mode 100644 index 000000000..7a61a48af --- /dev/null +++ b/modules/es_dev/es_dev.cpp @@ -0,0 +1,118 @@ +/************************************************* +* Device EntropySource Source File * +* (C) 1999-2007 The Botan Project * +*************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/************************************************* +* A class handling reading from a device * +*************************************************/ +class Device_Reader + { + public: + typedef int fd_type; + + Device_Reader(fd_type device_fd) : fd(device_fd) {} + ~Device_Reader() { close(fd); } + u32bit get(byte out[], u32bit length); + + static fd_type open(const std::string& pathname); + private: + fd_type fd; + }; + +/************************************************* +* Read from a device file * +*************************************************/ +u32bit Device_Reader::get(byte out[], u32bit length) + { + if(fd < 0) + return 0; + + if(fd >= FD_SETSIZE) + return 0; + + const u32bit READ_WAIT_MS = 10; + + 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; + + if(::select(fd + 1, &read_set, 0, 0, &timeout) < 0) + return 0; + + if(!(FD_ISSET(fd, &read_set))) + return 0; + + const ssize_t got = ::read(fd, out, length); + if(got <= 0) + return 0; + + const u32bit ret = static_cast(got); + + if(ret > length) + return 0; + + return ret; + } + +/************************************************* +* Attempt to open a device * +*************************************************/ +int Device_Reader::open(const std::string& pathname) + { +#ifndef O_NONBLOCK + #define O_NONBLOCK 0 +#endif + +#ifndef O_NOCTTY + #define O_NOCTTY 0 +#endif + + const int flags = O_RDONLY | O_NONBLOCK | O_NOCTTY; + return ::open(pathname.c_str(), flags); + } + +} + +/************************************************* +* Gather entropy from a RNG device * +*************************************************/ +u32bit Device_EntropySource::slow_poll(byte output[], u32bit length) + { + std::vector sources = + global_config().option_as_list("rng/es_files"); + + u32bit read = 0; + + for(size_t j = 0; j != sources.size(); ++j) + { + const std::string source = sources[j]; + + Device_Reader reader(Device_Reader::open(source)); + + read += reader.get(output + read, length - read); + + if(read == length) + break; + } + + return read; + } + +} diff --git a/modules/es_dev/es_dev.h b/modules/es_dev/es_dev.h new file mode 100644 index 000000000..d491a7b18 --- /dev/null +++ b/modules/es_dev/es_dev.h @@ -0,0 +1,24 @@ +/************************************************* +* Device EntropySource Header File * +* (C) 1999-2007 The Botan Project * +*************************************************/ + +#ifndef BOTAN_ENTROPY_SRC_DEVICE_H__ +#define BOTAN_ENTROPY_SRC_DEVICE_H__ + +#include + +namespace Botan { + +/************************************************* +* Device Based Entropy Source * +*************************************************/ +class Device_EntropySource : public EntropySource + { + public: + u32bit slow_poll(byte[], u32bit); + }; + +} + +#endif diff --git a/modules/es_dev/modinfo.txt b/modules/es_dev/modinfo.txt new file mode 100644 index 000000000..3a766013d --- /dev/null +++ b/modules/es_dev/modinfo.txt @@ -0,0 +1,11 @@ +realname "RNG Device Reader" + +define ENTROPY_SRC_DEVICE + +load_on auto +modset unix + + +es_dev.h +es_dev.cpp + -- cgit v1.2.3