Add arc4random support to the kernel.

This commit is contained in:
Jonas 'Sortie' Termansen 2015-05-10 22:24:45 +02:00
parent 5ba37a9924
commit 6405e2ea6e
4 changed files with 94 additions and 7 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
sortix/kernel/random.h
Kernel entropy gathering.
*******************************************************************************/
#ifndef INCLUDE_SORTIX_KERNEL_RANDOM_H
#define INCLUDE_SORTIX_KERNEL_RANDOM_H
#include <stddef.h>
namespace Sortix {
namespace Random {
bool HasEntropy();
void GetEntropy(void* buffer, size_t size);
} // namespace Random
} // namespace Sortix
#endif

View File

@ -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 <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sortix/clock.h>
@ -32,10 +34,17 @@
#include <sortix/kernel/time.h>
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;

View File

@ -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 \

View File

@ -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 <assert.h>
#include <endian.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#if !defined(__is_sortix_kernel)
#include <pthread.h>
#endif
#include <unistd.h>
#if defined(__is_sortix_kernel)
#include <sortix/kernel/kthread.h>
#include <sortix/kernel/random.h>
#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 )