在random.c
中的内核源代码中random.c
, get_random_int
是“与urandom类似,但是具有最小熵池耗尽的目标”。 但是, get_random_int
在哪里(以及如何)与熵池交互?
现在, urandom
实际上调用了extract_entropy_user
,但是我在get_random_int
中看不到任何类似的东西。 似乎get_random_int
使用自己的熵源(与键盘,鼠标和磁盘活动无关):
hash[0] += current->pid + jiffies + get_cycles();
并且不关心(也不更新)一般系统可用的熵的状态?
get_random_int
如何耗尽熵池? 哪里得到更新? 我知道我错过了某些东西,或者读了错误的源代码,因为当我执行一个程序时,我可以看到它是如何通过在entropy_avail上执行cat来消耗熵池的。
我已经浏览了http://xorl.wordpress.com/2011/01/16/linux-kernel-aslr-implementation/,但似乎没有提到这是如何工作的。
据我所知,它并不直接耗尽熵池。 它只是返回一个低(er)质量的随机数。 它取决于ISN seq生成(定期刷新)使用的秘密散列,它自己的per-cpu状态以及pid / time / cycles。
它与urandom类似,主要是因为它在熵低时不阻塞。
hash[0]
还与一个名为random_int_secret
的哈希混合在一起,该函数在函数random_int_secret_init()
启动早期只生成一次。 它使用get_random_bytes()
生成,这会消耗熵估计。
从drivers / char / random.c中定义了一个函数,它会生成这个一次散列,每次请求一个随机的int时,它会被重用。
static u32 random_int_secret[MD5_MESSAGE_BYTES / 4]; int random_int_secret_init(void) { get_random_bytes(random_int_secret, sizeof(random_int_secret)); /* XXX */ return 0; }
在函数get_random_int()
, random_int_secret
与hash
混合,之后hash[0]
作为请求的随机int返回。
static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash); unsigned int get_random_int(void) { __u32 *hash; unsigned int ret; if (arch_get_random_int(&ret)) return ret; hash = get_cpu_var(get_random_int_hash); hash[0] += current->pid + jiffies + random_get_entropy(); md5_transform(hash, random_int_secret); /* XXX */ ret = hash[0]; put_cpu_var(get_random_int_hash); return ret; } EXPORT_SYMBOL(get_random_int);
在启动过程开始的时候,在init / main.c中,生成这个种子:
static void __init do_basic_setup(void) { cpuset_init_smp(); shmem_init(); driver_init(); init_irq_proc(); do_ctors(); usermodehelper_enable(); do_initcalls(); random_int_secret_init(); /* XXX */ }
关于猫消耗池,我用记住它为什么这样做,但我现在不了了之。 不过,我很确定这不是ASLR,因为在带有RDRAND的系统上, get_random_int()
只能从指令中给出int,没有其他的。 我的系统有RDRAND,而且我也看到在产卵过程中熵计数下降。