summaryrefslogtreecommitdiff
path: root/kernel/random.c
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2024-07-04 18:29:17 +0200
committerAnton Kling <anton@kling.gg>2024-07-04 18:42:47 +0200
commit7d7f0aa9595bedf50083fb89dae049c1f064ca98 (patch)
tree9f821cb85e6deaf54b8c5b481325c7d9b231d907 /kernel/random.c
parentf7752e37ce29b903e15d2579d25d4ebbaad023e6 (diff)
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.
Diffstat (limited to 'kernel/random.c')
-rw-r--r--kernel/random.c65
1 files changed, 47 insertions, 18 deletions
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,