diff options
Diffstat (limited to 'libs/libc/random.c')
-rw-r--r-- | libs/libc/random.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/libs/libc/random.c b/libs/libc/random.c index 983357f..2cd7f93 100644 --- a/libs/libc/random.c +++ b/libs/libc/random.c @@ -15,36 +15,52 @@ void srand(u32 seed) g_seed = seed; } -static u32 default_rand(void) +static u32 rand_default(void) { g_seed = g_seed * 1103515245 + 12345; return (g_seed >> 16) & 0x7FFF; } -u32 rand(void) +static u32 rand_once(void) { #ifdef KERNEL - u32 rd; + u32 val = 0; if (cpu_extended_features.ebx & CPUID_EXT_FEAT_EBX_RDSEED) { __asm__ volatile("1:\n" "rdseed %0\n" "jnc 1b\n" - : "=r"(rd)); + : "=r"(val)); } else if (cpu_features.ecx & CPUID_FEAT_ECX_RDRND) { __asm__ volatile("1:\n" "rdrand %0\n" "jnc 1b\n" - : "=r"(rd)); + : "=r"(val)); } else { - rd = default_rand(); + val = rand_default(); } - return rd; + return val; #else - return default_rand(); + return rand_default(); #endif } +u32 rand(void) +{ + u32 ret = 0; + ret |= (rand_once() & (0xffu << 0)); + ret |= (rand_once() & (0xffu << 8)); + ret |= (rand_once() & (0xffu << 16)); + ret |= (rand_once() & (0xffu << 24)); + return ret; +} + +void rand_fill(void *buf, u32 size) +{ + for (u32 i = 0; i < size; i++) + ((u8 *)buf)[i] = rand_once() & 0xff; +} + char *randstr(u32 size) { if (!size) |