aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/botan/src/lib/rng
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/3rdparty/botan/src/lib/rng')
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp112
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h96
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/auto_rng/info.txt8
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp184
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.h159
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/info.txt8
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/info.txt3
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/info.txt13
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp83
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h61
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/rng.cpp74
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/rng.h264
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/stateful_rng/info.txt3
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.cpp112
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h151
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/system_rng/info.txt18
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp231
-rw-r--r--src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h41
18 files changed, 1621 insertions, 0 deletions
diff --git a/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp
new file mode 100644
index 0000000000..ec439e7cfb
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.cpp
@@ -0,0 +1,112 @@
+/*
+* (C) 2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/auto_rng.h>
+#include <botan/entropy_src.h>
+#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()
+ {
+ // for unique_ptr
+ }
+
+AutoSeeded_RNG::AutoSeeded_RNG(RandomNumberGenerator& underlying_rng,
+ size_t 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 HMAC_DRBG(MessageAuthenticationCode::create_or_throw(BOTAN_AUTO_RNG_HMAC),
+ entropy_sources,
+ reseed_interval));
+ force_reseed();
+ }
+
+AutoSeeded_RNG::AutoSeeded_RNG(RandomNumberGenerator& underlying_rng,
+ Entropy_Sources& entropy_sources,
+ size_t reseed_interval)
+ {
+ m_rng.reset(new HMAC_DRBG(
+ MessageAuthenticationCode::create_or_throw(BOTAN_AUTO_RNG_HMAC),
+ underlying_rng, entropy_sources, reseed_interval));
+ force_reseed();
+ }
+
+AutoSeeded_RNG::AutoSeeded_RNG(size_t reseed_interval) :
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ AutoSeeded_RNG(system_rng(), reseed_interval)
+#else
+ AutoSeeded_RNG(Entropy_Sources::global_sources(), reseed_interval)
+#endif
+ {
+ }
+
+void AutoSeeded_RNG::force_reseed()
+ {
+ m_rng->force_reseed();
+ m_rng->next_byte();
+
+ if(!m_rng->is_seeded())
+ {
+ throw Exception("AutoSeeded_RNG reseeding failed");
+ }
+ }
+
+bool AutoSeeded_RNG::is_seeded() const
+ {
+ return m_rng->is_seeded();
+ }
+
+void AutoSeeded_RNG::clear()
+ {
+ m_rng->clear();
+ }
+
+std::string AutoSeeded_RNG::name() const
+ {
+ return m_rng->name();
+ }
+
+void AutoSeeded_RNG::add_entropy(const uint8_t in[], size_t len)
+ {
+ m_rng->add_entropy(in, len);
+ }
+
+size_t AutoSeeded_RNG::reseed(Entropy_Sources& srcs,
+ size_t poll_bits,
+ std::chrono::milliseconds poll_timeout)
+ {
+ return m_rng->reseed(srcs, poll_bits, poll_timeout);
+ }
+
+void AutoSeeded_RNG::randomize(uint8_t output[], size_t output_len)
+ {
+ randomize_with_ts_input(output, output_len);
+ }
+
+void AutoSeeded_RNG::randomize_with_input(uint8_t output[], size_t output_len,
+ const uint8_t ad[], size_t ad_len)
+ {
+ m_rng->randomize_with_input(output, output_len, ad, ad_len);
+ }
+
+}
diff --git a/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h
new file mode 100644
index 0000000000..866c56e12f
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/auto_rng.h
@@ -0,0 +1,96 @@
+/*
+* Auto Seeded RNG
+* (C) 2008,2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_AUTO_SEEDING_RNG_H_
+#define BOTAN_AUTO_SEEDING_RNG_H_
+
+#include <botan/rng.h>
+
+namespace Botan {
+
+class Stateful_RNG;
+
+/**
+* A userspace PRNG
+*/
+class BOTAN_PUBLIC_API(2,0) AutoSeeded_RNG final : public RandomNumberGenerator
+ {
+ public:
+ void randomize(uint8_t out[], size_t len) override;
+
+ void randomize_with_input(uint8_t output[], size_t output_len,
+ const uint8_t input[], size_t input_len) override;
+
+ bool is_seeded() const override;
+
+ /**
+ * Mark state as requiring a reseed on next use
+ */
+ void force_reseed();
+
+ size_t reseed(Entropy_Sources& srcs,
+ size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
+ std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override;
+
+ void add_entropy(const uint8_t in[], size_t len) override;
+
+ std::string name() const override;
+
+ void clear() override;
+
+ /**
+ * Uses the system RNG (if available) or else a default group of
+ * entropy sources (all other systems) to gather seed material.
+ *
+ * @param reseed_interval specifies a limit of how many times
+ * the RNG will be called before automatic reseeding is performed
+ */
+ AutoSeeded_RNG(size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
+
+ /**
+ * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material.
+ *
+ * @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
+ */
+ AutoSeeded_RNG(RandomNumberGenerator& underlying_rng,
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
+
+ /**
+ * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material.
+ *
+ * @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
+ */
+ AutoSeeded_RNG(Entropy_Sources& entropy_sources,
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
+
+ /**
+ * Uses the BOTAN_AUTO_RNG_DRBG RNG to gather seed material.
+ *
+ * @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
+ */
+ AutoSeeded_RNG(RandomNumberGenerator& underlying_rng,
+ Entropy_Sources& entropy_sources,
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL);
+
+ ~AutoSeeded_RNG();
+
+ private:
+ std::unique_ptr<Stateful_RNG> m_rng;
+ };
+
+}
+
+#endif
diff --git a/src/libs/3rdparty/botan/src/lib/rng/auto_rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/info.txt
new file mode 100644
index 0000000000..f1adcc8001
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/auto_rng/info.txt
@@ -0,0 +1,8 @@
+<defines>
+AUTO_SEEDING_RNG -> 20160821
+AUTO_RNG -> 20161126
+</defines>
+
+<requires>
+hmac_drbg
+</requires>
diff --git a/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp
new file mode 100644
index 0000000000..a01b761d99
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.cpp
@@ -0,0 +1,184 @@
+/*
+* HMAC_DRBG
+* (C) 2014,2015,2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/hmac_drbg.h>
+#include <algorithm>
+
+namespace Botan {
+
+HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
+ RandomNumberGenerator& underlying_rng,
+ size_t reseed_interval,
+ size_t max_number_of_bytes_per_request) :
+ Stateful_RNG(underlying_rng, reseed_interval),
+ m_mac(std::move(prf)),
+ m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
+ {
+ BOTAN_ASSERT_NONNULL(m_mac);
+
+ if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
+ {
+ throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
+ }
+
+ clear();
+ }
+
+HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
+ RandomNumberGenerator& underlying_rng,
+ Entropy_Sources& entropy_sources,
+ size_t reseed_interval,
+ size_t max_number_of_bytes_per_request ) :
+ Stateful_RNG(underlying_rng, entropy_sources, reseed_interval),
+ m_mac(std::move(prf)),
+ m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
+ {
+ BOTAN_ASSERT_NONNULL(m_mac);
+
+ if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
+ {
+ throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
+ }
+
+ clear();
+ }
+
+HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
+ Entropy_Sources& entropy_sources,
+ size_t reseed_interval,
+ size_t max_number_of_bytes_per_request) :
+ Stateful_RNG(entropy_sources, reseed_interval),
+ m_mac(std::move(prf)),
+ m_max_number_of_bytes_per_request(max_number_of_bytes_per_request)
+ {
+ BOTAN_ASSERT_NONNULL(m_mac);
+
+ if(m_max_number_of_bytes_per_request == 0 || m_max_number_of_bytes_per_request > 64 * 1024)
+ {
+ throw Invalid_Argument("Invalid value for max_number_of_bytes_per_request");
+ }
+
+ clear();
+ }
+
+HMAC_DRBG::HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf) :
+ Stateful_RNG(),
+ m_mac(std::move(prf)),
+ m_max_number_of_bytes_per_request(64*1024)
+ {
+ BOTAN_ASSERT_NONNULL(m_mac);
+ clear();
+ }
+
+void HMAC_DRBG::clear()
+ {
+ Stateful_RNG::clear();
+
+ m_V.resize(m_mac->output_length());
+ for(size_t i = 0; i != m_V.size(); ++i)
+ m_V[i] = 0x01;
+ m_mac->set_key(std::vector<uint8_t>(m_mac->output_length(), 0x00));
+ }
+
+std::string HMAC_DRBG::name() const
+ {
+ return "HMAC_DRBG(" + m_mac->name() + ")";
+ }
+
+void HMAC_DRBG::randomize(uint8_t output[], size_t output_len)
+ {
+ randomize_with_input(output, output_len, nullptr, 0);
+ }
+
+/*
+* HMAC_DRBG generation
+* See NIST SP800-90A section 10.1.2.5
+*/
+void HMAC_DRBG::randomize_with_input(uint8_t output[], size_t output_len,
+ const uint8_t input[], size_t input_len)
+ {
+ while(output_len > 0)
+ {
+ size_t this_req = std::min(m_max_number_of_bytes_per_request, output_len);
+ output_len -= this_req;
+
+ reseed_check();
+
+ if(input_len > 0)
+ {
+ update(input, input_len);
+ }
+
+ while(this_req)
+ {
+ const size_t to_copy = std::min(this_req, m_V.size());
+ m_mac->update(m_V.data(), m_V.size());
+ m_mac->final(m_V.data());
+ copy_mem(output, m_V.data(), to_copy);
+
+ output += to_copy;
+ this_req -= to_copy;
+ }
+
+ update(input, input_len);
+ }
+
+ }
+
+/*
+* Reset V and the mac key with new values
+* See NIST SP800-90A section 10.1.2.2
+*/
+void HMAC_DRBG::update(const uint8_t input[], size_t input_len)
+ {
+ m_mac->update(m_V);
+ m_mac->update(0x00);
+ m_mac->update(input, input_len);
+ m_mac->set_key(m_mac->final());
+
+ m_mac->update(m_V.data(), m_V.size());
+ m_mac->final(m_V.data());
+
+ if(input_len > 0)
+ {
+ m_mac->update(m_V);
+ m_mac->update(0x01);
+ m_mac->update(input, input_len);
+ m_mac->set_key(m_mac->final());
+
+ m_mac->update(m_V.data(), m_V.size());
+ m_mac->final(m_V.data());
+ }
+ }
+
+void HMAC_DRBG::add_entropy(const uint8_t input[], size_t input_len)
+ {
+ update(input, input_len);
+
+ if(8*input_len >= security_level())
+ {
+ reset_reseed_counter();
+ }
+ }
+
+size_t HMAC_DRBG::security_level() const
+ {
+ // security strength of the hash function
+ // for pre-image resistance (see NIST SP 800-57)
+ // SHA-160: 128 bits, SHA-224, SHA-512/224: 192 bits,
+ // SHA-256, SHA-512/256, SHA-384, SHA-512: >= 256 bits
+ // NIST SP 800-90A only supports up to 256 bits though
+ if(m_mac->output_length() < 32)
+ {
+ return (m_mac->output_length() - 4) * 8;
+ }
+ else
+ {
+ return 32 * 8;
+ }
+ }
+}
diff --git a/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.h b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.h
new file mode 100644
index 0000000000..edf38b6842
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/hmac_drbg.h
@@ -0,0 +1,159 @@
+/*
+* HMAC_DRBG (SP800-90A)
+* (C) 2014,2015,2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_HMAC_DRBG_H_
+#define BOTAN_HMAC_DRBG_H_
+
+#include <botan/stateful_rng.h>
+#include <botan/mac.h>
+
+namespace Botan {
+
+class Entropy_Sources;
+
+/**
+* HMAC_DRBG from NIST SP800-90A
+*/
+class BOTAN_PUBLIC_API(2,0) HMAC_DRBG final : public Stateful_RNG
+ {
+ public:
+ /**
+ * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
+ *
+ * Automatic reseeding is disabled completely, as it has no access to
+ * any source for seed material.
+ *
+ * If a fork is detected, the RNG will be unable to reseed itself
+ * in response. In this case, an exception will be thrown rather
+ * than generating duplicated output.
+ */
+ explicit HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf);
+
+ /**
+ * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
+ *
+ * Automatic reseeding from @p underlying_rng will take place after
+ * @p reseed_interval many requests or after a fork was detected.
+ *
+ * @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
+ * @param max_number_of_bytes_per_request requests that are in size higher
+ * than max_number_of_bytes_per_request are treated as if multiple single
+ * requests of max_number_of_bytes_per_request size had been made.
+ * In theory SP 800-90A requires that we reject any request for a DRBG
+ * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
+ * the caller who wants an output larger than max_number_of_bytes_per_request,
+ * instead treat these requests as if multiple requests of
+ * max_number_of_bytes_per_request size had been made. NIST requires for
+ * HMAC_DRBG that every implementation set a value no more than 2**19 bits
+ * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
+ * example every 512 bit automatic reseeding occurs.
+ */
+ HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
+ RandomNumberGenerator& underlying_rng,
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
+ size_t max_number_of_bytes_per_request = 64 * 1024);
+
+ /**
+ * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
+ *
+ * Automatic reseeding from @p entropy_sources will take place after
+ * @p reseed_interval many requests or after a fork was detected.
+ *
+ * @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.
+ * @param max_number_of_bytes_per_request requests that are in size higher
+ * than max_number_of_bytes_per_request are treated as if multiple single
+ * requests of max_number_of_bytes_per_request size had been made.
+ * In theory SP 800-90A requires that we reject any request for a DRBG
+ * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
+ * the caller who wants an output larger than max_number_of_bytes_per_request,
+ * instead treat these requests as if multiple requests of
+ * max_number_of_bytes_per_request size had been made. NIST requires for
+ * HMAC_DRBG that every implementation set a value no more than 2**19 bits
+ * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
+ * example every 512 bit automatic reseeding occurs.
+ */
+ HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
+ Entropy_Sources& entropy_sources,
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
+ size_t max_number_of_bytes_per_request = 64 * 1024);
+
+ /**
+ * Initialize an HMAC_DRBG instance with the given MAC as PRF (normally HMAC)
+ *
+ * Automatic reseeding from @p underlying_rng and @p entropy_sources
+ * will take place after @p reseed_interval many requests or after
+ * a fork was detected.
+ *
+ * @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.
+ * @param max_number_of_bytes_per_request requests that are in size higher
+ * than max_number_of_bytes_per_request are treated as if multiple single
+ * requests of max_number_of_bytes_per_request size had been made.
+ * In theory SP 800-90A requires that we reject any request for a DRBG
+ * output longer than max_number_of_bytes_per_request. To avoid inconveniencing
+ * the caller who wants an output larger than max_number_of_bytes_per_request,
+ * instead treat these requests as if multiple requests of
+ * max_number_of_bytes_per_request size had been made. NIST requires for
+ * HMAC_DRBG that every implementation set a value no more than 2**19 bits
+ * (or 64 KiB). Together with @p reseed_interval = 1 you can enforce that for
+ * example every 512 bit automatic reseeding occurs.
+ */
+ HMAC_DRBG(std::unique_ptr<MessageAuthenticationCode> prf,
+ RandomNumberGenerator& underlying_rng,
+ Entropy_Sources& entropy_sources,
+ size_t reseed_interval = BOTAN_RNG_DEFAULT_RESEED_INTERVAL,
+ size_t max_number_of_bytes_per_request = 64 * 1024);
+
+ /**
+ * Constructor taking a string for the hash
+ */
+ explicit HMAC_DRBG(const std::string& hmac_hash) :
+ Stateful_RNG(),
+ m_mac(MessageAuthenticationCode::create_or_throw("HMAC(" + hmac_hash + ")")),
+ m_max_number_of_bytes_per_request(64 * 1024)
+ {
+ clear();
+ }
+
+ std::string name() const override;
+
+ void clear() override;
+
+ void randomize(uint8_t output[], size_t output_len) override;
+
+ void randomize_with_input(uint8_t output[], size_t output_len,
+ const uint8_t input[], size_t input_len) override;
+
+ void add_entropy(const uint8_t input[], size_t input_len) override;
+
+ size_t security_level() const override;
+
+ size_t max_number_of_bytes_per_request() const override
+ { return m_max_number_of_bytes_per_request; }
+
+ private:
+ void update(const uint8_t input[], size_t input_len);
+
+ std::unique_ptr<MessageAuthenticationCode> m_mac;
+ secure_vector<uint8_t> m_V;
+ const size_t m_max_number_of_bytes_per_request;
+ };
+
+}
+
+#endif
diff --git a/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/info.txt b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/info.txt
new file mode 100644
index 0000000000..a8922bdf0e
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/hmac_drbg/info.txt
@@ -0,0 +1,8 @@
+<defines>
+HMAC_DRBG -> 20140319
+</defines>
+
+<requires>
+hmac
+stateful_rng
+</requires>
diff --git a/src/libs/3rdparty/botan/src/lib/rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/info.txt
new file mode 100644
index 0000000000..4c88ba3826
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/info.txt
@@ -0,0 +1,3 @@
+<requires>
+entropy
+</requires>
diff --git a/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/info.txt
new file mode 100644
index 0000000000..0d0fc42a42
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/info.txt
@@ -0,0 +1,13 @@
+<defines>
+RDRAND_RNG -> 20160619
+</defines>
+
+need_isa rdrand
+
+<cc>
+gcc
+clang
+icc
+msvc
+</cc>
+
diff --git a/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp
new file mode 100644
index 0000000000..c365a5f760
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.cpp
@@ -0,0 +1,83 @@
+/*
+* RDRAND RNG
+* (C) 2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/rdrand_rng.h>
+#include <botan/loadstor.h>
+#include <botan/cpuid.h>
+
+#if !defined(BOTAN_USE_GCC_INLINE_ASM)
+ #include <immintrin.h>
+#endif
+
+namespace Botan {
+
+RDRAND_RNG::RDRAND_RNG()
+ {
+ if(!CPUID::has_rdrand())
+ throw Exception("Current CPU does not support RDRAND instruction");
+ }
+
+//static
+uint32_t RDRAND_RNG::rdrand()
+ {
+ for(;;)
+ {
+ bool ok = false;
+ uint32_t r = rdrand_status(ok);
+ if(ok)
+ return r;
+ }
+ }
+
+//static
+BOTAN_FUNC_ISA("rdrnd")
+uint32_t RDRAND_RNG::rdrand_status(bool& ok)
+ {
+ ok = false;
+ uint32_t r = 0;
+
+ for(size_t i = 0; i != BOTAN_ENTROPY_RDRAND_RETRIES; ++i)
+ {
+#if defined(BOTAN_USE_GCC_INLINE_ASM)
+ int cf = 0;
+
+ // Encoding of rdrand %eax
+ asm(".byte 0x0F, 0xC7, 0xF0; adcl $0,%1" :
+ "=a" (r), "=r" (cf) : "0" (r), "1" (cf) : "cc");
+#else
+ int cf = _rdrand32_step(&r);
+#endif
+ if(1 == cf)
+ {
+ ok = true;
+ break;
+ }
+ }
+
+ return r;
+ }
+
+void RDRAND_RNG::randomize(uint8_t out[], size_t out_len)
+ {
+ while(out_len >= 4)
+ {
+ uint32_t r = RDRAND_RNG::rdrand();
+
+ store_le(r, out);
+ out += 4;
+ out_len -= 4;
+ }
+
+ if(out_len) // between 1 and 3 trailing bytes
+ {
+ uint32_t r = RDRAND_RNG::rdrand();
+ for(size_t i = 0; i != out_len; ++i)
+ out[i] = get_byte(i, r);
+ }
+ }
+
+}
diff --git a/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h
new file mode 100644
index 0000000000..377de419f7
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/rdrand_rng/rdrand_rng.h
@@ -0,0 +1,61 @@
+/*
+* RDRAND RNG
+* (C) 2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_RNG_RDRAND_H_
+#define BOTAN_RNG_RDRAND_H_
+
+#include <botan/rng.h>
+
+namespace Botan {
+
+class BOTAN_PUBLIC_API(2,0) RDRAND_RNG final : public Hardware_RNG
+ {
+ public:
+ /**
+ * On correctly working hardware, RDRAND is always supposed to
+ * succeed within a set number of retries. If after that many
+ * retries RDRAND has still not suceeded, sets ok = false and
+ * returns 0.
+ */
+ static uint32_t rdrand_status(bool& ok);
+
+ /*
+ * Calls RDRAND until it succeeds, this could hypothetically
+ * loop forever on broken hardware.
+ */
+ static uint32_t rdrand();
+
+ /**
+ * Constructor will throw if CPU does not have RDRAND bit set
+ */
+ RDRAND_RNG();
+
+ /**
+ * Uses RDRAND to produce output
+ */
+ void randomize(uint8_t out[], size_t out_len) override;
+
+ /*
+ * No way to provide entropy to RDRAND generator, so add_entropy is ignored
+ */
+ void add_entropy(const uint8_t[], size_t) override
+ { /* no op */ }
+
+ /*
+ * No way to reseed RDRAND generator, so reseed is ignored
+ */
+ size_t reseed(Entropy_Sources&, size_t, std::chrono::milliseconds) override
+ { return 0; /* no op */ }
+
+ std::string name() const override { return "RDRAND"; }
+
+ bool is_seeded() const override { return true; }
+ };
+
+}
+
+#endif
diff --git a/src/libs/3rdparty/botan/src/lib/rng/rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/rng.cpp
new file mode 100644
index 0000000000..2cf3b7b81e
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/rng.cpp
@@ -0,0 +1,74 @@
+/*
+* (C) 2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/rng.h>
+#include <botan/entropy_src.h>
+#include <botan/loadstor.h>
+#include <botan/internal/os_utils.h>
+
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
+ #include <botan/auto_rng.h>
+#endif
+
+namespace Botan {
+
+void RandomNumberGenerator::randomize_with_ts_input(uint8_t output[], size_t output_len)
+ {
+ /*
+ Form additional input which is provided to the PRNG implementation
+ to paramaterize the KDF output.
+ */
+ uint8_t additional_input[16] = { 0 };
+ store_le(OS::get_system_timestamp_ns(), additional_input);
+ store_le(OS::get_high_resolution_clock(), additional_input + 8);
+
+ randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
+ }
+
+void RandomNumberGenerator::randomize_with_input(uint8_t output[], size_t output_len,
+ const uint8_t input[], size_t input_len)
+ {
+ this->add_entropy(input, input_len);
+ this->randomize(output, output_len);
+ }
+
+size_t RandomNumberGenerator::reseed(Entropy_Sources& srcs,
+ size_t poll_bits,
+ std::chrono::milliseconds poll_timeout)
+ {
+ return srcs.poll(*this, poll_bits, poll_timeout);
+ }
+
+void RandomNumberGenerator::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits)
+ {
+ secure_vector<uint8_t> buf(poll_bits / 8);
+ rng.randomize(buf.data(), buf.size());
+ this->add_entropy(buf.data(), buf.size());
+ }
+
+RandomNumberGenerator* RandomNumberGenerator::make_rng()
+ {
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
+ return new AutoSeeded_RNG;
+#else
+ throw Exception("make_rng failed, no AutoSeeded_RNG in this build");
+#endif
+ }
+
+#if defined(BOTAN_TARGET_OS_HAS_THREADS)
+
+#if defined(BOTAN_HAS_AUTO_SEEDING_RNG)
+Serialized_RNG::Serialized_RNG() : m_rng(new AutoSeeded_RNG) {}
+#else
+Serialized_RNG::Serialized_RNG()
+ {
+ throw Exception("Serialized_RNG default constructor failed: AutoSeeded_RNG disabled in build");
+ }
+#endif
+
+#endif
+
+}
diff --git a/src/libs/3rdparty/botan/src/lib/rng/rng.h b/src/libs/3rdparty/botan/src/lib/rng/rng.h
new file mode 100644
index 0000000000..f6fa80df06
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/rng.h
@@ -0,0 +1,264 @@
+/*
+* Random Number Generator base classes
+* (C) 1999-2009,2015,2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_RANDOM_NUMBER_GENERATOR_H_
+#define BOTAN_RANDOM_NUMBER_GENERATOR_H_
+
+#include <botan/secmem.h>
+#include <botan/exceptn.h>
+#include <botan/mutex.h>
+#include <chrono>
+#include <string>
+
+namespace Botan {
+
+class Entropy_Sources;
+
+/**
+* An interface to a cryptographic random number generator
+*/
+class BOTAN_PUBLIC_API(2,0) RandomNumberGenerator
+ {
+ public:
+ virtual ~RandomNumberGenerator() = default;
+
+ RandomNumberGenerator() = default;
+
+ /*
+ * Never copy a RNG, create a new one
+ */
+ RandomNumberGenerator(const RandomNumberGenerator& rng) = delete;
+ RandomNumberGenerator& operator=(const RandomNumberGenerator& rng) = delete;
+
+ /**
+ * Randomize a byte array.
+ * @param output the byte array to hold the random output.
+ * @param length the length of the byte array output in bytes.
+ */
+ virtual void randomize(uint8_t output[], size_t length) = 0;
+
+ /**
+ * Incorporate some additional data into the RNG state. For
+ * example adding nonces or timestamps from a peer's protocol
+ * message can help hedge against VM state rollback attacks.
+ * A few RNG types do not accept any externally provided input,
+ * in which case this function is a no-op.
+ *
+ * @param input a byte array containg the entropy to be added
+ * @param length the length of the byte array in
+ */
+ virtual void add_entropy(const uint8_t input[], size_t length) = 0;
+
+ /**
+ * Incorporate some additional data into the RNG state.
+ */
+ template<typename T> void add_entropy_T(const T& t)
+ {
+ this->add_entropy(reinterpret_cast<const uint8_t*>(&t), sizeof(T));
+ }
+
+ /**
+ * Incorporate entropy into the RNG state then produce output.
+ * Some RNG types implement this using a single operation, default
+ * calls add_entropy + randomize in sequence.
+ *
+ * Use this to further bind the outputs to your current
+ * process/protocol state. For instance if generating a new key
+ * for use in a session, include a session ID or other such
+ * value. See NIST SP 800-90 A, B, C series for more ideas.
+ *
+ * @param output buffer to hold the random output
+ * @param output_len size of the output buffer in bytes
+ * @param input entropy buffer to incorporate
+ * @param input_len size of the input buffer in bytes
+ */
+ virtual void randomize_with_input(uint8_t output[], size_t output_len,
+ const uint8_t input[], size_t input_len);
+
+ /**
+ * This calls `randomize_with_input` using some timestamps as extra input.
+ *
+ * For a stateful RNG using non-random but potentially unique data the
+ * extra input can help protect against problems with fork, VM state
+ * rollback, or other cases where somehow an RNG state is duplicated. If
+ * both of the duplicated RNG states later incorporate a timestamp (and the
+ * timestamps don't themselves repeat), their outputs will diverge.
+ */
+ virtual void randomize_with_ts_input(uint8_t output[], size_t output_len);
+
+ /**
+ * @return the name of this RNG type
+ */
+ virtual std::string name() const = 0;
+
+ /**
+ * Clear all internally held values of this RNG
+ * @post is_seeded() == false
+ */
+ virtual void clear() = 0;
+
+ /**
+ * Check whether this RNG is seeded.
+ * @return true if this RNG was already seeded, false otherwise.
+ */
+ virtual bool is_seeded() const = 0;
+
+ /**
+ * Poll provided sources for up to poll_bits bits of entropy
+ * or until the timeout expires. Returns estimate of the number
+ * of bits collected.
+ */
+ virtual size_t reseed(Entropy_Sources& srcs,
+ size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
+ std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT);
+
+ /**
+ * Reseed by reading specified bits from the RNG
+ */
+ virtual void reseed_from_rng(RandomNumberGenerator& rng,
+ size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS);
+
+ // Some utility functions built on the interface above:
+
+ /**
+ * Return a random vector
+ * @param bytes number of bytes in the result
+ * @return randomized vector of length bytes
+ */
+ secure_vector<uint8_t> random_vec(size_t bytes)
+ {
+ secure_vector<uint8_t> output(bytes);
+ this->randomize(output.data(), output.size());
+ return output;
+ }
+
+ /**
+ * Return a random byte
+ * @return random byte
+ */
+ uint8_t next_byte()
+ {
+ uint8_t b;
+ this->randomize(&b, 1);
+ return b;
+ }
+
+ /**
+ * @return a random byte that is greater than zero
+ */
+ uint8_t next_nonzero_byte()
+ {
+ uint8_t b = this->next_byte();
+ while(b == 0)
+ b = this->next_byte();
+ return b;
+ }
+
+ /**
+ * Create a seeded and active RNG object for general application use
+ * Added in 1.8.0
+ * Use AutoSeeded_RNG instead
+ */
+ BOTAN_DEPRECATED("Use AutoSeeded_RNG")
+ static RandomNumberGenerator* make_rng();
+ };
+
+/**
+* Convenience typedef
+*/
+typedef RandomNumberGenerator RNG;
+
+/**
+* Hardware_RNG has no members but exists to tag hardware RNG types
+* (PKCS11_RNG, TPM_RNG, RDRAND_RNG)
+*/
+class BOTAN_PUBLIC_API(2,0) Hardware_RNG : public RandomNumberGenerator
+ {
+ public:
+ virtual void clear() final override { /* no way to clear state of hardware RNG */ }
+ };
+
+/**
+* Null/stub RNG - fails if you try to use it for anything
+* This is not generally useful except for in certain tests
+*/
+class BOTAN_PUBLIC_API(2,0) Null_RNG final : public RandomNumberGenerator
+ {
+ public:
+ bool is_seeded() const override { return false; }
+
+ void clear() override {}
+
+ void randomize(uint8_t[], size_t) override
+ {
+ throw PRNG_Unseeded("Null_RNG called");
+ }
+
+ void add_entropy(const uint8_t[], size_t) override {}
+
+ std::string name() const override { return "Null_RNG"; }
+ };
+
+#if defined(BOTAN_TARGET_OS_HAS_THREADS)
+/**
+* Wraps access to a RNG in a mutex
+* Note that most of the time it's much better to use a RNG per thread
+* otherwise the RNG will act as an unnecessary contention point
+*/
+class BOTAN_PUBLIC_API(2,0) Serialized_RNG final : public RandomNumberGenerator
+ {
+ public:
+ void randomize(uint8_t out[], size_t len) override
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
+ m_rng->randomize(out, len);
+ }
+
+ bool is_seeded() const override
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
+ return m_rng->is_seeded();
+ }
+
+ void clear() override
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
+ m_rng->clear();
+ }
+
+ std::string name() const override
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
+ return m_rng->name();
+ }
+
+ size_t reseed(Entropy_Sources& src,
+ size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
+ std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
+ return m_rng->reseed(src, poll_bits, poll_timeout);
+ }
+
+ void add_entropy(const uint8_t in[], size_t len) override
+ {
+ lock_guard_type<mutex_type> lock(m_mutex);
+ m_rng->add_entropy(in, len);
+ }
+
+ BOTAN_DEPRECATED("Use Serialized_RNG(new AutoSeeded_RNG)") Serialized_RNG();
+
+ explicit Serialized_RNG(RandomNumberGenerator* rng) : m_rng(rng) {}
+ private:
+ mutable mutex_type m_mutex;
+ std::unique_ptr<RandomNumberGenerator> m_rng;
+ };
+#endif
+
+}
+
+#endif
diff --git a/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/info.txt
new file mode 100644
index 0000000000..edc2d91694
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/info.txt
@@ -0,0 +1,3 @@
+<defines>
+STATEFUL_RNG -> 20160819
+</defines>
diff --git a/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.cpp
new file mode 100644
index 0000000000..dec7917938
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.cpp
@@ -0,0 +1,112 @@
+/*
+* (C) 2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/stateful_rng.h>
+#include <botan/internal/os_utils.h>
+#include <botan/loadstor.h>
+
+namespace Botan {
+
+void Stateful_RNG::clear()
+ {
+ m_reseed_counter = 0;
+ m_last_pid = 0;
+ }
+
+void Stateful_RNG::force_reseed()
+ {
+ m_reseed_counter = 0;
+ }
+
+bool Stateful_RNG::is_seeded() const
+ {
+ return m_reseed_counter > 0;
+ }
+
+void Stateful_RNG::initialize_with(const uint8_t input[], size_t len)
+ {
+ add_entropy(input, len);
+
+ if(8*len >= security_level())
+ {
+ reset_reseed_counter();
+ }
+ }
+
+void Stateful_RNG::randomize_with_ts_input(uint8_t output[], size_t output_len)
+ {
+ uint8_t additional_input[24] = { 0 };
+ store_le(OS::get_system_timestamp_ns(), additional_input);
+ store_le(OS::get_high_resolution_clock(), additional_input + 8);
+ store_le(m_last_pid, additional_input + 16);
+ store_le(static_cast<uint32_t>(m_reseed_counter), additional_input + 20);
+
+ randomize_with_input(output, output_len, additional_input, sizeof(additional_input));
+ }
+
+size_t Stateful_RNG::reseed(Entropy_Sources& srcs,
+ size_t poll_bits,
+ std::chrono::milliseconds poll_timeout)
+ {
+ size_t bits_collected = RandomNumberGenerator::reseed(srcs, poll_bits, poll_timeout);
+
+ if(bits_collected >= security_level())
+ {
+ reset_reseed_counter();
+ }
+
+ return bits_collected;
+ }
+
+void Stateful_RNG::reseed_from_rng(RandomNumberGenerator& rng, size_t poll_bits)
+ {
+ RandomNumberGenerator::reseed_from_rng(rng, poll_bits);
+
+ if(poll_bits >= security_level())
+ {
+ reset_reseed_counter();
+ }
+ }
+
+void Stateful_RNG::reseed_check()
+ {
+ const uint32_t cur_pid = OS::get_process_id();
+
+ const bool fork_detected = (m_last_pid > 0) && (cur_pid != m_last_pid);
+
+ if(is_seeded() == false ||
+ fork_detected ||
+ (m_reseed_interval > 0 && m_reseed_counter >= m_reseed_interval))
+ {
+ m_reseed_counter = 0;
+ m_last_pid = cur_pid;
+
+ if(m_underlying_rng)
+ {
+ reseed_from_rng(*m_underlying_rng, security_level());
+ }
+
+ if(m_entropy_sources)
+ {
+ reseed(*m_entropy_sources, security_level());
+ }
+
+ if(!is_seeded())
+ {
+ if(fork_detected)
+ throw Exception("Detected use of fork but cannot reseed DRBG");
+ else
+ throw PRNG_Unseeded(name());
+ }
+ }
+ else
+ {
+ BOTAN_ASSERT(m_reseed_counter != 0, "RNG is seeded");
+ m_reseed_counter += 1;
+ }
+ }
+
+}
diff --git a/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h
new file mode 100644
index 0000000000..18697ae231
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/stateful_rng/stateful_rng.h
@@ -0,0 +1,151 @@
+/*
+* (C) 2016 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_STATEFUL_RNG_H_
+#define BOTAN_STATEFUL_RNG_H_
+
+#include <botan/rng.h>
+
+namespace Botan {
+
+/**
+* Inherited by RNGs which maintain in-process state, like HMAC_DRBG.
+* On Unix these RNGs are vulnerable to problems with fork, where the
+* RNG state is duplicated, and the parent and child process RNGs will
+* produce identical output until one of them reseeds. Stateful_RNG
+* reseeds itself whenever a fork is detected, or after a set number of
+* bytes have been output.
+*
+* Not implemented by RNGs which access an external RNG, such as the
+* system PRNG or a hardware RNG.
+*/
+class BOTAN_PUBLIC_API(2,0) Stateful_RNG : public RandomNumberGenerator
+ {
+ public:
+ /**
+ * @param 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
+ */
+ Stateful_RNG(RandomNumberGenerator& rng,
+ Entropy_Sources& entropy_sources,
+ size_t reseed_interval) :
+ m_underlying_rng(&rng),
+ m_entropy_sources(&entropy_sources),
+ m_reseed_interval(reseed_interval)
+ {}
+
+ /**
+ * @param 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
+ */
+ Stateful_RNG(RandomNumberGenerator& rng, size_t reseed_interval) :
+ m_underlying_rng(&rng),
+ m_reseed_interval(reseed_interval)
+ {}
+
+ /**
+ * @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
+ */
+ Stateful_RNG(Entropy_Sources& entropy_sources, size_t reseed_interval) :
+ m_entropy_sources(&entropy_sources),
+ m_reseed_interval(reseed_interval)
+ {}
+
+ /**
+ * In this case, automatic reseeding is impossible
+ */
+ Stateful_RNG() : m_reseed_interval(0) {}
+
+ /**
+ * Consume this input and mark the RNG as initialized regardless
+ * of the length of the input or the current seeded state of
+ * the RNG.
+ */
+ void initialize_with(const uint8_t input[], size_t length);
+
+ bool is_seeded() const override final;
+
+ /**
+ * Mark state as requiring a reseed on next use
+ */
+ void force_reseed();
+
+ void reseed_from_rng(RandomNumberGenerator& rng,
+ size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS) override final;
+
+ /**
+ * Overrides default implementation and also includes the current
+ * process ID and the reseed counter.
+ */
+ void randomize_with_ts_input(uint8_t output[], size_t output_len) override final;
+
+ /**
+ * Poll provided sources for up to poll_bits bits of entropy
+ * or until the timeout expires. Returns estimate of the number
+ * of bits collected.
+ */
+ size_t reseed(Entropy_Sources& srcs,
+ size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS,
+ std::chrono::milliseconds poll_timeout = BOTAN_RNG_RESEED_DEFAULT_TIMEOUT) override;
+
+ /**
+ * @return intended security level of this DRBG
+ */
+ virtual size_t security_level() const = 0;
+
+ /**
+ * Some DRBGs have a notion of the maximum number of bytes per
+ * request. Longer requests (to randomize) will be treated as
+ * multiple requests, and may initiate reseeding multiple times,
+ * depending on the values of max_number_of_bytes_per_request and
+ * reseed_interval(). This function returns zero if the RNG in
+ * question does not have such a notion.
+ *
+ * @return max number of bytes per request (or zero)
+ */
+ virtual size_t max_number_of_bytes_per_request() const = 0;
+
+ size_t reseed_interval() const { return m_reseed_interval; }
+
+ void clear() override;
+
+ protected:
+ void reseed_check();
+
+ /**
+ * Called by a subclass to notify that a reseed has been
+ * successfully performed.
+ */
+ void reset_reseed_counter() { m_reseed_counter = 1; }
+
+ private:
+ // A non-owned and possibly null pointer to shared RNG
+ RandomNumberGenerator* m_underlying_rng = nullptr;
+
+ // A non-owned and possibly null pointer to a shared Entropy_Source
+ Entropy_Sources* m_entropy_sources = nullptr;
+
+ const size_t m_reseed_interval;
+ uint32_t m_last_pid = 0;
+
+ /*
+ * Set to 1 after a successful seeding, then incremented. Reset
+ * to 0 by clear() or a fork. This logic is used even if
+ * automatic reseeding is disabled (via m_reseed_interval = 0)
+ */
+ size_t m_reseed_counter = 0;
+ };
+
+}
+
+#endif
diff --git a/src/libs/3rdparty/botan/src/lib/rng/system_rng/info.txt b/src/libs/3rdparty/botan/src/lib/rng/system_rng/info.txt
new file mode 100644
index 0000000000..da4fce4e36
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/system_rng/info.txt
@@ -0,0 +1,18 @@
+<defines>
+SYSTEM_RNG -> 20141202
+</defines>
+
+<os_features>
+dev_random,posix1
+arc4random
+rtlgenrandom
+crypto_ng
+</os_features>
+
+<libs>
+uwp -> bcrypt.lib
+</libs>
+
+<requires>
+rtlgenrandom?dyn_load
+</requires>
diff --git a/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp
new file mode 100644
index 0000000000..c3b37ea9cc
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.cpp
@@ -0,0 +1,231 @@
+/*
+* System RNG
+* (C) 2014,2015,2017,2018 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#include <botan/system_rng.h>
+
+#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)
+ #include <botan/dyn_load.h>
+ #define NOMINMAX 1
+ #define _WINSOCKAPI_ // stop windows.h including winsock.h
+ #include <windows.h>
+
+#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG)
+ #include <bcrypt.h>
+
+#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
+ #include <stdlib.h>
+
+#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <errno.h>
+#endif
+
+namespace Botan {
+
+namespace {
+
+#if defined(BOTAN_TARGET_OS_HAS_RTLGENRANDOM)
+
+class System_RNG_Impl final : public RandomNumberGenerator
+ {
+ public:
+ System_RNG_Impl() : m_advapi("advapi32.dll")
+ {
+ // This throws if the function is not found
+ m_rtlgenrandom = m_advapi.resolve<RtlGenRandom_fptr>("SystemFunction036");
+ }
+
+ void randomize(uint8_t buf[], size_t len) override
+ {
+ bool success = m_rtlgenrandom(buf, len) == TRUE;
+ if(!success)
+ throw Exception("RtlGenRandom failed");
+ }
+
+ void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
+ bool is_seeded() const override { return true; }
+ void clear() override { /* not possible */ }
+ std::string name() const override { return "RtlGenRandom"; }
+ private:
+ // Use type BYTE instead of BOOLEAN because of a naming conflict
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa387694(v=vs.85).aspx
+ // https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx
+ using RtlGenRandom_fptr = BYTE (NTAPI *)(PVOID, ULONG);
+
+ Dynamically_Loaded_Library m_advapi;
+ RtlGenRandom_fptr m_rtlgenrandom;
+ };
+
+#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG)
+
+class System_RNG_Impl final : public RandomNumberGenerator
+ {
+ public:
+ System_RNG_Impl()
+ {
+ NTSTATUS ret = ::BCryptOpenAlgorithmProvider(&m_prov,
+ BCRYPT_RNG_ALGORITHM,
+ MS_PRIMITIVE_PROVIDER, 0);
+ if(ret != STATUS_SUCCESS)
+ throw Exception("System_RNG failed to acquire crypto provider");
+ }
+
+ ~System_RNG_Impl()
+ {
+ ::BCryptCloseAlgorithmProvider(m_prov, 0);
+ }
+
+ void randomize(uint8_t buf[], size_t len) override
+ {
+ NTSTATUS ret = ::BCryptGenRandom(m_prov, static_cast<PUCHAR>(buf), static_cast<ULONG>(len), 0);
+ if(ret != STATUS_SUCCESS)
+ throw Exception("System_RNG call to BCryptGenRandom failed");
+ }
+
+ void add_entropy(const uint8_t in[], size_t length) override
+ {
+ /*
+ There is a flag BCRYPT_RNG_USE_ENTROPY_IN_BUFFER to provide
+ entropy inputs, but it is ignored in Windows 8 and later.
+ */
+ }
+
+ bool is_seeded() const override { return true; }
+ void clear() override { /* not possible */ }
+ std::string name() const override { return "crypto_ng"; }
+ private:
+ BCRYPT_ALG_HANDLE m_handle;
+ };
+
+#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
+
+class System_RNG_Impl final : public RandomNumberGenerator
+ {
+ public:
+ // No constructor or destructor needed as no userland state maintained
+
+ void randomize(uint8_t buf[], size_t len) override
+ {
+ ::arc4random_buf(buf, len);
+ }
+
+ void add_entropy(const uint8_t[], size_t) override { /* ignored */ }
+ bool is_seeded() const override { return true; }
+ void clear() override { /* not possible */ }
+ std::string name() const override { return "arc4random"; }
+ };
+
+#elif defined(BOTAN_TARGET_OS_HAS_DEV_RANDOM)
+
+// Read a random device
+
+class System_RNG_Impl final : public RandomNumberGenerator
+ {
+ public:
+ System_RNG_Impl()
+ {
+ #ifndef O_NOCTTY
+ #define O_NOCTTY 0
+ #endif
+
+ m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY);
+
+ /*
+ Cannot open in read-write mode. Fall back to read-only,
+ calls to add_entropy will fail, but randomize will work
+ */
+ if(m_fd < 0)
+ m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY | O_NOCTTY);
+
+ if(m_fd < 0)
+ throw Exception("System_RNG failed to open RNG device");
+ }
+
+ ~System_RNG_Impl()
+ {
+ ::close(m_fd);
+ m_fd = -1;
+ }
+
+ void randomize(uint8_t buf[], size_t len) override;
+ void add_entropy(const uint8_t in[], size_t length) override;
+ bool is_seeded() const override { return true; }
+ void clear() override { /* not possible */ }
+ std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; }
+ private:
+ int m_fd;
+ };
+
+void System_RNG_Impl::randomize(uint8_t buf[], size_t len)
+ {
+ while(len)
+ {
+ ssize_t got = ::read(m_fd, buf, len);
+
+ if(got < 0)
+ {
+ if(errno == EINTR)
+ continue;
+ throw Exception("System_RNG read failed error " + std::to_string(errno));
+ }
+ if(got == 0)
+ throw Exception("System_RNG EOF on device"); // ?!?
+
+ buf += got;
+ len -= got;
+ }
+ }
+
+void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
+ {
+ while(len)
+ {
+ ssize_t got = ::write(m_fd, input, len);
+
+ if(got < 0)
+ {
+ if(errno == EINTR)
+ continue;
+
+ /*
+ * This is seen on OS X CI, despite the fact that the man page
+ * for Darwin urandom explicitly states that writing to it is
+ * supported, and write(2) does not document EPERM at all.
+ * But in any case EPERM seems indicative of a policy decision
+ * by the OS or sysadmin that additional entropy is not wanted
+ * in the system pool, so we accept that and return here,
+ * since there is no corrective action possible.
+ *
+ * In Linux EBADF or EPERM is returned if m_fd is not opened for
+ * writing.
+ */
+ if(errno == EPERM || errno == EBADF)
+ return;
+
+ // maybe just ignore any failure here and return?
+ throw Exception("System_RNG write failed error " + std::to_string(errno));
+ }
+
+ input += got;
+ len -= got;
+ }
+ }
+
+#endif
+
+}
+
+RandomNumberGenerator& system_rng()
+ {
+ static System_RNG_Impl g_system_rng;
+ return g_system_rng;
+ }
+
+}
diff --git a/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h
new file mode 100644
index 0000000000..4e3beaf9fb
--- /dev/null
+++ b/src/libs/3rdparty/botan/src/lib/rng/system_rng/system_rng.h
@@ -0,0 +1,41 @@
+/*
+* System RNG interface
+* (C) 2014,2015 Jack Lloyd
+*
+* Botan is released under the Simplified BSD License (see license.txt)
+*/
+
+#ifndef BOTAN_SYSTEM_RNG_H_
+#define BOTAN_SYSTEM_RNG_H_
+
+#include <botan/rng.h>
+
+namespace Botan {
+
+/**
+* Return a shared reference to a global PRNG instance provided by the
+* operating system. For instance might be instantiated by /dev/urandom
+* or CryptGenRandom.
+*/
+BOTAN_PUBLIC_API(2,0) RandomNumberGenerator& system_rng();
+
+/*
+* Instantiable reference to the system RNG.
+*/
+class BOTAN_PUBLIC_API(2,0) System_RNG final : public RandomNumberGenerator
+ {
+ public:
+ std::string name() const override { return system_rng().name(); }
+
+ void randomize(uint8_t out[], size_t len) override { system_rng().randomize(out, len); }
+
+ void add_entropy(const uint8_t in[], size_t length) override { system_rng().add_entropy(in, length); }
+
+ bool is_seeded() const override { return system_rng().is_seeded(); }
+
+ void clear() override { system_rng().clear(); }
+ };
+
+}
+
+#endif