9#include <botan/internal/ffi_util.h>
10#include <botan/internal/ffi_rng.h>
11#include <botan/system_rng.h>
12#include <botan/auto_rng.h>
17#if defined(BOTAN_HAS_PROCESSOR_RNG)
18#include <botan/processor_rng.h>
28 if(rng_out ==
nullptr)
31 const std::string rng_type_s(rng_type ? rng_type :
"system");
33 std::unique_ptr<Botan::RandomNumberGenerator> rng;
35 if(rng_type_s ==
"system")
37 rng = std::make_unique<Botan::System_RNG>();
39 else if(rng_type_s ==
"user" || rng_type_s ==
"user-threadsafe")
41 rng = std::make_unique<Botan::AutoSeeded_RNG>();
43 else if(rng_type_s ==
"null")
45 rng = std::make_unique<Botan::Null_RNG>();
47#if defined(BOTAN_HAS_PROCESSOR_RNG)
50 rng = std::make_unique<Botan::Processor_RNG>();
59 *rng_out =
new botan_rng_struct(std::move(rng));
65 int(* get_cb)(
void* context, uint8_t* out,
size_t out_len),
66 int(* add_entropy_cb)(
void* context,
const uint8_t input[],
size_t length),
67 void(* destroy_cb)(
void* context))
70 if(rng_out ==
nullptr)
73 if(rng_name ==
nullptr)
82 Custom_RNG(std::string_view
name,
void* context,
83 int(* get_cb)(
void* context, uint8_t* out,
size_t out_len),
84 int(* add_entropy_cb)(
void* context,
const uint8_t input[],
size_t length),
85 void(* destroy_cb)(
void* context)) :
90 m_add_entropy_cb = add_entropy_cb;
91 m_destroy_cb = destroy_cb;
94 ~Custom_RNG()
override
98 m_destroy_cb(m_context);
102 Custom_RNG(
const Custom_RNG& other) =
delete;
103 Custom_RNG(Custom_RNG&& other) =
delete;
104 Custom_RNG& operator=(
const Custom_RNG& other) =
delete;
105 Custom_RNG& operator=(Custom_RNG&& other) =
delete;
108 void fill_bytes_with_input(std::span<uint8_t> output, std::span<const uint8_t> input)
override
110 if(accepts_input() && !input.empty())
112 int rc = m_add_entropy_cb(m_context, input.data(), input.size());
121 int rc = m_get_cb(m_context, output.data(), output.size());
130 bool accepts_input()
const override
132 return m_add_entropy_cb !=
nullptr;
135 std::string
name()
const override
140 void clear()
override
144 bool is_seeded()
const override
152 std::function<int(
void* context, uint8_t* out,
size_t out_len)> m_get_cb;
153 std::function<int(
void* context,
const uint8_t input[],
size_t length)> m_add_entropy_cb;
154 std::function<void(
void* context)> m_destroy_cb;
157 auto rng = std::make_unique<Custom_RNG>(rng_name, context, get_cb, add_entropy_cb, destroy_cb);
159 *rng_out =
new botan_rng_struct(std::move(rng));
171 return BOTAN_FFI_VISIT(rng, [=](
auto& r) { r.randomize(out, out_len); });
190 return BOTAN_FFI_VISIT(rng, [=](
auto& r) { r.add_entropy(input, len); });
void randomize(std::span< uint8_t > output)
struct botan_rng_struct * botan_rng_t
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
@ BOTAN_FFI_ERROR_NULL_POINTER
int botan_rng_reseed_from_rng(botan_rng_t rng, botan_rng_t source_rng, size_t bits)
int botan_rng_init_custom(botan_rng_t *rng_out, const char *rng_name, void *context, int(*get_cb)(void *context, uint8_t *out, size_t out_len), int(*add_entropy_cb)(void *context, const uint8_t input[], size_t length), void(*destroy_cb)(void *context))
int botan_rng_reseed(botan_rng_t rng, size_t bits)
int botan_rng_add_entropy(botan_rng_t rng, const uint8_t *input, size_t len)
int botan_rng_init(botan_rng_t *rng_out, const char *rng_type)
int botan_system_rng_get(uint8_t *out, size_t out_len)
int botan_rng_get(botan_rng_t rng, uint8_t *out, size_t out_len)
int botan_rng_destroy(botan_rng_t rng)
#define BOTAN_FFI_VISIT(obj, lambda)
#define BOTAN_FFI_CHECKED_DELETE(o)
T & safe_get(botan_struct< T, M > *p)
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
RandomNumberGenerator & system_rng()