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();
+}