Add basic urandom device
This commit is contained in:
+2
-1
@@ -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 \
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
#include "sys/types.h"
|
||||
|
||||
void random_init(uint64_t seed);
|
||||
uint64_t random_single(void);
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user