From 23d07dae3815879cfdeae63e93613c6e00054a81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrien=20B=C3=A9raud?= <> Date: Sun, 10 Dec 2023 15:15:27 -0500 Subject: [PATCH] rng: drop custom random_device implementation for MinGW/Windows MinGW now has std::random_device support on Windows: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85494 --- include/opendht/crypto.h | 2 +- include/opendht/infohash.h | 2 +- include/opendht/rng.h | 87 +------------------------------------- src/crypto.cpp | 10 ++--- src/dht_proxy_client.cpp | 2 +- src/securedht.cpp | 2 +- tools/dhtchat.cpp | 2 +- 7 files changed, 12 insertions(+), 95 deletions(-) diff --git a/include/opendht/crypto.h b/include/opendht/crypto.h index c93129cd..67c95f1b 100644 --- a/include/opendht/crypto.h +++ b/include/opendht/crypto.h @@ -685,7 +685,7 @@ public: static secure_vector<T> getRandom(size_t size) { secure_vector<T> ret(size); - crypto::random_device rdev; + std::random_device rdev; #ifdef _WIN32 std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint8_t>::max() }; #else diff --git a/include/opendht/infohash.h b/include/opendht/infohash.h index fda05222..29e152a3 100644 --- a/include/opendht/infohash.h +++ b/include/opendht/infohash.h @@ -323,7 +323,7 @@ Hash<N> Hash<N>::getRandom() { Hash h; - crypto::random_device rdev; + std::random_device rdev; std::uniform_int_distribution<uint32_t> rand_int; auto a = reinterpret_cast<uint32_t*>(h.data()); auto b = reinterpret_cast<uint32_t*>(h.data() + h.size()); diff --git a/include/opendht/rng.h b/include/opendht/rng.h index 356c56b9..5c5414e1 100644 --- a/include/opendht/rng.h +++ b/include/opendht/rng.h @@ -27,96 +27,13 @@ namespace dht { namespace crypto { -#ifndef _MSC_VER -#ifdef _WIN32 - -/** - * Hardware random number generator using Intel RDRAND/RDSEED, - * API-compatible with std::random_device. - */ -class random_device { -public: - using result_type = std::random_device::result_type; - using pseudo_engine = std::mt19937_64; - - /** - * Current implementation assumption : result_type must be of a size - * supported by Intel RDRAND/RDSEED. - * result_type is unsigned int so this is currently safe. - */ - static_assert( - sizeof(result_type) == 2 || - sizeof(result_type) == 4 || - sizeof(result_type) == 8, - "result_type must be 16, 32 or 64 bits"); - - random_device(); - - result_type operator()(); - - static constexpr result_type min() { - return std::numeric_limits<result_type>::lowest(); - } - - static constexpr result_type max() { - return std::numeric_limits<result_type>::max(); - } - - double entropy() const { - if (hasRdrand() or hasRdseed()) - return 1.; - return 0.; - } - - static bool hasRdrand() { - static const bool hasrdrand = _hasRdrand(); - return hasrdrand; - } - - static bool hasRdseed() { - static const bool hasrdseed = _hasRdseed(); - return hasrdseed; - } - -private: - random_device& operator=(random_device&) = delete; - - pseudo_engine gen; - std::uniform_int_distribution<result_type> dis {}; - - static bool hasIntelCpu(); - static bool _hasRdrand(); - static bool _hasRdseed(); - - struct CPUIDinfo { - unsigned int EAX; - unsigned int EBX; - unsigned int ECX; - unsigned int EDX; - CPUIDinfo(const unsigned int func, const unsigned int subfunc); - }; - bool rdrandStep(result_type* r); - bool rdrand(result_type* r); - bool rdseedStep(result_type* r); - bool rdseed(result_type* r); -}; - -#else - -using random_device = std::random_device; - -#endif -#else -using random_device = std::random_device; -#endif - /** * Generate a seeded random engine. */ template<class T = std::mt19937, std::size_t N = T::state_size+1> auto getSeededRandomEngine() -> typename std::enable_if<!!N, T>::type { std::array<typename T::result_type, N> random_data; - constexpr auto gen = [](random_device& source) -> typename T::result_type { + constexpr auto gen = [](std::random_device& source) -> typename T::result_type { for (unsigned j=0; j<64; j++) { try { return source(); @@ -128,7 +45,7 @@ auto getSeededRandomEngine() -> typename std::enable_if<!!N, T>::type { }; for (unsigned i=0; i<8; i++) { try { - random_device source; + std::random_device source; for (auto& r : random_data) r = gen(source); std::seed_seq seed( diff --git a/src/crypto.cpp b/src/crypto.cpp index e097a2d9..4b6ee226 100644 --- a/src/crypto.cpp +++ b/src/crypto.cpp @@ -92,7 +92,7 @@ Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key) Blob ret(data_length + GCM_IV_SIZE + GCM_DIGEST_SIZE); { - crypto::random_device rdev; + std::random_device rdev; std::generate_n(ret.begin(), GCM_IV_SIZE, std::bind(rand_byte, std::ref(rdev))); } struct gcm_aes_ctx aes; @@ -191,7 +191,7 @@ Blob stretchKey(std::string_view password, Blob& salt, size_t key_length) { if (salt.empty()) { salt.resize(PASSWORD_SALT_LENGTH); - crypto::random_device rdev; + std::random_device rdev; std::generate_n(salt.begin(), salt.size(), std::bind(rand_byte, std::ref(rdev))); } Blob res; @@ -539,7 +539,7 @@ PublicKey::encrypt(const uint8_t* data, size_t data_len) const throw CryptoException("Key is not long enough for AES128"); Blob key(aes_key_sz); { - crypto::random_device rdev; + std::random_device rdev; std::generate_n(key.begin(), key.size(), std::bind(rand_byte, std::ref(rdev))); } auto data_encrypted = aesEncrypt(data, data_len, key); @@ -1193,7 +1193,7 @@ setValidityPeriod(gnutls_x509_crt_t cert, int64_t validity) void setRandomSerial(gnutls_x509_crt_t cert) { - random_device rdev; + std::random_device rdev; std::uniform_int_distribution<int64_t> dist{1}; int64_t cert_serial = dist(rdev); gnutls_x509_crt_set_serial(cert, &cert_serial, sizeof(cert_serial)); @@ -1666,7 +1666,7 @@ RevocationList::sign(const PrivateKey& key, const Certificate& ca, duration vali if (number == 0) { // initialize to a random number number_sz = sizeof(number); - random_device rdev; + std::random_device rdev; std::generate_n((uint8_t*)&number, sizeof(number), std::bind(rand_byte, std::ref(rdev))); } else number = endian(endian(number) + 1); diff --git a/src/dht_proxy_client.cpp b/src/dht_proxy_client.cpp index e70615fd..d054423a 100644 --- a/src/dht_proxy_client.cpp +++ b/src/dht_proxy_client.cpp @@ -98,7 +98,7 @@ std::string getRandomSessionId(size_t length = 8) { static constexpr const char chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~"; std::string str(length, 0); - crypto::random_device rdev; + std::random_device rdev; std::uniform_int_distribution<> dist(0, (sizeof(chars)/sizeof(char)) - 2); std::generate_n( str.begin(), length, [&]{ return chars[dist(rdev)]; } ); return str; diff --git a/src/securedht.cpp b/src/securedht.cpp index f7e145ad..9aca9fb4 100644 --- a/src/securedht.cpp +++ b/src/securedht.cpp @@ -337,7 +337,7 @@ SecureDht::putSigned(const InfoHash& hash, Sp<Value> val, DoneCallback callback, return; } if (val->id == Value::INVALID_ID) { - crypto::random_device rdev; + std::random_device rdev; std::uniform_int_distribution<Value::Id> rand_id; val->id = rand_id(rdev); } diff --git a/tools/dhtchat.cpp b/tools/dhtchat.cpp index c4590026..a1c6d8d4 100644 --- a/tools/dhtchat.cpp +++ b/tools/dhtchat.cpp @@ -30,7 +30,7 @@ extern "C" { using namespace dht; -static std::mt19937_64 rd {dht::crypto::random_device{}()}; +static std::mt19937_64 rd {dht::crypto::getSeededRandomEngine<std::mt19937_64>()}; static std::uniform_int_distribution<dht::Value::Id> rand_id; const std::string printTime(const std::time_t& now) { -- GitLab