函数add_disk_randomness如何工作?

时间:2018-07-31 20:35:28

标签: random linux-kernel

我试图从Linux内核中了解add_disk_randomness函数。我读了几篇论文,但是他们对它的描述不太好。这段代码来自/drivers/char/random.c

add_timer_randomness(disk->random, 0x100 + disk_devt(disk));

disk_devt(disk)保存变量disk->devt。我将其理解为唯一的块设备编号。但是主要和次要设备号是什么?

然后将块设备号和十六进制0x100加在一起。

然后,我们还收集时间值disk->random。这是每个块的寻道时间吗?

这两个值将传递给函数add_timer_randomness。最好有一个带有值的例子。

1 个答案:

答案 0 :(得分:4)

add_timer_randomness的第一个参数是指向struct timer_rand_state的指针。您可以通过选中struct gendisk来确认。

timer_rand_state来自random.c,如下所示

/* There is one of these per entropy source */
struct timer_rand_state {
    cycles_t last_time;
    long last_delta, last_delta2;
};

此结构存储最后一个输入事件的时间戳以及先前的“增量”。 add_timer_randomness首先获取当前时间(以吉比特为单位),然后读取last_time(也以吉比特为单位),然后用第一个值覆盖last_time

跟踪一阶,二阶和三阶“增量”,作为估计熵的一种手段。硬盘事件产生的熵的主要来源是这些事件的时间安排。更多数据被散列到熵池中,但是它们对熵估计没有贡献。 (重要的是不要过高估计散列数据的不可预测性。否则,熵池以及RNG输出也可能是可预测的。另一方面,低估熵不能使RNG输出更可预测。总是更好在这方面使用悲观的估算器。这就是为什么仍然对熵估算没有帮助的数据仍被散列到熵池中的原因。)

Delta是两个事件之间的时间。 (时间戳之间的差异。)二阶增量是两个事件之间的时间之间的差异。 (增量之间的差异。)三阶增量是二阶增量之间的差异。 timer_rand_state指针是跟踪先前时间戳和增量的内存位置。 delta3不需要存储。

根据此计时数据估算的熵是基于最大绝对值delta一,二和三的对数。 (不完全是对数。例如,它始终是整数。它总是四舍五入。如果您采用的几乎对数的值为零,则结果也为零。)

假设您有一个用作熵源的设备,该设备每50毫秒生成一个新事件。增量将始终为50ms。二阶增量始终为零。由于三个增量之一为零,因此可以防止依赖该设备的时序作为重要的熵源。熵估算器无法成功高估输入熵,因此即使将此设备用作熵源,它也不会以可预测的方式“毒化”熵池。

熵估计不是基于任何形式上的数学。我们无法构造一个准确的熵源模型,因为我们不知道它是什么。我们不知道用户计算机上的硬件究竟是什么,或者在未知环境中的行为如何。我们只想知道,如果将一个加到(估计的)熵计数器上,那么我们就将至少一比特的熵值不可预测的数据散列到了熵池中。除了计时以外,额外的数据也被散列到池中而不增加熵计数器,因此我们希望,如果基于计时器的熵估算器超出估算时间,那么基于非计时器的源中可能存在一些不可预测性,我们不会占。 (如果是这样,您的RNG仍然是安全的。)

我敢肯定这听起来令人信服,但我不知道该如何帮助。我尽力解释了random.c代码的相关部分。即使我介意融合并提供有关该过程如何工作的直觉,也可能仍然不能令人满意。