Ubuntu 会在内核中启用 RANDOM_TRUST_CPU 吗?会产生什么效果?

Ubuntu 会在内核中启用 RANDOM_TRUST_CPU 吗?会产生什么效果?

根据这个2018 年 8 月 28 日 The Register 文章和其他文章中提到,Linux 内核版本 4.19 将有一个名为 的编译标志RANDOM_TRUST_CPU。这里还有一个邮件列表条目链接由补丁作者提供,包括实际的代码更改。据我所知,这将允许系统在某些情况下加快启动过程,通过不是等待从各种来源收集到足够的熵来安全地为随机数生成器提供种子,但跳过该部分并仅依靠 CPU 的内置随机数生成器。

这会削弱系统的加密安全性,因为(如果我理解正确的话)它不仅依赖 CPU 作为单一熵源,而且如果该 CPU 的实现不可信(错误、故意的后门……),还会完全破坏安全性。

  • 那么,内核的随机数生成器是否将始终仅从 CPU 的生成器进行初始化,或者它是否仅在早期启动阶段执行此操作,并在稍后将更多来自“传统”源的熵添加到池中,从而随着时间的推移将加密安全性再次提高到当前/旧的水平?

  • 由于这显然是一个编译时标志,Ubuntu 存储库中提供的内核包是否会启用或禁用此标志?

  • 除了从现在开始自己编译内核之外,是否还有其他方法可以选择加入或退出?

  • 有没有办法实际测试这是否会对启动时间产生影响?目前是否有任何关于启动过程中等待熵所花费时间的指标?

  • 哪些 Ubuntu 版本可以运行 4.19 或更高版本的内核版本?

答案1

首先,合理地说,无论是否使用 CPU 的内置 HWRNG(例如RDRAND英特尔),系统的加密安全性(即不可预测性)都不会以任何方式改变,否则,正如您所说,这将不可避免地削弱 RNG(以及任何依赖于它的东西)的安全性。

简单来说,在引导过程中,内核加载随机驱动程序后,Linux RNG初始化所有随机池(熵池,它们只是保存随机数据的内存区域),包括主池(输入池),通过使用来自 HWRNG 的熵(如果可用)来填充它们,否则通过random_get_entropy(),它是 的宏get_cycles(),其实现因体系结构而异(例如在 aarch64 中读取CNTVCT_EL0寄存器已经完成了,它是一种频率计数器,而不是时钟频率,而是通过读取 TSC reg 在 x86-64 中使用的时钟频率)。所有这些数据都提供给主密码状态(primary_crng,类型为 的对象struct crng_state,它是ChaCha20算法),其中包含 384 位真正随机数的密钥,最终提供给/dev/urandom接口。

现在,根据这个上下文,回答你的问题,内核的 RNG 实际初始化通过rand_initialize(),作为一个early_initcall,显然只发生在启动时(像所有的一样*_initcall()),特别是在的最后start_kernel(),内核例程rest_init()被调用,它做的第一件事就是生成一个内核线程(kernel_init),目的之一是启动该 initcall(还要注意,它add_device_randomness()甚至被称为,但实际上并没有添加任何熵数据);因此,是的,根据来源,ChaCha20、主池和阻塞池的密码状态将使用 进行初始化arch_get_random_long(),这将利用RDRANDx86 处理器中的指令(同样,如果它可用,并且如果可用,则内核警告你关于这一点)。但我不会说它是唯一使用的来源(即使RDRAND可用),因为至少:

  1. 固件时间被使用并混入池中在初始化期间(可能没有那么熵,但攻击者仍然必须以极高的精度推断时间戳);

  2. 还有另外一个小池(每个 CPU 一个,称为快速池) 收集来自 的熵add_interrupt_randomness(),使用 IRQ(理论上还有其他内核事件,甚至来自 CPU 硬件 RNG 的一些种子(如果有))作为输入,混合所有,然后将其注入输入池。这种情况每秒都会发生。

因此,从 HWRNG 和其他来源收集熵的过程是同时发生的;当然,第一个过程占主导地位(因为熵质量肯定更高,它是一个真正的 RNG),并且发生在启动时,以及从用户空间,每当getrandom()使用伪随机设备(或系统调用)时。但在第二种情况下,池已经初始化,并且只是primary_crng(密码状态)重新播种。是的,正如您所指出的,CPU 内置 RNG 肯定会提高整体随机性。

最后,我想补充一点,特别是在嵌入式系统中,可能缺少一些源噪声(如键盘、硬盘等),使用 HWRNG 会产生重大影响。请注意,始终根据文档,如果您担心安全性,您可以RDRAND在引入之前禁用内核的使用。RANDOM_TRUST_CPU

相关内容