#ifndef FORTUNA_FORTUNA_H #define FORTUNA_FORTUNA_H #include "accumulator.h" #include "generator.h" #include #include #include #include #include namespace fortuna { class Fortuna { public: // in microseconds static constexpr const unsigned int reseed_interval{10000}; static constexpr const char num_of_pools{32}; std::mutex mtx; std::mutex print_mtx; std::thread th_gen; std::thread th_accu; std::thread th_sfm; Fortuna(); ~Fortuna() noexcept; auto random_data(unsigned int) -> void; auto set_reseed_ctr_to_null() -> void { std::lock_guard lg(mtx); Fortuna::R.null_da_ctr(); } auto incr_reseed_ctr() -> void { std::lock_guard lg(mtx); ++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 set_reseed_ctr_to_null(); std::unique_lock p_ul(print_mtx); try { std::unique_lock ul(mtx); R.initialize_pools(); ul.unlock(); fmt::print("[i] fortuna: pools initialized\n"); p_ul.unlock(); ul.lock(); accumulator.set_gen(R.Gen); 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(); ul.lock(); R.Gen.reseed("fortuna"); ul.unlock(); } catch (std::exception& e) { p_ul.try_lock(); fmt::print( "{}\n[!] fortuna: fatal error, PRNG initialization FAILED!\n\n", e.what()); } p_ul.try_lock(); fmt::print("[*] fortuna: PRNG initialized\n"); } auto generator_service(std::shared_ptr Gen) -> void; auto accumulator_service() -> void; auto seed_file_manager_service() -> void; auto urandom_entropy_src_service() -> void; // PRNG state class R_state { friend fortuna::Fortuna; public: R_state() noexcept {} ~R_state() noexcept = default; protected: auto null_da_ctr() -> void { reseed_ctr = 0x00; fmt::print("reseed_ctr set to 0x00\n"); } auto initialize_pools() -> void { for (unsigned int i = accumulator::Accumulator::init_pool_num; i < num_of_pools; ++i) { pools[i].initialize_pool(i); } } private: generator::Generator Gen; uint64_t reseed_ctr{0x00}; accumulator::Pool pools[num_of_pools]; std::chrono::steady_clock::time_point last_reseed; }; // class R_state fortuna::Fortuna::R_state R; fortuna::accumulator::Accumulator accumulator; }; // class Fortuna } // namespace fortuna #endif // FORTUNA_FORTUNA_H