8#include <botan/jitter_rng.h>
10#include <botan/assert.h>
11#include <botan/exceptn.h>
12#include <botan/mutex.h>
14#include <jitterentropy.h>
18class Jitter_RNG_Internal final {
20 Jitter_RNG_Internal();
21 ~Jitter_RNG_Internal();
22 void collect_into_buffer(std::span<uint8_t> buf);
24 Jitter_RNG_Internal(
const Jitter_RNG_Internal& other) =
delete;
25 Jitter_RNG_Internal(Jitter_RNG_Internal&& other) =
delete;
26 Jitter_RNG_Internal& operator=(
const Jitter_RNG_Internal& other) =
delete;
27 Jitter_RNG_Internal& operator=(Jitter_RNG_Internal&& other) =
delete;
31 rand_data* m_rand_data;
34Jitter_RNG_Internal::Jitter_RNG_Internal() {
35 constexpr unsigned int oversampling_rate = 0;
36 constexpr unsigned int flags = JENT_FORCE_FIPS;
39 static const int result = jent_entropy_init_ex(oversampling_rate, flags);
46 m_rand_data = jent_entropy_collector_alloc(oversampling_rate, flags);
47 if(m_rand_data ==
nullptr) {
48 throw Internal_Error(
"Jitter_RNG_Internal collector allocation failed");
52Jitter_RNG_Internal::~Jitter_RNG_Internal() {
54 if(m_rand_data !=
nullptr) {
55 jent_entropy_collector_free(m_rand_data);
56 m_rand_data =
nullptr;
60void Jitter_RNG_Internal::collect_into_buffer(std::span<uint8_t> buf) {
68 ssize_t num_bytes = jent_read_entropy_safe(&m_rand_data,
reinterpret_cast<char*
>(buf.data()), buf.size());
70 const auto error_msg = [&]() -> std::string_view {
73 return "JitterRNG: Uninitilialized";
75 return "JitterRNG: SP800-90B repetition count online health test failed";
77 return "JitterRNG: SP800-90B adaptive proportion online health test failed";
79 return "JitterRNG: Internal timer generator could not be initialized";
81 return "JitterRNG: LAG predictor health test failed";
83 return "JitterRNG: Repetitive count test (RCT) failed permanently";
85 return "JitterRNG: Adaptive proportion test (APT) failed permanently";
87 return "JitterRNG: LAG prediction test failed permanently";
89 return "JitterRNG: Error reading entropy";
98 BOTAN_ASSERT(
static_cast<size_t>(num_bytes) == buf.size(),
"JitterRNG produced the expected number of bytes");
109void Jitter_RNG::fill_bytes_with_input(std::span<uint8_t> out, std::span<const uint8_t> in) {
112 m_jitter->collect_into_buffer(out);
#define BOTAN_STATE_CHECK(expr)
#define BOTAN_ASSERT(expr, assertion_made)
secure_vector< T > lock(const std::vector< T > &in)
lock_guard< T > lock_guard_type