This repository has been archived on 2022-02-10. You can view files and clone it, but cannot push or open issues or pull requests.
fortuna/accumulator.cpp
surtur 52de785399
All checks were successful
continuous-integration/drone/push Build is passing
fortuna: properly handle reseeds
* move reseed_ctr and related member functions to Accumulator

* create a std::shared_ptr<Accumulator> to Fortuna's internal
  Accumulator object and feed that into SeedFileManager instead of a
  reference, which used to get copied to a new object in SeedFileManager

* make Accumulator non-copyable, since it's only to be created once.
  instead, a shared_ptr is used to facilitate multiple-access

* handle concurrency in Accumulator as the reseed_ctr-related functions
  can now be accessed from both Fortuna and SeedFileManager, declare mtx
  as mutable (since it's also used in a const function)

* use std::scoped_lock in 'initialize_prng()' to safely lock both mutexes
2022-01-22 18:36:51 +01:00

115 lines
2.4 KiB
C++

#ifndef FORTUNA_ACCUMULATOR_CPP
#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>
namespace fortuna {
namespace accumulator {
auto wait_for(const unsigned int& milliseconds) -> void {
std::this_thread::sleep_for(std::chrono::milliseconds{milliseconds});
}
Accumulator::Accumulator() noexcept {
this->Gen = nullptr;
this->_p_pools = nullptr;
}
Accumulator::~Accumulator() noexcept {}
auto Accumulator::set_reseed_ctr_to_null() -> void {
std::lock_guard<std::mutex> lg(mtx);
this->reseed_ctr = 0x00;
}
auto Accumulator::incr_reseed_ctr() -> void {
std::lock_guard<std::mutex> lg(mtx);
{ ++this->reseed_ctr; }
}
auto Accumulator::get_reseed_ctr() const -> uint64_t {
std::lock_guard<std::mutex> lg(mtx);
return this->reseed_ctr;
}
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};
static uint8_t _src_id{};
if (std::any_of(this->entropy_sources.begin(),
this->entropy_sources.end(),
[&](auto& src_id) { return src_id == id; })) {
reg = true;
_src_id = id;
}
if (reg) {
fmt::print(
"[!] acc(add_source): entropy source \"{}\" already registered",
_src_id);
return true;
}
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;
}
auto Accumulator::get_random_data(const unsigned int& n_bytes) -> std::string {
std::string data{""};
try {
data = this->Gen->generate_random_data(n_bytes);
}
catch (std::exception& e) {
// FIXME: handle the exception
throw;
}
return data;
}
auto Accumulator::call_reseed(const std::string& seed) -> void {
try {
incr_reseed_ctr();
this->Gen->reseed(seed);
}
catch (std::exception& e) {
// FIXME: handle the exception
throw;
}
}
} // namespace accumulator
} // namespace fortuna
#endif // FORTUNA_ACCUMULATOR_CPP