Bläddra i källkod

Kernel: Use word-sized entropy as much as possible in syscall

Calvin Buckley 5 år sedan
förälder
incheckning
5050f7b5ee
2 ändrade filer med 19 tillägg och 9 borttagningar
  1. 19 6
      Kernel/Process.cpp
  2. 0 3
      Libraries/LibC/stdlib.cpp

+ 19 - 6
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;
 }

+ 0 - 3
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;
 }