aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlexander Bluhm <[email protected]>2017-03-30 17:12:15 +0200
committerAlexander Bluhm <[email protected]>2017-03-30 17:33:26 +0200
commitda2e1a873b732f9a0de2821c526e60de13cf4e9d (patch)
tree60c9527878d4f9e003a36de380f947942aa0fb49 /src
parentd218baa7722f6e8e216a9127cbd577e305d4a490 (diff)
Use arc4random(3) as system rng on OpenBSD.
OpenBSD provides the arc4random(3) function in libc for user land programs that need good random data. Use this to implement the Botan system random number generator. It has the advantage over /dev/urandom that it works without file descriptors and in chroot(2) environment. Internally libc is currently using a ChaCha20 cipher as PRNG and getentropy(2) to reseed itself automatically.
Diffstat (limited to 'src')
-rw-r--r--src/build-data/os/openbsd.txt1
-rw-r--r--src/lib/rng/system_rng/system_rng.cpp15
2 files changed, 16 insertions, 0 deletions
diff --git a/src/build-data/os/openbsd.txt b/src/build-data/os/openbsd.txt
index 89d291ddc..632879381 100644
--- a/src/build-data/os/openbsd.txt
+++ b/src/build-data/os/openbsd.txt
@@ -5,6 +5,7 @@ soname_pattern_abi "libbotan-{version_major}.so.{abi_rev}"
soname_pattern_patch "libbotan-{version_major}.so.{abi_rev}.{version_minor}"
<target_features>
+arc4random
clock_gettime
gettimeofday
posix_mlock
diff --git a/src/lib/rng/system_rng/system_rng.cpp b/src/lib/rng/system_rng/system_rng.cpp
index 12b087661..ed0cc3d2e 100644
--- a/src/lib/rng/system_rng/system_rng.cpp
+++ b/src/lib/rng/system_rng/system_rng.cpp
@@ -6,6 +6,7 @@
*/
#include <botan/system_rng.h>
+#include <botan/build.h>
#if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
@@ -13,6 +14,10 @@
#define NOMINMAX 1
#include <wincrypt.h>
+#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
+
+#include <stdlib.h>
+
#else
#include <sys/types.h>
@@ -55,6 +60,8 @@ 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
@@ -67,6 +74,8 @@ System_RNG_Impl::System_RNG_Impl()
if(!CryptAcquireContext(&m_prov, 0, 0, BOTAN_SYSTEM_RNG_CRYPTOAPI_PROV_TYPE, CRYPT_VERIFYCONTEXT))
throw Exception("System_RNG failed to acquire crypto provider");
+#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
+ // Nothing to do, arc4random(3) works from the beginning.
#else
#ifndef O_NOCTTY
@@ -89,6 +98,8 @@ 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;
@@ -117,6 +128,8 @@ void System_RNG_Impl::add_entropy(const uint8_t input[], size_t len)
secure_vector<uint8_t> buf(input, input + len);
::CryptGenRandom(m_prov, static_cast<DWORD>(buf.size()), buf.data());
}
+#elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
+ // arc4random(3) reseeds itself from the OpenBSD kernel, not from user land.
#else
while(len)
{
@@ -156,6 +169,8 @@ 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)
{