blob: 268a21f3be38a54c778f88d84fce0f877bbdeb59 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
// MIT License, Copyright (c) 2020 Marvin Borner
#include <def.h>
#include <mem.h>
#include <rand.h>
#ifdef KERNEL
#include <cpu.h>
#endif
static u32 g_seed = 1;
void srand(u32 seed)
{
g_seed = seed;
}
static u32 rand_default(void)
{
g_seed = g_seed * 1103515245 + 12345;
return (g_seed >> 16) & 0x7FFF;
}
static u32 rand_once(void)
{
#ifdef KERNEL
u32 val = 0;
if (cpu_extended_features.ebx & CPUID_EXT_FEAT_EBX_RDSEED) {
__asm__ volatile("1:\n"
"rdseed %0\n"
"jnc 1b\n"
: "=r"(val));
} else if (cpu_features.ecx & CPUID_FEAT_ECX_RDRND) {
__asm__ volatile("1:\n"
"rdrand %0\n"
"jnc 1b\n"
: "=r"(val));
} else {
val = rand_default();
}
return val;
#else
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)
return NULL;
char *buf = malloc(size + 1);
const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
size--;
for (u32 i = 0; i < size; i++) {
int key = rand() % (sizeof(charset) - 1);
buf[i] = charset[key];
}
buf[size] = '\0';
return buf;
}
|