mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-19 05:37:54 +00:00
lx_emul & wireguard & wifi: centralized random.cc
Both the Wifi driver and the WireGuard port used local implementations for their source of randomness. Wifi used a Xoroshiro128+ PRNG for rapid generation of random values but initialized this PRNG always with the same static seed value. WireGuard, in contrast, requested each random byte directly from the jitterentropy lib, which is considered to be very time intensive. This commit removes the local variants of random.cc and introduces a new centralized lx_emul/random.cc . The new variant combines the former approaches, so, that jitterentropy is accessed only in order to generate a random seed for a Xoroshiro128+ PRNG. Front-end requests for random values are then fulfilled efficiently via the PRNG. :Warning: The output of the Xoroshiro128+ PRNG that is used in the new implementation of 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, we strongly advise against the use of the lx_emul randomness functions for security-critical purposes. Ref #4397
This commit is contained in:
parent
63b0f1a2f7
commit
ab0bce77ec
@ -19,7 +19,7 @@
|
||||
|
||||
void get_random_bytes(void * buf,int nbytes)
|
||||
{
|
||||
lx_emul_random_bytes(buf, nbytes);
|
||||
lx_emul_gen_random_bytes(buf, nbytes);
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,7 @@ int wait_for_random_bytes(void)
|
||||
u32 get_random_u32(void)
|
||||
{
|
||||
u8 buf[4];
|
||||
lx_emul_random_bytes(buf, sizeof(buf));
|
||||
lx_emul_gen_random_bytes(buf, sizeof(buf));
|
||||
return *((u32*)&buf);
|
||||
}
|
||||
|
||||
@ -47,7 +47,7 @@ u32 get_random_u32(void)
|
||||
u32 prandom_u32(void)
|
||||
{
|
||||
u8 buf[4];
|
||||
lx_emul_random_bytes(buf, sizeof(buf));
|
||||
lx_emul_gen_random_bytes(buf, sizeof(buf));
|
||||
return *((u32*)&buf);
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ u32 prandom_u32(void)
|
||||
|
||||
int __must_check get_random_bytes_arch(void * buf,int nbytes)
|
||||
{
|
||||
lx_emul_random_bytes(buf, nbytes);
|
||||
lx_emul_gen_random_bytes(buf, nbytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
/**
|
||||
* \brief Randomness generation of lx_emul
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2022-01-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _LX_EMUL__RANDOM_H_
|
||||
#define _LX_EMUL__RANDOM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void lx_emul_random_bytes(void * buf, int bytes);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LX_EMUL__RANDOM_H_ */
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* \brief Randomness backend for lx_emul
|
||||
* \author Stefan Kalkowski
|
||||
* \date 2022-01-12
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#include <base/log.h>
|
||||
#include <lx_kit/env.h>
|
||||
#include <lx_emul/random.h>
|
||||
#include <jitterentropy.h>
|
||||
|
||||
|
||||
extern "C" void lx_emul_random_bytes(void * buf, int bytes)
|
||||
{
|
||||
static rand_data * jent = nullptr;
|
||||
|
||||
if (!jent) {
|
||||
jitterentropy_init(Lx_kit::env().heap);
|
||||
|
||||
if (jent_entropy_init() != 0)
|
||||
Genode::error("jitterentropy library could not be initialized!");
|
||||
|
||||
jent = jent_entropy_collector_alloc(0, 0);
|
||||
if (!jent)
|
||||
Genode::error("jitterentropy could not allocate entropy collector!");
|
||||
}
|
||||
|
||||
jent_read_entropy(jent, (char*)buf, bytes);
|
||||
}
|
@ -13,9 +13,10 @@ SRC_CC += ipv4_config.cc
|
||||
SRC_CC += irq.cc
|
||||
SRC_CC += main.cc
|
||||
SRC_CC += nic_connection.cc
|
||||
SRC_CC += random.cc
|
||||
SRC_CC += lx_emul/random.cc
|
||||
SRC_CC += uplink_connection.cc
|
||||
|
||||
vpath %.cc $(GEN_DIR)
|
||||
vpath %.cc $(REP_DIR)/src/lib
|
||||
|
||||
CC_CXX_WARN_STRICT_CONVERSION =
|
||||
|
50
repos/dde_linux/src/include/lx_emul/random.h
Normal file
50
repos/dde_linux/src/include/lx_emul/random.h
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* \brief Source of randomness in lx_emul
|
||||
* \author Josef Soentgen
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin Stein
|
||||
* \date 2022-05-19
|
||||
*
|
||||
* :Warning:
|
||||
*
|
||||
* The output of the Xoroshiro128+ PRNG that is used in the implementation of
|
||||
* 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,
|
||||
* we strongly advise against the use of the lx_emul randomness functions for
|
||||
* security-critical purposes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
#ifndef _LX_EMUL__RANDOM_H_
|
||||
#define _LX_EMUL__RANDOM_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Write a certain number of consecutive, random byte values beginning at
|
||||
* a given address.
|
||||
*/
|
||||
void lx_emul_gen_random_bytes(void *dst,
|
||||
unsigned long nr_of_bytes);
|
||||
|
||||
/**
|
||||
* Return a random unsigned integer value.
|
||||
*/
|
||||
unsigned int lx_emul_gen_random_uint(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _LX_EMUL__RANDOM_H_ */
|
148
repos/dde_linux/src/lib/lx_emul/random.cc
Normal file
148
repos/dde_linux/src/lib/lx_emul/random.cc
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* \brief Source of randomness in lx_emul
|
||||
* \author Josef Soentgen
|
||||
* \author Stefan Kalkowski
|
||||
* \author Martin Stein
|
||||
* \date 2022-05-19
|
||||
*
|
||||
* :Warning:
|
||||
*
|
||||
* The output of the Xoroshiro128+ PRNG that is used in the implementation of
|
||||
* 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,
|
||||
* we strongly advise against the use of the lx_emul randomness functions for
|
||||
* security-critical purposes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2022 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* base/include */
|
||||
#include <base/log.h>
|
||||
#include <base/fixed_stdint.h>
|
||||
#include <util/string.h>
|
||||
|
||||
/* dde_linux/src/include */
|
||||
#include <lx_emul/random.h>
|
||||
#include <lx_kit/env.h>
|
||||
|
||||
/* contrib/linux/src/linux/crypto */
|
||||
#include <jitterentropy.h>
|
||||
|
||||
using namespace Genode;
|
||||
|
||||
/*
|
||||
* Xoroshiro128+ written in 2014-2016 by Sebastiano Vigna (vigna@acm.org)
|
||||
*
|
||||
* (see http://xoroshiro.di.unimi.it/xorshift128plus.c and
|
||||
* http://xoroshiro.di.unimi.it/splitmix64.c)
|
||||
*/
|
||||
class Xoroshiro_128_plus
|
||||
{
|
||||
private:
|
||||
|
||||
uint64_t _seed;
|
||||
uint64_t _s[2];
|
||||
|
||||
uint64_t _splitmix64()
|
||||
{
|
||||
uint64_t z = (_seed += __UINT64_C(0x9E3779B97F4A7C15));
|
||||
z = (z ^ (z >> 30)) * __UINT64_C(0xBF58476D1CE4E5B9);
|
||||
z = (z ^ (z >> 27)) * __UINT64_C(0x94D049BB133111EB);
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
static uint64_t _rotl(uint64_t const x, int k)
|
||||
{
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
Xoroshiro_128_plus(uint64_t seed) : _seed(seed)
|
||||
{
|
||||
_s[0] = _splitmix64();
|
||||
_s[1] = _splitmix64();
|
||||
}
|
||||
|
||||
uint64_t get_u64()
|
||||
{
|
||||
uint64_t const s0 = _s[0];
|
||||
uint64_t s1 = _s[1];
|
||||
uint64_t const result = s0 + s1;
|
||||
|
||||
s1 ^= s0;
|
||||
|
||||
_s[0] = _rotl(s0, 55) ^ s1 ^ (s1 << 14);
|
||||
_s[1] = _rotl(s1, 36);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
static uint64_t jitterentropy_gen_random_u64()
|
||||
{
|
||||
static rand_data *jent { nullptr };
|
||||
if (jent == nullptr) {
|
||||
jitterentropy_init(Lx_kit::env().heap);
|
||||
|
||||
if (jent_entropy_init() != 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()
|
||||
{
|
||||
static Xoroshiro_128_plus xoroshiro { jitterentropy_gen_random_u64() };
|
||||
return xoroshiro;
|
||||
}
|
||||
|
||||
|
||||
void lx_emul_gen_random_bytes(void *dst,
|
||||
unsigned long nr_of_bytes)
|
||||
{
|
||||
/* validate arguments */
|
||||
if (dst == nullptr || nr_of_bytes == 0) {
|
||||
Genode::error("lx_emul_gen_random_bytes called with invalid args!");
|
||||
return;
|
||||
}
|
||||
/* fill up the destination with random 64-bit values as far as possible */
|
||||
char *dst_char { reinterpret_cast<char*>(dst) };
|
||||
unsigned long const nr_of_rounds { nr_of_bytes >> 3 };
|
||||
for (unsigned long round_idx { 0 }; round_idx < nr_of_rounds; round_idx++) {
|
||||
|
||||
uint64_t const rand_u64 { xoroshiro().get_u64() };
|
||||
Genode::memcpy(dst_char, &rand_u64, 8);
|
||||
dst_char += 8;
|
||||
}
|
||||
/* fill up remaining bytes from one additional random 64-bit value */
|
||||
nr_of_bytes -= (nr_of_rounds << 3);
|
||||
if (nr_of_bytes == 0) {
|
||||
return;
|
||||
}
|
||||
uint64_t const rand_u64 { xoroshiro().get_u64() };
|
||||
Genode::memcpy(dst_char, &rand_u64, nr_of_bytes);
|
||||
|
||||
}
|
||||
|
||||
|
||||
unsigned int lx_emul_gen_random_uint()
|
||||
{
|
||||
return (unsigned int)xoroshiro().get_u64();
|
||||
}
|
@ -6,13 +6,13 @@ SHARED_LIB := yes
|
||||
|
||||
LD_OPT += --version-script=$(TARGET_LIB_DIR)/symbol.map
|
||||
|
||||
LIBS += base pc_linux_generated pc_lx_emul
|
||||
LIBS += base jitterentropy pc_linux_generated pc_lx_emul
|
||||
INC_DIR := $(TARGET_LIB_DIR)
|
||||
SRC_CC += wlan.cc
|
||||
SRC_CC += misc.cc
|
||||
SRC_CC += firmware.cc
|
||||
SRC_CC += socket_call.cc
|
||||
SRC_CC += random.cc
|
||||
SRC_CC += lx_emul/random.cc
|
||||
SRC_CC += time.cc
|
||||
|
||||
SRC_C += dummies.c
|
||||
|
@ -1,10 +1,11 @@
|
||||
base
|
||||
genode_c_api
|
||||
jitterentropy
|
||||
libc
|
||||
nic_session
|
||||
openssl
|
||||
os
|
||||
pc_linux
|
||||
nic_session
|
||||
platform_session
|
||||
report_session
|
||||
timer_session
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <lx_emul.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <lx_emul/random.h>
|
||||
#include <lx_emul/alloc.h>
|
||||
#include <lx_emul/io_mem.h>
|
||||
|
||||
@ -442,7 +443,7 @@ void __put_page(struct page * page)
|
||||
|
||||
u32 get_random_u32(void)
|
||||
{
|
||||
return lx_emul_get_random_u32();
|
||||
return lx_emul_gen_random_uint();
|
||||
}
|
||||
|
||||
|
||||
@ -451,7 +452,7 @@ int __must_check get_random_bytes_arch(void *buf, int nbytes)
|
||||
if (nbytes < 0)
|
||||
return -1;
|
||||
|
||||
lx_emul_get_random_bytes(buf, (unsigned long)nbytes);
|
||||
lx_emul_gen_random_bytes(buf, (unsigned long)nbytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -467,13 +468,13 @@ void get_random_bytes(void *buf, int nbytes)
|
||||
|
||||
void prandom_bytes(void *buf, size_t bytes)
|
||||
{
|
||||
lx_emul_get_random_bytes(buf, bytes);
|
||||
lx_emul_gen_random_bytes(buf, bytes);
|
||||
}
|
||||
|
||||
|
||||
u32 prandom_u32(void)
|
||||
{
|
||||
return lx_emul_get_random_u32();
|
||||
return lx_emul_gen_random_uint();
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,9 +28,6 @@ void lx_backtrace(void);
|
||||
|
||||
void lx_emul_time_udelay(unsigned long usec);
|
||||
|
||||
void lx_emul_get_random_bytes(void *buf, unsigned long nbytes);
|
||||
unsigned int lx_emul_get_random_u32(void);
|
||||
|
||||
int lx_emul_rfkill_get_any(void);
|
||||
void lx_emul_rfkill_switch_all(int blocked);
|
||||
|
||||
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* \brief Linux random emulation code
|
||||
* \author Josef Soentgen
|
||||
* \date 2016-10-19
|
||||
*
|
||||
* For all intents and purposes this random back end should be treated
|
||||
* as a gloryfied counter.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2016-2021 Genode Labs GmbH
|
||||
*
|
||||
* This file is distributed under the terms of the GNU General Public License
|
||||
* version 2.
|
||||
*/
|
||||
|
||||
/* Genode includes */
|
||||
#include <base/log.h>
|
||||
#include <base/fixed_stdint.h>
|
||||
#include <util/string.h>
|
||||
|
||||
|
||||
using Genode::uint64_t;
|
||||
|
||||
/*
|
||||
* Xoroshiro128+ written in 2014-2016 by Sebastiano Vigna (vigna@acm.org)
|
||||
*
|
||||
* (see http://xoroshiro.di.unimi.it/xorshift128plus.c and
|
||||
* http://xoroshiro.di.unimi.it/splitmix64.c)
|
||||
*/
|
||||
|
||||
struct Xoroshiro
|
||||
{
|
||||
uint64_t seed;
|
||||
|
||||
uint64_t splitmix64()
|
||||
{
|
||||
uint64_t z = (seed += __UINT64_C(0x9E3779B97F4A7C15));
|
||||
z = (z ^ (z >> 30)) * __UINT64_C(0xBF58476D1CE4E5B9);
|
||||
z = (z ^ (z >> 27)) * __UINT64_C(0x94D049BB133111EB);
|
||||
return z ^ (z >> 31);
|
||||
}
|
||||
|
||||
Xoroshiro(uint64_t seed) : seed(seed)
|
||||
{
|
||||
s[0] = splitmix64();
|
||||
s[1] = splitmix64();
|
||||
}
|
||||
|
||||
uint64_t s[2];
|
||||
|
||||
static uint64_t rotl(uint64_t const x, int k) {
|
||||
return (x << k) | (x >> (64 - k));
|
||||
}
|
||||
|
||||
uint64_t get()
|
||||
{
|
||||
uint64_t const s0 = s[0];
|
||||
uint64_t s1 = s[1];
|
||||
uint64_t const result = s0 + s1;
|
||||
|
||||
s1 ^= s0;
|
||||
|
||||
s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14);
|
||||
s[1] = rotl(s1, 36);
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static Xoroshiro &xoroshiro()
|
||||
{
|
||||
static Xoroshiro inst(0x636864324d766931);
|
||||
return inst;
|
||||
}
|
||||
|
||||
|
||||
/********************
|
||||
** linux/random.h **
|
||||
********************/
|
||||
|
||||
extern "C" void lx_emul_get_random_bytes(void *buf, unsigned long nbytes)
|
||||
{
|
||||
if (!buf || !nbytes)
|
||||
return;
|
||||
|
||||
char *p = reinterpret_cast<char*>(buf);
|
||||
|
||||
unsigned long const rounds = nbytes / 8;
|
||||
for (unsigned long i = 0; i < rounds; i++) {
|
||||
uint64_t const v = xoroshiro().get();
|
||||
|
||||
Genode::memcpy(p, &v, 8);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
unsigned long const remain = nbytes - rounds * 8;
|
||||
if (!remain) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint64_t const v = xoroshiro().get();
|
||||
Genode::memcpy(p, &v, remain);
|
||||
}
|
||||
|
||||
|
||||
extern "C" unsigned int lx_emul_get_random_u32(void)
|
||||
{
|
||||
return (unsigned int)xoroshiro().get();
|
||||
}
|
Loading…
Reference in New Issue
Block a user