diff options
-rw-r--r-- | kernel/drivers/pit.c | 4 | ||||
-rw-r--r-- | kernel/init/kernel.c | 7 | ||||
-rw-r--r-- | kernel/random.c | 65 | ||||
-rw-r--r-- | kernel/random.h | 4 | ||||
-rw-r--r-- | 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 <arch/i386/tsc.h> +#include <random.h> #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 <fs/devfs.h> #include <interrupts.h> #include <math.h> +#include <random.h> #include <time.h> #include <timer.h> #include <typedefs.h> @@ -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()); } |