8 #include <botan/system_rng.h> 10 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) 12 #define _WINSOCKAPI_ // stop windows.h including winsock.h 16 #elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG) 19 #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM) 23 #include <sys/types.h> 34 #if defined(BOTAN_TARGET_OS_HAS_CRYPTGENRANDOM) 36 class System_RNG_Impl final :
public RandomNumberGenerator
41 if(!CryptAcquireContext(&m_prov,
nullptr,
nullptr,
42 BOTAN_SYSTEM_RNG_CRYPTOAPI_PROV_TYPE, CRYPT_VERIFYCONTEXT))
43 throw Exception(
"System_RNG failed to acquire crypto provider");
48 ::CryptReleaseContext(m_prov, 0);
51 void randomize(uint8_t buf[],
size_t len)
override 53 ::CryptGenRandom(m_prov, static_cast<DWORD>(len), buf);
56 void add_entropy(
const uint8_t in[],
size_t length)
override 62 std::vector<uint8_t> buf(in, in + length);
63 ::CryptGenRandom(m_prov, static_cast<DWORD>(buf.size()), buf.data());
66 bool is_seeded()
const override {
return true; }
67 void clear()
override { }
68 std::string name()
const override {
return "cryptoapi"; }
73 #elif defined(BOTAN_TARGET_OS_HAS_CRYPTO_NG) 75 class System_RNG_Impl final :
public RandomNumberGenerator
80 NTSTATUS ret = ::BCryptOpenAlgorithmProvider(&m_prov,
82 MS_PRIMITIVE_PROVIDER, 0);
83 if(ret != STATUS_SUCCESS)
84 throw Exception(
"System_RNG failed to acquire crypto provider");
89 ::BCryptCloseAlgorithmProvider(m_prov, 0);
92 void randomize(uint8_t buf[],
size_t len)
override 94 ::BCryptGenRandom(m_prov, static_cast<PUCHAR>(buf), static_cast<ULONG>(len), 0);
97 void add_entropy(
const uint8_t in[],
size_t length)
override 105 bool is_seeded()
const override {
return true; }
106 void clear()
override { }
107 std::string name()
const override {
return "crypto_ng"; }
109 BCRYPT_ALG_HANDLE m_handle;
112 #elif defined(BOTAN_TARGET_OS_HAS_ARC4RANDOM) 114 class System_RNG_Impl final :
public RandomNumberGenerator
119 void randomize(uint8_t buf[],
size_t len)
override 121 ::arc4random_buf(buf, len);
124 void add_entropy(
const uint8_t[],
size_t)
override { }
125 bool is_seeded()
const override {
return true; }
126 void clear()
override { }
127 std::string name()
const override {
return "arc4random"; }
134 class System_RNG_Impl final :
public RandomNumberGenerator
143 m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDWR |
O_NOCTTY);
150 m_fd = ::open(BOTAN_SYSTEM_RNG_DEVICE, O_RDONLY |
O_NOCTTY);
153 throw Exception(
"System_RNG failed to open RNG device");
162 void randomize(uint8_t buf[],
size_t len)
override;
163 void add_entropy(
const uint8_t in[],
size_t length)
override;
164 bool is_seeded()
const override {
return true; }
165 void clear()
override { }
166 std::string name()
const override {
return BOTAN_SYSTEM_RNG_DEVICE; }
171 void System_RNG_Impl::randomize(uint8_t buf[],
size_t len)
175 ssize_t got = ::read(m_fd, buf, len);
181 throw Exception(
"System_RNG read failed error " +
std::to_string(errno));
184 throw Exception(
"System_RNG EOF on device");
191 void System_RNG_Impl::add_entropy(
const uint8_t input[],
size_t len)
195 ssize_t got = ::write(m_fd, input, len);
214 if(errno == EPERM || errno == EBADF)
218 throw Exception(
"System_RNG write failed error " +
std::to_string(errno));
232 static System_RNG_Impl g_system_rng;
RandomNumberGenerator & system_rng()
std::string to_string(const BER_Object &obj)