From 7d7f0aa9595bedf50083fb89dae049c1f064ca98 Mon Sep 17 00:00:00 2001 From: Anton Kling Date: Thu, 4 Jul 2024 18:29:17 +0200 Subject: Random: Improve random seeding. Now it appears to be sufficiently good at producing a distinct seed at each boot without using a /etc/seed file. Previously it did not do this. Of course this is nowhere near cryptographically secure but randomness does assist with things such as kmalloc. --- kernel/drivers/pit.c | 4 +++- kernel/init/kernel.c | 7 +++--- kernel/random.c | 65 +++++++++++++++++++++++++++++++++++++--------------- kernel/random.h | 4 ++++ kernel/timer.c | 3 +++ 5 files changed, 61 insertions(+), 22 deletions(-) diff --git a/kernel/drivers/pit.c b/kernel/drivers/pit.c index 70dc0f9..b8a8aac 100644 --- a/kernel/drivers/pit.c +++ b/kernel/drivers/pit.c @@ -1,5 +1,6 @@ #include "pit.h" #include +#include #define PIT_IO_CHANNEL_0 0x40 #define PIT_IO_MODE_COMMAND 0x43 @@ -46,7 +47,8 @@ u64 last_tsc = 0; extern int is_switching_tasks; void int_clock(reg_t *regs) { - + u64 current_tsc = tsc_get(); + random_add_entropy_fast((u8 *)¤t_tsc, sizeof(current_tsc)); switch_counter++; if (clock_num_ms_ticks - last_flush > 50) { tcp_flush_acks(); diff --git a/kernel/init/kernel.c b/kernel/init/kernel.c index 6e5c9b4..4c7ed89 100644 --- a/kernel/init/kernel.c +++ b/kernel/init/kernel.c @@ -60,6 +60,7 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, klog(LOG_SUCCESS, "Paging Initalized"); mb = mmu_map_frames((multiboot_info_t *)addr, sizeof(multiboot_info_t)); assert(mb); + assert(display_driver_init(mb)); gdt_init(); klog(LOG_SUCCESS, "GDT Initalized"); @@ -67,6 +68,8 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, idt_init(); klog(LOG_SUCCESS, "IDT Initalized"); + setup_random(); + timer_start_init(); syscalls_init(); @@ -107,8 +110,6 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, shm_init(); - setup_random(); - add_keyboard(); add_mouse(); @@ -121,8 +122,8 @@ void kernel_main(u32 kernel_end, unsigned long magic, unsigned long addr, setup_network(gateway, bitmask); gen_ipv4(&ip_address, 10, 0, 2, 15); + enable_interrupts(); - assert(display_driver_init(mb)); add_vbe_device(); int pid; if (0 == (pid = fork())) { diff --git a/kernel/random.c b/kernel/random.c index 7c868ed..3ac36f2 100644 --- a/kernel/random.c +++ b/kernel/random.c @@ -104,9 +104,25 @@ void add_hash_pool(void) { memcpy(internal_chacha_block + KEY, new_chacha_key, KEY_SIZE); mix_chacha(); + + u64 seed[4]; + get_random((u8 *)seed, sizeof(seed)); + seed_xoshiro_256_pp(seed); } -void add_entropy(u8 *buffer, size_t size) { +u64 entropy_fast_state = 0; + +static inline uint64_t xorshift64(void) { + uint64_t x = entropy_fast_state; + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + return entropy_fast_state = x; +} + +void random_add_entropy(u8 *buffer, u64 size) { + SHA1_Update(&hash_pool, &entropy_fast_state, sizeof(entropy_fast_state)); + xorshift64(); SHA1_Update(&hash_pool, buffer, size); hash_pool_size += size; if (hash_pool_size >= HASH_LEN * 2) { @@ -114,13 +130,42 @@ void add_entropy(u8 *buffer, size_t size) { } } +void random_add_entropy_fast(u8 *buffer, u64 size) { + for (u64 i = 0; i < size; i++) { + entropy_fast_state ^= (buffer[i] << (8 * (i % 8))); + if (0 == i % 8) { + xorshift64(); + } + } + xorshift64(); +} + void setup_random(void) { SHA1_Init(&hash_pool); + return; +} +int random_write(BYTEPTR buffer, u64 offset, u64 len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + random_add_entropy(buffer, len); + return len; // random_add_entropy() never fails to recieve (len) amount of + // data. +} + +int random_read(BYTEPTR buffer, u64 offset, u64 len, vfs_fd_t *fd) { + (void)offset; + (void)fd; + get_random(buffer, len); + return len; // get_random() never fails to give "len" amount of data. +} + +void add_random_devices(void) { BYTE seed[1024]; int rand_fd = vfs_open("/etc/seed", O_RDWR, 0); if (0 > rand_fd) { klog(LOG_WARN, "/etc/seed not found"); + add_hash_pool(); return; } @@ -130,7 +175,7 @@ void setup_random(void) { klog(LOG_WARN, "/etc/seed read error"); break; } - add_entropy(seed, rc); + random_add_entropy(seed, rc); } add_hash_pool(); @@ -139,23 +184,7 @@ void setup_random(void) { get_random(seed, 1024); vfs_pwrite(rand_fd, seed, 1024, 0); vfs_close(rand_fd); -} - -int random_write(BYTEPTR buffer, u64 offset, u64 len, vfs_fd_t *fd) { - (void)offset; - (void)fd; - add_entropy(buffer, len); - return len; // add_entropy() never fails to recieve (len) amount of data. -} -int random_read(BYTEPTR buffer, u64 offset, u64 len, vfs_fd_t *fd) { - (void)offset; - (void)fd; - get_random(buffer, len); - return len; // get_random() never fails to give "len" amount of data. -} - -void add_random_devices(void) { devfs_add_file("/random", random_read, random_write, NULL, always_has_data, always_can_write, FS_TYPE_CHAR_DEVICE); devfs_add_file("/urandom", random_read, random_write, NULL, always_has_data, diff --git a/kernel/random.h b/kernel/random.h index 9a44bb3..533209e 100644 --- a/kernel/random.h +++ b/kernel/random.h @@ -6,3 +6,7 @@ void setup_random(void); void add_random_devices(void); void get_random(u8 *buffer, u64 len); void get_fast_insecure_random(u8 *buffer, u64 len); +void random_add_entropy(u8 *buffer, u64 size); +// A interface that is not as expensive to run in comparison to +// random_add_entropy which may take longer. +void random_add_entropy_fast(u8 *buffer, u64 size); diff --git a/kernel/timer.c b/kernel/timer.c index d0ef113..2121462 100644 --- a/kernel/timer.c +++ b/kernel/timer.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -14,6 +15,7 @@ u64 start_tsc_time; void timer_start_init(void) { tsc_init(); start_tsc_time = tsc_get(); + random_add_entropy((u8 *)&start_tsc_time, sizeof(start_tsc_time)); enable_interrupts(); cmos_init(); cmos_start_call(1, &has_unix_time, &start_unix_time); @@ -26,6 +28,7 @@ void timer_wait_for_init(void) { ; } +u64 timer_current_uptime = 0; // This gets updated by the PIT handler u64 timer_get_uptime(void) { return tsc_calculate_ms(tsc_get()); } -- cgit v1.2.3