diff options
author | Calvin Buckley <calvin@cmpct.info> | 2019-10-13 12:55:58 -0300 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-10-13 18:03:21 +0200 |
commit | 5050f7b5eec273344ab91335d4ebdbbcbc487689 (patch) | |
tree | 4bd7b401be191d3bcc3fd2bd50a908fdef55c48b | |
parent | aa42f56210bad3253008de1cbbc7e6cf33e46c7e (diff) | |
download | serenity-5050f7b5eec273344ab91335d4ebdbbcbc487689.zip |
Kernel: Use word-sized entropy as much as possible in syscall
-rw-r--r-- | Kernel/Process.cpp | 25 | ||||
-rw-r--r-- | Libraries/LibC/stdlib.cpp | 3 |
2 files changed, 19 insertions, 9 deletions
diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index ed70fc25b7..84f02cef54 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -3088,12 +3088,25 @@ int Process::sys$getrandom(void* buffer, size_t buffer_size, unsigned int flags if (!validate_write(buffer, buffer_size)) return -EFAULT; - // XXX: We probably lose a lot of entropy here, out of an already marginal - // PRNG. A better implementation would not throw away bits for the sake of - // array indexing, and use a better PRNG in the first place. - uint8_t* bytes = (uint8_t*)buffer; - for (size_t i = 0; i < buffer_size; i++) - bytes[i] = (uint8_t)(RandomDevice::random_value() % 255); + + // We prefer to get whole words of entropy. + // If the length is unaligned, we can work with bytes instead. + // Mask out the bottom two bits for words. + size_t words_len = buffer_size & ~3; + if (words_len) { + uint32_t* words = (uint32_t*)buffer; + for (size_t i = 0; i < words_len / 4; i++) + words[i] = RandomDevice::random_value(); + } + // The remaining non-whole word bytes we can fill in. + size_t bytes_len = buffer_size & 3; + if (bytes_len) { + uint8_t* bytes = (uint8_t*)buffer + words_len; + // Get a whole word of entropy to use. + uint32_t word = RandomDevice::random_value(); + for (size_t i = 0; i < bytes_len; i++) + bytes[i] = ((uint8_t*)&word)[i]; + } return 0; } diff --git a/Libraries/LibC/stdlib.cpp b/Libraries/LibC/stdlib.cpp index 791e680f4e..94c23b23a0 100644 --- a/Libraries/LibC/stdlib.cpp +++ b/Libraries/LibC/stdlib.cpp @@ -511,9 +511,6 @@ unsigned long long strtoull(const char* str, char** endptr, int base) uint32_t arc4random(void) { char buf[4]; - // XXX: RandomDevice does return a uint32_t but the syscall works with - // a byte at a time. It could be better optimzied for this use case - // while remaining generic. syscall(SC_getrandom, buf, 4, 0); return *(uint32_t*)buf; } |