diff --git a/repos/dde_linux/src/app/wireguard/lx_emul.c b/repos/dde_linux/src/app/wireguard/lx_emul.c index 730dc18635..bed8660613 100644 --- a/repos/dde_linux/src/app/wireguard/lx_emul.c +++ b/repos/dde_linux/src/app/wireguard/lx_emul.c @@ -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; } diff --git a/repos/dde_linux/src/app/wireguard/lx_emul/random.h b/repos/dde_linux/src/app/wireguard/lx_emul/random.h deleted file mode 100644 index 9ed5f1eef0..0000000000 --- a/repos/dde_linux/src/app/wireguard/lx_emul/random.h +++ /dev/null @@ -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_ */ diff --git a/repos/dde_linux/src/app/wireguard/random.cc b/repos/dde_linux/src/app/wireguard/random.cc deleted file mode 100644 index f6e7dd8936..0000000000 --- a/repos/dde_linux/src/app/wireguard/random.cc +++ /dev/null @@ -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 -#include -#include -#include - - -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); -} diff --git a/repos/dde_linux/src/app/wireguard/target.inc b/repos/dde_linux/src/app/wireguard/target.inc index 7cf9ebe747..0080d06b74 100644 --- a/repos/dde_linux/src/app/wireguard/target.inc +++ b/repos/dde_linux/src/app/wireguard/target.inc @@ -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 = diff --git a/repos/dde_linux/src/include/lx_emul/random.h b/repos/dde_linux/src/include/lx_emul/random.h new file mode 100644 index 0000000000..143090cba4 --- /dev/null +++ b/repos/dde_linux/src/include/lx_emul/random.h @@ -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_ */ diff --git a/repos/dde_linux/src/lib/lx_emul/random.cc b/repos/dde_linux/src/lib/lx_emul/random.cc new file mode 100644 index 0000000000..6a4b114dad --- /dev/null +++ b/repos/dde_linux/src/lib/lx_emul/random.cc @@ -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 +#include +#include + +/* dde_linux/src/include */ +#include +#include + +/* contrib/linux/src/linux/crypto */ +#include + +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(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(); +} diff --git a/repos/pc/lib/mk/wifi.inc b/repos/pc/lib/mk/wifi.inc index 0db265de1a..2115410fd8 100644 --- a/repos/pc/lib/mk/wifi.inc +++ b/repos/pc/lib/mk/wifi.inc @@ -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 diff --git a/repos/pc/recipes/src/pc_wifi_drv/used_apis b/repos/pc/recipes/src/pc_wifi_drv/used_apis index e00fd16fee..300a5d60a2 100644 --- a/repos/pc/recipes/src/pc_wifi_drv/used_apis +++ b/repos/pc/recipes/src/pc_wifi_drv/used_apis @@ -1,10 +1,11 @@ base genode_c_api +jitterentropy libc +nic_session openssl os pc_linux -nic_session platform_session report_session timer_session diff --git a/repos/pc/src/lib/wifi/lx_emul.c b/repos/pc/src/lib/wifi/lx_emul.c index 813b771e2f..f950e464e1 100644 --- a/repos/pc/src/lib/wifi/lx_emul.c +++ b/repos/pc/src/lib/wifi/lx_emul.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -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(); } diff --git a/repos/pc/src/lib/wifi/lx_emul.h b/repos/pc/src/lib/wifi/lx_emul.h index 86c5220732..0915c039ac 100644 --- a/repos/pc/src/lib/wifi/lx_emul.h +++ b/repos/pc/src/lib/wifi/lx_emul.h @@ -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); diff --git a/repos/pc/src/lib/wifi/random.cc b/repos/pc/src/lib/wifi/random.cc deleted file mode 100644 index cd8ee6bafe..0000000000 --- a/repos/pc/src/lib/wifi/random.cc +++ /dev/null @@ -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 -#include -#include - - -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(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(); -}