Compare commits

...
13 Commits
Author SHA1 Message Date
Adrien Béraud 88d15be4ea build: update version to 3.1.7 2024-01-02 16:25:16 -05:00
Adrien Béraud 0c4942439b move secure_vector to its own file 2024-01-02 16:22:02 -05:00
Adrien Béraud b03df3f7a6 aesEncrypt: allow to provide salt 2024-01-02 15:18:44 -05:00
Adrien Béraud 6a6816ada7 build/meson: allow to build c binding 2023-12-11 22:16:58 -05:00
Adrien Béraud 372c87ac12 build: remove rng.cpp 2023-12-11 21:18:15 -05:00
Adrien Béraud 728c99999f getDerivedRandomEngine: use 32 bit input for std::seed_seq 2023-12-11 21:12:50 -05:00
Adrien Béraud 2017473156 build: update version to 3.1.6 2023-12-11 09:57:51 -05:00
Adrien Béraud 08d6367fdc pht: move to std::random_device 2023-12-10 16:02:56 -05:00
Adrien Béraud 23d07dae38 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
2023-12-10 15:18:59 -05:00
Adrien Béraud 29c83d9c97 rng: improve getSeededRandomEngine
* Make sure to use 32 bit input for std::seed_seq
* Retry using random device every use
* Adjust delays and retry count to keep approx. the same max timeout.
 In practice the actual average timeout should be reduced, because
 the algo doesn't lose existing data and can move forward in case
 of occasional failure/retry.
2023-12-10 15:07:39 -05:00
Adrien Béraud abbc77744e dhtrunner: allow to configure rng used by the dht 2023-12-10 15:07:39 -05:00
Adrien Béraud 7a61fa371f dht: allow to provide rng to constructor 2023-12-10 15:06:51 -05:00
Adrien Béraud ce7f592b1c search: return if added node is actually removed 2023-12-08 11:02:21 -05:00
20 changed files with 210 additions and 330 deletions

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@ include(cmake/CheckAtomic.cmake)
include(CTest)
set (opendht_VERSION_MAJOR 3)
set (opendht_VERSION_MINOR 1.4)
set (opendht_VERSION_MINOR 1.7)
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
set (PACKAGE_VERSION ${opendht_VERSION})
set (VERSION "${opendht_VERSION}")
+1 -1
View File
@@ -1,7 +1,7 @@
dnl define macros
m4_define([opendht_major_version], 3)
m4_define([opendht_minor_version], 1)
m4_define([opendht_patch_version], 4)
m4_define([opendht_patch_version], 7)
m4_define([opendht_version],
[opendht_major_version.opendht_minor_version.opendht_patch_version])
+4 -89
View File
@@ -670,94 +670,6 @@ private:
gnutls_x509_trust_list_t trust {nullptr};
};
template <class T>
class OPENDHT_PUBLIC secure_vector
{
public:
secure_vector() {}
secure_vector(secure_vector<T> const&) = default;
secure_vector(secure_vector<T> &&) = default;
explicit secure_vector(unsigned size): data_(size) {}
explicit secure_vector(unsigned size, T _item): data_(size, _item) {}
explicit secure_vector(const std::vector<T>& c): data_(c) {}
secure_vector(std::vector<T>&& c): data_(std::move(c)) {}
~secure_vector() { clean(); }
static secure_vector<T> getRandom(size_t size) {
secure_vector<T> ret(size);
crypto::random_device rdev;
#ifdef _WIN32
std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint8_t>::max() };
#else
std::uniform_int_distribution<uint8_t> rand_byte;
#endif
std::generate_n((uint8_t*)ret.data_.data(), ret.size()*sizeof(T), std::bind(rand_byte, std::ref(rdev)));
return ret;
}
secure_vector<T>& operator=(const secure_vector<T>& c) {
if (&c == this)
return *this;
clean();
data_ = c.data_;
return *this;
}
secure_vector<T>& operator=(secure_vector<T>&& c) {
if (&c == this)
return *this;
clean();
data_ = std::move(c.data_);
return *this;
}
secure_vector<T>& operator=(std::vector<T>&& c) {
clean();
data_ = std::move(c);
return *this;
}
std::vector<T>& writable() { clean(); return data_; }
const std::vector<T>& makeInsecure() const { return data_; }
const uint8_t* data() const { return data_.data(); }
void clean() {
clean(data_.begin(), data_.end());
}
void clear() { clean(); data_.clear(); }
size_t size() const { return data_.size(); }
bool empty() const { return data_.empty(); }
void swap(secure_vector<T>& other) { data_.swap(other.data_); }
void resize(size_t s) {
if (s == data_.size()) return;
if (s < data_.size()) {
//shrink
clean(data_.begin()+s, data_.end());
data_.resize(s);
} else {
//grow
auto data = std::move(data_); // move protected data
clear();
data_.resize(s);
std::copy(data.begin(), data.end(), data_.begin());
clean(data.begin(), data.end());
}
}
private:
/**
* Securely wipe memory
*/
static void clean(const typename std::vector<T>::iterator& i, const typename std::vector<T>::iterator& j) {
volatile uint8_t* b = reinterpret_cast<uint8_t*>(&*i);
volatile uint8_t* e = reinterpret_cast<uint8_t*>(&*j);
std::fill(b, e, 0);
}
std::vector<T> data_;
};
using SecureBlob = secure_vector<uint8_t>;
/**
* Generate an RSA key pair (4096 bits) and a certificate.
* @param name the name used in the generated certificate
@@ -807,8 +719,11 @@ OPENDHT_PUBLIC inline Blob aesEncrypt(const Blob& data, const Blob& key) {
* This function uses `stretchKey` to generate an AES key from the password and a random salt.
* The result is a bundle including the salt that can be decrypted with `aesDecrypt(data, password)`.
* If needed, the salt or encrypted data can be individually extracted from the bundle with `aesGetSalt` and `aesGetEncrypted`.
* @param data: data to encrypt
* @param password: password to encrypt the data with
* @param salt: optional salt to use for key derivation. If not provided, a random salt will be generated.
*/
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, std::string_view password);
OPENDHT_PUBLIC Blob aesEncrypt(const Blob& data, std::string_view password, const Blob& salt = {});
/**
* AES-GCM decryption.
+114
View File
@@ -0,0 +1,114 @@
/*
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#pragma once
#include <vector>
#include <random>
namespace dht {
namespace crypto {
template <class T>
class secure_vector
{
public:
secure_vector() {}
secure_vector(secure_vector<T> const&) = default;
secure_vector(secure_vector<T> &&) = default;
explicit secure_vector(unsigned size): data_(size) {}
explicit secure_vector(unsigned size, T _item): data_(size, _item) {}
explicit secure_vector(const std::vector<T>& c): data_(c) {}
secure_vector(std::vector<T>&& c): data_(std::move(c)) {}
~secure_vector() { clean(); }
static secure_vector<T> getRandom(size_t size) {
secure_vector<T> ret(size);
std::random_device rdev;
#ifdef _WIN32
std::uniform_int_distribution<int> rand_byte{ 0, std::numeric_limits<uint8_t>::max() };
#else
std::uniform_int_distribution<uint8_t> rand_byte;
#endif
std::generate_n((uint8_t*)ret.data_.data(), ret.size()*sizeof(T), std::bind(rand_byte, std::ref(rdev)));
return ret;
}
secure_vector<T>& operator=(const secure_vector<T>& c) {
if (&c == this)
return *this;
clean();
data_ = c.data_;
return *this;
}
secure_vector<T>& operator=(secure_vector<T>&& c) {
if (&c == this)
return *this;
clean();
data_ = std::move(c.data_);
return *this;
}
secure_vector<T>& operator=(std::vector<T>&& c) {
clean();
data_ = std::move(c);
return *this;
}
std::vector<T>& writable() { clean(); return data_; }
const std::vector<T>& makeInsecure() const { return data_; }
const uint8_t* data() const { return data_.data(); }
void clean() {
clean(data_.begin(), data_.end());
}
void clear() { clean(); data_.clear(); }
size_t size() const { return data_.size(); }
bool empty() const { return data_.empty(); }
void swap(secure_vector<T>& other) { data_.swap(other.data_); }
void resize(size_t s) {
if (s == data_.size()) return;
if (s < data_.size()) {
//shrink
clean(data_.begin()+s, data_.end());
data_.resize(s);
} else {
//grow
auto data = std::move(data_); // move protected data
clear();
data_.resize(s);
std::copy(data.begin(), data.end(), data_.begin());
clean(data.begin(), data.end());
}
}
private:
/**
* Securely wipe memory
*/
static void clean(const typename std::vector<T>::iterator& i, const typename std::vector<T>::iterator& j) {
volatile uint8_t* b = reinterpret_cast<uint8_t*>(&*i);
volatile uint8_t* e = reinterpret_cast<uint8_t*>(&*j);
std::fill(b, e, 0);
}
std::vector<T> data_;
};
using SecureBlob = secure_vector<uint8_t>;
}
}
+2 -2
View File
@@ -65,7 +65,7 @@ public:
* Initialise the Dht with two open sockets (for IPv4 and IP6)
* and an ID for the node.
*/
Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Sp<Logger>& l = {});
Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Sp<Logger>& l = {}, std::unique_ptr<std::mt19937_64>&& rd = {});
virtual ~Dht();
@@ -372,7 +372,7 @@ private:
Dht(const Dht&) = delete;
Dht& operator=(const Dht&) = delete;
std::mt19937_64 rd {crypto::getSeededRandomEngine<std::mt19937_64>()};
std::mt19937_64 rd;
InfoHash myid {};
+1
View File
@@ -79,6 +79,7 @@ public:
CertificateStoreQuery certificateStore {};
IdentityAnnouncedCb identityAnnouncedCb {};
PublicAddressChangedCb publicAddressChangedCb {};
std::unique_ptr<std::mt19937_64> rng {};
Context() {}
};
+1 -1
View File
@@ -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());
+37 -92
View File
@@ -27,104 +27,49 @@
namespace dht {
namespace crypto {
#ifndef _MSC_VER
#ifdef _WIN32
/**
* Hardware random number generator using Intel RDRAND/RDSEED,
* API-compatible with std::random_device.
/**
* Generate a seeded random engine.
*/
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);
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 = [](std::random_device& source) -> typename T::result_type {
for (unsigned j=0; j<64; j++) {
try {
return source();
} catch (...) {
std::this_thread::sleep_for(std::chrono::microseconds(500));
}
}
throw std::runtime_error("Can't generate random number");
};
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
template<class T = std::mt19937, std::size_t N = T::state_size>
auto getSeededRandomEngine () -> typename std::enable_if<!!N, T>::type {
typename T::result_type random_data[N];
for (unsigned i=0; i<256; i++) {
for (unsigned i=0; i<8; i++) {
try {
random_device source;
std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
std::seed_seq seeds(std::begin(random_data), std::end(random_data));
T seededEngine (seeds);
return seededEngine;
std::random_device source;
for (auto& r : random_data)
r = gen(source);
std::seed_seq seed(
(std::seed_seq::result_type*)random_data.data(),
(std::seed_seq::result_type*)(random_data.data() + random_data.size()));
return T(seed);
} catch (...) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
std::this_thread::sleep_for(std::chrono::microseconds(500));
}
}
throw std::runtime_error("Can't seed random engine");
throw std::runtime_error("Can't seed random seed");
}
/**
* Generate a random engine from another source.
*/
template<class T = std::mt19937, std::size_t N = T::state_size+1>
auto getDerivedRandomEngine(T& source) -> typename std::enable_if<!!N, T>::type {
std::array<typename T::result_type, N> random_data;
std::generate(random_data.begin(), random_data.end(), std::ref(source));
std::seed_seq seed(
(std::seed_seq::result_type*)random_data.data(),
(std::seed_seq::result_type*)(random_data.data() + random_data.size()));
return T(seed);
}
}} // dht::crypto
+26 -7
View File
@@ -1,5 +1,5 @@
project('opendht', 'c', 'cpp',
version: '3.1.4',
version: '3.1.7',
default_options: [
'cpp_std=c++17',
'warning_level=3'
@@ -74,26 +74,45 @@ opendht = shared_library('opendht',
install : true)
readline = meson.get_compiler('c').find_library('readline', required: get_option('tools'))
if get_option('c').enabled()
opendht_c = shared_library('opendht-c',
['c/opendht.cpp', 'c/opendht_c.h'],
include_directories : opendht_interface_inc,
link_with : opendht,
dependencies : [msgpack, fmt],
cpp_args : ['-DOPENDHT_C_BUILD', '-Dopendht_c_EXPORTS'],
install : true)
if get_option('tools').enabled()
dhtcnode = executable('dhtcnode', 'tools/dhtcnode.c',
include_directories : ['c', opendht_interface_inc],
link_with : opendht_c,
dependencies : [readline],
install : true)
endif
endif
if get_option('tools').enabled()
dhtnode = executable('dhtnode', 'tools/dhtnode.cpp',
include_directories : opendht_interface_inc,
link_with : opendht,
dependencies : [readline, msgpack, fmt],
dependencies : [readline, msgpack, fmt, openssl],
install : true)
dhtchat = executable('dhtchat', 'tools/dhtchat.cpp',
include_directories : opendht_interface_inc,
link_with : opendht,
dependencies : [readline, msgpack, fmt],
dependencies : [readline, msgpack, fmt, openssl],
install : true)
dhtscanner = executable('dhtscanner', 'tools/dhtscanner.cpp',
include_directories : opendht_interface_inc,
link_with : opendht,
dependencies : [readline, msgpack, fmt],
dependencies : [readline, msgpack, fmt, openssl],
install : true)
if http_parser.found()
durl = executable('durl', 'tools/durl.cpp',
include_directories : opendht_interface_inc,
link_with : opendht,
dependencies : [msgpack, openssl])
include_directories : opendht_interface_inc,
link_with : opendht,
dependencies : [msgpack, openssl])
endif
endif
+1
View File
@@ -2,3 +2,4 @@ option('proxy_client', type : 'feature', value : 'disabled')
option('proxy_server', type : 'feature', value : 'disabled')
option('peer_discovery', type : 'feature', value : 'enabled')
option('tools', type : 'feature', value : 'enabled')
option('c', type : 'feature', value : 'enabled')
-4
View File
@@ -29,10 +29,6 @@ libopendht_la_SOURCES = \
network_utils.cpp \
thread_pool.cpp
if WIN32
libopendht_la_SOURCES += rng.cpp
endif
nobase_include_HEADERS = \
../include/opendht.h \
../include/opendht/def.h \
+9 -9
View File
@@ -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;
@@ -103,11 +103,11 @@ Blob aesEncrypt(const uint8_t* data, size_t data_length, const Blob& key)
return ret;
}
Blob aesEncrypt(const Blob& data, std::string_view password)
Blob aesEncrypt(const Blob& data, std::string_view password, const Blob& salt)
{
Blob salt;
Blob key = stretchKey(password, salt, 256 / 8);
return aesBuildEncrypted(aesEncrypt(data, key), salt);
Blob salt_actual = salt;
Blob key = stretchKey(password, salt_actual, 256 / 8);
return aesBuildEncrypted(aesEncrypt(data, key), salt_actual);
}
Blob aesDecrypt(const uint8_t* data, size_t data_length, const Blob& key)
@@ -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);
+2 -1
View File
@@ -1815,8 +1815,9 @@ fromDhtConfig(const Config& config)
return netConf;
}
Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Sp<Logger>& l)
Dht::Dht(std::unique_ptr<net::DatagramSocket>&& sock, const Config& config, const Sp<Logger>& l, std::unique_ptr<std::mt19937_64>&& rda)
: DhtInterface(l),
rd(rda ? std::move(*rda) : crypto::getSeededRandomEngine<std::mt19937_64>()),
myid(config.node_id ? config.node_id : InfoHash::getRandom(rd)),
store(),
store_quota(),
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -167,7 +167,7 @@ DhtRunner::run(const Config& config, Context&& context)
outConfig << context.sock->getBoundRef(AF_INET).getPort() << std::endl;
outConfig << context.sock->getBoundRef(AF_INET6).getPort() << std::endl;
}
auto dht = std::make_unique<Dht>(std::move(context.sock), SecureDht::getConfig(config.dht_config), context.logger);
auto dht = std::make_unique<Dht>(std::move(context.sock), SecureDht::getConfig(config.dht_config), context.logger, std::move(context.rng));
dht_ = std::make_unique<SecureDht>(std::move(dht), config.dht_config, std::move(context.identityAnnouncedCb), context.logger);
} else {
enableProxy(true);
+1 -1
View File
@@ -316,7 +316,7 @@ void Pht::updateCanary(Prefix p) {
dht_->put(p.hash(), std::move(canary_value),
[=](bool){
static std::bernoulli_distribution d(0.5);
crypto::random_device rd;
std::random_device rd;
if (p.size_ and d(rd))
updateCanary(p.getPrefix(-1));
}
-117
View File
@@ -1,117 +0,0 @@
/*
* Copyright (C) 2014-2023 Savoir-faire Linux Inc.
* Author : Adrien Béraud <adrien.beraud@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "rng.h"
#include <chrono>
#include <cstring>
namespace dht {
namespace crypto {
random_device::random_device() :
gen(std::chrono::system_clock::now().time_since_epoch().count() ^ std::chrono::high_resolution_clock::now().count())
{}
random_device::result_type
random_device::operator()()
{
result_type prand = dis(gen);
result_type hwrand;
if (hasRdseed() and rdseed(&hwrand))
prand ^= hwrand;
else if (hasRdrand() and rdrand(&hwrand))
prand ^= hwrand;
return prand;
}
random_device::CPUIDinfo::CPUIDinfo(const unsigned int func, const unsigned int subfunc)
{
__asm__ __volatile__ (
"cpuid"
: "=a"(EAX), "=b"(EBX), "=c"(ECX), "=d"(EDX)
: "a"(func), "c"(subfunc)
);
}
bool
random_device::hasIntelCpu()
{
CPUIDinfo info (0, 0);
return (memcmp((char *) (&info.EBX), "Genu", 4) == 0
&& memcmp((char *) (&info.EDX), "ineI", 4) == 0
&& memcmp((char *) (&info.ECX), "ntel", 4) == 0);
}
bool
random_device::_hasRdrand()
{
return hasIntelCpu() && (CPUIDinfo {1, 0}.ECX & (1 << 30));
}
bool
random_device::_hasRdseed()
{
return hasIntelCpu() && (CPUIDinfo {7, 0}.ECX & (1 << 18));
}
bool
random_device::rdrandStep(result_type* r)
{
unsigned char ok;
asm volatile ("rdrand %0; setc %1"
: "=r" (*r), "=qm" (ok));
return ok;
}
bool
random_device::rdrand(result_type* r)
{
result_type res;
unsigned retries = 8;
while (retries--)
if (rdrandStep(&res)) {
*r = res;
return true;
}
return false;
}
bool
random_device::rdseedStep(result_type* r)
{
unsigned char ok;
asm volatile ("rdseed %0; setc %1"
: "=r" (*r), "=qm" (ok));
return ok;
}
bool
random_device::rdseed(result_type* r)
{
result_type res;
unsigned retries = 256;
while (retries--)
if (rdseedStep(&res)) {
*r = res;
return true;
}
return false;
}
}}
+6 -1
View File
@@ -854,12 +854,17 @@ Dht::Search::insertNode(const Sp<Node>& snode, time_point now, const Blob& token
expired = false;
}
while (nodes.size() - bad > SEARCH_NODES) {
while (nodes.size() - bad > SEARCH_NODES) {
bool removingNode = nodes.back()->node == snode;
if (not expired and nodes.back()->isBad())
bad--;
nodes.pop_back();
if (removingNode)
return false;
}
}
if (n == nodes.end() or not *n)
return false;
if (not token.empty()) {
(*n)->candidate = false;
(*n)->last_get_reply = now;
+1 -1
View File
@@ -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);
}
+1 -1
View File
@@ -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) {