diff --git a/repos/dde_linux/lib/mk/lxip.mk b/repos/dde_linux/lib/mk/lxip.mk index a9f20a5e82..82f7f3ee26 100644 --- a/repos/dde_linux/lib/mk/lxip.mk +++ b/repos/dde_linux/lib/mk/lxip.mk @@ -27,7 +27,7 @@ CC_C_OPT += -include $(LIB_INC_DIR)/lx_emul.h CC_CXX_OPT = -fpermissive SRC_CC = dummies.cc lxcc_emul.cc nic_handler.cc socket_handler.cc \ - timer_handler.cc + timer_handler.cc random.cc SRC_CC += malloc.cc printf.cc diff --git a/repos/dde_linux/src/lib/lxip/include/lx_emul.h b/repos/dde_linux/src/lib/lxip/include/lx_emul.h index 30f1231f19..7d69a1282f 100644 --- a/repos/dde_linux/src/lib/lxip/include/lx_emul.h +++ b/repos/dde_linux/src/lib/lxip/include/lx_emul.h @@ -3186,22 +3186,14 @@ static inline bool ipv4_is_loopback(__be32 addr) ** linux/random.h ** ********************/ -static inline void get_random_bytes(void *buf, int nbytes) -{ - char *b = (char *)buf; - - /* FIXME not random */ - int i; - for (i = 0; i < nbytes; ++i) - b[i] = i + 1; -} +void get_random_bytes(void *buf, int nbytes); static inline void get_random_once(void *buf, int nbytes) { return get_random_bytes(buf, nbytes); } -static inline u32 prandom_u32(void) { return 4; /* fair dice roll */ } +u32 prandom_u32(void); static inline void prandom_bytes(void *buf, size_t nbytes) { diff --git a/repos/dde_linux/src/lib/lxip/random.cc b/repos/dde_linux/src/lib/lxip/random.cc new file mode 100644 index 0000000000..5613183c76 --- /dev/null +++ b/repos/dde_linux/src/lib/lxip/random.cc @@ -0,0 +1,104 @@ +/** + * \brief Linux random emulation code + * \author Josef Soentgen + * \date 2016-10-19 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* Genode includes */ +#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(42); + + +/******************** + ** linux/random.h ** + ********************/ + +extern "C" void get_random_bytes(void *buf, int nbytes) +{ + if (nbytes <= 0) { + return; + } + + char *p = reinterpret_cast(buf); + + int const rounds = nbytes / 8; + for (int i = 0; i < rounds; i++) { + uint64_t const v = xoroshiro.get(); + + Genode::memcpy(p, &v, 8); + p += 8; + } + + int const remain = nbytes - rounds * 8; + if (!remain) { + return; + } + + uint64_t const v = xoroshiro.get(); + Genode::memcpy(p, &v, remain); +} + + +extern "C" unsigned int prandom_u32(void) +{ + return xoroshiro.get(); +}