mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
lx_emul/random: re-seed the local PRNG regularly
With this commit, the Xoroshiro128+ PRNG in lx_emul/random.cc gets wrapped by a new class that automatically re-seeds the PRNG with jitterentropy every 1024 * 1024 + random(0..4095) bytes of generated output. Ref #4397
This commit is contained in:
parent
ab0bce77ec
commit
03349f9fff
@ -11,8 +11,7 @@
|
||||
* the lx_emul randomness functions has known statistical problems (see
|
||||
* https://en.wikipedia.org/wiki/Xoroshiro128%2B#Statistical_Quality).
|
||||
* Furthermore, the integration of Xoroshir128+ with the lx_emul code was not
|
||||
* reviewed/audited for its security-related properties, so far, and has the
|
||||
* known deficiency of seeding the PRNG only once during initialization. Thus,
|
||||
* reviewed/audited for its security-related properties, so far. Thus,
|
||||
* we strongly advise against the use of the lx_emul randomness functions for
|
||||
* security-critical purposes.
|
||||
*/
|
||||
|
@ -11,8 +11,7 @@
|
||||
* the lx_emul randomness functions has known statistical problems (see
|
||||
* https://en.wikipedia.org/wiki/Xoroshiro128%2B#Statistical_Quality).
|
||||
* Furthermore, the integration of Xoroshir128+ with the lx_emul code was not
|
||||
* reviewed/audited for its security-related properties, so far, and has the
|
||||
* known deficiency of seeding the PRNG only once during initialization. Thus,
|
||||
* reviewed/audited for its security-related properties, so far. Thus,
|
||||
* we strongly advise against the use of the lx_emul randomness functions for
|
||||
* security-critical purposes.
|
||||
*/
|
||||
@ -87,29 +86,105 @@ class Xoroshiro_128_plus
|
||||
}
|
||||
};
|
||||
|
||||
static uint64_t jitterentropy_gen_random_u64()
|
||||
|
||||
class Entropy_source : Interface
|
||||
{
|
||||
static rand_data *jent { nullptr };
|
||||
if (jent == nullptr) {
|
||||
jitterentropy_init(Lx_kit::env().heap);
|
||||
public:
|
||||
|
||||
virtual uint64_t gen_random_u64() = 0;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* A wrapper for the Xoroshiro128+ PRNG that reseeds the PRNG every
|
||||
* 1024 * 1024 + random(0..4095) bytes of generated output.
|
||||
*/
|
||||
class Xoroshiro_128_plus_reseeding
|
||||
{
|
||||
private:
|
||||
|
||||
enum { NR_OF_GEN_BYTES_BASE_LIMIT = 1024 * 1024 };
|
||||
|
||||
Entropy_source &_entropy_src;
|
||||
uint64_t _seed { 0 };
|
||||
size_t _nr_of_gen_bytes { 0 };
|
||||
size_t _nr_of_gen_bytes_limit { 0 };
|
||||
Constructible<Xoroshiro_128_plus> _xoroshiro { };
|
||||
|
||||
void _reseed()
|
||||
{
|
||||
_seed = _entropy_src.gen_random_u64();
|
||||
_nr_of_gen_bytes = 0;
|
||||
_nr_of_gen_bytes_limit =
|
||||
NR_OF_GEN_BYTES_BASE_LIMIT + (_seed & 0xfff);
|
||||
|
||||
_xoroshiro.construct(_seed);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Xoroshiro_128_plus_reseeding(Entropy_source &entropy_src)
|
||||
:
|
||||
_entropy_src { entropy_src }
|
||||
{
|
||||
_reseed();
|
||||
}
|
||||
|
||||
uint64_t get_u64()
|
||||
{
|
||||
_nr_of_gen_bytes += 8;
|
||||
if (_nr_of_gen_bytes >= _nr_of_gen_bytes_limit) {
|
||||
_reseed();
|
||||
_nr_of_gen_bytes += 8;
|
||||
}
|
||||
return _xoroshiro->get_u64();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class Jitterentropy : public Entropy_source
|
||||
{
|
||||
private:
|
||||
|
||||
rand_data *_rand_data { nullptr };
|
||||
|
||||
Jitterentropy(Jitterentropy const &) = delete;
|
||||
|
||||
Jitterentropy & operator = (Jitterentropy const &) = delete;
|
||||
|
||||
public:
|
||||
|
||||
Jitterentropy(Allocator &alloc)
|
||||
{
|
||||
jitterentropy_init(alloc);
|
||||
|
||||
if (jent_entropy_init() != 0) {
|
||||
Genode::error("jitterentropy library could not be initialized!");
|
||||
error("jitterentropy library could not be initialized!");
|
||||
}
|
||||
jent = jent_entropy_collector_alloc(0, 0);
|
||||
if (jent == nullptr) {
|
||||
Genode::error("jitterentropy could not allocate entropy collector!");
|
||||
_rand_data = jent_entropy_collector_alloc(0, 0);
|
||||
if (_rand_data == nullptr) {
|
||||
error("jitterentropy could not allocate entropy collector!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** Entropy_source **
|
||||
********************/
|
||||
|
||||
uint64_t gen_random_u64() override
|
||||
{
|
||||
uint64_t result;
|
||||
jent_read_entropy(jent, (char*)&result, sizeof(result));
|
||||
jent_read_entropy(_rand_data, (char*)&result, sizeof(result));
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Xoroshiro_128_plus &xoroshiro()
|
||||
static Xoroshiro_128_plus_reseeding &xoroshiro()
|
||||
{
|
||||
static Xoroshiro_128_plus xoroshiro { jitterentropy_gen_random_u64() };
|
||||
static Jitterentropy jitterentropy { Lx_kit::env().heap };
|
||||
static Xoroshiro_128_plus_reseeding xoroshiro { jitterentropy };
|
||||
return xoroshiro;
|
||||
}
|
||||
|
||||
@ -119,7 +194,7 @@ void lx_emul_gen_random_bytes(void *dst,
|
||||
{
|
||||
/* validate arguments */
|
||||
if (dst == nullptr || nr_of_bytes == 0) {
|
||||
Genode::error("lx_emul_gen_random_bytes called with invalid args!");
|
||||
error("lx_emul_gen_random_bytes called with invalid args!");
|
||||
return;
|
||||
}
|
||||
/* fill up the destination with random 64-bit values as far as possible */
|
||||
@ -138,7 +213,6 @@ void lx_emul_gen_random_bytes(void *dst,
|
||||
}
|
||||
uint64_t const rand_u64 { xoroshiro().get_u64() };
|
||||
Genode::memcpy(dst_char, &rand_u64, nr_of_bytes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user