aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/base/botan.h2
-rw-r--r--src/lib/entropy/beos_stats/es_beos.cpp66
-rw-r--r--src/lib/entropy/beos_stats/es_beos.h28
-rw-r--r--src/lib/entropy/beos_stats/info.txt17
-rw-r--r--src/lib/entropy/egd/es_egd.cpp157
-rw-r--r--src/lib/entropy/egd/es_egd.h52
-rw-r--r--src/lib/entropy/egd/info.txt32
-rw-r--r--src/lib/entropy/entropy_srcs.cpp28
-rw-r--r--src/lib/entropy/unix_procs/info.txt25
-rw-r--r--src/lib/entropy/unix_procs/unix_proc_sources.cpp65
-rw-r--r--src/lib/entropy/unix_procs/unix_procs.cpp292
-rw-r--r--src/lib/entropy/unix_procs/unix_procs.h93
-rw-r--r--src/lib/rng/auto_rng/auto_rng.cpp32
-rw-r--r--src/lib/rng/auto_rng/info.txt4
-rw-r--r--src/lib/rng/hmac_rng/hmac_rng.cpp199
-rw-r--r--src/lib/rng/hmac_rng/hmac_rng.h103
-rw-r--r--src/lib/rng/hmac_rng/info.txt6
-rw-r--r--src/lib/rng/x931_rng/info.txt5
-rw-r--r--src/lib/rng/x931_rng/x931_rng.cpp119
-rw-r--r--src/lib/rng/x931_rng/x931_rng.h54
20 files changed, 19 insertions, 1360 deletions
diff --git a/src/lib/base/botan.h b/src/lib/base/botan.h
index 230ac4244..5054b34b1 100644
--- a/src/lib/base/botan.h
+++ b/src/lib/base/botan.h
@@ -37,7 +37,7 @@ namespace Botan {
* <dt>Message Authentication Codes<dd>
* @ref CBC_MAC "CBC-MAC", CMAC, HMAC, Poly1305, SipHash, ANSI_X919_MAC
* <dt>Random Number Generators<dd>
-* AutoSeeded_RNG, HMAC_DRBG, HMAC_RNG, RDRAND_RNG, System_RNG, ANSI_X931_RNG
+* AutoSeeded_RNG, HMAC_DRBG, RDRAND_RNG, System_RNG
* <dt>Key Derivation<dd>
* HKDF, @ref KDF1 "KDF1 (IEEE 1363)", @ref KDF1_18033 "KDF1 (ISO 18033-2)", @ref KDF2 "KDF2 (IEEE 1363)",
* @ref sp800_108.h "SP800-108", @ref SP800_56C "SP800-56C", @ref PKCS5_PBKDF1 "PBKDF1 (PKCS#5),
diff --git a/src/lib/entropy/beos_stats/es_beos.cpp b/src/lib/entropy/beos_stats/es_beos.cpp
deleted file mode 100644
index 907ca37bb..000000000
--- a/src/lib/entropy/beos_stats/es_beos.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
-* BeOS EntropySource
-* (C) 1999-2008 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/es_beos.h>
-
-#include <kernel/OS.h>
-#include <kernel/image.h>
-#include <interface/InterfaceDefs.h>
-
-namespace Botan {
-
-/**
-* BeOS entropy poll
-*/
-size_t BeOS_EntropySource::poll(RandomNumberGenerator& rng)
- {
- size_t bits = 0;
-
- system_info info_sys;
- get_system_info(&info_sys);
- rng.add_entropy_T(info_sys);
-
- key_info info_key; // current state of the keyboard
- get_key_info(&info_key);
- rng.add_entropy_T(info_key);
-
- team_info info_team;
- int32 cookie_team = 0;
-
- while(get_next_team_info(&cookie_team, &info_team) == B_OK)
- {
- rng.add_entropy_T(info_team);
-
- team_id id = info_team.team;
- int32 cookie = 0;
-
- thread_info info_thr;
- while(get_next_thread_info(id, &cookie, &info_thr) == B_OK)
- rng.add_entropy_T(info_thr);
-
- cookie = 0;
- image_info info_img;
- while(get_next_image_info(id, &cookie, &info_img) == B_OK)
- rng.add_entropy_T(info_img);
-
- cookie = 0;
- sem_info info_sem;
- while(get_next_sem_info(id, &cookie, &info_sem) == B_OK)
- rng.add_entropy_T(info_sem);
-
- cookie = 0;
- area_info info_area;
- while(get_next_area_info(id, &cookie, &info_area) == B_OK)
- rng.add_entropy_T(info_area);
-
- bits += 32;
- }
-
- return bits;
- }
-
-}
diff --git a/src/lib/entropy/beos_stats/es_beos.h b/src/lib/entropy/beos_stats/es_beos.h
deleted file mode 100644
index e40433b6c..000000000
--- a/src/lib/entropy/beos_stats/es_beos.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-* BeOS EntropySource
-* (C) 1999-2008 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ENTROPY_SRC_BEOS_H__
-#define BOTAN_ENTROPY_SRC_BEOS_H__
-
-#include <botan/entropy_src.h>
-
-namespace Botan {
-
-/**
-* BeOS Entropy Source
-*/
-class BeOS_EntropySource final : public Entropy_Source
- {
- private:
- std::string name() const override { return "system_stats"; }
-
- size_t poll(RandomNumberGenerator& rng) override;
- };
-
-}
-
-#endif
diff --git a/src/lib/entropy/beos_stats/info.txt b/src/lib/entropy/beos_stats/info.txt
deleted file mode 100644
index 9ae527f49..000000000
--- a/src/lib/entropy/beos_stats/info.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-define ENTROPY_SRC_BEOS 20131128
-
-<source>
-es_beos.cpp
-</source>
-
-<header:internal>
-es_beos.h
-</header:internal>
-
-<os>
-haiku
-</os>
-
-<libs>
-haiku -> root,be
-</libs>
diff --git a/src/lib/entropy/egd/es_egd.cpp b/src/lib/entropy/egd/es_egd.cpp
deleted file mode 100644
index fdc1c9a0f..000000000
--- a/src/lib/entropy/egd/es_egd.cpp
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
-* EGD EntropySource
-* (C) 1999-2009 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/es_egd.h>
-#include <botan/parsing.h>
-#include <botan/exceptn.h>
-#include <botan/mem_ops.h>
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <sys/socket.h>
-#include <sys/un.h>
-
-#ifndef PF_LOCAL
- #define PF_LOCAL PF_UNIX
-#endif
-
-namespace Botan {
-
-EGD_EntropySource::EGD_Socket::EGD_Socket(const std::string& path) :
- m_socket_path(path), m_fd(-1)
- {
- }
-
-/**
-* Attempt a connection to an EGD/PRNGD socket
-*/
-int EGD_EntropySource::EGD_Socket::open_socket(const std::string& path)
- {
- int fd = ::socket(PF_LOCAL, SOCK_STREAM, 0);
-
- if(fd >= 0)
- {
- sockaddr_un addr;
- clear_mem(&addr, 1);
- addr.sun_family = PF_LOCAL;
-
- if(path.length() >= sizeof(addr.sun_path))
- throw Invalid_Argument("EGD socket path is too long");
-
- std::strncpy(addr.sun_path, path.c_str(), sizeof(addr.sun_path));
-
- int len = sizeof(addr.sun_family) + std::strlen(addr.sun_path) + 1;
-
- if(::connect(fd, reinterpret_cast<struct ::sockaddr*>(&addr), len) < 0)
- {
- ::close(fd);
- fd = -1;
- }
- }
-
- return fd;
- }
-
-/**
-* Attempt to read entropy from EGD
-*/
-size_t EGD_EntropySource::EGD_Socket::read(byte outbuf[], size_t length)
- {
- if(length == 0)
- return 0;
-
- if(m_fd < 0)
- {
- m_fd = open_socket(m_socket_path);
- if(m_fd < 0)
- return 0;
- }
-
- try
- {
- // 1 == EGD command for non-blocking read
- byte egd_read_command[2] = {
- 1, static_cast<byte>(std::min<size_t>(length, 255)) };
-
- if(::write(m_fd, egd_read_command, 2) != 2)
- throw Exception("Writing entropy read command to EGD failed");
-
- byte out_len = 0;
- if(::read(m_fd, &out_len, 1) != 1)
- throw Exception("Reading response length from EGD failed");
-
- if(out_len > egd_read_command[1])
- throw Exception("Bogus length field received from EGD");
-
- ssize_t count = ::read(m_fd, outbuf, out_len);
-
- if(count != out_len)
- throw Exception("Reading entropy result from EGD failed");
-
- return static_cast<size_t>(count);
- }
- catch(std::exception)
- {
- this->close();
- // Will attempt to reopen next poll
- }
-
- return 0;
- }
-
-void EGD_EntropySource::EGD_Socket::close()
- {
- if(m_fd >= 0)
- {
- ::close(m_fd);
- m_fd = -1;
- }
- }
-
-/**
-* EGD_EntropySource constructor
-*/
-EGD_EntropySource::EGD_EntropySource(const std::vector<std::string>& paths)
- {
- for(size_t i = 0; i != paths.size(); ++i)
- m_sockets.push_back(EGD_Socket(paths[i]));
- }
-
-EGD_EntropySource::~EGD_EntropySource()
- {
- for(size_t i = 0; i != m_sockets.size(); ++i)
- m_sockets[i].close();
- m_sockets.clear();
- }
-
-/**
-* Gather Entropy from EGD
-*/
-size_t EGD_EntropySource::poll(RandomNumberGenerator& rng)
- {
- lock_guard_type<mutex_type> lock(m_mutex);
-
- secure_vector<byte> buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);
-
- for(size_t i = 0; i != m_sockets.size(); ++i)
- {
- size_t got = m_sockets[i].read(m_io_buf.data(), m_io_buf.size());
-
- if(got)
- {
- rng.add_entropy(m_io_buf.data(), got);
- return got * 8;
- }
- }
-
- return 0;
- }
-
-}
diff --git a/src/lib/entropy/egd/es_egd.h b/src/lib/entropy/egd/es_egd.h
deleted file mode 100644
index e0fb9c2d5..000000000
--- a/src/lib/entropy/egd/es_egd.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
-* EGD EntropySource
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ENTROPY_SRC_EGD_H__
-#define BOTAN_ENTROPY_SRC_EGD_H__
-
-#include <botan/entropy_src.h>
-#include <string>
-#include <vector>
-#include <botan/mutex.h>
-
-namespace Botan {
-
-/**
-* EGD Entropy Source
-*/
-class EGD_EntropySource final : public Entropy_Source
- {
- public:
- std::string name() const override { return "egd"; }
-
- size_t poll(RandomNumberGenerator& rng) override;
-
- EGD_EntropySource(const std::vector<std::string>&);
- ~EGD_EntropySource();
- private:
- class EGD_Socket
- {
- public:
- EGD_Socket(const std::string& path);
-
- void close();
- size_t read(byte outbuf[], size_t length);
- private:
- static int open_socket(const std::string& path);
-
- std::string m_socket_path;
- int m_fd; // cached fd
- };
-
- mutex_type m_mutex;
- std::vector<EGD_Socket> m_sockets;
- secure_vector<uint8_t> m_io_buf;
- };
-
-}
-
-#endif
diff --git a/src/lib/entropy/egd/info.txt b/src/lib/entropy/egd/info.txt
deleted file mode 100644
index b7b951c2b..000000000
--- a/src/lib/entropy/egd/info.txt
+++ /dev/null
@@ -1,32 +0,0 @@
-define ENTROPY_SRC_EGD 20131128
-
-load_on auto
-
-<source>
-es_egd.cpp
-</source>
-
-<header:internal>
-es_egd.h
-</header:internal>
-
-<libs>
-solaris -> socket
-qnx -> socket
-</libs>
-
-<os>
-android
-aix
-cygwin
-darwin
-freebsd
-dragonfly
-hpux
-irix
-linux
-netbsd
-openbsd
-qnx
-solaris
-</os>
diff --git a/src/lib/entropy/entropy_srcs.cpp b/src/lib/entropy/entropy_srcs.cpp
index 5c232a56e..21dfcff41 100644
--- a/src/lib/entropy/entropy_srcs.cpp
+++ b/src/lib/entropy/entropy_srcs.cpp
@@ -24,18 +24,6 @@
#include <botan/internal/dev_random.h>
#endif
-#if defined(BOTAN_HAS_ENTROPY_SRC_EGD)
- #include <botan/internal/es_egd.h>
-#endif
-
-#if defined(BOTAN_HAS_ENTROPY_SRC_UNIX_PROCESS_RUNNER)
- #include <botan/internal/unix_procs.h>
-#endif
-
-#if defined(BOTAN_HAS_ENTROPY_SRC_BEOS)
- #include <botan/internal/es_beos.h>
-#endif
-
#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI)
#include <botan/internal/es_capi.h>
#endif
@@ -116,22 +104,6 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
{
#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
return std::unique_ptr<Entropy_Source>(new Win32_EntropySource);
-#elif defined(BOTAN_HAS_ENTROPY_SRC_BEOS)
- return std::unique_ptr<Entropy_Source>(new BeOS_EntropySource);
-#endif
- }
-
- if(name == "unix_procs")
- {
-#if defined(BOTAN_HAS_ENTROPY_SRC_UNIX_PROCESS_RUNNER)
- return std::unique_ptr<Entropy_Source>(new Unix_EntropySource(BOTAN_ENTROPY_SAFE_PATHS));
-#endif
- }
-
- if(name == "egd")
- {
-#if defined(BOTAN_HAS_ENTROPY_SRC_EGD)
- return std::unique_ptr<Entropy_Source>(new EGD_EntropySource(BOTAN_ENTROPY_EGD_PATHS));
#endif
}
diff --git a/src/lib/entropy/unix_procs/info.txt b/src/lib/entropy/unix_procs/info.txt
deleted file mode 100644
index ee382d8da..000000000
--- a/src/lib/entropy/unix_procs/info.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-define ENTROPY_SRC_UNIX_PROCESS_RUNNER 20131128
-
-<source>
-unix_procs.cpp
-unix_proc_sources.cpp
-</source>
-
-<header:internal>
-unix_procs.h
-</header:internal>
-
-<os>
-android
-aix
-cygwin
-darwin
-freebsd
-haiku
-hpux
-irix
-linux
-netbsd
-qnx
-solaris
-</os>
diff --git a/src/lib/entropy/unix_procs/unix_proc_sources.cpp b/src/lib/entropy/unix_procs/unix_proc_sources.cpp
deleted file mode 100644
index 429198706..000000000
--- a/src/lib/entropy/unix_procs/unix_proc_sources.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-* Program List for Unix_EntropySource
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/unix_procs.h>
-
-namespace Botan {
-
-/**
-* Default Commands for Entropy Gathering
-*/
-std::vector<std::vector<std::string>> Unix_EntropySource::get_default_sources()
- {
- std::vector<std::vector<std::string>> srcs;
-
- srcs.push_back({ "netstat", "-in" });
- srcs.push_back({ "pfstat" });
- srcs.push_back({ "vmstat", "-s" });
- srcs.push_back({ "vmstat" });
-
- srcs.push_back({ "arp", "-a", "-n" });
- srcs.push_back({ "ifconfig", "-a" });
- srcs.push_back({ "iostat" });
- srcs.push_back({ "ipcs", "-a" });
- srcs.push_back({ "mpstat" });
- srcs.push_back({ "netstat", "-an" });
- srcs.push_back({ "netstat", "-s" });
- srcs.push_back({ "nfsstat" });
- srcs.push_back({ "portstat" });
- srcs.push_back({ "procinfo", "-a" });
- srcs.push_back({ "pstat", "-T" });
- srcs.push_back({ "pstat", "-s" });
- srcs.push_back({ "uname", "-a" });
- srcs.push_back({ "uptime" });
-
- srcs.push_back({ "listarea" });
- srcs.push_back({ "listdev" });
- srcs.push_back({ "ps", "-A" });
- srcs.push_back({ "sysinfo" });
-
- srcs.push_back({ "finger" });
- srcs.push_back({ "mailstats" });
- srcs.push_back({ "rpcinfo", "-p", "localhost" });
- srcs.push_back({ "who" });
-
- srcs.push_back({ "df", "-l" });
- srcs.push_back({ "dmesg" });
- srcs.push_back({ "last", "-5" });
- srcs.push_back({ "ls", "-alni", "/proc" });
- srcs.push_back({ "ls", "-alni", "/tmp" });
- srcs.push_back({ "pstat", "-f" });
-
- srcs.push_back({ "ps", "-elf" });
- srcs.push_back({ "ps", "aux" });
-
- srcs.push_back({ "lsof", "-n" });
- srcs.push_back({ "sar", "-A" });
-
- return srcs;
- }
-
-}
diff --git a/src/lib/entropy/unix_procs/unix_procs.cpp b/src/lib/entropy/unix_procs/unix_procs.cpp
deleted file mode 100644
index eae1b5255..000000000
--- a/src/lib/entropy/unix_procs/unix_procs.cpp
+++ /dev/null
@@ -1,292 +0,0 @@
- /*
-* Gather entropy by running various system commands in the hopes that
-* some of the output cannot be guessed by a remote attacker.
-*
-* (C) 1999-2009,2013 Jack Lloyd
-* 2012 Markus Wanner
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/unix_procs.h>
-#include <botan/exceptn.h>
-#include <botan/parsing.h>
-#include <algorithm>
-#include <atomic>
-
-#include <sys/time.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <sys/resource.h>
-#include <unistd.h>
-#include <signal.h>
-#include <stdlib.h>
-
-namespace Botan {
-
-namespace {
-
-std::string find_full_path_if_exists(const std::vector<std::string>& trusted_path,
- const std::string& proc)
- {
- for(auto dir : trusted_path)
- {
- const std::string full_path = dir + "/" + proc;
- if(::access(full_path.c_str(), X_OK) == 0)
- return full_path;
- }
-
- return "";
- }
-
-size_t concurrent_processes(size_t user_request)
- {
- const size_t DEFAULT_CONCURRENT = 2;
- const size_t MAX_CONCURRENT = 8;
-
- if(user_request > 0)
- return std::min(user_request, MAX_CONCURRENT);
-
- const long online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);
-
- if(online_cpus > 0)
- return static_cast<size_t>(online_cpus); // maybe fewer?
-
- return DEFAULT_CONCURRENT;
- }
-
-}
-
-/**
-* Unix_EntropySource Constructor
-*/
-Unix_EntropySource::Unix_EntropySource(const std::vector<std::string>& trusted_paths,
- size_t proc_count) :
- m_trusted_paths(trusted_paths),
- m_concurrent(concurrent_processes(proc_count))
- {
- }
-
-size_t UnixProcessInfo_EntropySource::poll(RandomNumberGenerator& rng)
- {
- rng.add_entropy_T(::getpid());
- rng.add_entropy_T(::getppid());
- rng.add_entropy_T(::getuid());
- rng.add_entropy_T(::getgid());
- rng.add_entropy_T(::getpgrp());
-
- struct ::rusage usage;
- ::getrusage(RUSAGE_SELF, &usage);
- rng.add_entropy_T(usage);
-
-#if defined(BOTAN_TARGET_OS_HAS_CLOCK_GETTIME)
-
-#define CLOCK_GETTIME_POLL(src) \
- do { \
- struct timespec ts; \
- ::clock_gettime(src, &ts); \
- rng.add_entropy_T(ts); \
- } while(0)
-
-#if defined(CLOCK_REALTIME)
- CLOCK_GETTIME_POLL(CLOCK_REALTIME);
-#endif
-
-#if defined(CLOCK_MONOTONIC)
- CLOCK_GETTIME_POLL(CLOCK_MONOTONIC);
-#endif
-
-#if defined(CLOCK_MONOTONIC_RAW)
- CLOCK_GETTIME_POLL(CLOCK_MONOTONIC_RAW);
-#endif
-
-#if defined(CLOCK_PROCESS_CPUTIME_ID)
- CLOCK_GETTIME_POLL(CLOCK_PROCESS_CPUTIME_ID);
-#endif
-
-#if defined(CLOCK_THREAD_CPUTIME_ID)
- CLOCK_GETTIME_POLL(CLOCK_THREAD_CPUTIME_ID);
-#endif
-
-#undef CLOCK_GETTIME_POLL
-
-#endif
-
- return 0;
- }
-
-void Unix_EntropySource::Unix_Process::spawn(const std::vector<std::string>& args)
- {
- if(args.empty())
- throw Invalid_Argument("Cannot spawn process without path");
-
- shutdown();
-
- int pipe[2];
- if(::pipe(pipe) != 0)
- return;
-
- pid_t pid = ::fork();
-
- if(pid == -1)
- {
- ::close(pipe[0]);
- ::close(pipe[1]);
- }
- else if(pid > 0) // in parent
- {
- m_pid = pid;
- m_fd = pipe[0];
- ::close(pipe[1]);
- }
- else // in child
- {
- if(::dup2(pipe[1], STDOUT_FILENO) == -1)
- ::exit(127);
- if(::close(pipe[0]) != 0 || ::close(pipe[1]) != 0)
- ::exit(127);
- if(close(STDERR_FILENO) != 0)
- ::exit(127);
-
- const char* arg0 = args[0].c_str();
- const char* arg1 = (args.size() > 1) ? args[1].c_str() : nullptr;
- const char* arg2 = (args.size() > 2) ? args[2].c_str() : nullptr;
- const char* arg3 = (args.size() > 3) ? args[3].c_str() : nullptr;
- const char* arg4 = (args.size() > 4) ? args[4].c_str() : nullptr;
-
- ::execl(arg0, arg0, arg1, arg2, arg3, arg4, NULL);
- ::exit(127);
- }
- }
-
-void Unix_EntropySource::Unix_Process::shutdown()
- {
- if(m_pid == -1)
- return;
-
- ::close(m_fd);
- m_fd = -1;
-
- pid_t reaped = waitpid(m_pid, nullptr, WNOHANG);
-
- if(reaped == 0)
- {
- /*
- * Child is still alive - send it SIGTERM, sleep for a bit and
- * try to reap again, if still alive send SIGKILL
- */
- kill(m_pid, SIGTERM);
-
- struct ::timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
- select(0, nullptr, nullptr, nullptr, &tv);
-
- reaped = ::waitpid(m_pid, nullptr, WNOHANG);
-
- if(reaped == 0)
- {
- ::kill(m_pid, SIGKILL);
- do
- reaped = ::waitpid(m_pid, nullptr, 0);
- while(reaped == -1);
- }
- }
-
- m_pid = -1;
- }
-
-const std::vector<std::string>& Unix_EntropySource::next_source()
- {
- const auto& src = m_sources.at(m_sources_idx);
- m_sources_idx = (m_sources_idx + 1) % m_sources.size();
- return src;
- }
-
-size_t Unix_EntropySource::poll(RandomNumberGenerator& rng)
- {
- // refuse to run setuid or setgid, or as root
- if((getuid() != geteuid()) || (getgid() != getegid()) || (geteuid() == 0))
- return 0;
-
- lock_guard_type<mutex_type> lock(m_mutex);
-
- if(m_sources.empty())
- {
- auto sources = get_default_sources();
-
- for(auto src : sources)
- {
- const std::string path = find_full_path_if_exists(m_trusted_paths, src[0]);
- if(path != "")
- {
- src[0] = path;
- m_sources.push_back(src);
- }
- }
- }
-
- if(m_sources.empty())
- return 0; // still empty, really nothing to try
-
- const size_t MS_WAIT_TIME = 32;
-
- m_buf.resize(4096);
-
- size_t bytes = 0;
-
- while(bytes < 128 * 1024) // arbitrary limit...
- {
- while(m_procs.size() < m_concurrent)
- m_procs.emplace_back(Unix_Process(next_source()));
-
- fd_set read_set;
- FD_ZERO(&read_set);
-
- std::vector<int> fds;
-
- for(auto& proc : m_procs)
- {
- int fd = proc.fd();
- if(fd > 0)
- {
- fds.push_back(fd);
- FD_SET(fd, &read_set);
- }
- }
-
- if(fds.empty())
- break;
-
- const int max_fd = *std::max_element(fds.begin(), fds.end());
-
- struct ::timeval timeout;
- timeout.tv_sec = (MS_WAIT_TIME / 1000);
- timeout.tv_usec = (MS_WAIT_TIME % 1000) * 1000;
-
- if(::select(max_fd + 1, &read_set, nullptr, nullptr, &timeout) < 0)
- break; // or continue?
-
- for(auto& proc : m_procs)
- {
- int fd = proc.fd();
-
- if(FD_ISSET(fd, &read_set))
- {
- const ssize_t got = ::read(fd, m_buf.data(), m_buf.size());
-
- if(got > 0)
- {
- rng.add_entropy(m_buf.data(), got);
- bytes += got;
- }
- else
- proc.spawn(next_source());
- }
- }
- }
-
- return bytes / 1024;
- }
-
-}
diff --git a/src/lib/entropy/unix_procs/unix_procs.h b/src/lib/entropy/unix_procs/unix_procs.h
deleted file mode 100644
index 24c10fff0..000000000
--- a/src/lib/entropy/unix_procs/unix_procs.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-* Unix EntropySource
-* (C) 1999-2009,2013 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ENTROPY_SRC_UNIX_H__
-#define BOTAN_ENTROPY_SRC_UNIX_H__
-
-#include <botan/entropy_src.h>
-#include <vector>
-#include <botan/mutex.h>
-
-namespace Botan {
-
-/**
-* Entropy source for generic Unix. Runs various programs trying to
-* gather data hard for a remote attacker to guess. Probably not too
-* effective against local attackers as they can sample from the same
-* distribution.
-*/
-class Unix_EntropySource final : public Entropy_Source
- {
- public:
- std::string name() const override { return "unix_procs"; }
-
- size_t poll(RandomNumberGenerator& rng) override;
-
- /**
- * @param trusted_paths is a list of directories that are assumed
- * to contain only 'safe' binaries. If an attacker can write
- * an executable to one of these directories then we will
- * run arbitrary code.
- * @param proc_count number of concurrent processes executing,
- * when set to zero, number of processors is used
- */
- Unix_EntropySource(const std::vector<std::string>& trusted_paths,
- size_t proc_count = 0);
- private:
- static std::vector<std::vector<std::string>> get_default_sources();
-
- class Unix_Process
- {
- public:
- int fd() const { return m_fd; }
-
- void spawn(const std::vector<std::string>& args);
- void shutdown();
-
- Unix_Process() {}
-
- Unix_Process(const std::vector<std::string>& args) { spawn(args); }
-
- ~Unix_Process() { shutdown(); }
-
- Unix_Process(Unix_Process&& other)
- {
- std::swap(m_fd, other.m_fd);
- std::swap(m_pid, other.m_pid);
- }
-
- Unix_Process(const Unix_Process&) = delete;
- Unix_Process& operator=(const Unix_Process&) = delete;
- private:
- int m_fd = -1;
- int m_pid = -1;
- };
-
- const std::vector<std::string>& next_source();
-
- mutex_type m_mutex;
- const std::vector<std::string> m_trusted_paths;
- const size_t m_concurrent;
-
- std::vector<std::vector<std::string>> m_sources;
- size_t m_sources_idx = 0;
-
- std::vector<Unix_Process> m_procs;
- secure_vector<byte> m_buf;
- };
-
-class UnixProcessInfo_EntropySource final : public Entropy_Source
- {
- public:
- std::string name() const override { return "proc_info"; }
-
- size_t poll(RandomNumberGenerator& rng) override;
- };
-
-}
-
-#endif
diff --git a/src/lib/rng/auto_rng/auto_rng.cpp b/src/lib/rng/auto_rng/auto_rng.cpp
index a9da085bc..e631604c9 100644
--- a/src/lib/rng/auto_rng/auto_rng.cpp
+++ b/src/lib/rng/auto_rng/auto_rng.cpp
@@ -6,19 +6,16 @@
#include <botan/auto_rng.h>
#include <botan/entropy_src.h>
-
-#if defined(BOTAN_HAS_HMAC_DRBG)
- #include <botan/hmac_drbg.h>
-#endif
-
-#if defined(BOTAN_HAS_HMAC_RNG)
- #include <botan/hmac_rng.h>
-#endif
+#include <botan/hmac_drbg.h>
#if defined(BOTAN_HAS_SYSTEM_RNG)
#include <botan/system_rng.h>
#endif
+#if !defined(BOTAN_AUTO_RNG_HMAC)
+#error "No hash function defined for AutoSeeded_RNG in build.h (try enabling sha2_32)"
+#endif
+
namespace Botan {
AutoSeeded_RNG::~AutoSeeded_RNG()
@@ -29,18 +26,18 @@ AutoSeeded_RNG::~AutoSeeded_RNG()
AutoSeeded_RNG::AutoSeeded_RNG(RandomNumberGenerator& underlying_rng,
size_t reseed_interval)
{
- m_rng.reset(new BOTAN_AUTO_RNG_DRBG(MessageAuthenticationCode::create(BOTAN_AUTO_RNG_HMAC),
- underlying_rng,
- reseed_interval));
+ m_rng.reset(new HMAC_DRBG(MessageAuthenticationCode::create_or_throw(BOTAN_AUTO_RNG_HMAC),
+ underlying_rng,
+ reseed_interval));
force_reseed();
}
AutoSeeded_RNG::AutoSeeded_RNG(Entropy_Sources& entropy_sources,
size_t reseed_interval)
{
- m_rng.reset(new BOTAN_AUTO_RNG_DRBG(MessageAuthenticationCode::create(BOTAN_AUTO_RNG_HMAC),
- entropy_sources,
- reseed_interval));
+ m_rng.reset(new HMAC_DRBG(MessageAuthenticationCode::create_or_throw(BOTAN_AUTO_RNG_HMAC),
+ entropy_sources,
+ reseed_interval));
force_reseed();
}
@@ -48,10 +45,9 @@ AutoSeeded_RNG::AutoSeeded_RNG(RandomNumberGenerator& underlying_rng,
Entropy_Sources& entropy_sources,
size_t reseed_interval)
{
- m_rng.reset(new BOTAN_AUTO_RNG_DRBG(MessageAuthenticationCode::create(BOTAN_AUTO_RNG_HMAC),
- underlying_rng,
- entropy_sources,
- reseed_interval));
+ m_rng.reset(new HMAC_DRBG(
+ MessageAuthenticationCode::create_or_throw(BOTAN_AUTO_RNG_HMAC),
+ underlying_rng, entropy_sources, reseed_interval));
force_reseed();
}
diff --git a/src/lib/rng/auto_rng/info.txt b/src/lib/rng/auto_rng/info.txt
index b77e6aa54..b66aafb45 100644
--- a/src/lib/rng/auto_rng/info.txt
+++ b/src/lib/rng/auto_rng/info.txt
@@ -1 +1,5 @@
define AUTO_SEEDING_RNG 20160821
+
+<requires>
+hmac_drbg
+</requires>
diff --git a/src/lib/rng/hmac_rng/hmac_rng.cpp b/src/lib/rng/hmac_rng/hmac_rng.cpp
deleted file mode 100644
index 081d8b38a..000000000
--- a/src/lib/rng/hmac_rng/hmac_rng.cpp
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
-* HMAC_RNG
-* (C) 2008,2009,2013,2015,2016 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/hmac_rng.h>
-#include <botan/entropy_src.h>
-#include <botan/internal/os_utils.h>
-#include <algorithm>
-
-namespace Botan {
-
-HMAC_RNG::HMAC_RNG(std::unique_ptr<MessageAuthenticationCode> prf,
- RandomNumberGenerator& underlying_rng,
- Entropy_Sources& entropy_sources,
- size_t reseed_interval) :
- Stateful_RNG(underlying_rng, entropy_sources, reseed_interval),
- m_prf(std::move(prf))
- {
- BOTAN_ASSERT_NONNULL(m_prf);
-
- if(!m_prf->valid_keylength(m_prf->output_length()))
- {
- throw Invalid_Argument("HMAC_RNG cannot use " + m_prf->name());
- }
-
- m_extractor.reset(m_prf->clone());
- this->clear();
- }
-
-HMAC_RNG::HMAC_RNG(std::unique_ptr<MessageAuthenticationCode> prf,
- RandomNumberGenerator& underlying_rng,
- size_t reseed_interval) :
- Stateful_RNG(underlying_rng, reseed_interval),
- m_prf(std::move(prf))
- {
- BOTAN_ASSERT_NONNULL(m_prf);
-
- if(!m_prf->valid_keylength(m_prf->output_length()))
- {
- throw Invalid_Argument("HMAC_RNG cannot use " + m_prf->name());
- }
-
- m_extractor.reset(m_prf->clone());
- this->clear();
- }
-
-HMAC_RNG::HMAC_RNG(std::unique_ptr<MessageAuthenticationCode> prf,
- Entropy_Sources& entropy_sources,
- size_t reseed_interval) :
- Stateful_RNG(entropy_sources, reseed_interval),
- m_prf(std::move(prf)),
- m_extractor(m_prf->clone())
- {
- BOTAN_ASSERT_NONNULL(m_prf);
-
- if(!m_prf->valid_keylength(m_prf->output_length()))
- {
- throw Invalid_Argument("HMAC_RNG cannot use " + m_prf->name());
- }
-
- m_extractor.reset(m_prf->clone());
- this->clear();
- }
-
-HMAC_RNG::HMAC_RNG(std::unique_ptr<MessageAuthenticationCode> prf) :
- Stateful_RNG(),
- m_prf(std::move(prf))
- {
- BOTAN_ASSERT_NONNULL(m_prf);
-
- if(!m_prf->valid_keylength(m_prf->output_length()))
- {
- throw Invalid_Argument("HMAC_RNG cannot use " + m_prf->name());
- }
-
- m_extractor.reset(m_prf->clone());
- this->clear();
- }
-
-void HMAC_RNG::clear()
- {
- Stateful_RNG::clear();
- m_counter = 0;
-
- // First PRF inputs are all zero, as specified in section 2
- m_K.resize(m_prf->output_length());
- zeroise(m_K);
-
- /*
- Normally we want to feedback PRF outputs to the extractor function
- to ensure a single bad poll does not reduce entropy. Thus in reseed
- we'll want to invoke the PRF before we reset the PRF key, but until
- the first reseed the PRF is unkeyed. Rather than trying to keep
- track of this, just set the initial PRF key to constant zero.
- Since all PRF inputs in the first reseed are constants, this
- amounts to suffixing the seed in the first poll with a fixed
- constant string.
-
- The PRF key will not be used to generate outputs until after reseed
- sets m_seeded to true.
- */
- std::vector<byte> prf_zero_key(m_extractor->output_length());
- m_prf->set_key(prf_zero_key.data(), prf_zero_key.size());
-
- /*
- Use PRF("Botan HMAC_RNG XTS") as the intitial XTS key.
-
- This will be used during the first extraction sequence; XTS values
- after this one are generated using the PRF.
-
- If I understand the E-t-E paper correctly (specifically Section 4),
- using this fixed initial extractor key is safe to do.
- */
- m_extractor->set_key(m_prf->process("Botan HMAC_RNG XTS"));
- }
-
-void HMAC_RNG::new_K_value(byte label)
- {
- m_prf->update(m_K);
- m_prf->update_be(last_pid());
- m_prf->update_be(OS::get_processor_timestamp());
- m_prf->update_be(OS::get_system_timestamp_ns());
- m_prf->update_be(m_counter++);
- m_prf->update(label);
- m_prf->final(m_K.data());
- }
-
-/*
-* Generate a buffer of random bytes
-*/
-void HMAC_RNG::randomize(byte out[], size_t length)
- {
- reseed_check();
-
- while(length)
- {
- new_K_value(Running);
-
- const size_t copied = std::min<size_t>(length, m_prf->output_length());
-
- copy_mem(out, m_K.data(), copied);
- out += copied;
- length -= copied;
- }
-
- new_K_value(BlockFinished);
- }
-
-size_t HMAC_RNG::reseed(Entropy_Sources& srcs,
- size_t poll_bits,
- std::chrono::milliseconds timeout)
- {
- new_K_value(Reseed);
- m_extractor->update(m_K); // m_K is the PRF output
-
- /*
- * This ends up calling add_entropy which provides input to the extractor
- */
- size_t bits_collected = Stateful_RNG::reseed(srcs, poll_bits, timeout);
-
- /*
- Now derive the new PRK using everything that has been fed into
- the extractor, and set the PRF key to that
- */
- m_prf->set_key(m_extractor->final());
-
- // Now generate a new PRF output to use as the XTS extractor salt
- new_K_value(ExtractorSeed);
- m_extractor->set_key(m_K);
-
- // Reset state
- zeroise(m_K);
- m_counter = 0;
-
- return bits_collected;
- }
-
-/*
-* Add user-supplied entropy to the extractor input then set remaining
-* output length to for a reseed on next use.
-*/
-void HMAC_RNG::add_entropy(const byte input[], size_t length)
- {
- m_extractor->update(input, length);
- force_reseed();
- }
-
-/*
-* Return the name of this type
-*/
-std::string HMAC_RNG::name() const
- {
- return "HMAC_RNG(" + m_extractor->name() + "," + m_prf->name() + ")";
- }
-
-}
diff --git a/src/lib/rng/hmac_rng/hmac_rng.h b/src/lib/rng/hmac_rng/hmac_rng.h
deleted file mode 100644
index e4cb4a2bf..000000000
--- a/src/lib/rng/hmac_rng/hmac_rng.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
-* HMAC RNG
-* (C) 2008,2013,2016 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_HMAC_RNG_H__
-#define BOTAN_HMAC_RNG_H__
-
-#include <botan/stateful_rng.h>
-#include <botan/mac.h>
-
-namespace Botan {
-
-/**
-* HMAC_RNG - based on the design described in "On Extract-then-Expand
-* Key Derivation Functions and an HMAC-based KDF" by Hugo Krawczyk
-* (henceforce, 'E-t-E')
-*
-* However it actually could be parameterized with any two MAC functions,
-* not restricted to HMAC (this variation is also described in
-* Krawczyk's paper), for instance one could use HMAC(SHA-512) as the
-* extractor and CMAC(AES-256) as the PRF.
-*/
-class BOTAN_DLL HMAC_RNG final : public Stateful_RNG
- {
- public:
- /**
- * Initialize an HMAC_RNG instance with the given MAC as PRF (normally HMAC)
- * @param prf MAC to use as a PRF
- * @param underlying_rng is a reference to some RNG which will be used
- * to perform the periodic reseeding.
- * @param entropy_sources will be polled to perform reseeding periodically
- * @param reseed_interval specifies a limit of how many times
- * the RNG will be called before automatic reseeding is performed.
- */
- HMAC_RNG(std::unique_ptr<MessageAuthenticationCode> prf,
- RandomNumberGenerator& underlying_rng,
- Entropy_Sources& entropy_sources,
- size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
-
- /**
- * Initialize an HMAC_RNG instance with the given MAC as PRF (normally HMAC)
- * @param prf MAC to use as a PRF
- * @param underlying_rng is a reference to some RNG which will be used
- * to perform the periodic reseeding.
- * @param reseed_interval specifies a limit of how many times
- * the RNG will be called before automatic reseeding is performed.
- */
- HMAC_RNG(std::unique_ptr<MessageAuthenticationCode> prf,
- RandomNumberGenerator& underlying_rng,
- size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
-
- /*
- * Initialize an HMAC_RNG instance with the given MAC as PRF (normally HMAC)
- * @param prf MAC to use as a PRF
- * @param entropy_sources will be polled to perform reseeding periodically
- * @param reseed_interval specifies a limit of how many times
- * the RNG will be called before automatic reseeding is performed.
- */
- HMAC_RNG(std::unique_ptr<MessageAuthenticationCode> prf,
- Entropy_Sources& entropy_sources,
- size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
-
- /**
- * Initialize an HMAC_RNG instance with the given MAC as PRF (normally HMAC)
- * Automatic reseeding is disabled completely.
- * @param prf MAC to use as a PRF
- */
- HMAC_RNG(std::unique_ptr<MessageAuthenticationCode> prf);
-
- void randomize(byte buf[], size_t len) override;
- void clear() override;
- std::string name() const override;
-
- size_t reseed(Entropy_Sources& srcs,
- size_t poll_bits,
- std::chrono::milliseconds poll_timeout) override;
-
- void add_entropy(const byte[], size_t) override;
-
- size_t security_level() const override { return m_prf->output_length() * 8 / 2; }
-
- private:
- std::unique_ptr<MessageAuthenticationCode> m_prf;
- std::unique_ptr<MessageAuthenticationCode> m_extractor;
-
- enum HMAC_PRF_Label {
- Running,
- BlockFinished,
- Reseed,
- ExtractorSeed,
- };
- void new_K_value(byte label);
-
- secure_vector<byte> m_K;
- u32bit m_counter = 0;
- };
-
-}
-
-#endif
diff --git a/src/lib/rng/hmac_rng/info.txt b/src/lib/rng/hmac_rng/info.txt
deleted file mode 100644
index 2b7f49c8a..000000000
--- a/src/lib/rng/hmac_rng/info.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-define HMAC_RNG 20131128
-
-<requires>
-mac
-stateful_rng
-</requires>
diff --git a/src/lib/rng/x931_rng/info.txt b/src/lib/rng/x931_rng/info.txt
deleted file mode 100644
index 4a4418083..000000000
--- a/src/lib/rng/x931_rng/info.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-define X931_RNG 20131128
-
-<requires>
-stateful_rng
-</requires>
diff --git a/src/lib/rng/x931_rng/x931_rng.cpp b/src/lib/rng/x931_rng/x931_rng.cpp
deleted file mode 100644
index ed44dc743..000000000
--- a/src/lib/rng/x931_rng/x931_rng.cpp
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
-* ANSI X9.31 RNG
-* (C) 1999-2009,2014 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/x931_rng.h>
-#include <algorithm>
-
-namespace Botan {
-
-void ANSI_X931_RNG::randomize(byte out[], size_t length)
- {
- if(!is_seeded())
- {
- rekey();
-
- if(!is_seeded())
- throw PRNG_Unseeded(name());
- }
-
- while(length)
- {
- if(m_R_pos == m_R.size())
- update_buffer();
-
- const size_t copied = std::min<size_t>(length, m_R.size() - m_R_pos);
-
- copy_mem(out, &m_R[m_R_pos], copied);
- out += copied;
- length -= copied;
- m_R_pos += copied;
- }
- }
-
-/*
-* Refill the internal state
-*/
-void ANSI_X931_RNG::update_buffer()
- {
- const size_t BLOCK_SIZE = m_cipher->block_size();
-
- secure_vector<byte> DT = m_prng->random_vec(BLOCK_SIZE);
- m_cipher->encrypt(DT);
-
- xor_buf(m_R.data(), m_V.data(), DT.data(), BLOCK_SIZE);
- m_cipher->encrypt(m_R);
-
- xor_buf(m_V.data(), m_R.data(), DT.data(), BLOCK_SIZE);
- m_cipher->encrypt(m_V);
-
- m_R_pos = 0;
- }
-
-/*
-* Reset V and the cipher key with new values
-*/
-void ANSI_X931_RNG::rekey()
- {
- const size_t BLOCK_SIZE = m_cipher->block_size();
-
- if(m_prng->is_seeded())
- {
- m_cipher->set_key(m_prng->random_vec(m_cipher->maximum_keylength()));
-
- if(m_V.size() != BLOCK_SIZE)
- m_V.resize(BLOCK_SIZE);
- m_prng->randomize(m_V.data(), m_V.size());
-
- update_buffer();
- }
- }
-
-size_t ANSI_X931_RNG::reseed(Entropy_Sources& srcs,
- size_t poll_bits,
- std::chrono::milliseconds poll_timeout)
- {
- size_t bits = m_prng->reseed(srcs, poll_bits, poll_timeout);
- rekey();
- return bits;
- }
-
-void ANSI_X931_RNG::add_entropy(const byte input[], size_t length)
- {
- m_prng->add_entropy(input, length);
- rekey();
- }
-
-bool ANSI_X931_RNG::is_seeded() const
- {
- return (m_V.size() > 0);
- }
-
-void ANSI_X931_RNG::clear()
- {
- m_cipher->clear();
- m_prng->clear();
- zeroise(m_R);
- m_V.clear();
-
- m_R_pos = 0;
- }
-
-std::string ANSI_X931_RNG::name() const
- {
- return "X9.31(" + m_cipher->name() + ")";
- }
-
-ANSI_X931_RNG::ANSI_X931_RNG(BlockCipher* cipher,
- RandomNumberGenerator* prng) :
- m_cipher(cipher),
- m_prng(prng),
- m_R(m_cipher->block_size()),
- m_R_pos(0)
- {
- }
-
-}
diff --git a/src/lib/rng/x931_rng/x931_rng.h b/src/lib/rng/x931_rng/x931_rng.h
deleted file mode 100644
index 861fcffde..000000000
--- a/src/lib/rng/x931_rng/x931_rng.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
-* ANSI X9.31 RNG
-* (C) 1999-2009 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ANSI_X931_RNG_H__
-#define BOTAN_ANSI_X931_RNG_H__
-
-#include <botan/rng.h>
-#include <botan/block_cipher.h>
-
-namespace Botan {
-
-/**
-* ANSI X9.31 RNG
-*/
-class BOTAN_DLL ANSI_X931_RNG final : public RandomNumberGenerator
- {
- public:
- void randomize(byte[], size_t) override;
- bool is_seeded() const override;
- void clear() override;
- std::string name() const override;
-
- size_t reseed(Entropy_Sources& srcs,
- size_t poll_bits,
- std::chrono::milliseconds poll_timeout) override;
-
- void add_entropy(const byte[], size_t) override;
-
- /**
- * @param cipher the block cipher to use in this PRNG
- * @param rng the underlying PRNG for generating inputs
- * (eg, an HMAC_RNG)
- */
- BOTAN_DEPRECATED("X9.31 RNG is deprecated and will be removed soon")
- ANSI_X931_RNG(BlockCipher* cipher,
- RandomNumberGenerator* rng);
-
- private:
- void rekey();
- void update_buffer();
-
- std::unique_ptr<BlockCipher> m_cipher;
- std::unique_ptr<RandomNumberGenerator> m_prng;
- secure_vector<byte> m_V, m_R;
- size_t m_R_pos;
- };
-
-}
-
-#endif