forked from ak-fortuna/fortuna
feat: "prepare to add proper entropy source" nits
general * make greater use of "this" Fortuna * declare da_pools as a proper std::array of 32 Pool objects * declare da_pools as const * use std::shared_ptr _p_pools to access da_pools and share access to it * reflect change of pools[] -> std::array in how the array elements are accessed, which is a) via _p_pools pointer and b) using ".at(i)" function * pass _p_pools shared_ptr to Accumulator * refactor member function names and variable names * add member function attribute [[optimize_for_synchronized]] * secure conversions with static_cast-s Accumulator * make use of _p_pools * add _p_pools-related member functions * add a static constexpr variable NUM_OF_POOLS UrandomEntropySrc * implement event adding logic using _p_pools * make std::vector<char> non-static in urandom_entropy_src * implement proper urandom entropy source event "sourcing" (from /dev/urandom), event adding, clear bytes array at the end * properly convert using reinterpret_cast * protect access to the main function with std::lock_guard * receive EventAdderImpl as a ref * use return value from "add_entropy()" member function and create sanity guard checking the return code "int ret" EventAdder * pass event (std::vector<char>) by const& EventAdderImpl * make use of _p_pools shared_ptr * implement proper pool-rotating event-adding logic Pool * delete all copy constructors and assignment operator, the objects will not be copied or assigned to * receive parameters by const& where possible/sensible * handle concurrency: * declare std:string s as mutable * declare a rw std::mutex intended for writing and mutable std::recursive_mutex for read-only operations in const member functions ref: https://herbsutter.com/2013/05/24/gotw-6a-const-correctness-part-1-3/ ref: https://arne-mertz.de/2017/10/mutable/ * use std::lock_guard and std::unique_lock * refactor "add_entropy()" member function * get rid of intermediate "event_str" and directly use the "event" std::vector<char> for all operations * add a lock guard to prevent multiple threads (should that route be taken) from modifying pool resources simultaneously * add all_ok bool for basic sanity checking * add print statements (at least for now) * rename "get_s_length()" member function to "get_s_byte_count()" and repurpose it to return byte count of the stored entropy std::string s
This commit is contained in:
parent
e899c03da2
commit
d404681889
|
@ -2,12 +2,15 @@
|
|||
#define FORTUNA_ACCUMULATOR_CPP
|
||||
|
||||
#include "accumulator.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
|
@ -20,10 +23,20 @@ auto wait_for(const unsigned int& milliseconds) -> void {
|
|||
|
||||
Accumulator::Accumulator() noexcept {
|
||||
this->Gen = nullptr;
|
||||
this->_p_pools = nullptr;
|
||||
}
|
||||
Accumulator::~Accumulator() noexcept {}
|
||||
|
||||
|
||||
auto Accumulator::_p_pools_equal(
|
||||
std::shared_ptr<std::array<accumulator::Pool, Accumulator::NUM_OF_POOLS>>
|
||||
p_pools) const -> bool {
|
||||
if (this->_p_pools == p_pools) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if given source id is an id of an already registered entropy source
|
||||
auto Accumulator::src_is_registered(const uint8_t& id) -> bool {
|
||||
bool reg{false};
|
||||
|
@ -46,6 +59,12 @@ auto Accumulator::src_is_registered(const uint8_t& id) -> bool {
|
|||
return false;
|
||||
}
|
||||
|
||||
auto Accumulator::set_pools_ptr(
|
||||
std::shared_ptr<std::array<accumulator::Pool, Accumulator::NUM_OF_POOLS>>
|
||||
p_pools) -> void {
|
||||
this->_p_pools = p_pools;
|
||||
}
|
||||
|
||||
auto Accumulator::set_gen(fortuna::generator::Generator& gen) -> void {
|
||||
// this->Gen = std::move(&gen); // TODO(me): does this make sense?
|
||||
this->Gen = &gen;
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
#include <fmt/core.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <exception>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace fortuna {
|
||||
|
@ -18,8 +20,12 @@ namespace accumulator {
|
|||
class Accumulator {
|
||||
private:
|
||||
static constexpr const uint8_t MAX_SOURCES{255};
|
||||
static constexpr const uint8_t NUM_OF_POOLS{32};
|
||||
|
||||
std::vector<uint8_t> entropy_sources{};
|
||||
fortuna::generator::Generator* Gen;
|
||||
std::shared_ptr<std::array<accumulator::Pool, Accumulator::NUM_OF_POOLS>>
|
||||
_p_pools;
|
||||
|
||||
protected:
|
||||
unsigned int src_count{0};
|
||||
|
@ -27,6 +33,11 @@ protected:
|
|||
public:
|
||||
constexpr static const unsigned int init_pool_num{0};
|
||||
|
||||
auto _p_pools_equal(
|
||||
std::shared_ptr<std::array<accumulator::Pool,
|
||||
Accumulator::NUM_OF_POOLS>> p_pools) const
|
||||
-> bool;
|
||||
|
||||
[[maybe_unused]] auto add_source() -> void {
|
||||
static unsigned int src_id{this->src_count};
|
||||
// make really sure we don't add a duplicate src_id
|
||||
|
@ -35,8 +46,7 @@ public:
|
|||
try {
|
||||
entropy_sources.push_back(static_cast<uint8_t>(src_id));
|
||||
++src_count;
|
||||
accumulator::Pool pools[32];
|
||||
EventAdderImpl event_adder(src_id, pools);
|
||||
EventAdderImpl event_adder(src_id, this->_p_pools);
|
||||
[[maybe_unused]] bool scheduled;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
|
@ -47,6 +57,11 @@ public:
|
|||
|
||||
[[maybe_unused]] auto src_is_registered(const uint8_t& id) -> bool;
|
||||
|
||||
auto set_pools_ptr(
|
||||
std::shared_ptr<
|
||||
std::array<accumulator::Pool, Accumulator::NUM_OF_POOLS>> p_pools)
|
||||
-> void;
|
||||
|
||||
auto set_gen(fortuna::generator::Generator& Gen) -> void;
|
||||
|
||||
auto get_random_data(const unsigned int& n_bytes) -> std::string;
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace accumulator {
|
|||
|
||||
class EventAdder {
|
||||
public:
|
||||
virtual void add(std::vector<char> e) = 0;
|
||||
virtual void add(const std::vector<char>& e) = 0;
|
||||
};
|
||||
|
||||
} // namespace accumulator
|
||||
|
|
|
@ -4,33 +4,51 @@
|
|||
#include "event_adder.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace fortuna {
|
||||
namespace accumulator {
|
||||
|
||||
class EventAdderImpl final : public EventAdder {
|
||||
public:
|
||||
static constexpr const uint8_t p_size{32};
|
||||
|
||||
private:
|
||||
uint8_t pool_id;
|
||||
static unsigned int _source_id;
|
||||
static accumulator::Pool _pools[p_size];
|
||||
uint64_t where_to{0};
|
||||
unsigned int _source_id;
|
||||
std::shared_ptr<
|
||||
std::array<accumulator::Pool, accumulator::Pool::NUM_OF_POOLS>>
|
||||
_pools;
|
||||
|
||||
public:
|
||||
EventAdderImpl(const unsigned int source_id,
|
||||
const accumulator::Pool pools[p_size]) {
|
||||
EventAdderImpl(
|
||||
const unsigned int source_id,
|
||||
std::shared_ptr<std::array<accumulator::Pool,
|
||||
accumulator::Pool::NUM_OF_POOLS>> pools) {
|
||||
this->_source_id = source_id;
|
||||
for (uint8_t i{0}; i < this->p_size; i++) {
|
||||
this->_pools[i] = pools[i];
|
||||
if (pools) {
|
||||
this->_pools = pools;
|
||||
}
|
||||
else {
|
||||
throw std::runtime_error(
|
||||
"[!] adder: pools pointer no longer valid\n");
|
||||
}
|
||||
this->pool_id = 0;
|
||||
}
|
||||
|
||||
void add(std::vector<char> event) override {
|
||||
this->pool_id = static_cast<uint8_t>((this->pool_id + 1) % p_size);
|
||||
_pools[this->pool_id].add_entropy(_source_id, event);
|
||||
void add(const std::vector<char>& event) override {
|
||||
this->pool_id = (this->where_to) % 32;
|
||||
fmt::print("[i] add to pool {}\n", this->pool_id);
|
||||
int ret{this->_pools->at(this->pool_id)
|
||||
.add_entropy(this->_source_id, event)};
|
||||
if (ret == 1) {
|
||||
throw std::runtime_error(
|
||||
"\t[!] event_adder: error adding event!\n");
|
||||
}
|
||||
// FIXME: this WILL overflow, too
|
||||
++where_to;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
13
fortuna.cpp
13
fortuna.cpp
|
@ -58,16 +58,19 @@ auto Fortuna::random_data(unsigned int n_bytes) -> void {
|
|||
const int pools_to_use{ffsll(static_cast<int>(get_reseed_ctr()))};
|
||||
|
||||
fmt::print("[*] fortuna: current p0 length: {}\n",
|
||||
R.pools[0].get_s_length());
|
||||
if (R.Gen.time_to_reseed(R.pools[0].get_s_length(),
|
||||
this->R._p_pools->at(0).get_s_byte_count());
|
||||
if (R.Gen.time_to_reseed(R._p_pools->at(0).get_s_byte_count(),
|
||||
min_pool_size,
|
||||
elapsed,
|
||||
R.Gen.reseed_interval)) {
|
||||
for (int i = 0; i < static_cast<int>(pools_to_use); ++i) {
|
||||
if (R.reseed_ctr % static_cast<int>(pow(2, i)) == 0) {
|
||||
if (this->R.reseed_ctr %
|
||||
static_cast<int>(pow(2, static_cast<double>(i))) ==
|
||||
0) {
|
||||
try {
|
||||
s.append(fortuna::Util::do_sha(R.pools[i].get_s()));
|
||||
R.pools[i].clear_pool();
|
||||
s.append(
|
||||
fortuna::Util::do_sha(this->R._p_pools->at(i).get_s()));
|
||||
this->R._p_pools->at(i).clear_pool();
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
fmt::print("{}\n", e.what());
|
||||
|
|
30
fortuna.h
30
fortuna.h
|
@ -3,9 +3,11 @@
|
|||
|
||||
#include "accumulator.h"
|
||||
#include "generator.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
@ -15,9 +17,7 @@ namespace fortuna {
|
|||
|
||||
class Fortuna {
|
||||
public:
|
||||
// in microseconds
|
||||
static constexpr const unsigned int reseed_interval{10000};
|
||||
static constexpr const char num_of_pools{32};
|
||||
static constexpr const char NUM_OF_POOLS{32};
|
||||
std::mutex mtx;
|
||||
std::mutex accu_mtx;
|
||||
std::mutex print_mtx;
|
||||
|
@ -28,7 +28,7 @@ public:
|
|||
Fortuna();
|
||||
~Fortuna() noexcept;
|
||||
|
||||
auto random_data(unsigned int) -> void;
|
||||
[[optimize_for_synchronized]] auto random_data(unsigned int) -> void;
|
||||
|
||||
auto set_reseed_ctr_to_null() -> void {
|
||||
std::lock_guard<std::mutex> lg(mtx);
|
||||
|
@ -52,18 +52,20 @@ public:
|
|||
std::unique_lock<std::mutex> a_ul(accu_mtx);
|
||||
try {
|
||||
R.initialize_pools();
|
||||
a_ul.unlock();
|
||||
fmt::print("[i] fortuna: pools initialized\n");
|
||||
p_ul.unlock();
|
||||
a_ul.lock();
|
||||
accumulator.set_pools_ptr(R._p_pools);
|
||||
accumulator.set_gen(R.Gen);
|
||||
a_ul.unlock();
|
||||
|
||||
// FIXME: bogus first reseed here, P_0 definitely hasn't collected
|
||||
// enough entropy by now
|
||||
incr_reseed_ctr();
|
||||
|
||||
p_ul.lock();
|
||||
fmt::print("first reseed\n");
|
||||
p_ul.unlock();
|
||||
|
||||
std::unique_lock<std::mutex> ul(mtx);
|
||||
R.Gen.reseed("fortuna");
|
||||
ul.unlock();
|
||||
|
@ -103,16 +105,26 @@ public:
|
|||
|
||||
auto initialize_pools() -> void {
|
||||
for (unsigned int i = accumulator::Accumulator::init_pool_num;
|
||||
i < num_of_pools;
|
||||
i < Fortuna::NUM_OF_POOLS;
|
||||
++i) {
|
||||
pools[i].initialize_pool(i);
|
||||
this->_p_pools->at(i).initialize_pool(i);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
generator::Generator Gen;
|
||||
uint64_t reseed_ctr{0x00};
|
||||
accumulator::Pool pools[num_of_pools];
|
||||
|
||||
// da_pools is to be used solely for creating a shared_ptr of the
|
||||
// object: _p_pools. any further access to the structure should be
|
||||
// facilitated by the subject _p_pools shared_ptr. to convey this,
|
||||
// da_pools is declared const
|
||||
const std::array<accumulator::Pool, Fortuna::NUM_OF_POOLS> da_pools;
|
||||
|
||||
// _p_pools points to the da_pools array of 32 Pool objects
|
||||
std::shared_ptr<std::array<accumulator::Pool, Fortuna::NUM_OF_POOLS>>
|
||||
_p_pools{std::make_shared<
|
||||
std::array<accumulator::Pool, Fortuna::NUM_OF_POOLS>>()};
|
||||
|
||||
std::chrono::steady_clock::time_point last_reseed;
|
||||
}; // class R_state
|
||||
|
|
116
pool.cpp
116
pool.cpp
|
@ -5,6 +5,12 @@
|
|||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <climits>
|
||||
#include <cstddef>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace fortuna {
|
||||
namespace accumulator {
|
||||
|
||||
|
@ -22,62 +28,116 @@ auto Pool::initialize_pool(const unsigned int& id) -> void {
|
|||
fmt::print("\tid set to: {}\n", this->get_id());
|
||||
}
|
||||
|
||||
auto Pool::add_entropy(const uint source, const std::vector<char>& event)
|
||||
-> int {
|
||||
auto Pool::add_entropy(const unsigned int& source,
|
||||
const std::vector<char>& event) -> int {
|
||||
const size_t event_size{sizeof(char) * event.size()};
|
||||
const size_t max_event_size{32};
|
||||
std::string event_str;
|
||||
const size_t event_size{event.size()};
|
||||
bool all_ok{false};
|
||||
|
||||
fmt::print("\tevent_size (bytes): {}\n", event_size);
|
||||
try {
|
||||
if (source > 255) {
|
||||
throw std::invalid_argument(
|
||||
"source number outside of interval <0,255>\n");
|
||||
}
|
||||
if (event_size < 1 || event_size > 32) {
|
||||
throw std::invalid_argument("the length of the event needs to "
|
||||
"be from the interval <1,32>\n");
|
||||
fmt::print("\tsource_id: {}\n", source);
|
||||
|
||||
if (event_size < 1 || event_size > max_event_size) {
|
||||
const std::string msg{
|
||||
"[!] add_entropy: the length of the event needs to "
|
||||
"be from the interval <1,32>"};
|
||||
fmt::print("\tsource: {}\n{}\nevent size: {}\n\tpool_id: {}",
|
||||
source,
|
||||
msg,
|
||||
event_size,
|
||||
this->pool_id);
|
||||
throw std::invalid_argument(msg);
|
||||
}
|
||||
else {
|
||||
all_ok = true;
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
fmt::print("{}", e.what());
|
||||
fmt::print("{}\n", e.what());
|
||||
}
|
||||
fmt::print("\tall_ok: {}\n", all_ok);
|
||||
|
||||
try {
|
||||
event_str = std::string(event.begin(), event.end());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
fmt::print("{}", e.what());
|
||||
}
|
||||
if (all_ok) {
|
||||
try {
|
||||
// FIXME: check for overflow - std::string size bounding?
|
||||
event_str.assign(event.begin(), event.end());
|
||||
|
||||
try {
|
||||
std::string digest(fortuna::Util::do_sha(event_str));
|
||||
size += event_size;
|
||||
append_s(digest);
|
||||
digest.clear();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
fmt::print("{}", e.what());
|
||||
}
|
||||
fmt::print("\tevent_str length: {}\n", event_str.length());
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
fmt::print("\t[!] add_entropy: {}\n", e.what());
|
||||
throw std::runtime_error(e.what());
|
||||
}
|
||||
|
||||
return 0;
|
||||
try {
|
||||
// FIXME: check size for overflow
|
||||
// also, atm this counts event size but actually what gets appended
|
||||
// are digests of 64 characters (hex-encoded 32 bytes)
|
||||
size += event_size;
|
||||
|
||||
{
|
||||
const std::string digest(fortuna::Util::do_sha(event));
|
||||
|
||||
fmt::print("\t[i] add_entropy(digest): {}\n", digest);
|
||||
|
||||
append_s(digest);
|
||||
}
|
||||
|
||||
std::unique_lock<std::recursive_mutex> ul(ro_mtx_s);
|
||||
fmt::print("\t[i] s.length() (simple char count): {}\n"
|
||||
"\t[i] get_s_byte_count() (byte count): {}\n"
|
||||
"\t[i] pool_id: {}\n"
|
||||
"\t[i] s: {}\n",
|
||||
this->s.length(),
|
||||
this->get_s_byte_count(),
|
||||
this->pool_id,
|
||||
// "");
|
||||
this->s);
|
||||
ul.unlock();
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
fmt::print("[!] pool(add_entropy): {}\n", e.what());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
// everything not ok
|
||||
return 1;
|
||||
}
|
||||
} // add_entropy
|
||||
|
||||
auto Pool::get_s_length() const -> uint64_t {
|
||||
// returns total length of entropy contained in this pool
|
||||
return this->s.length();
|
||||
auto Pool::get_s_byte_count() const -> uint64_t {
|
||||
// returns total byte count of (hex-encoded) entropy string contained in
|
||||
// the pool. since the string is hex-encoded, we divide its char count by 2
|
||||
// to get proper byte count. we need this since we actually don't care about
|
||||
// the length of the hex string as it is, rather we care about what it came
|
||||
// from (the raw entropy event)
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lg(ro_mtx_s);
|
||||
return this->s.length() / 2;
|
||||
}
|
||||
|
||||
auto Pool::get_s() const -> std::string {
|
||||
std::lock_guard<std::recursive_mutex> lg(ro_mtx_s);
|
||||
return this->s;
|
||||
}
|
||||
|
||||
auto Pool::clear_pool() -> void {
|
||||
std::lock_guard<std::mutex> lg(mtx);
|
||||
this->s.clear();
|
||||
}
|
||||
|
||||
|
||||
auto Pool::append_s(const std::string& entropy_s) -> void {
|
||||
std::lock_guard<std::mutex> lg(mtx);
|
||||
try {
|
||||
(this->s).append(std::string(entropy_s));
|
||||
this->s.append(entropy_s);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
fmt::print("{}\n", e.what());
|
||||
|
|
16
pool.h
16
pool.h
|
@ -3,14 +3,19 @@
|
|||
|
||||
#include "util.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
namespace fortuna {
|
||||
namespace accumulator {
|
||||
|
||||
class Pool {
|
||||
public:
|
||||
static constexpr const uint8_t NUM_OF_POOLS{32};
|
||||
|
||||
Pool() noexcept {};
|
||||
Pool(const Pool& pool) = delete; // no copy
|
||||
Pool(const Pool&) = delete; // no copy
|
||||
Pool(Pool&) = delete;
|
||||
Pool& operator=(const Pool&) = delete;
|
||||
~Pool() noexcept = default;
|
||||
|
||||
auto set_id(const unsigned int& id) noexcept -> void;
|
||||
|
@ -20,9 +25,10 @@ public:
|
|||
auto initialize_pool(const unsigned int& id) -> void;
|
||||
|
||||
// add entropy contained in a random event of 1 to 32 bytes
|
||||
auto add_entropy(const uint source, const std::vector<char>& event) -> int;
|
||||
auto add_entropy(const unsigned int& source, const std::vector<char>& event)
|
||||
-> int;
|
||||
|
||||
auto get_s_length() const -> uint64_t;
|
||||
auto get_s_byte_count() const -> uint64_t;
|
||||
|
||||
auto get_s() const -> std::string;
|
||||
|
||||
|
@ -33,8 +39,10 @@ protected:
|
|||
|
||||
private:
|
||||
unsigned int pool_id{0};
|
||||
std::string s{""};
|
||||
mutable std::string s{""};
|
||||
uint64_t size{0};
|
||||
std::mutex mtx; // mutex for write locks
|
||||
mutable std::recursive_mutex ro_mtx_s; // mtx for readers of s
|
||||
|
||||
}; // class Pool
|
||||
|
||||
|
|
|
@ -2,42 +2,67 @@
|
|||
#define FORTUNA_URANDOM_ENTROPY_SRC_CPP
|
||||
|
||||
#include "urandom_entropy_src.h"
|
||||
#include "event_adder_impl.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <mutex>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
namespace fortuna {
|
||||
namespace accumulator {
|
||||
|
||||
std::vector<char> UrandomEntropySrc::bytes{};
|
||||
auto UrandomEntropySrc::event(accumulator::EventAdderImpl& adder) -> void {
|
||||
std::lock_guard<std::mutex> lg(mtx);
|
||||
|
||||
auto UrandomEntropySrc::schedule(accumulator::EventSchedulerImpl scheduler)
|
||||
-> void {
|
||||
scheduler.schedule(std::chrono::milliseconds(100));
|
||||
}
|
||||
|
||||
auto UrandomEntropySrc::event(accumulator::EventAdderImpl adder) -> void {
|
||||
std::ifstream file;
|
||||
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
|
||||
try {
|
||||
std::ifstream urandom("/dev/urandom", std::ios::in | std::ios::binary);
|
||||
// how much to get at once
|
||||
static constexpr const unsigned int this_many_bytes{32};
|
||||
|
||||
this->bytes.resize(this_many_bytes);
|
||||
|
||||
assert((bytes.size()) == this_many_bytes);
|
||||
|
||||
// check if stream is open
|
||||
if (urandom) {
|
||||
urandom.read(
|
||||
reinterpret_cast<char*>(&UrandomEntropySrc::bytes),
|
||||
static_cast<int64_t>(reinterpret_cast<uint64_t>(UrandomEntropySrc::bytes.size())));
|
||||
fmt::print(stderr, "[i] ues: /dev/urandom stream open\n");
|
||||
|
||||
std::unique_lock<std::mutex> ul;
|
||||
urandom.read(reinterpret_cast<char*>(&this->bytes.front()),
|
||||
this_many_bytes);
|
||||
urandom.close();
|
||||
}
|
||||
else {
|
||||
// open failed
|
||||
fmt::print(stderr, "Failed to open /dev/urandom\n");
|
||||
const std::string msg{"\t[!] Failed to open /dev/urandom\n"};
|
||||
|
||||
fmt::print(stderr, "{}", msg);
|
||||
throw std::runtime_error(msg);
|
||||
}
|
||||
}
|
||||
catch (std::ifstream::failure& e) {
|
||||
fmt::print("io exception caugth: {}\n", e.what());
|
||||
}
|
||||
|
||||
try {
|
||||
adder.add(this->bytes);
|
||||
std::memset(this->bytes.data(), 0x00, this->bytes.size()); // clear out
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
fmt::print("[!] ues: exception caugth: {}\n", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
UrandomEntropySrc::UrandomEntropySrc() : EntropySrc::EntropySrc() {}
|
||||
UrandomEntropySrc::~UrandomEntropySrc() noexcept {}
|
||||
|
||||
|
||||
} // namespace accumulator
|
||||
} // namespace fortuna
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
|
||||
#include "entropy_src.h"
|
||||
#include "event_adder_impl.h"
|
||||
#include "event_scheduler_impl.h"
|
||||
|
||||
#include <fmt/core.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace fortuna {
|
||||
|
@ -17,14 +17,16 @@ namespace accumulator {
|
|||
|
||||
class UrandomEntropySrc : public EntropySrc {
|
||||
private:
|
||||
static std::vector<char> bytes;
|
||||
std::vector<char> bytes{0};
|
||||
std::mutex mtx;
|
||||
|
||||
public:
|
||||
auto schedule(accumulator::EventSchedulerImpl scheduler) -> void;
|
||||
|
||||
auto event(accumulator::EventAdderImpl adder) -> void;
|
||||
auto event(accumulator::EventAdderImpl& adder) -> void;
|
||||
|
||||
auto urandom_entropy_src_service() -> int;
|
||||
|
||||
UrandomEntropySrc();
|
||||
~UrandomEntropySrc() noexcept;
|
||||
};
|
||||
|
||||
} // namespace accumulator
|
||||
|
|
Loading…
Reference in New Issue