diff options
author | lloyd <[email protected]> | 2007-11-17 02:29:00 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2007-11-17 02:29:00 +0000 |
commit | 0c0a18ea9ea67a47c48c37b344745af44877e218 (patch) | |
tree | 8eaf1d83c6ec3825cfd336d823924578f8e4b726 /modules/es_dev | |
parent | fedea15eb92bed68148a57fbd3b0b5ab3d2cb4b8 (diff) |
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.
Diffstat (limited to 'modules/es_dev')
-rw-r--r-- | modules/es_dev/es_dev.cpp | 118 | ||||
-rw-r--r-- | modules/es_dev/es_dev.h | 24 | ||||
-rw-r--r-- | modules/es_dev/modinfo.txt | 11 |
3 files changed, 153 insertions, 0 deletions
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 <botan/es_dev.h> +#include <botan/config.h> +#include <sys/select.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/fcntl.h> +#include <unistd.h> + +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<u32bit>(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<std::string> 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 <botan/base.h> + +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 + +<add> +es_dev.h +es_dev.cpp +</add> |