我开始于kaslr.c并发现它使用 kaslr_get_random_long() 中定义的kaslr.h 并实施于库/kaslr.c它可能使用 RDRAND(英特尔的硬件 PRNG)、时间戳和至少一个系统计时器来生成更多熵。
unsigned long raw, random = get_boot_seed();
bool use_i8254 = true;
debug_putstr(purpose);
debug_putstr(" KASLR using");
if (has_cpuflag(X86_FEATURE_RDRAND)) {
debug_putstr(" RDRAND");
if (rdrand_long(&raw)) {
random ^= raw;
use_i8254 = false;
}
}
if (has_cpuflag(X86_FEATURE_TSC)) {
debug_putstr(" RDTSC");
raw = rdtsc();
random ^= raw;
use_i8254 = false;
}
if (use_i8254) {
debug_putstr(" i8254");
random ^= i8254();
}
返回值通过一些 asm 循环乘法稍微扩散。
/* Circular multiply for better bit diffusion */
asm(_ASM_MUL "%3"
: "=a" (random), "=d" (raw)
: "a" (random), "rm" (mix_const));
random += raw;
get_boot_seed 似乎是一个非常简单的线性异或 PRNG,其哈希设置为静态 0。它使用依赖于内核启动参数的非常简单的异或。
/* Attempt to create a simple but unpredictable starting entropy. */
static unsigned long get_boot_seed(void)
{
unsigned long hash = 0;
hash = rotate_xor(hash, build_str, sizeof(build_str));
hash = rotate_xor(hash, boot_params, sizeof(*boot_params));
return hash;
}
这似乎是一种“足够好”的方法,并且想知道是否有另一个发行版对其进行了修补以使用更强大的 CSPRNG?对于性能/安全性的权衡,我可以理解这个选择。然而,我相当肯定有人已经修补了这个,以便为硬化内核提供更多选项。