Increase randomness quality by adding rdseed instruction support
diff --git a/qloader2.bin b/qloader2.bin
index dc477f15..39b12f50 100644
Binary files a/qloader2.bin and b/qloader2.bin differ
diff --git a/src/lib/rand.c b/src/lib/rand.c
index ff3550ef..56889b86 100644
--- a/src/lib/rand.c
+++ b/src/lib/rand.c
@@ -19,6 +19,17 @@
ret; \
})
+#define rdseed(type) ({ \
+ type ret; \
+ asm volatile ( \
+ "1: " \
+ "rdrand %0;" \
+ "jnc 1b;" \
+ : "=r" (ret) \
+ ); \
+ ret; \
+})
+
#define rdtsc(type) ({ \
type ret; \
asm volatile ( \
@@ -28,27 +39,25 @@
ret; \
})
-static bool rdrand_available = false;
-
-void init_rand(void) {
- {
- uint32_t eax, ebx, ecx, edx;
- int ret = cpuid(1, 0, &eax, &ebx, &ecx, &edx);
-
- if (!ret && (ecx & (1 << 30)))
- rdrand_available = true;
- }
+static bool rand_initialised = false;
+static void init_rand(void) {
uint32_t seed = ((uint32_t)0xc597060c * rdtsc(uint32_t))
* ((uint32_t)0xce86d624)
^ ((uint32_t)0xee0da130 * rdtsc(uint32_t));
- if (!rdrand_available) {
- srand(seed);
- } else {
+ uint32_t eax, ebx, ecx, edx;
+
+ // Check for rdseed
+ if (!cpuid(0x07, 0, &eax, &ebx, &ecx, &edx) && (ebx & (1 << 18))) {
+ seed *= (seed ^ rdseed(uint32_t));
+ } else if (!cpuid(0x01, 0, &eax, &ebx, &ecx, &edx) && (ecx & (1 << 30))) {
seed *= (seed ^ rdrand(uint32_t));
- srand(seed);
}
+
+ srand(seed);
+
+ rand_initialised = true;
}
#define n ((int)624)
@@ -67,6 +76,9 @@ void srand(uint32_t s) {
}
uint32_t rand32(void) {
+ if (!rand_initialised)
+ init_rand();
+
const uint32_t mag01[2] = {0, matrix_a};
if (ctr >= n) {
diff --git a/src/lib/rand.h b/src/lib/rand.h
index 0a2f88a3..75764d29 100644
--- a/src/lib/rand.h
+++ b/src/lib/rand.h
@@ -3,8 +3,6 @@
#include <stdint.h>
-void init_rand(void);
-
void srand(uint32_t s);
uint32_t rand32(void);
diff --git a/src/main.c b/src/main.c
index 725e0f19..7807463a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,7 +22,6 @@ asm (
#include <lib/config.h>
#include <lib/e820.h>
#include <lib/print.h>
-#include <lib/rand.h>
#include <fs/file.h>
#include <lib/elf.h>
#include <protos/stivale.h>
@@ -99,7 +98,6 @@ refresh:
void main(int boot_drive) {
// Initial prompt.
init_vga_textmode();
- init_rand();
print("qloader2\n\n");
