fortuna: handle reseeds+clear pools for seed

* actually clear out entropy of the pools before a reseed
* correctly prepare the seed for the reseed
* add a couple of helper methods to Pool that assist with getting
  length, retrieving and clearing of the collected entropy
* catch exceptions in main(), handle them gracefully
This commit is contained in:
surtur 2021-12-13 04:59:11 +01:00
parent 65c476dbd6
commit 7eaaef2fdb
Signed by: wanderer
GPG Key ID: 19CE1EC1D9E0486D
4 changed files with 40 additions and 10 deletions

View File

@ -36,13 +36,25 @@ namespace fortuna {
)
};
fmt::print("last_reseed: {} ago\n", elapsed);
const int pools_to_use{ffsll(static_cast<int>(get_reseed_ctr()))};
std::string s;
if (sizeof(R.pools[0]) >= min_pool_size && elapsed > R.Gen.reseed_interval) {
if (R.pools[0].get_s_length() >= min_pool_size && elapsed > R.Gen.reseed_interval) {
#pragma omp parallel for
for (int i = 0; i < static_cast<int>(pools_to_use); ++i) {
if (R.reseed_ctr % static_cast<int>(pow(2,i)) == 0) {
try {
s.append(fortuna::Util::do_sha(R.pools[i].get_s()));
R.pools[i].clear_pool();
} catch(std::exception& e) {
fmt::print("{}\n", e.what());
}
}
}
incr_reseed_ctr();
// TODO(me): Append the hashes of all the pools we will use to s
R.Gen.reseed(fortuna::Util::do_sha(s));
R.Gen.reseed(s);
R.last_reseed = std::chrono::steady_clock::now();
s.clear();
}
std::string n{R.Gen.generate_random_data(n_bytes)};

View File

@ -29,6 +29,10 @@ public:
++Fortuna::R.reseed_ctr;
}
auto get_reseed_ctr() const -> uint64_t {
return R.reseed_ctr;
}
auto initialize_prng() -> void {
// TODO(me): handle the reseeds here as per Cryptography Engineering,
// p. 153
@ -63,10 +67,7 @@ public:
private:
generator::Generator Gen;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
unsigned __int128 reseed_ctr;
#pragma GCC diagnostic pop
uint64_t reseed_ctr{0x00};
accumulator::Pool pools[num_of_pools];
std::chrono::steady_clock::time_point last_reseed;

View File

@ -1,10 +1,13 @@
#include "fortuna.h"
#include <fmt/core.h>
int main() {
fmt::print("[*] doing evil stuff\n");
fortuna::Fortuna f;
f.random_data(4); // number of bytes requested
try {
f.random_data(4); // number of bytes requested
} catch (std::exception& e) {
fmt::print("[!] exiting due to \"{}\"\n", e.what());
exit(0);
}
return 0;
}

14
pool.h
View File

@ -25,6 +25,7 @@ public:
set_id(id);
}
// add entropy contained in a random event of 1 to 32 bytes
auto add_entropy(const uint source, const std::vector<char> &event) -> int {
std::string event_str;
const size_t event_size{event.size()};
@ -58,6 +59,19 @@ public:
return 0;
}
auto get_s_length() const -> uint64_t {
// returns total length of entropy contained in this pool
return this->s.length();
}
auto get_s() const -> std::string {
return this->s;
}
auto clear_pool() -> void {
this->s.clear();
}
protected:
auto set_s(const std::string& entropy_s) -> void {
try {