Botan 3.6.1
Crypto and TLS for C&
ffi_rng.cpp File Reference
#include <botan/ffi.h>
#include <botan/auto_rng.h>
#include <botan/system_rng.h>
#include <botan/internal/ffi_rng.h>
#include <botan/internal/ffi_util.h>
#include <functional>
#include <memory>

Go to the source code of this file.

Functions

int botan_rng_add_entropy (botan_rng_t rng, const uint8_t *input, size_t len)
 
int botan_rng_destroy (botan_rng_t rng)
 
int botan_rng_get (botan_rng_t rng, uint8_t *out, size_t out_len)
 
int botan_rng_init (botan_rng_t *rng_out, const char *rng_type)
 
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_reseed_from_rng (botan_rng_t rng, botan_rng_t source_rng, size_t bits)
 
int botan_system_rng_get (uint8_t *out, size_t out_len)
 

Function Documentation

◆ botan_rng_add_entropy()

int botan_rng_add_entropy ( botan_rng_t rng,
const uint8_t * entropy,
size_t entropy_len )

Add some seed material to a random number generator

Parameters
rngrng object
entropythe data to add
entropy_lenlength of entropy buffer
Returns
0 on success, a negative value on failure

Definition at line 171 of file ffi_rng.cpp.

171 {
172 return BOTAN_FFI_VISIT(rng, [=](auto& r) { r.add_entropy(input, len); });
173}
#define BOTAN_FFI_VISIT(obj, lambda)
Definition ffi_util.h:124

References BOTAN_FFI_VISIT.

◆ botan_rng_destroy()

int botan_rng_destroy ( botan_rng_t rng)

Frees all resources of the random number generator object

Parameters
rngrng object
Returns
0 if success, error if invalid object handle

Definition at line 152 of file ffi_rng.cpp.

152 {
153 return BOTAN_FFI_CHECKED_DELETE(rng);
154}
#define BOTAN_FFI_CHECKED_DELETE(o)
Definition ffi_util.h:143

References BOTAN_FFI_CHECKED_DELETE.

◆ botan_rng_get()

int botan_rng_get ( botan_rng_t rng,
uint8_t * out,
size_t out_len )

Get random bytes from a random number generator

Parameters
rngrng object
outoutput buffer of size out_len
out_lennumber of requested bytes
Returns
0 on success, negative on failure

Definition at line 156 of file ffi_rng.cpp.

156 {
157 return BOTAN_FFI_VISIT(rng, [=](auto& r) { r.randomize(out, out_len); });
158}

References BOTAN_FFI_VISIT.

◆ botan_rng_init()

int botan_rng_init ( botan_rng_t * rng,
const char * rng_type )

Initialize a random number generator object

Parameters
rngrng object
rng_typetype of the rng, possible values: "system": system RNG "user": userspace RNG "user-threadsafe": userspace RNG, with internal locking "rdrand": directly read RDRAND Set rng_type to null to let the library choose some default.

Definition at line 30 of file ffi_rng.cpp.

30 {
31 return ffi_guard_thunk(__func__, [=]() -> int {
32 if(rng_out == nullptr) {
34 }
35
36 const std::string rng_type_s(rng_type ? rng_type : "system");
37
38 std::unique_ptr<Botan::RandomNumberGenerator> rng;
39
40 if(rng_type_s == "system") {
41 rng = std::make_unique<Botan::System_RNG>();
42 } else if(rng_type_s == "user" || rng_type_s == "user-threadsafe") {
43 rng = std::make_unique<Botan::AutoSeeded_RNG>();
44 } else if(rng_type_s == "null") {
45 rng = std::make_unique<Botan::Null_RNG>();
46 }
47#if defined(BOTAN_HAS_PROCESSOR_RNG)
48 else if((rng_type_s == "rdrand" || rng_type_s == "hwrng") && Botan::Processor_RNG::available()) {
49 rng = std::make_unique<Botan::Processor_RNG>();
50 }
51#endif
52#if defined(BOTAN_HAS_JITTER_RNG)
53 else if(rng_type_s == "jitter") {
54 rng = std::make_unique<Botan::Jitter_RNG>();
55 }
56#endif
57
58 if(!rng) {
60 }
61
62 *rng_out = new botan_rng_struct(std::move(rng));
63 return BOTAN_FFI_SUCCESS;
64 });
65}
@ BOTAN_FFI_ERROR_NOT_IMPLEMENTED
Definition ffi.h:135
@ BOTAN_FFI_ERROR_NULL_POINTER
Definition ffi.h:129
@ BOTAN_FFI_SUCCESS
Definition ffi.h:114
int ffi_guard_thunk(const char *func_name, const std::function< int()> &thunk)
Definition ffi.cpp:118

References Botan::Processor_RNG::available(), BOTAN_FFI_ERROR_NOT_IMPLEMENTED, BOTAN_FFI_ERROR_NULL_POINTER, BOTAN_FFI_SUCCESS, and Botan_FFI::ffi_guard_thunk().

◆ botan_rng_init_custom()

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) )

Initialize a custom random number generator from a set of callback functions

Parameters
rng_outrng object to create
rng_namename of the rng
contextAn application-specific context passed to the callback functions
get_cbCallback for getting random bytes from the rng, return 0 for success
add_entropy_cbCallback for adding entropy to the rng, return 0 for success, may be NULL
destroy_cbCallback called when rng is destroyed, may be NULL

Definition at line 67 of file ffi_rng.cpp.

72 {
73 return ffi_guard_thunk(__func__, [=]() -> int {
74 if(rng_out == nullptr) {
76 }
77
78 if(rng_name == nullptr) {
80 }
81
82 if(get_cb == nullptr) {
84 }
85
86 class Custom_RNG : public Botan::RandomNumberGenerator {
87 public:
88 Custom_RNG(std::string_view name,
89 void* context,
90 int (*get_cb)(void* context, uint8_t* out, size_t out_len),
91 int (*add_entropy_cb)(void* context, const uint8_t input[], size_t length),
92 void (*destroy_cb)(void* context)) :
93 m_name(name) {
94 m_context = context;
95 m_get_cb = get_cb;
96 m_add_entropy_cb = add_entropy_cb;
97 m_destroy_cb = destroy_cb;
98 }
99
100 ~Custom_RNG() override {
101 if(m_destroy_cb) {
102 m_destroy_cb(m_context);
103 }
104 }
105
106 Custom_RNG(const Custom_RNG& other) = delete;
107 Custom_RNG(Custom_RNG&& other) = delete;
108 Custom_RNG& operator=(const Custom_RNG& other) = delete;
109 Custom_RNG& operator=(Custom_RNG&& other) = delete;
110
111 protected:
112 void fill_bytes_with_input(std::span<uint8_t> output, std::span<const uint8_t> input) override {
113 if(accepts_input() && !input.empty()) {
114 int rc = m_add_entropy_cb(m_context, input.data(), input.size());
115 if(rc) {
116 throw Botan::Invalid_State("Failed to add entropy via C callback, rc=" + std::to_string(rc));
117 }
118 }
119
120 if(!output.empty()) {
121 int rc = m_get_cb(m_context, output.data(), output.size());
122 if(rc) {
123 throw Botan::Invalid_State("Failed to get random from C callback, rc=" + std::to_string(rc));
124 }
125 }
126 }
127
128 public:
129 bool accepts_input() const override { return m_add_entropy_cb != nullptr; }
130
131 std::string name() const override { return m_name; }
132
133 void clear() override {}
134
135 bool is_seeded() const override { return true; }
136
137 private:
138 std::string m_name;
139 void* m_context;
140 std::function<int(void* context, uint8_t* out, size_t out_len)> m_get_cb;
141 std::function<int(void* context, const uint8_t input[], size_t length)> m_add_entropy_cb;
142 std::function<void(void* context)> m_destroy_cb;
143 };
144
145 auto rng = std::make_unique<Custom_RNG>(rng_name, context, get_cb, add_entropy_cb, destroy_cb);
146
147 *rng_out = new botan_rng_struct(std::move(rng));
148 return BOTAN_FFI_SUCCESS;
149 });
150}
std::string name

References BOTAN_FFI_ERROR_NULL_POINTER, BOTAN_FFI_SUCCESS, Botan_FFI::ffi_guard_thunk(), and name.

◆ botan_rng_reseed()

int botan_rng_reseed ( botan_rng_t rng,
size_t bits )

Reseed a random number generator Uses the System_RNG as a seed generator.

Parameters
rngrng object
bitsnumber of bits to reseed with
Returns
0 on success, a negative value on failure

Definition at line 167 of file ffi_rng.cpp.

167 {
168 return BOTAN_FFI_VISIT(rng, [=](auto& r) { r.reseed_from_rng(Botan::system_rng(), bits); });
169}
RandomNumberGenerator & system_rng()

References BOTAN_FFI_VISIT, and Botan::system_rng().

◆ botan_rng_reseed_from_rng()

int botan_rng_reseed_from_rng ( botan_rng_t rng,
botan_rng_t source_rng,
size_t bits )

Reseed a random number generator

Parameters
rngrng object
source_rngthe rng that will be read from
bitsnumber of bits to reseed with
Returns
0 on success, a negative value on failure

Definition at line 175 of file ffi_rng.cpp.

175 {
176 return BOTAN_FFI_VISIT(rng, [=](auto& r) { r.reseed_from_rng(safe_get(source_rng), bits); });
177}
T & safe_get(botan_struct< T, M > *p)
Definition ffi_util.h:63

References BOTAN_FFI_VISIT, and Botan_FFI::safe_get().

◆ botan_system_rng_get()

int botan_system_rng_get ( uint8_t * out,
size_t out_len )

Get random bytes from system random number generator

Parameters
outoutput buffer of size out_len
out_lennumber of requested bytes
Returns
0 on success, negative on failure

Definition at line 160 of file ffi_rng.cpp.

160 {
161 return ffi_guard_thunk(__func__, [=]() -> int {
162 Botan::system_rng().randomize(out, out_len);
163 return BOTAN_FFI_SUCCESS;
164 });
165}
void randomize(std::span< uint8_t > output)
Definition rng.h:53

References BOTAN_FFI_SUCCESS, Botan_FFI::ffi_guard_thunk(), Botan::RandomNumberGenerator::randomize(), and Botan::system_rng().