Add basic urandom device

This commit is contained in:
Mark
2020-01-09 15:28:02 +02:00
parent 9da01f0d46
commit ecf8fe5d46
5 changed files with 79 additions and 1 deletions
+2 -1
View File
@@ -69,7 +69,8 @@ OBJS+=$(O)/sys/debug.o \
$(O)/sys/net/netdev.o \
$(O)/sys/vfs/pseudo.o \
$(O)/sys/vfs/pty.o \
$(O)/sys/reboot.o
$(O)/sys/reboot.o \
$(O)/sys/random.o
ifeq ($(VESA_ENABLE),1)
OBJS+=$(O)/sys/psf.o \
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "sys/types.h"
void random_init(uint64_t seed);
uint64_t random_single(void);
+14
View File
@@ -14,6 +14,8 @@
#include "sys/amd64/hw/ps2.h"
#include "sys/amd64/hw/rtc.h"
#include "sys/amd64/hw/con.h"
#include "sys/random.h"
#include "sys/time.h"
#include "sys/panic.h"
#include "sys/assert.h"
#include "sys/fs/vfs.h"
@@ -24,6 +26,15 @@
static multiboot_info_t *multiboot_info;
static void amd64_make_random_seed(void) {
struct rtc_time t;
rtc_read(&t);
uint64_t s = 137831;
s += t.second + t.minute * 60 + t.hour * 3600 + t.day * 86400;
random_init(s + system_time);
}
void kernel_main(struct amd64_loader_data *data) {
// Reinitialize RS232 properly
ps2_init();
@@ -56,6 +67,9 @@ void kernel_main(struct amd64_loader_data *data) {
tarfs_init();
}
// Initial random seed
amd64_make_random_seed();
#if defined(AMD64_SMP)
amd64_smp_init();
#endif
+25
View File
@@ -0,0 +1,25 @@
#include "sys/random.h"
#include "sys/panic.h"
#include "sys/debug.h"
static int random_ready = 0;
static uint64_t xs64_state;
void random_init(uint64_t s) {
if (random_ready) {
kinfo("Random is ready already\n");
}
random_ready = 1;
xs64_state = s;
}
uint64_t random_single(void) {
if (!random_ready) {
panic("Random was not ready\n");
}
uint64_t x = xs64_state;
x ^= x << 13;
x ^= x >> 7;
x ^= x << 17;
return xs64_state = x;
}
+33
View File
@@ -1,15 +1,31 @@
#include "sys/string.h"
#include "sys/random.h"
#include "sys/panic.h"
#include "sys/errno.h"
#include "sys/attr.h"
#include "sys/blk.h"
#include "sys/dev.h"
#define DEV_ZERO 0
#define DEV_NULL 1
#define DEV_URANDOM 2
static ssize_t pseudo_write(struct blkdev *dev, const void *buf, size_t pos, size_t lim);
static ssize_t pseudo_read(struct blkdev *dev, void *buf, size_t pos, size_t lim);
static void urandom_fill(void *buf, size_t lim) {
uint64_t val;
size_t i = 0;
while (i < lim) {
val = random_single();
memcpy(buf + i, &val, MIN(lim - i, 8));
i += 8;
}
}
static struct blkdev _dev_null = {
.dev_data = (void *) DEV_NULL,
.write = pseudo_write,
@@ -32,12 +48,25 @@ static struct dev_entry _ent_zero = {
.dev_subclass = DEV_BLOCK_PSEUDO,
.dev_name = "zero"
};
static struct blkdev _dev_urandom = {
.dev_data = (void *) DEV_URANDOM,
.write = pseudo_write,
.read = pseudo_read
};
static struct dev_entry _ent_urandom = {
.dev = &_dev_urandom,
.dev_class = DEV_CLASS_BLOCK,
.dev_subclass = DEV_BLOCK_PSEUDO,
.dev_name = "urandom"
};
static ssize_t pseudo_write(struct blkdev *dev, const void *buf, size_t pos, size_t lim) {
switch ((uint64_t) dev->dev_data) {
case DEV_NULL:
case DEV_ZERO:
return lim;
case DEV_URANDOM:
return -EINVAL;
default:
panic("Unexpected dev id: %p\n", dev->dev_data);
}
@@ -50,6 +79,9 @@ static ssize_t pseudo_read(struct blkdev *dev, void *buf, size_t pos, size_t lim
return lim;
case DEV_NULL:
return 0;
case DEV_URANDOM:
urandom_fill(buf, lim);
return lim;
default:
panic("Unexpected dev id: %p\n", dev->dev_data);
}
@@ -58,4 +90,5 @@ static ssize_t pseudo_read(struct blkdev *dev, void *buf, size_t pos, size_t lim
static __init void pseudo_init(void) {
dev_entry_add(&_ent_null);
dev_entry_add(&_ent_zero);
dev_entry_add(&_ent_urandom);
}