diff --git a/random.c b/random.c index 3fa1096..0cbb74d 100644 --- a/random.c +++ b/random.c @@ -1,4 +1,5 @@ #include +#include #include @@ -22,12 +23,27 @@ void get_random_seed(void *buf, size_t size) { } } -void random_state_init(UNUSED struct random_state *state) { +void random_state_init(struct random_state *state) { + state->index = RANDOM_CACHE_SIZE; } -// TODO: add ChaCha20-based CSPRNG, for now avoid using this other than during initialization... -void get_random_bytes(UNUSED struct random_state *state, void *buf, size_t size) { - get_random_seed(buf, size); +void get_random_bytes(struct random_state *state, void *buf, size_t size) { + if (size > RANDOM_CACHE_SIZE / 2) { + get_random_seed(buf, size); + return; + } + + while (size) { + if (state->index == RANDOM_CACHE_SIZE) { + state->index = 0; + get_random_seed(state->cache, RANDOM_CACHE_SIZE); + } + size_t remaining = RANDOM_CACHE_SIZE - state->index; + size_t copy_size = size < remaining ? size : remaining; + memcpy(buf, state->cache + state->index, copy_size); + state->index += copy_size; + size -= copy_size; + } } size_t get_random_size(struct random_state *state) { diff --git a/random.h b/random.h index 613e75f..40f97ee 100644 --- a/random.h +++ b/random.h @@ -1,8 +1,13 @@ #ifndef RANDOM_H #define RANDOM_H +#include + +#define RANDOM_CACHE_SIZE 4096 + struct random_state { - char unused; + size_t index; + uint8_t cache[RANDOM_CACHE_SIZE]; }; void get_random_seed(void *buf, size_t size);