diff --git a/kernel/kernel.c b/kernel/kernel.c index 189e4ac1..5c3c37c2 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -17,6 +17,7 @@ #include "networking/processes/net_proc.h" #include "memory/page_allocator.h" #include "networking/network.h" +#include "math/random.h" void kernel_main() { @@ -27,7 +28,11 @@ void kernel_main() { enable_uart(); kprintf_l("UART output enabled"); // enable_talloc_verbose(); - + uint64_t seed; + asm volatile("mrs %0, cntvct_el0" : "=r"(seed)); //virtual timer counter as entropy source for rng seed + rng_init_global(seed); + kprintf("Random init. seed: %i\n", seed); + //kprintf("Next32: %i\n", rng_next32(&global_rng)); set_exception_vectors(); kprintf_l("Exception vectors set"); @@ -86,4 +91,4 @@ void kernel_main() { panic("Kernel did not activate any process"); -} \ No newline at end of file +} diff --git a/shared/math/random.c b/shared/math/random.c new file mode 100644 index 00000000..f9e17dba --- /dev/null +++ b/shared/math/random.c @@ -0,0 +1,84 @@ +#include "random.h" +#include "std/memfunctions.h" + +rng_t global_rng; + +void rng_seed(rng_t* rng, uint64_t seed){ //i guess it is "private", no definition in header + uint64_t z = seed + 0x9E3779B97F4A7C15; + z = (z ^ (z >> 30)) * 0xBF58476D1CE4E5B9; + z = (z ^ (z >> 27)) *0x94D049BB133111EB; + rng->s0 = z ^ (z >> 31); + + z = seed + 0x9E3779B97F4A7C15 + 1; + z = (z ^ (z >> 30)) *0xBF58476D1CE4E5B9; + z = (z ^ (z >> 27))*0x94D049BB133111EB; + rng->s1 = z ^ (z >> 31); +} + +uint64_t rng_next64(rng_t* rng){ + uint64_t s0 = rng->s0; + uint64_t s1 = rng->s1; + uint64_t result = s0 + s1; + + s1 ^= s0; + rng->s0 = rotl(s0, 55)^s1^(s1 << 14); + rng->s1 = rotl(s1, 36); + + return result; +} + +uint32_t rng_next32(rng_t* rng){ + return (uint32_t)(rng_next64(rng) >> 32); +} + +uint16_t rng_next16(rng_t* rng){ + return (uint16_t)(rng_next64(rng) >> 48); +} + +uint8_t rng_next8(rng_t* rng){ + return (uint8_t)(rng_next64(rng) >> 56); +} + +uint64_t rng_between64(rng_t* rng, uint64_t min, uint64_t max){ + if (max <= min) return min; + return rng_next64(rng) % (max - min) + min; +} + +uint32_t rng_between32(rng_t* rng, uint32_t min, uint32_t max){ + if (max <= min) return min; + return rng_next64(rng) % (max - min) + min; +} + +uint16_t rng_between16(rng_t* rng, uint16_t min, uint16_t max){ + if (max <= min) return min; + return (uint16_t)(rng_next64(rng) % (max - min)) + min; +} + +uint8_t rng_between8(rng_t* rng, uint8_t min, uint8_t max){ + if (max <= min) return min; + return (uint8_t)(rng_next64(rng) % (max - min)) + min; +} + +void rng_fill64(rng_t* rng, uint64_t* dst, uint32_t count){ + for (uint32_t i = 0; i < count; i++) + dst[i] = rng_next64(rng); +} + +void rng_fill32(rng_t* rng, uint32_t* dst, uint32_t count){ + for (uint32_t i = 0; i < count; i++) + dst[i] = rng_next32(rng); +} + +void rng_fill16(rng_t* rng, uint16_t* dst, uint32_t count){ + for (uint32_t i = 0; i < count; i++) + dst[i] = rng_next16(rng); +} + +void rng_fill8(rng_t* rng, uint8_t* dst, uint32_t count){ + for (uint32_t i = 0; i < count; i++) + dst[i] = rng_next8(rng); +} + +void rng_init_global(uint64_t seed) { + rng_seed(&global_rng, seed); +} diff --git a/shared/math/random.h b/shared/math/random.h new file mode 100644 index 00000000..dabba730 --- /dev/null +++ b/shared/math/random.h @@ -0,0 +1,41 @@ +#pragma once + +#include "types.h" + +#ifdef __cplusplus +extern "C" { +#endif +//xoroshiro128+, pseudorandom +typedef struct{ + uint64_t s0; + uint64_t s1; +}rng_t; + +static inline uint64_t rotl(uint64_t x, int k){ + return (x << k)|(x >> (64 - k)); +} +extern rng_t global_rng; //use &global_rng as rng_t* rng argument +//init +void rng_init_global(uint64_t seed); +//single random +uint8_t rng_next8(rng_t* rng); +uint16_t rng_next16(rng_t* rng); +uint32_t rng_next32(rng_t* rng); +uint64_t rng_next64(rng_t* rng); + +//random in range +uint8_t rng_between8(rng_t* rng, uint8_t min, uint8_t max); +uint16_t rng_between16(rng_t* rng, uint16_t min, uint16_t max); +uint32_t rng_between32(rng_t* rng, uint32_t min, uint32_t max); +uint64_t rng_between64(rng_t* rng, uint64_t min, uint64_t max); + +//array fill +void rng_fill8(rng_t* rng, uint8_t* dst, uint32_t count); +void rng_fill16(rng_t* rng, uint16_t* dst, uint32_t count); +void rng_fill32(rng_t* rng, uint32_t* dst, uint32_t count); +void rng_fill64(rng_t* rng, uint64_t* dst, uint32_t count); + +#ifdef __cplusplus +} +#endif + diff --git a/shared/net/dhcp.c b/shared/net/dhcp.c index 0245b152..9e098070 100644 --- a/shared/net/dhcp.c +++ b/shared/net/dhcp.c @@ -1,5 +1,6 @@ #include "dhcp.h" #include "std/memfunctions.h" +#include "math/random.h" void create_dhcp_packet(uintptr_t p, dhcp_request *payload){ network_connection_ctx source = (network_connection_ctx){ @@ -15,7 +16,7 @@ void create_dhcp_packet(uintptr_t p, dhcp_request *payload){ .htype = 1,//Ethernet .hlen = 6,//Mac length .hops = 0, - .xid = 372,//Transaction ID: Static, could be random + .xid = rng_next32(&global_rng),//Transaction ID: RANDOM .secs = 0, .flags = __builtin_bswap16(0x8000),//Broadcast .ciaddr = 0, @@ -63,4 +64,6 @@ uint16_t dhcp_parse_option(dhcp_packet *pack, uint16_t option){ if (pack->options[i] == option) return i; return 0; -} \ No newline at end of file +} + +