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
|
* the lx_emul randomness functions has known statistical problems (see
|
||||||
* https://en.wikipedia.org/wiki/Xoroshiro128%2B#Statistical_Quality).
|
* https://en.wikipedia.org/wiki/Xoroshiro128%2B#Statistical_Quality).
|
||||||
* Furthermore, the integration of Xoroshir128+ with the lx_emul code was not
|
* Furthermore, the integration of Xoroshir128+ with the lx_emul code was not
|
||||||
* reviewed/audited for its security-related properties, so far, and has the
|
* reviewed/audited for its security-related properties, so far. Thus,
|
||||||
* known deficiency of seeding the PRNG only once during initialization. Thus,
|
|
||||||
* we strongly advise against the use of the lx_emul randomness functions for
|
* we strongly advise against the use of the lx_emul randomness functions for
|
||||||
* security-critical purposes.
|
* security-critical purposes.
|
||||||
*/
|
*/
|
||||||
|
@ -11,8 +11,7 @@
|
|||||||
* the lx_emul randomness functions has known statistical problems (see
|
* the lx_emul randomness functions has known statistical problems (see
|
||||||
* https://en.wikipedia.org/wiki/Xoroshiro128%2B#Statistical_Quality).
|
* https://en.wikipedia.org/wiki/Xoroshiro128%2B#Statistical_Quality).
|
||||||
* Furthermore, the integration of Xoroshir128+ with the lx_emul code was not
|
* Furthermore, the integration of Xoroshir128+ with the lx_emul code was not
|
||||||
* reviewed/audited for its security-related properties, so far, and has the
|
* reviewed/audited for its security-related properties, so far. Thus,
|
||||||
* known deficiency of seeding the PRNG only once during initialization. Thus,
|
|
||||||
* we strongly advise against the use of the lx_emul randomness functions for
|
* we strongly advise against the use of the lx_emul randomness functions for
|
||||||
* security-critical purposes.
|
* 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 };
|
public:
|
||||||
if (jent == nullptr) {
|
|
||||||
jitterentropy_init(Lx_kit::env().heap);
|
|
||||||
|
|
||||||
if (jent_entropy_init() != 0) {
|
virtual uint64_t gen_random_u64() = 0;
|
||||||
Genode::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!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
uint64_t result;
|
|
||||||
jent_read_entropy(jent, (char*)&result, sizeof(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static Xoroshiro_128_plus &xoroshiro()
|
/*
|
||||||
|
* 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
|
||||||
{
|
{
|
||||||
static Xoroshiro_128_plus xoroshiro { jitterentropy_gen_random_u64() };
|
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) {
|
||||||
|
error("jitterentropy library could not be initialized!");
|
||||||
|
}
|
||||||
|
_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(_rand_data, (char*)&result, sizeof(result));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static Xoroshiro_128_plus_reseeding &xoroshiro()
|
||||||
|
{
|
||||||
|
static Jitterentropy jitterentropy { Lx_kit::env().heap };
|
||||||
|
static Xoroshiro_128_plus_reseeding xoroshiro { jitterentropy };
|
||||||
return xoroshiro;
|
return xoroshiro;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +194,7 @@ void lx_emul_gen_random_bytes(void *dst,
|
|||||||
{
|
{
|
||||||
/* validate arguments */
|
/* validate arguments */
|
||||||
if (dst == nullptr || nr_of_bytes == 0) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
/* fill up the destination with random 64-bit values as far as possible */
|
/* 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() };
|
uint64_t const rand_u64 { xoroshiro().get_u64() };
|
||||||
Genode::memcpy(dst_char, &rand_u64, nr_of_bytes);
|
Genode::memcpy(dst_char, &rand_u64, nr_of_bytes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user