diff --git a/kernel/include/sortix/kernel/random.h b/kernel/include/sortix/kernel/random.h
new file mode 100644
index 00000000..630807f7
--- /dev/null
+++ b/kernel/include/sortix/kernel/random.h
@@ -0,0 +1,39 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2015.
+
+ This file is part of Sortix.
+
+ Sortix is free software: you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option) any later
+ version.
+
+ Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
+
+ sortix/kernel/random.h
+ Kernel entropy gathering.
+
+*******************************************************************************/
+
+#ifndef INCLUDE_SORTIX_KERNEL_RANDOM_H
+#define INCLUDE_SORTIX_KERNEL_RANDOM_H
+
+#include
+
+namespace Sortix {
+namespace Random {
+
+bool HasEntropy();
+void GetEntropy(void* buffer, size_t size);
+
+} // namespace Random
+} // namespace Sortix
+
+#endif
diff --git a/kernel/random.cpp b/kernel/random.cpp
index 85a1d84d..7aaf51ee 100644
--- a/kernel/random.cpp
+++ b/kernel/random.cpp
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2014.
+ Copyright(C) Jonas 'Sortie' Termansen 2014, 2015.
This file is part of Sortix.
@@ -23,6 +23,8 @@
*******************************************************************************/
#include
+#include
+#include
#include
@@ -32,10 +34,17 @@
#include
namespace Sortix {
+namespace Random {
static unsigned long sequence = 0;
-int sys_getentropy(void* user_buffer, size_t size)
+bool HasEntropy()
+{
+ // We only have new entropy once and that's at boot.
+ return sequence == 0;
+}
+
+void GetEntropy(void* result, size_t size)
{
union
{
@@ -48,7 +57,7 @@ int sys_getentropy(void* user_buffer, size_t size)
} seed;
};
if ( sizeof(buffer) < size )
- return errno = EIO, -1;
+ size = sizeof(buffer);
// TODO: SECURITY: We need to actually gather entropy and deliver it.
for ( size_t i = 0; i < size; i++ )
buffer[i] = i;
@@ -60,6 +69,20 @@ int sys_getentropy(void* user_buffer, size_t size)
seed.realtime = Time::Get(CLOCK_REALTIME);
seed.monotonic = Time::Get(CLOCK_MONOTONIC);
seed.sequence = InterlockedIncrement(&sequence).o;
+ memcpy(result, buffer, size);
+}
+
+} // namespace Random
+} // namespace Sortix
+
+namespace Sortix {
+
+int sys_getentropy(void* user_buffer, size_t size)
+{
+ unsigned char buffer[256];
+ if ( sizeof(buffer) < size )
+ return errno = EIO, -1;
+ arc4random_buf(buffer, sizeof(buffer));
if ( !CopyToUser(user_buffer, buffer, size) )
return -1;
return 0;
diff --git a/libc/Makefile b/libc/Makefile
index d4d1708b..3bdd12d7 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -153,6 +153,9 @@ stdio/vsprintf.o \
stdio/vsscanf.o \
stdlib/abort.o \
stdlib/abs.o \
+stdlib/arc4random_buf.o \
+stdlib/arc4random.o \
+stdlib/arc4random_uniform.o \
stdlib/atof.o \
stdlib/atoi.o \
stdlib/atoll.o \
@@ -432,9 +435,6 @@ stdio/tmpfile.o \
stdio/vfprintf.o \
stdio/vprintf.o \
stdio/vscanf.o \
-stdlib/arc4random_buf.o \
-stdlib/arc4random.o \
-stdlib/arc4random_uniform.o \
stdlib/atexit.o \
stdlib/canonicalize_file_name_at.o \
stdlib/canonicalize_file_name.o \
diff --git a/libc/stdlib/arc4random_buf.cpp b/libc/stdlib/arc4random_buf.cpp
index 143a4837..3b9c463e 100644
--- a/libc/stdlib/arc4random_buf.cpp
+++ b/libc/stdlib/arc4random_buf.cpp
@@ -26,16 +26,32 @@
* Public domain.
*/
-/* Adapted for Sortix libc by Jonas 'Sortie' Termansen in 2014. */
+/* Adapted for Sortix libc by Jonas 'Sortie' Termansen in 2014, 2015. */
#include
#include
#include
#include
#include
+#if !defined(__is_sortix_kernel)
#include
+#endif
#include
+#if defined(__is_sortix_kernel)
+#include
+#include
+#endif
+
+#if defined(__is_sortix_kernel)
+#define PTHREAD_MUTEX_INITIALIZER Sortix::KTHREAD_MUTEX_INITIALIZER
+#define pthread_mutex_t Sortix::kthread_mutex_t
+#define pthread_mutex_lock Sortix::kthread_mutex_lock
+#define pthread_mutex_unlock Sortix::kthread_mutex_unlock
+#define getpid() 0
+#define getentropy Sortix::Random::GetEntropy
+#endif
+
struct chacha
{
uint32_t input[16];
@@ -163,6 +179,15 @@ extern "C" void arc4random_buf(void* buffer_ptr, size_t size)
pthread_mutex_lock(&arc4random_mutex);
+#if defined(__is_sortix_kernel)
+ if ( Sortix::Random::HasEntropy() )
+ {
+ rs_count = 0;
+ rs_have = 0;
+ memset(rs_buf, 0, sizeof(rs_buf));
+ }
+#endif
+
/* TODO: Employ zero-memory-on-fork semantics instead. */
/* pid_t are never reused on Sortix at the moment. */
if ( getpid() != rs_pid )