mirror of
https://github.com/limine-bootloader/limine
synced 2024-12-23 22:36:48 +03:00
Add a more proper rand implementation
This commit is contained in:
parent
045c4078a0
commit
42906fef15
BIN
qloader2.bin
BIN
qloader2.bin
Binary file not shown.
101
src/lib/rand.c
Normal file
101
src/lib/rand.c
Normal file
@ -0,0 +1,101 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include <lib/blib.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/rand.h>
|
||||
|
||||
// TODO: Find where this mersenne twister implementation is inspired from
|
||||
// and properly credit the original author(s).
|
||||
|
||||
#define rdrand(type) ({ \
|
||||
type ret; \
|
||||
asm volatile ( \
|
||||
"1: " \
|
||||
"rdrand %0;" \
|
||||
"jnc 1b;" \
|
||||
: "=r" (ret) \
|
||||
); \
|
||||
ret; \
|
||||
})
|
||||
|
||||
#define rdtsc(type) ({ \
|
||||
type ret; \
|
||||
asm volatile ( \
|
||||
"rdtsc;" \
|
||||
: "=A" (ret) \
|
||||
); \
|
||||
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;
|
||||
}
|
||||
|
||||
uint32_t seed = ((uint32_t)0xc597060c * rdtsc(uint32_t))
|
||||
* ((uint32_t)0xce86d624)
|
||||
^ ((uint32_t)0xee0da130 * rdtsc(uint32_t));
|
||||
|
||||
if (!rdrand_available) {
|
||||
srand(seed);
|
||||
} else {
|
||||
seed *= (seed ^ rdrand(uint32_t));
|
||||
srand(seed);
|
||||
}
|
||||
}
|
||||
|
||||
#define n ((int)624)
|
||||
#define m ((int)397)
|
||||
#define matrix_a ((uint32_t)0x9908b0df)
|
||||
#define msb ((uint32_t)0x80000000)
|
||||
#define lsbs ((uint32_t)0x7fffffff)
|
||||
|
||||
static uint32_t status[n];
|
||||
static int ctr;
|
||||
|
||||
void srand(uint32_t s) {
|
||||
status[0] = s;
|
||||
for (ctr = 1; ctr < n; ctr++)
|
||||
status[ctr] = (1812433253 * (status[ctr - 1] ^ (status[ctr - 1] >> 30)) + ctr);
|
||||
}
|
||||
|
||||
uint32_t rand32(void) {
|
||||
const uint32_t mag01[2] = {0, matrix_a};
|
||||
|
||||
if (ctr >= n) {
|
||||
for (int kk = 0; kk < n - m; kk++) {
|
||||
uint32_t y = (status[kk] & msb) | (status[kk + 1] & lsbs);
|
||||
status[kk] = status[kk + m] ^ (y >> 1) ^ mag01[y & 1];
|
||||
}
|
||||
|
||||
for (int kk = n - m; kk < n - 1; kk++) {
|
||||
uint32_t y = (status[kk] & msb) | (status[kk + 1] & lsbs);
|
||||
status[kk] = status[kk + (m - n)] ^ (y >> 1) ^ mag01[y & 1];
|
||||
}
|
||||
|
||||
uint32_t y = (status[n - 1] & msb) | (status[0] & lsbs);
|
||||
status[n - 1] = status[m - 1] ^ (y >> 1) ^ mag01[y & 1];
|
||||
|
||||
ctr = 0;
|
||||
}
|
||||
|
||||
uint32_t res = status[ctr++];
|
||||
|
||||
res ^= (res >> 11);
|
||||
res ^= (res << 7) & 0x9d2c5680;
|
||||
res ^= (res << 15) & 0xefc60000;
|
||||
res ^= (res >> 18);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
uint64_t rand64(void) {
|
||||
return (((uint64_t)rand32()) << 32) | (uint64_t)rand32();
|
||||
}
|
13
src/lib/rand.h
Normal file
13
src/lib/rand.h
Normal file
@ -0,0 +1,13 @@
|
||||
#ifndef __LIB__RAND_H__
|
||||
#define __LIB__RAND_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void init_rand(void);
|
||||
|
||||
void srand(uint32_t s);
|
||||
|
||||
uint32_t rand32(void);
|
||||
uint64_t rand64(void);
|
||||
|
||||
#endif
|
@ -1,48 +0,0 @@
|
||||
#include <lib/blib.h>
|
||||
|
||||
int rdrand_available = 0;
|
||||
|
||||
static void check_rdrand(void) {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
int ret = cpuid(1, 0, &eax, &ebx, &ecx, &edx);
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
if (ecx & (1 << 30))
|
||||
rdrand_available = 1;
|
||||
}
|
||||
|
||||
static void init_simple_rand(void) {
|
||||
// TODO: Some fallback randomness init
|
||||
}
|
||||
|
||||
void init_random(void) {
|
||||
check_rdrand();
|
||||
if (!rdrand_available) {
|
||||
init_simple_rand();
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t rdrand(void) {
|
||||
uint32_t val;
|
||||
|
||||
asm (
|
||||
"1:rdrand %0\n\t"
|
||||
"jnc 1b\n\t"
|
||||
:"=r"(val)
|
||||
);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static uint32_t simple_rand(void) {
|
||||
// TODO: Some fallback randomness
|
||||
return 0xFEEDFACE;
|
||||
}
|
||||
|
||||
uint32_t get_random(void) {
|
||||
if (rdrand_available)
|
||||
return rdrand();
|
||||
else
|
||||
return simple_rand();
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
#ifndef __LIB__RANDOM_H__
|
||||
#define __LIB__RANDOM_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void init_random(void);
|
||||
|
||||
uint32_t get_random(void);
|
||||
|
||||
#endif
|
@ -22,7 +22,7 @@ asm (
|
||||
#include <lib/config.h>
|
||||
#include <lib/e820.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/random.h>
|
||||
#include <lib/rand.h>
|
||||
#include <fs/file.h>
|
||||
#include <lib/elf.h>
|
||||
#include <protos/stivale.h>
|
||||
@ -99,7 +99,7 @@ refresh:
|
||||
void main(int boot_drive) {
|
||||
// Initial prompt.
|
||||
init_vga_textmode();
|
||||
init_random();
|
||||
init_rand();
|
||||
|
||||
print("qloader2\n\n");
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <lib/config.h>
|
||||
#include <lib/time.h>
|
||||
#include <lib/print.h>
|
||||
#include <lib/random.h>
|
||||
#include <lib/rand.h>
|
||||
#include <lib/real.h>
|
||||
#include <drivers/vbe.h>
|
||||
#include <drivers/vga_textmode.h>
|
||||
@ -110,7 +110,7 @@ void stivale_load(char *cmdline, int boot_drive) {
|
||||
|
||||
if (!ret && ((stivale_hdr.flags >> 2) & 1)) {
|
||||
// KASLR is enabled, set the slide
|
||||
slide = get_random() & KASLR_SLIDE_BITMASK;
|
||||
slide = rand64() & KASLR_SLIDE_BITMASK;
|
||||
|
||||
// Re-read the .stivalehdr with slid relocations
|
||||
ret = elf64_load_section(fd, &stivale_hdr, ".stivalehdr", sizeof(struct stivale_header), slide);
|
||||
|
Loading…
Reference in New Issue
Block a user