aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-09-02 18:34:37 -0400
committerJack Lloyd <[email protected]>2017-09-02 18:34:37 -0400
commit87f19427dbc3662636a84e56b7c7a8a49f1246df (patch)
tree267749bedfa5e4ee9490d3d50a83e08c50c097ea /src
parente2036b0dba7084728b209fc3901398e8d46b72b9 (diff)
Refactor RNGs to support Windows Phone
This OS has its own crypto API and does not support CryptGenRandom. Splits System_RNG_Impl into distinct declarations one per implementation type. Easier to read now that we are up to 4 distinct versions. Removes the CryptoAPI entropy source, and replaces it with an entropy source that calls the system RNG. This is nominally a bit less flexible in that the entropy source allowed polling multiple providers (though we didn't actually make use of that). Plus side is it works on all systems. Currently the dev_random entropy source is still there because we do actually use it to poll both /dev/random and /dev/urandom, and it might be useful (on certain systems) to also poll a HW RNG, which are often assigned their own device node. This could debatably also be removed in favor of just reading the system RNG.
Diffstat (limited to 'src')
-rw-r--r--src/build-data/buildh.in13
-rw-r--r--src/build-data/os/winphone.txt26
-rw-r--r--src/build-data/policy/bsi.txt1
-rw-r--r--src/build-data/policy/modern.txt1
-rw-r--r--src/build-data/policy/nist.txt1
-rw-r--r--src/lib/entropy/cryptoapi_rng/es_capi.cpp95
-rw-r--r--src/lib/entropy/cryptoapi_rng/es_capi.h44
-rw-r--r--src/lib/entropy/cryptoapi_rng/info.txt20
-rw-r--r--src/lib/entropy/entropy_srcs.cpp69
-rw-r--r--src/lib/rng/system_rng/info.txt8
-rw-r--r--src/lib/rng/system_rng/system_rng.cpp250
11 files changed, 227 insertions, 301 deletions
diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in
index 6e60718ee..e1337318e 100644
--- a/src/build-data/buildh.in
+++ b/src/build-data/buildh.in
@@ -117,15 +117,14 @@
/*
* Specifies (in order) the list of entropy sources that will be used
-* to seed an in-memory RNG. The first in the default list: "rdseed" and "rdrand"
-* do not count as contributing any entropy
-* but are included as they are fast and help protect against a
-* seriously broken system RNG.
+* to seed an in-memory RNG. The first in the default list: "rdseed"
+* and "rdrand" do not count as contributing any entropy but are
+* included as they are fast and help protect against a seriously
+* broken system RNG.
*/
#define BOTAN_ENTROPY_DEFAULT_SOURCES \
- { "rdseed", "rdrand", "darwin_secrandom", "getentropy", "dev_random", \
- "win32_cryptoapi", "proc_walk", "system_stats" }
-
+ { "rdseed", "rdrand", "darwin_secrandom", "getentropy", \
+ "dev_random", "system_rng", "proc_walk", "system_stats" }
/* Multiplier on a block cipher's native parallelism */
#define BOTAN_BLOCK_CIPHER_PAR_MULT 4
diff --git a/src/build-data/os/winphone.txt b/src/build-data/os/winphone.txt
new file mode 100644
index 000000000..ee43ee702
--- /dev/null
+++ b/src/build-data/os/winphone.txt
@@ -0,0 +1,26 @@
+os_type windows
+
+# ?
+program_suffix .exe
+obj_suffix obj
+static_suffix lib
+building_shared_supported no
+
+install_root c:\\Botan
+doc_dir docs
+
+install_cmd_data "copy"
+install_cmd_exec "copy"
+
+<target_features>
+crypto_ng
+gmtime_s
+loadlibrary
+mkgmtime
+query_perf_counter
+rtlsecurezeromemory
+#stl_filesystem_msvc
+threads
+filesystem
+sockets
+</target_features>
diff --git a/src/build-data/policy/bsi.txt b/src/build-data/policy/bsi.txt
index 0f053c337..f66f634ed 100644
--- a/src/build-data/policy/bsi.txt
+++ b/src/build-data/policy/bsi.txt
@@ -57,7 +57,6 @@ aes_ssse3
clmul
# entropy sources
-cryptoapi_rng
darwin_secrandom
dev_random
proc_walk
diff --git a/src/build-data/policy/modern.txt b/src/build-data/policy/modern.txt
index 588fc7fc8..fb435636c 100644
--- a/src/build-data/policy/modern.txt
+++ b/src/build-data/policy/modern.txt
@@ -76,7 +76,6 @@ rdrand_rng
system_rng
# entropy sources
-cryptoapi_rng
darwin_secrandom
dev_random
proc_walk
diff --git a/src/build-data/policy/nist.txt b/src/build-data/policy/nist.txt
index 50948d4dc..ad7a552dc 100644
--- a/src/build-data/policy/nist.txt
+++ b/src/build-data/policy/nist.txt
@@ -61,7 +61,6 @@ sha2_32_armv8
clmul
# entropy sources
-cryptoapi_rng
darwin_secrandom
dev_random
proc_walk
diff --git a/src/lib/entropy/cryptoapi_rng/es_capi.cpp b/src/lib/entropy/cryptoapi_rng/es_capi.cpp
deleted file mode 100644
index 58503c66d..000000000
--- a/src/lib/entropy/cryptoapi_rng/es_capi.cpp
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-* Win32 CryptoAPI EntropySource
-* (C) 1999-2009,2016 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#include <botan/internal/es_capi.h>
-#include <botan/parsing.h>
-#define NOMINMAX 1
-#define _WINSOCKAPI_ // stop windows.h including winsock.h
-#include <windows.h>
-#include <wincrypt.h>
-
-namespace Botan {
-
-namespace {
-
-class CSP_Handle_Impl : public Win32_CAPI_EntropySource::CSP_Handle
- {
- public:
- explicit CSP_Handle_Impl(uint64_t capi_provider)
- {
- m_valid = ::CryptAcquireContext(&m_handle,
- nullptr,
- nullptr,
- static_cast<DWORD>(capi_provider),
- CRYPT_VERIFYCONTEXT);
- }
-
- ~CSP_Handle_Impl()
- {
- if(m_valid)
- ::CryptReleaseContext(m_handle, 0);
- }
-
- size_t gen_random(uint8_t out[], size_t n) const
- {
- if(m_valid && ::CryptGenRandom(m_handle, static_cast<DWORD>(n), out))
- return n;
- return 0;
- }
-
- private:
- bool m_valid;
- HCRYPTPROV m_handle;
- };
-
-}
-
-/*
-* Gather Entropy from Win32 CAPI
-*/
-size_t Win32_CAPI_EntropySource::poll(RandomNumberGenerator& rng)
- {
- secure_vector<uint8_t> buf(BOTAN_SYSTEM_RNG_POLL_REQUEST);
- size_t bits = 0;
-
- for(size_t i = 0; i != m_csp_provs.size(); ++i)
- {
- size_t got = m_csp_provs[i]->gen_random(buf.data(), buf.size());
-
- if(got > 0)
- {
- rng.add_entropy(buf.data(), got);
- bits += got * 8;
- }
- }
-
- return bits;
- }
-
-/*
-* Win32_Capi_Entropysource Constructor
-*/
-Win32_CAPI_EntropySource::Win32_CAPI_EntropySource(const std::string& provs)
- {
- for(std::string prov_name : split_on(provs, ':'))
- {
- DWORD prov_type;
-
- if(prov_name == "RSA_FULL")
- prov_type = PROV_RSA_FULL;
- else if(prov_name == "INTEL_SEC")
- prov_type = PROV_INTEL_SEC;
- else if(prov_name == "RNG")
- prov_type = PROV_RNG;
- else
- continue;
-
- m_csp_provs.push_back(std::unique_ptr<CSP_Handle>(new CSP_Handle_Impl(prov_type)));
- }
- }
-
-}
diff --git a/src/lib/entropy/cryptoapi_rng/es_capi.h b/src/lib/entropy/cryptoapi_rng/es_capi.h
deleted file mode 100644
index 8439e62fa..000000000
--- a/src/lib/entropy/cryptoapi_rng/es_capi.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-* Win32 CAPI EntropySource
-* (C) 1999-2007 Jack Lloyd
-*
-* Botan is released under the Simplified BSD License (see license.txt)
-*/
-
-#ifndef BOTAN_ENTROPY_SRC_WIN32_CAPI_H__
-#define BOTAN_ENTROPY_SRC_WIN32_CAPI_H__
-
-#include <botan/entropy_src.h>
-#include <vector>
-
-namespace Botan {
-
-/**
-* Win32 CAPI Entropy Source
-*/
-class Win32_CAPI_EntropySource final : public Entropy_Source
- {
- public:
- std::string name() const override { return "win32_cryptoapi"; }
-
- size_t poll(RandomNumberGenerator& rng) override;
-
- /**
- * Win32_Capi_Entropysource Constructor
- * @param provs list of providers, separated by ':'
- */
- explicit Win32_CAPI_EntropySource(const std::string& provs = "");
-
- class CSP_Handle
- {
- public:
- virtual ~CSP_Handle() {}
- virtual size_t gen_random(uint8_t out[], size_t n) const = 0;
- };
- private:
- std::vector<std::unique_ptr<CSP_Handle>> m_csp_provs;
- };
-
-}
-
-#endif
diff --git a/src/lib/entropy/cryptoapi_rng/info.txt b/src/lib/entropy/cryptoapi_rng/info.txt
deleted file mode 100644
index 21b42f2a0..000000000
--- a/src/lib/entropy/cryptoapi_rng/info.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-<defines>
-ENTROPY_SRC_CAPI -> 20131128
-</defines>
-
-<header:internal>
-es_capi.h
-</header:internal>
-
-# 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
-mingw
-</os>
-
-<libs>
-windows -> advapi32.lib
-mingw -> advapi32
-</libs>
diff --git a/src/lib/entropy/entropy_srcs.cpp b/src/lib/entropy/entropy_srcs.cpp
index d9d5cfe4b..76546c5da 100644
--- a/src/lib/entropy/entropy_srcs.cpp
+++ b/src/lib/entropy/entropy_srcs.cpp
@@ -8,6 +8,10 @@
#include <botan/entropy_src.h>
#include <botan/rng.h>
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ #include <botan/system_rng.h>
+#endif
+
#if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND)
#include <botan/internal/rdrand.h>
#endif
@@ -20,10 +24,6 @@
#include <botan/internal/dev_random.h>
#endif
-#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI)
- #include <botan/internal/es_capi.h>
-#endif
-
#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
#include <botan/internal/es_win32.h>
#endif
@@ -42,65 +42,86 @@
namespace Botan {
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+
+namespace {
+
+class System_RNG_EntropySource : public Entropy_Source
+ {
+ public:
+ size_t poll(RandomNumberGenerator& rng) override
+ {
+ const size_t poll_bits = BOTAN_RNG_RESEED_POLL_BITS;
+ rng.reseed_from_rng(system_rng(), poll_bits);
+ return poll_bits;
+ }
+
+ std::string name() const override { return system_rng().name(); }
+ };
+
+}
+
+#endif
+
std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
{
- if(name == "rdrand")
+#if defined(BOTAN_HAS_SYSTEM_RNG)
+ if(name == "system_rng" || name == "win32_cryptoapi")
{
+ return std::unique_ptr<Entropy_Source>(new System_RNG_EntropySource);
+ }
+#endif
+
#if defined(BOTAN_HAS_ENTROPY_SRC_RDRAND)
+ if(name == "rdrand")
+ {
return std::unique_ptr<Entropy_Source>(new Intel_Rdrand);
-#endif
}
+#endif
+#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
if(name == "rdseed")
{
-#if defined(BOTAN_HAS_ENTROPY_SRC_RDSEED)
return std::unique_ptr<Entropy_Source>(new Intel_Rdseed);
-#endif
}
+#endif
+#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM)
if(name == "darwin_secrandom")
{
-#if defined(BOTAN_HAS_ENTROPY_SRC_DARWIN_SECRANDOM)
return std::unique_ptr<Entropy_Source>(new Darwin_SecRandom);
-#endif
}
+#endif
+#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
if(name == "getentropy")
{
-#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
return std::unique_ptr<Entropy_Source>(new Getentropy);
-#endif
}
+#endif
+#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM)
if(name == "dev_random")
{
-#if defined(BOTAN_HAS_ENTROPY_SRC_DEV_RANDOM)
return std::unique_ptr<Entropy_Source>(new Device_EntropySource(BOTAN_SYSTEM_RNG_POLL_DEVICES));
-#endif
}
-
- if(name == "win32_cryptoapi")
- {
-#if defined(BOTAN_HAS_ENTROPY_SRC_CAPI)
- return std::unique_ptr<Entropy_Source>(new Win32_CAPI_EntropySource("RSA_FULL"));
#endif
- }
+#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
if(name == "proc_walk")
{
-#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH;
if(!root_dir.empty())
return std::unique_ptr<Entropy_Source>(new ProcWalking_EntropySource(root_dir));
-#endif
}
+#endif
+#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
if(name == "system_stats")
{
-#if defined(BOTAN_HAS_ENTROPY_SRC_WIN32)
return std::unique_ptr<Entropy_Source>(new Win32_EntropySource);
-#endif
}
+#endif
return std::unique_ptr<Entropy_Source>();
}
diff --git a/src/lib/rng/system_rng/info.txt b/src/lib/rng/system_rng/info.txt
index 3df7dd387..1ea7eb388 100644
--- a/src/lib/rng/system_rng/info.txt
+++ b/src/lib/rng/system_rng/info.txt
@@ -24,4 +24,12 @@ openbsd
qnx
solaris
windows
+winphone
</os>
+
+<libs>
+windows -> advapi32.lib
+winphone -> bcrypt.lib
+
+mingw -> advapi32
+</libs>
diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp
index 1c3b8e50a..cafdaac78 100644
--- a/src/lib/rng/system_rng/system_rng.cpp
+++ b/src/lib/rng/system_rng/system_rng.cpp
@@ -1,6 +1,6 @@
/*
* System RNG
-* (C) 2014,2015 Jack Lloyd
+* (C) 2014,2015,2017 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -9,128 +9,187 @@
#include <botan/build.h>
#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
+ #define NOMINMAX 1
+ #include <windows.h>
+ #include <wincrypt.h>
-#define NOMINMAX 1
-#include <windows.h>
-#include <wincrypt.h>
+#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG)
+ #include <bcrypt.h>
#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
-
-#include <stdlib.h>
+ #include <stdlib.h>
#else
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-
+ #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_CRYPTGENRANDOM)
+
class System_RNG_Impl final : public RandomNumberGenerator
{
public:
- System_RNG_Impl();
- ~System_RNG_Impl();
+ System_RNG_Impl()
+ {
+ if(!CryptAcquireContext(&m_prov, nullptr, nullptr,
+ BOTAN_SYSTEM_RNG_CRYPTOAPI_PROV_TYPE, CRYPT_VERIFYCONTEXT))
+ throw Exception("System_RNG failed to acquire crypto provider");
+ }
- bool is_seeded() const override { return true; }
+ ~System_RNG_Impl()
+ {
+ ::CryptReleaseContext(m_prov, 0);
+ }
+
+ void randomize(uint8_t buf[], size_t len) override
+ {
+ ::CryptGenRandom(m_prov, static_cast<DWORD>(len), buf);
+ }
+
+ void add_entropy(const uint8_t in[], size_t length) override
+ {
+ /*
+ There is no explicit ConsumeRandom, but all values provided in
+ the call are incorporated into the state.
+ */
+ std::vector<uint8_t> buf(in, in + length);
+ ::CryptGenRandom(m_prov, static_cast<DWORD>(buf.size()), buf.data());
+ }
+ bool is_seeded() const override { return true; }
void clear() override {}
+ std::string name() const override { return "cryptoapi"; }
+ private:
+ HCRYPTPROV m_prov;
+ };
- void randomize(uint8_t out[], size_t len) override;
+#elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG)
- void add_entropy(const uint8_t in[], size_t length) override;
+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);
+ }
- std::string name() const override;
+ void randomize(uint8_t buf[], size_t len) override
+ {
+ ::BCryptGenRandom(m_prov, static_cast<PUCHAR>(buf), static_cast<ULONG>(len), 0);
+ }
+ 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 {}
+ std::string name() const override { return "crypto_ng"; }
private:
-#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
- HCRYPTPROV m_prov;
-#else
- int m_fd;
-#endif
+ BCRYPT_ALG_HANDLE m_handle;
};
-std::string System_RNG_Impl::name() const
- {
-#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
- return "cryptoapi";
#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
- return "arc4random";
-#else
- return BOTAN_SYSTEM_RNG_DEVICE;
-#endif
- }
-System_RNG_Impl::System_RNG_Impl()
+class System_RNG_Impl final : public RandomNumberGenerator
{
-#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
+ public:
+ // No constructor or destructor needed as no userland state maintained
- if(!CryptAcquireContext(&m_prov, nullptr, nullptr, BOTAN_SYSTEM_RNG_CRYPTOAPI_PROV_TYPE, CRYPT_VERIFYCONTEXT))
- throw Exception("System_RNG failed to acquire crypto provider");
+ 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 {}
+ std::string name() const override { return "arc4random"; }
+ };
-#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
- // Nothing to do, arc4random(3) works from the beginning.
#else
-#ifndef O_NOCTTY
- #define O_NOCTTY 0
-#endif
+// Read a random device
- 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);
+class System_RNG_Impl final : public RandomNumberGenerator
+ {
+ public:
+ System_RNG_Impl()
+ {
+ #ifndef O_NOCTTY
+ #define O_NOCTTY 0
+ #endif
- if(m_fd < 0)
- throw Exception("System_RNG failed to open RNG device");
-#endif
- }
+ m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR | O_NOCTTY);
-System_RNG_Impl::~System_RNG_Impl()
- {
-#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
- ::CryptReleaseContext(m_prov, 0);
-#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
- // Nothing to do.
-#else
- ::close(m_fd);
- m_fd = -1;
-#endif
- }
+ /*
+ 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);
-void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
- {
-#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
- /*
- There is no explicit ConsumeRandom, but all values provided in
- the call are incorporated into the state.
+ if(m_fd < 0)
+ throw Exception("System_RNG failed to open RNG device");
+ }
- TODO: figure out a way to avoid this copy. Byte at a time updating
- seems worse than the allocation.
+ ~System_RNG_Impl()
+ {
+ ::close(m_fd);
+ m_fd = -1;
+ }
- for(size_t i = 0; i != len; ++i)
- {
- uint8_t b = input[i];
- ::CryptGenRandom(m_prov, 1, &b);
- }
- */
+ 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 {}
+ std::string name() const override { return BOTAN_SYSTEM_RNG_DEVICE; }
+ private:
+ int m_fd;
+ };
- if(len > 0)
+void System_RNG_Impl::randomize(uint8_t buf[], size_t len)
+ {
+ while(len)
{
- secure_vector<uint8_t> buf(input, input + len);
- ::CryptGenRandom(m_prov, static_cast<DWORD>(buf.size()), buf.data());
+ 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;
}
-#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
- // arc4random(3) reseeds itself from the OpenBSD kernel, not from user land.
-#else
+ }
+
+void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
+ {
while(len)
{
ssize_t got = ::write(m_fd, input, len);
@@ -162,34 +221,9 @@ void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
input += got;
len -= got;
}
-#endif
}
-void System_RNG_Impl::randomize(uint8_t buf[], size_t len)
- {
-#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
- ::CryptGenRandom(m_prov, static_cast<DWORD>(len), buf);
-#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
- ::arc4random_buf(buf, len);
-#else
- 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;
- }
#endif
- }
}