8 #include <botan/system_rng.h>
9 #include <botan/build.h>
11 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
17 #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
23 #include <sys/types.h>
35 class System_RNG_Impl final :
public RandomNumberGenerator
41 bool is_seeded()
const override {
return true; }
43 void clear()
override {}
45 void randomize(uint8_t out[],
size_t len)
override;
47 void add_entropy(
const uint8_t in[],
size_t length)
override;
49 std::string name()
const override;
52 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
59 std::string System_RNG_Impl::name()
const
61 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
63 #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
66 return BOTAN_SYSTEM_RNG_DEVICE;
70 System_RNG_Impl::System_RNG_Impl()
72 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
74 if(!CryptAcquireContext(&m_prov, 0, 0, BOTAN_SYSTEM_RNG_CRYPTOAPI_PROV_TYPE, CRYPT_VERIFYCONTEXT))
75 throw Exception(
"System_RNG failed to acquire crypto provider");
77 #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
85 m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR |
O_NOCTTY);
90 m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY |
O_NOCTTY);
93 throw Exception(
"System_RNG failed to open RNG device");
97 System_RNG_Impl::~System_RNG_Impl()
99 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
100 ::CryptReleaseContext(m_prov, 0);
101 #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
109 void System_RNG_Impl::add_entropy(
const uint8_t input[],
size_t len)
111 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
128 secure_vector<uint8_t> buf(input, input + len);
129 ::CryptGenRandom(m_prov, static_cast<DWORD>(buf.size()), buf.data());
131 #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
136 ssize_t got = ::write(
m_fd, input, len);
155 if(errno == EPERM || errno == EBADF)
159 throw Exception(
"System_RNG write failed error " +
std::to_string(errno));
168 void System_RNG_Impl::randomize(uint8_t buf[],
size_t len)
170 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM)
171 ::CryptGenRandom(m_prov, static_cast<DWORD>(len), buf);
172 #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM)
173 ::arc4random_buf(buf, len);
177 ssize_t got = ::read(
m_fd, buf, len);
183 throw Exception(
"System_RNG read failed error " +
std::to_string(errno));
186 throw Exception(
"System_RNG EOF on device");
198 static System_RNG_Impl g_system_rng;
std::string to_string(const BER_Object &obj)
RandomNumberGenerator & system_rng()