aboutsummaryrefslogtreecommitdiffstats
path: root/modules/entropy
diff options
context:
space:
mode:
Diffstat (limited to 'modules/entropy')
-rw-r--r--modules/entropy/beos_stats/es_beos.cpp65
-rw-r--r--modules/entropy/beos_stats/es_beos.h25
-rw-r--r--modules/entropy/beos_stats/modinfo.txt19
-rw-r--r--modules/entropy/cryptoapi_rng/es_capi.cpp87
-rw-r--r--modules/entropy/cryptoapi_rng/es_capi.h28
-rw-r--r--modules/entropy/cryptoapi_rng/modinfo.txt21
-rw-r--r--modules/entropy/dev_random/es_dev.cpp112
-rw-r--r--modules/entropy/dev_random/es_dev.h28
-rw-r--r--modules/entropy/dev_random/modinfo.txt27
-rw-r--r--modules/entropy/egd/es_egd.cpp76
-rw-r--r--modules/entropy/egd/es_egd.h30
-rw-r--r--modules/entropy/egd/modinfo.txt31
-rw-r--r--modules/entropy/proc_walk/es_ftw.cpp147
-rw-r--r--modules/entropy/proc_walk/es_ftw.h31
-rw-r--r--modules/entropy/proc_walk/modinfo.txt29
-rw-r--r--modules/entropy/unix_procs/es_unix.cpp112
-rw-r--r--modules/entropy/unix_procs/es_unix.h35
-rw-r--r--modules/entropy/unix_procs/modinfo.txt29
-rw-r--r--modules/entropy/unix_procs/unix_cmd.cpp240
-rw-r--r--modules/entropy/unix_procs/unix_cmd.h57
-rw-r--r--modules/entropy/unix_procs/unix_src.cpp59
-rw-r--r--modules/entropy/win32_stats/es_win32.cpp109
-rw-r--r--modules/entropy/win32_stats/es_win32.h25
-rw-r--r--modules/entropy/win32_stats/modinfo.txt23
24 files changed, 1445 insertions, 0 deletions
diff --git a/modules/entropy/beos_stats/es_beos.cpp b/modules/entropy/beos_stats/es_beos.cpp
new file mode 100644
index 000000000..80d5605d0
--- /dev/null
+++ b/modules/entropy/beos_stats/es_beos.cpp
@@ -0,0 +1,65 @@
+/*************************************************
+* BeOS EntropySource Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_beos.h>
+#include <kernel/OS.h>
+#include <kernel/image.h>
+#include <interface/InterfaceDefs.h>
+
+namespace Botan {
+
+/*************************************************
+* BeOS Fast Poll *
+*************************************************/
+void BeOS_EntropySource::do_fast_poll()
+ {
+ system_info info_sys;
+ get_system_info(&info_sys);
+ add_bytes(&info_sys, sizeof(system_info));
+
+ key_info info_key;
+ get_key_info(&info_key);
+ add_bytes(&info_key, sizeof(key_info));
+
+ add_bytes(idle_time());
+ }
+
+/*************************************************
+* BeOS Slow Poll *
+*************************************************/
+void BeOS_EntropySource::do_slow_poll()
+ {
+ team_info info_team;
+ int32 cookie_team = 0;
+
+ while(get_next_team_info(&cookie_team, &info_team) == B_OK)
+ {
+ add_bytes(&info_team, sizeof(team_info));
+
+ team_id id = info_team.team;
+ int32 cookie = 0;
+
+ thread_info info_thr;
+ while(get_next_thread_info(id, &cookie, &info_thr) == B_OK)
+ add_bytes(&info_thr, sizeof(thread_info));
+
+ cookie = 0;
+ image_info info_img;
+ while(get_next_image_info(id, &cookie, &info_img) == B_OK)
+ add_bytes(&info_img, sizeof(image_info));
+
+ cookie = 0;
+ sem_info info_sem;
+ while(get_next_sem_info(id, &cookie, &info_sem) == B_OK)
+ add_bytes(&info_sem, sizeof(sem_info));
+
+ cookie = 0;
+ area_info info_area;
+ while(get_next_area_info(id, &cookie, &info_area) == B_OK)
+ add_bytes(&info_area, sizeof(area_info));
+ }
+ }
+
+}
diff --git a/modules/entropy/beos_stats/es_beos.h b/modules/entropy/beos_stats/es_beos.h
new file mode 100644
index 000000000..11808d2b8
--- /dev/null
+++ b/modules/entropy/beos_stats/es_beos.h
@@ -0,0 +1,25 @@
+/*************************************************
+* BeOS EntropySource Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EXT_ENTROPY_SRC_BEOS_H__
+#define BOTAN_EXT_ENTROPY_SRC_BEOS_H__
+
+#include <botan/buf_es.h>
+
+namespace Botan {
+
+/*************************************************
+* BeOS Entropy Source *
+*************************************************/
+class BeOS_EntropySource : public Buffered_EntropySource
+ {
+ private:
+ void do_fast_poll();
+ void do_slow_poll();
+ };
+
+}
+
+#endif
diff --git a/modules/entropy/beos_stats/modinfo.txt b/modules/entropy/beos_stats/modinfo.txt
new file mode 100644
index 000000000..a7e62cfb3
--- /dev/null
+++ b/modules/entropy/beos_stats/modinfo.txt
@@ -0,0 +1,19 @@
+realname "BeOS Entropy Source"
+
+define ENTROPY_SRC_BEOS
+modset beos
+
+load_on auto
+
+<add>
+es_beos.h
+es_beos.cpp
+</add>
+
+<os>
+beos
+</os>
+
+<libs>
+beos -> root,be
+</libs>
diff --git a/modules/entropy/cryptoapi_rng/es_capi.cpp b/modules/entropy/cryptoapi_rng/es_capi.cpp
new file mode 100644
index 000000000..7d1e0e753
--- /dev/null
+++ b/modules/entropy/cryptoapi_rng/es_capi.cpp
@@ -0,0 +1,87 @@
+/*************************************************
+* Win32 CryptoAPI EntropySource Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_capi.h>
+#include <botan/parsing.h>
+#include <windows.h>
+#include <wincrypt.h>
+
+namespace Botan {
+
+/*************************************************
+* Gather Entropy from Win32 CAPI *
+*************************************************/
+u32bit Win32_CAPI_EntropySource::slow_poll(byte output[], u32bit length)
+ {
+
+ class CSP_Handle
+ {
+ public:
+ CSP_Handle(u64bit capi_provider)
+ {
+ valid = false;
+ DWORD prov_type = (DWORD)capi_provider;
+
+ if(CryptAcquireContext(&handle, 0, 0,
+ prov_type, CRYPT_VERIFYCONTEXT))
+ valid = true;
+ }
+
+ ~CSP_Handle()
+ {
+ if(is_valid())
+ CryptReleaseContext(handle, 0);
+ }
+
+ void gen_random(byte out[], u32bit n) const
+ {
+ if(is_valid())
+ CryptGenRandom(handle, n, out);
+ }
+
+ bool is_valid() const { return valid; }
+
+ HCRYPTPROV get_handle() const { return handle; }
+ private:
+ HCRYPTPROV handle;
+ bool valid;
+ };
+
+
+ if(length > 64)
+ length = 64;
+
+ for(u32bit j = 0; j != prov_types.size(); ++j)
+ {
+ CSP_Handle csp(prov_types[j]);
+ if(!csp.is_valid())
+ continue;
+
+ csp.gen_random(output, length);
+ break;
+ }
+ return length;
+ }
+
+/*************************************************
+* Gather Entropy from Win32 CAPI *
+*************************************************/
+Win32_CAPI_EntropySource::Win32_CAPI_EntropySource(const std::string& provs)
+ {
+ std::vector<std::string> capi_provs = split_on(provs, ':');
+
+ for(u32bit j = 0; j != capi_provs.size(); ++j)
+ {
+ if(capi_provs[j] == "RSA_FULL") prov_types.push_back(PROV_RSA_FULL);
+ if(capi_provs[j] == "INTEL_SEC") prov_types.push_back(PROV_INTEL_SEC);
+ if(capi_provs[j] == "FORTEZZA") prov_types.push_back(PROV_FORTEZZA);
+ if(capi_provs[j] == "RNG") prov_types.push_back(PROV_RNG);
+ }
+
+ if(prov_types.size() == 0)
+ prov_types.push_back(PROV_RSA_FULL);
+ }
+
+}
diff --git a/modules/entropy/cryptoapi_rng/es_capi.h b/modules/entropy/cryptoapi_rng/es_capi.h
new file mode 100644
index 000000000..36b4acd8d
--- /dev/null
+++ b/modules/entropy/cryptoapi_rng/es_capi.h
@@ -0,0 +1,28 @@
+/*************************************************
+* Win32 CAPI EntropySource Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EXT_ENTROPY_SRC_WIN32_CAPI_H__
+#define BOTAN_EXT_ENTROPY_SRC_WIN32_CAPI_H__
+
+#include <botan/rng.h>
+#include <vector>
+
+namespace Botan {
+
+/*************************************************
+* Win32 CAPI Entropy Source *
+*************************************************/
+class Win32_CAPI_EntropySource : public EntropySource
+ {
+ public:
+ u32bit slow_poll(byte[], u32bit);
+ Win32_CAPI_EntropySource(const std::string& = "");
+ private:
+ std::vector<u64bit> prov_types;
+ };
+
+}
+
+#endif
diff --git a/modules/entropy/cryptoapi_rng/modinfo.txt b/modules/entropy/cryptoapi_rng/modinfo.txt
new file mode 100644
index 000000000..40104664b
--- /dev/null
+++ b/modules/entropy/cryptoapi_rng/modinfo.txt
@@ -0,0 +1,21 @@
+realname "Win32 CryptoAPI Entropy Source"
+
+define ENTROPY_SRC_CAPI
+load_on auto
+modset win32
+
+<add>
+es_capi.h
+es_capi.cpp
+</add>
+
+# We'll just assume CAPI is there; this is OK except for 3.x, early versions
+# of 95, and maybe NT 3.5
+<os>
+windows
+cygwin
+</os>
+
+<libs>
+windows -> advapi32
+</libs>
diff --git a/modules/entropy/dev_random/es_dev.cpp b/modules/entropy/dev_random/es_dev.cpp
new file mode 100644
index 000000000..310620716
--- /dev/null
+++ b/modules/entropy/dev_random/es_dev.cpp
@@ -0,0 +1,112 @@
+/*************************************************
+* Device EntropySource Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_dev.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() { if(fd > 0) { ::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)
+ {
+ u32bit read = 0;
+
+ for(size_t j = 0; j != fsnames.size(); ++j)
+ {
+ Device_Reader reader(Device_Reader::open(fsnames[j]));
+
+ read += reader.get(output + read, length - read);
+
+ if(read == length)
+ break;
+ }
+
+ return read;
+ }
+
+}
diff --git a/modules/entropy/dev_random/es_dev.h b/modules/entropy/dev_random/es_dev.h
new file mode 100644
index 000000000..21d28b9bb
--- /dev/null
+++ b/modules/entropy/dev_random/es_dev.h
@@ -0,0 +1,28 @@
+/*************************************************
+* Device EntropySource Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_ENTROPY_SRC_DEVICE_H__
+#define BOTAN_ENTROPY_SRC_DEVICE_H__
+
+#include <botan/rng.h>
+#include <vector>
+
+namespace Botan {
+
+/*************************************************
+* Device Based Entropy Source *
+*************************************************/
+class Device_EntropySource : public EntropySource
+ {
+ public:
+ Device_EntropySource(const std::vector<std::string>& fs) : fsnames(fs) {}
+ u32bit slow_poll(byte[], u32bit);
+ private:
+ std::vector<std::string> fsnames;
+ };
+
+}
+
+#endif
diff --git a/modules/entropy/dev_random/modinfo.txt b/modules/entropy/dev_random/modinfo.txt
new file mode 100644
index 000000000..6622886af
--- /dev/null
+++ b/modules/entropy/dev_random/modinfo.txt
@@ -0,0 +1,27 @@
+realname "RNG Device Reader"
+
+define ENTROPY_SRC_DEVICE
+
+load_on auto
+modset unix
+
+<add>
+es_dev.h
+es_dev.cpp
+</add>
+
+<os>
+aix
+beos
+cygwin
+darwin
+freebsd
+hpux
+irix
+linux
+netbsd
+openbsd
+qnx
+solaris
+tru64
+</os>
diff --git a/modules/entropy/egd/es_egd.cpp b/modules/entropy/egd/es_egd.cpp
new file mode 100644
index 000000000..da4aaf847
--- /dev/null
+++ b/modules/entropy/egd/es_egd.cpp
@@ -0,0 +1,76 @@
+/*************************************************
+* EGD EntropySource Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_egd.h>
+#include <botan/bit_ops.h>
+#include <botan/parsing.h>
+#include <cstring>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <unistd.h>
+
+#ifndef PF_LOCAL
+ #define PF_LOCAL PF_UNIX
+#endif
+
+namespace Botan {
+
+/*************************************************
+* Gather Entropy from EGD *
+*************************************************/
+u32bit EGD_EntropySource::do_poll(byte output[], u32bit length,
+ const std::string& path) const
+ {
+ if(length > 128)
+ length = 128;
+
+ sockaddr_un addr;
+ std::memset(&addr, 0, sizeof(addr));
+ addr.sun_family = PF_LOCAL;
+
+ if(sizeof(addr.sun_path) < path.length() + 1)
+ throw Exception("EGD_EntropySource: Socket path is too long");
+ std::strcpy(addr.sun_path, path.c_str());
+
+ int fd = ::socket(addr.sun_family, SOCK_STREAM, 0);
+ if(fd == -1) return 0;
+
+ int len = sizeof(addr.sun_family) + std::strlen(addr.sun_path) + 1;
+ if(::connect(fd, reinterpret_cast<struct ::sockaddr*>(&addr), len))
+ { ::close(fd); return 0; }
+
+ byte buffer[2];
+ buffer[0] = 1;
+ buffer[1] = static_cast<byte>(length);
+
+ if(::write(fd, buffer, 2) != 2) { ::close(fd); return 0; }
+ if(::read(fd, buffer, 1) != 1) { ::close(fd); return 0; }
+
+ ssize_t count = ::read(fd, output, buffer[0]);
+
+ if(count == -1) { close(fd); return 0; }
+
+ ::close(fd);
+
+ return count;
+ }
+
+/*************************************************
+* Gather Entropy from EGD *
+*************************************************/
+u32bit EGD_EntropySource::slow_poll(byte output[], u32bit length)
+ {
+ for(u32bit j = 0; j != paths.size(); j++)
+ {
+ u32bit got = do_poll(output, length, paths[j]);
+ if(got)
+ return got;
+ }
+ return 0;
+ }
+
+}
diff --git a/modules/entropy/egd/es_egd.h b/modules/entropy/egd/es_egd.h
new file mode 100644
index 000000000..e3ff2fec8
--- /dev/null
+++ b/modules/entropy/egd/es_egd.h
@@ -0,0 +1,30 @@
+/*************************************************
+* EGD EntropySource Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EXT_ENTROPY_SRC_EGD_H__
+#define BOTAN_EXT_ENTROPY_SRC_EGD_H__
+
+#include <botan/rng.h>
+#include <string>
+#include <vector>
+
+namespace Botan {
+
+/*************************************************
+* EGD Entropy Source *
+*************************************************/
+class EGD_EntropySource : public EntropySource
+ {
+ public:
+ u32bit slow_poll(byte[], u32bit);
+ EGD_EntropySource(const std::vector<std::string>& p) : paths(p) {}
+ private:
+ u32bit do_poll(byte[], u32bit, const std::string&) const;
+ const std::vector<std::string> paths;
+ };
+
+}
+
+#endif
diff --git a/modules/entropy/egd/modinfo.txt b/modules/entropy/egd/modinfo.txt
new file mode 100644
index 000000000..6b34f395c
--- /dev/null
+++ b/modules/entropy/egd/modinfo.txt
@@ -0,0 +1,31 @@
+realname "EGD Entropy Source"
+
+define ENTROPY_SRC_EGD
+
+load_on auto
+modset unix
+
+<add>
+es_egd.h
+es_egd.cpp
+</add>
+
+<libs>
+solaris -> socket
+qnx -> socket
+</libs>
+
+<os>
+aix
+cygwin
+darwin
+freebsd
+hpux
+irix
+linux
+netbsd
+openbsd
+qnx
+solaris
+tru64
+</os>
diff --git a/modules/entropy/proc_walk/es_ftw.cpp b/modules/entropy/proc_walk/es_ftw.cpp
new file mode 100644
index 000000000..ec11378f8
--- /dev/null
+++ b/modules/entropy/proc_walk/es_ftw.cpp
@@ -0,0 +1,147 @@
+/*************************************************
+* FTW EntropySource Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_ftw.h>
+#include <botan/util.h>
+#include <cstring>
+#include <deque>
+
+#ifndef _POSIX_C_SOURCE
+ #define _POSIX_C_SOURCE 199309
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <fcntl.h>
+
+namespace Botan {
+
+namespace {
+
+class Directory_Walker
+ {
+ public:
+ Directory_Walker(const std::string& root) { add_directory(root); }
+ ~Directory_Walker();
+
+ int next_fd();
+ private:
+ void add_directory(const std::string&);
+
+ std::deque<std::pair<DIR*, std::string> > dirs;
+ };
+
+void Directory_Walker::add_directory(const std::string& dirname)
+ {
+ DIR* dir = ::opendir(dirname.c_str());
+ if(dir)
+ dirs.push_back(std::make_pair(dir, dirname));
+ }
+
+Directory_Walker::~Directory_Walker()
+ {
+ while(dirs.size())
+ {
+ ::closedir(dirs[0].first);
+ dirs.pop_front();
+ }
+ }
+
+int Directory_Walker::next_fd()
+ {
+ while(dirs.size())
+ {
+ std::pair<DIR*, std::string> dirinfo = dirs[0];
+
+ struct dirent* entry = ::readdir(dirinfo.first);
+
+ if(!entry)
+ {
+ ::closedir(dirinfo.first);
+ dirs.pop_front();
+ continue;
+ }
+
+ const std::string filename = entry->d_name;
+
+ if(filename == "." || filename == "..")
+ continue;
+
+ const std::string full_path = dirinfo.second + '/' + filename;
+
+ struct stat stat_buf;
+ if(::lstat(full_path.c_str(), &stat_buf) == -1)
+ continue;
+
+ if(S_ISDIR(stat_buf.st_mode))
+ add_directory(full_path);
+ else if(S_ISREG(stat_buf.st_mode))
+ {
+ int fd = ::open(full_path.c_str(), O_RDONLY | O_NOCTTY);
+
+ if(fd > 0)
+ return fd;
+ }
+ }
+
+ return -1;
+ }
+
+}
+
+/*************************************************
+* FTW_EntropySource Constructor *
+*************************************************/
+FTW_EntropySource::FTW_EntropySource(const std::string& p) : path(p)
+ {
+ }
+
+/*************************************************
+* FTW Fast Poll *
+*************************************************/
+void FTW_EntropySource::do_fast_poll()
+ {
+ poll(32*1024);
+ }
+
+/*************************************************
+* FTW Slow Poll *
+*************************************************/
+void FTW_EntropySource::do_slow_poll()
+ {
+ poll(256*1024);
+ }
+
+/*************************************************
+* FTW Poll *
+*************************************************/
+void FTW_EntropySource::poll(u32bit max_read)
+ {
+ Directory_Walker dir(path);
+ SecureVector<byte> read_buf(1024);
+
+ u32bit read_so_far = 0;
+ while(read_so_far < max_read)
+ {
+ int fd = dir.next_fd();
+
+ if(fd == -1)
+ break;
+
+ ssize_t got = ::read(fd, read_buf.begin(), read_buf.size());
+
+ if(got > 0)
+ {
+ add_bytes(read_buf, got);
+ read_so_far += got;
+ }
+
+ ::close(fd);
+ }
+ }
+
+}
diff --git a/modules/entropy/proc_walk/es_ftw.h b/modules/entropy/proc_walk/es_ftw.h
new file mode 100644
index 000000000..0a48cc551
--- /dev/null
+++ b/modules/entropy/proc_walk/es_ftw.h
@@ -0,0 +1,31 @@
+/*************************************************
+* File Tree Walking EntropySource Header File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EXT_ENTROPY_SRC_FTW_H__
+#define BOTAN_EXT_ENTROPY_SRC_FTW_H__
+
+#include <botan/buf_es.h>
+
+namespace Botan {
+
+/*************************************************
+* File Tree Walking Entropy Source *
+*************************************************/
+class FTW_EntropySource : public Buffered_EntropySource
+ {
+ public:
+ FTW_EntropySource(const std::string& root_dir);
+ private:
+ void do_fast_poll();
+ void do_slow_poll();
+
+ void poll(u32bit max_read);
+
+ const std::string path;
+ };
+
+}
+
+#endif
diff --git a/modules/entropy/proc_walk/modinfo.txt b/modules/entropy/proc_walk/modinfo.txt
new file mode 100644
index 000000000..d932523fd
--- /dev/null
+++ b/modules/entropy/proc_walk/modinfo.txt
@@ -0,0 +1,29 @@
+realname "File Tree Walking Entropy Source"
+
+define ENTROPY_SRC_FTW
+
+load_on auto
+modset unix
+
+<add>
+es_ftw.h
+es_ftw.cpp
+</add>
+
+<os>
+aix
+cygwin
+darwin
+freebsd
+hpux
+irix
+linux
+openbsd
+qnx
+solaris
+tru64
+
+# Doesn't build on 2.0.2/x86 due to libc/libstdc++ header issues; no
+# big deal since it has /dev/*random
+#netbsd
+</os>
diff --git a/modules/entropy/unix_procs/es_unix.cpp b/modules/entropy/unix_procs/es_unix.cpp
new file mode 100644
index 000000000..c503c20ae
--- /dev/null
+++ b/modules/entropy/unix_procs/es_unix.cpp
@@ -0,0 +1,112 @@
+/*************************************************
+* Unix EntropySource Source File *
+* (C) 1999-2008 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_unix.h>
+#include <botan/unix_cmd.h>
+#include <botan/parsing.h>
+#include <algorithm>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <unistd.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Sort ordering by priority *
+*************************************************/
+bool Unix_Program_Cmp(const Unix_Program& a, const Unix_Program& b)
+ { return (a.priority < b.priority); }
+
+}
+
+/*************************************************
+* Unix_EntropySource Constructor *
+*************************************************/
+Unix_EntropySource::Unix_EntropySource(const std::vector<std::string>& path) :
+ PATH(path)
+ {
+ add_default_sources(sources);
+ }
+
+/*************************************************
+* Add sources to the list *
+*************************************************/
+void Unix_EntropySource::add_sources(const Unix_Program srcs[], u32bit count)
+ {
+ sources.insert(sources.end(), srcs, srcs + count);
+ std::sort(sources.begin(), sources.end(), Unix_Program_Cmp);
+ }
+
+/*************************************************
+* Unix Fast Poll *
+*************************************************/
+void Unix_EntropySource::do_fast_poll()
+ {
+ const char* STAT_TARGETS[] = { "/", "/tmp", ".", "..", 0 };
+
+ for(u32bit j = 0; STAT_TARGETS[j]; j++)
+ {
+ struct stat statbuf;
+ clear_mem(&statbuf, 1);
+ ::stat(STAT_TARGETS[j], &statbuf);
+ add_bytes(&statbuf, sizeof(statbuf));
+ }
+
+ add_bytes(::getpid());
+ add_bytes(::getppid());
+
+ add_bytes(::getuid());
+ add_bytes(::getgid());
+ add_bytes(::geteuid());
+ add_bytes(::getegid());
+
+ add_bytes(::getpgrp());
+ add_bytes(::getsid(0));
+
+ struct ::rusage usage;
+
+ clear_mem(&usage, 1);
+ ::getrusage(RUSAGE_SELF, &usage);
+ add_bytes(&usage, sizeof(usage));
+
+ ::getrusage(RUSAGE_CHILDREN, &usage);
+ add_bytes(&usage, sizeof(usage));
+ }
+
+/*************************************************
+* Unix Slow Poll *
+*************************************************/
+void Unix_EntropySource::do_slow_poll()
+ {
+ const u32bit TRY_TO_GET = 16 * 1024;
+ const u32bit MINIMAL_WORKING = 32;
+
+ u32bit got = 0;
+ for(u32bit j = 0; j != sources.size(); j++)
+ {
+ DataSource_Command pipe(sources[j].name_and_args, PATH);
+ SecureVector<byte> buffer(DEFAULT_BUFFERSIZE);
+
+ u32bit got_from_src = 0;
+
+ while(!pipe.end_of_data())
+ {
+ u32bit this_loop = pipe.read(buffer, buffer.size());
+ add_bytes(buffer, this_loop);
+ got_from_src += this_loop;
+ }
+
+ sources[j].working = (got_from_src >= MINIMAL_WORKING) ? true : false;
+ got += got_from_src;
+
+ if(got >= TRY_TO_GET)
+ break;
+ }
+ }
+
+}
diff --git a/modules/entropy/unix_procs/es_unix.h b/modules/entropy/unix_procs/es_unix.h
new file mode 100644
index 000000000..a1e279633
--- /dev/null
+++ b/modules/entropy/unix_procs/es_unix.h
@@ -0,0 +1,35 @@
+/*************************************************
+* Unix EntropySource Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EXT_ENTROPY_SRC_UNIX_H__
+#define BOTAN_EXT_ENTROPY_SRC_UNIX_H__
+
+#include <botan/buf_es.h>
+#include <botan/unix_cmd.h>
+#include <vector>
+
+namespace Botan {
+
+/*************************************************
+* Unix Entropy Source *
+*************************************************/
+class Unix_EntropySource : public Buffered_EntropySource
+ {
+ public:
+ void add_sources(const Unix_Program[], u32bit);
+ Unix_EntropySource(const std::vector<std::string>& path);
+ private:
+ static void add_default_sources(std::vector<Unix_Program>&);
+
+ void do_fast_poll();
+ void do_slow_poll();
+
+ const std::vector<std::string> PATH;
+ std::vector<Unix_Program> sources;
+ };
+
+}
+
+#endif
diff --git a/modules/entropy/unix_procs/modinfo.txt b/modules/entropy/unix_procs/modinfo.txt
new file mode 100644
index 000000000..f16e21289
--- /dev/null
+++ b/modules/entropy/unix_procs/modinfo.txt
@@ -0,0 +1,29 @@
+realname "Generic Unix Entropy Source"
+
+define ENTROPY_SRC_UNIX
+modset unix,beos
+
+load_on auto
+
+<add>
+es_unix.cpp
+unix_src.cpp
+unix_cmd.cpp
+es_unix.h
+unix_cmd.h
+</add>
+
+<os>
+aix
+beos
+cygwin
+darwin
+#freebsd
+hpux
+irix
+linux
+netbsd
+qnx
+solaris
+tru64
+</os>
diff --git a/modules/entropy/unix_procs/unix_cmd.cpp b/modules/entropy/unix_procs/unix_cmd.cpp
new file mode 100644
index 000000000..32829b91b
--- /dev/null
+++ b/modules/entropy/unix_procs/unix_cmd.cpp
@@ -0,0 +1,240 @@
+/*************************************************
+* Unix Command Execution Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef _XOPEN_SOURCE
+ #define _XOPEN_SOURCE 500
+#endif
+
+#ifndef _XOPEN_SOURCE_EXTENDED
+ #define _XOPEN_SOURCE_EXTENDED 1
+#endif
+
+#include <botan/unix_cmd.h>
+#include <botan/parsing.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+
+namespace Botan {
+
+namespace {
+
+/*************************************************
+* Attempt to execute the command *
+************************************************/
+void do_exec(const std::vector<std::string>& arg_list,
+ const std::vector<std::string>& paths)
+ {
+ const u32bit args = arg_list.size() - 1;
+
+ const char* arg1 = (args >= 1) ? arg_list[1].c_str() : 0;
+ const char* arg2 = (args >= 2) ? arg_list[2].c_str() : 0;
+ const char* arg3 = (args >= 3) ? arg_list[3].c_str() : 0;
+ const char* arg4 = (args >= 4) ? arg_list[4].c_str() : 0;
+
+ for(u32bit j = 0; j != paths.size(); j++)
+ {
+ const std::string full_path = paths[j] + "/" + arg_list[0];
+ const char* fsname = full_path.c_str();
+ ::execl(fsname, fsname, arg1, arg2, arg3, arg4, NULL);
+ }
+ }
+
+}
+
+/*************************************************
+* Local information about the pipe *
+*************************************************/
+struct pipe_wrapper
+ {
+ int fd;
+ pid_t pid;
+ pipe_wrapper() { fd = -1; pid = 0; }
+ };
+
+/*************************************************
+* Read from the pipe *
+*************************************************/
+u32bit DataSource_Command::read(byte buf[], u32bit length)
+ {
+ if(end_of_data())
+ return 0;
+
+ fd_set set;
+ FD_ZERO(&set);
+ FD_SET(pipe->fd, &set);
+
+ struct ::timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = MAX_BLOCK_USECS;
+
+ ssize_t got = 0;
+ if(::select(pipe->fd + 1, &set, 0, 0, &tv) == 1)
+ {
+ if(FD_ISSET(pipe->fd, &set))
+ got = ::read(pipe->fd, buf, length);
+ }
+
+ if(got <= 0)
+ {
+ shutdown_pipe();
+ return 0;
+ }
+
+ return static_cast<u32bit>(got);
+ }
+
+/*************************************************
+* Peek at the pipe contents *
+*************************************************/
+u32bit DataSource_Command::peek(byte[], u32bit, u32bit) const
+ {
+ if(end_of_data())
+ throw Invalid_State("DataSource_Command: Cannot peek when out of data");
+ throw Stream_IO_Error("Cannot peek/seek on a command pipe");
+ }
+
+/*************************************************
+* Check if we reached EOF *
+*************************************************/
+bool DataSource_Command::end_of_data() const
+ {
+ return (pipe) ? false : true;
+ }
+
+/*************************************************
+* Return the Unix file descriptor of the pipe *
+*************************************************/
+int DataSource_Command::fd() const
+ {
+ if(!pipe)
+ return -1;
+ return pipe->fd;
+ }
+
+/*************************************************
+* Return a human-readable ID for this stream *
+*************************************************/
+std::string DataSource_Command::id() const
+ {
+ return "Unix command: " + arg_list[0];
+ }
+
+/*************************************************
+* Create the pipe *
+*************************************************/
+void DataSource_Command::create_pipe(const std::vector<std::string>& paths)
+ {
+ bool found_something = false;
+ for(u32bit j = 0; j != paths.size(); j++)
+ {
+ const std::string full_path = paths[j] + "/" + arg_list[0];
+ if(::access(full_path.c_str(), X_OK) == 0)
+ {
+ found_something = true;
+ break;
+ }
+ }
+ if(!found_something)
+ return;
+
+ int pipe_fd[2];
+ if(::pipe(pipe_fd) != 0)
+ return;
+
+ pid_t pid = ::fork();
+
+ if(pid == -1)
+ {
+ ::close(pipe_fd[0]);
+ ::close(pipe_fd[1]);
+ }
+ else if(pid > 0)
+ {
+ pipe = new pipe_wrapper;
+ pipe->fd = pipe_fd[0];
+ pipe->pid = pid;
+ ::close(pipe_fd[1]);
+ }
+ else
+ {
+ if(dup2(pipe_fd[1], STDOUT_FILENO) == -1)
+ ::exit(127);
+ if(close(pipe_fd[0]) != 0 || close(pipe_fd[1]) != 0)
+ ::exit(127);
+ if(close(STDERR_FILENO) != 0)
+ ::exit(127);
+
+ do_exec(arg_list, paths);
+ ::exit(127);
+ }
+ }
+
+/*************************************************
+* Shutdown the pipe *
+*************************************************/
+void DataSource_Command::shutdown_pipe()
+ {
+ if(pipe)
+ {
+ pid_t reaped = waitpid(pipe->pid, 0, WNOHANG);
+
+ if(reaped == 0)
+ {
+ kill(pipe->pid, SIGTERM);
+
+ struct ::timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = KILL_WAIT;
+ select(0, 0, 0, 0, &tv);
+
+ reaped = ::waitpid(pipe->pid, 0, WNOHANG);
+
+ if(reaped == 0)
+ {
+ ::kill(pipe->pid, SIGKILL);
+ do
+ reaped = ::waitpid(pipe->pid, 0, 0);
+ while(reaped == -1);
+ }
+ }
+
+ ::close(pipe->fd);
+ delete pipe;
+ pipe = 0;
+ }
+ }
+
+/*************************************************
+* DataSource_Command Constructor *
+*************************************************/
+DataSource_Command::DataSource_Command(const std::string& prog_and_args,
+ const std::vector<std::string>& paths) :
+ MAX_BLOCK_USECS(100000), KILL_WAIT(10000)
+ {
+ arg_list = split_on(prog_and_args, ' ');
+
+ if(arg_list.size() == 0)
+ throw Invalid_Argument("DataSource_Command: No command given");
+ if(arg_list.size() > 5)
+ throw Invalid_Argument("DataSource_Command: Too many args");
+
+ pipe = 0;
+ create_pipe(paths);
+ }
+
+/*************************************************
+* DataSource_Command Destructor *
+*************************************************/
+DataSource_Command::~DataSource_Command()
+ {
+ if(!end_of_data())
+ shutdown_pipe();
+ }
+
+}
diff --git a/modules/entropy/unix_procs/unix_cmd.h b/modules/entropy/unix_procs/unix_cmd.h
new file mode 100644
index 000000000..0e187db03
--- /dev/null
+++ b/modules/entropy/unix_procs/unix_cmd.h
@@ -0,0 +1,57 @@
+/*************************************************
+* Unix Command Execution Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EXT_UNIX_CMD_H__
+#define BOTAN_EXT_UNIX_CMD_H__
+
+#include <botan/types.h>
+#include <botan/data_src.h>
+#include <string>
+#include <vector>
+
+namespace Botan {
+
+/*************************************************
+* Unix Program Info *
+*************************************************/
+struct Unix_Program
+ {
+ Unix_Program(const char* n, u32bit p)
+ { name_and_args = n; priority = p; working = true; }
+
+ std::string name_and_args;
+ u32bit priority;
+ bool working;
+ };
+
+/*************************************************
+* Command Output DataSource *
+*************************************************/
+class DataSource_Command : public DataSource
+ {
+ public:
+ u32bit read(byte[], u32bit);
+ u32bit peek(byte[], u32bit, u32bit) const;
+ bool end_of_data() const;
+ std::string id() const;
+
+ int fd() const;
+
+ DataSource_Command(const std::string&,
+ const std::vector<std::string>& paths);
+ ~DataSource_Command();
+ private:
+ void create_pipe(const std::vector<std::string>&);
+ void shutdown_pipe();
+
+ const u32bit MAX_BLOCK_USECS, KILL_WAIT;
+
+ std::vector<std::string> arg_list;
+ struct pipe_wrapper* pipe;
+ };
+
+}
+
+#endif
diff --git a/modules/entropy/unix_procs/unix_src.cpp b/modules/entropy/unix_procs/unix_src.cpp
new file mode 100644
index 000000000..9d44dbf4f
--- /dev/null
+++ b/modules/entropy/unix_procs/unix_src.cpp
@@ -0,0 +1,59 @@
+/*************************************************
+* Program List for Unix_EntropySource *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_unix.h>
+
+namespace Botan {
+
+/*************************************************
+* Default Commands for Entropy Gathering *
+*************************************************/
+void Unix_EntropySource::add_default_sources(std::vector<Unix_Program>& srcs)
+ {
+ srcs.push_back(Unix_Program("vmstat", 1));
+ srcs.push_back(Unix_Program("vmstat -s", 1));
+ srcs.push_back(Unix_Program("pfstat", 1));
+ srcs.push_back(Unix_Program("netstat -in", 1));
+
+ srcs.push_back(Unix_Program("iostat", 2));
+ srcs.push_back(Unix_Program("mpstat", 2));
+ srcs.push_back(Unix_Program("nfsstat", 2));
+ srcs.push_back(Unix_Program("portstat", 2));
+ srcs.push_back(Unix_Program("arp -a -n", 2));
+ srcs.push_back(Unix_Program("ifconfig -a", 2));
+ srcs.push_back(Unix_Program("pstat -T", 2));
+ srcs.push_back(Unix_Program("pstat -s", 2));
+ srcs.push_back(Unix_Program("uname -a", 2));
+ srcs.push_back(Unix_Program("uptime", 2));
+ srcs.push_back(Unix_Program("ipcs -a", 2));
+ srcs.push_back(Unix_Program("procinfo -a", 2));
+
+ srcs.push_back(Unix_Program("sysinfo", 3));
+ srcs.push_back(Unix_Program("listarea", 3));
+ srcs.push_back(Unix_Program("listdev", 3));
+
+ srcs.push_back(Unix_Program("who", 3));
+ srcs.push_back(Unix_Program("finger", 3));
+ srcs.push_back(Unix_Program("netstat -s", 3));
+ srcs.push_back(Unix_Program("netstat -an", 3));
+ srcs.push_back(Unix_Program("ps -A", 3));
+ srcs.push_back(Unix_Program("mailstats", 3));
+ srcs.push_back(Unix_Program("rpcinfo -p localhost", 3));
+
+ srcs.push_back(Unix_Program("dmesg", 4));
+ srcs.push_back(Unix_Program("ls -alni /tmp", 4));
+ srcs.push_back(Unix_Program("ls -alni /proc", 4));
+ srcs.push_back(Unix_Program("df -l", 4));
+ srcs.push_back(Unix_Program("last -5", 4));
+ srcs.push_back(Unix_Program("pstat -f", 4));
+
+ srcs.push_back(Unix_Program("ps aux", 5));
+ srcs.push_back(Unix_Program("ps -elf", 5));
+
+ srcs.push_back(Unix_Program("sar -A", 6));
+ srcs.push_back(Unix_Program("lsof", 6));
+ }
+
+}
diff --git a/modules/entropy/win32_stats/es_win32.cpp b/modules/entropy/win32_stats/es_win32.cpp
new file mode 100644
index 000000000..febed59c0
--- /dev/null
+++ b/modules/entropy/win32_stats/es_win32.cpp
@@ -0,0 +1,109 @@
+/*************************************************
+* Win32 EntropySource Source File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#include <botan/es_win32.h>
+#include <windows.h>
+#include <tlhelp32.h>
+
+namespace Botan {
+
+/*************************************************
+* Win32 Slow Poll *
+*************************************************/
+void Win32_EntropySource::do_slow_poll()
+ {
+ const u32bit MAX_ITEMS = 256;
+
+ do_fast_poll();
+
+ HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
+
+#define TOOLHELP32_ITER(DATA_TYPE, FUNC_FIRST, FUNC_NEXT) \
+ { \
+ u32bit items = 0; \
+ DATA_TYPE info; \
+ info.dwSize = sizeof(DATA_TYPE); \
+ if(FUNC_FIRST(snapshot, &info)) \
+ { \
+ do \
+ { \
+ if(items++ > MAX_ITEMS) break; \
+ add_bytes(&info, sizeof(info)); \
+ } while(FUNC_NEXT(snapshot, &info)); \
+ } \
+ }
+
+ TOOLHELP32_ITER(MODULEENTRY32, Module32First, Module32Next);
+ TOOLHELP32_ITER(PROCESSENTRY32, Process32First, Process32Next);
+ TOOLHELP32_ITER(THREADENTRY32, Thread32First, Thread32Next);
+
+#undef TOOLHELP32_ITER
+
+ u32bit heap_lists_found = 0;
+ HEAPLIST32 heap_list;
+ heap_list.dwSize = sizeof(HEAPLIST32);
+
+ const u32bit HEAP_LISTS_MAX = 32;
+ const u32bit HEAP_OBJS_PER_LIST = 128;
+ if(Heap32ListFirst(snapshot, &heap_list))
+ {
+ do
+ {
+ add_bytes(&heap_list, sizeof(HEAPLIST32));
+
+ if(heap_lists_found++ > HEAP_LISTS_MAX)
+ break;
+
+ u32bit heap_objs_found = 0;
+ HEAPENTRY32 heap_entry;
+ heap_entry.dwSize = sizeof(HEAPENTRY32);
+ if(Heap32First(&heap_entry, heap_list.th32ProcessID,
+ heap_list.th32HeapID))
+ {
+ do
+ {
+ if(heap_objs_found++ > HEAP_OBJS_PER_LIST)
+ break;
+ add_bytes(&heap_entry, sizeof(HEAPENTRY32));
+ } while(Heap32Next(&heap_entry));
+ }
+ } while(Heap32ListNext(snapshot, &heap_list));
+ }
+
+ CloseHandle(snapshot);
+ }
+
+/*************************************************
+* Win32 Fast Poll *
+*************************************************/
+void Win32_EntropySource::do_fast_poll()
+ {
+ add_bytes(GetTickCount());
+ add_bytes(GetMessagePos());
+ add_bytes(GetMessageTime());
+ add_bytes(GetInputState());
+ add_bytes(GetCurrentProcessId());
+ add_bytes(GetCurrentThreadId());
+
+ SYSTEM_INFO sys_info;
+ GetSystemInfo(&sys_info);
+ add_bytes(&sys_info, sizeof(sys_info));
+
+ MEMORYSTATUS mem_info;
+ GlobalMemoryStatus(&mem_info);
+ add_bytes(&mem_info, sizeof(mem_info));
+
+ POINT point;
+ GetCursorPos(&point);
+ add_bytes(&point, sizeof(point));
+ GetCaretPos(&point);
+ add_bytes(&point, sizeof(point));
+
+ LARGE_INTEGER perf_counter;
+ QueryPerformanceCounter(&perf_counter);
+ add_bytes(&perf_counter, sizeof(perf_counter));
+ }
+
+}
diff --git a/modules/entropy/win32_stats/es_win32.h b/modules/entropy/win32_stats/es_win32.h
new file mode 100644
index 000000000..19b664a2f
--- /dev/null
+++ b/modules/entropy/win32_stats/es_win32.h
@@ -0,0 +1,25 @@
+/*************************************************
+* Win32 EntropySource Header File *
+* (C) 1999-2007 Jack Lloyd *
+*************************************************/
+
+#ifndef BOTAN_EXT_ENTROPY_SRC_WIN32_H__
+#define BOTAN_EXT_ENTROPY_SRC_WIN32_H__
+
+#include <botan/buf_es.h>
+
+namespace Botan {
+
+/*************************************************
+* Win32 Entropy Source *
+*************************************************/
+class Win32_EntropySource : public Buffered_EntropySource
+ {
+ private:
+ void do_fast_poll();
+ void do_slow_poll();
+ };
+
+}
+
+#endif
diff --git a/modules/entropy/win32_stats/modinfo.txt b/modules/entropy/win32_stats/modinfo.txt
new file mode 100644
index 000000000..931760979
--- /dev/null
+++ b/modules/entropy/win32_stats/modinfo.txt
@@ -0,0 +1,23 @@
+realname "Win32 Entropy Source"
+
+# Probably not much of an issue anymore
+#note "This module will not run under NT4"
+
+define ENTROPY_SRC_WIN32
+modset win32
+
+load_on auto
+
+<add>
+es_win32.h
+es_win32.cpp
+</add>
+
+<os>
+windows
+cygwin
+</os>
+
+<libs>
+windows -> user32
+</libs>