149 lines
3.6 KiB
C++
149 lines
3.6 KiB
C++
#ifndef FORTUNA_POOL_CPP
|
|
#define FORTUNA_POOL_CPP
|
|
|
|
#include "pool.h"
|
|
|
|
#include <fmt/core.h>
|
|
|
|
#include <climits>
|
|
#include <cstddef>
|
|
#include <mutex>
|
|
#include <stdexcept>
|
|
#include <utility>
|
|
|
|
namespace fortuna {
|
|
namespace accumulator {
|
|
|
|
auto Pool::set_id(const unsigned int& id) noexcept -> void {
|
|
this->pool_id = id;
|
|
}
|
|
|
|
auto Pool::get_id() const noexcept -> unsigned int {
|
|
return this->pool_id;
|
|
}
|
|
|
|
auto Pool::initialize_pool(const unsigned int& id) -> void {
|
|
fmt::print("\tpool init: {}\n", id);
|
|
set_id(id);
|
|
fmt::print("\tid set to: {}\n", this->get_id());
|
|
}
|
|
|
|
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;
|
|
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");
|
|
}
|
|
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("{}\n", e.what());
|
|
throw;
|
|
}
|
|
fmt::print("\tall_ok: {}\n", all_ok);
|
|
|
|
if (all_ok) {
|
|
try {
|
|
// FIXME: check for overflow - std::string size bounding?
|
|
event_str.assign(event.begin(), event.end());
|
|
|
|
fmt::print("\tevent_str length: {}\n", event_str.length());
|
|
|
|
// 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());
|
|
// FIXME: handle this (as all the other unhandled exceptions)
|
|
throw;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
else {
|
|
// everything not ok
|
|
return 1;
|
|
}
|
|
} // add_entropy
|
|
|
|
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(entropy_s);
|
|
}
|
|
catch (const std::exception& e) {
|
|
fmt::print("{}\n", e.what());
|
|
}
|
|
}
|
|
|
|
|
|
} // namespace accumulator
|
|
} // namespace fortuna
|
|
|
|
#endif // FORTUNA_POOL_CPP
|