熵集合 TODO

我会在实习期结束时写下来,用来记录一些我没听到的事情。

RdRand 的正确使用

在 x86 上,RdRand 从确定性 CPRNG(从硬件熵源的种子)中读取数据。较新的 RdSeed 指令会直接从底层熵源读取数据(好的,需要进行一些后处理)。目前,我们更愿意使用 RdSeed,但如果无法使用,我们将回退到 RdRand。不过,我们只是直接从 RdRand 绘制随机位,这违反了 Intel HWRNG 指南(点击此处在线查看;请参阅第 4.2.5 节“保证 DBRG 重新种子”)。我们应该解决这个问题。

在运行时重新种子 (CPRNG)

我的 virtio 驱动程序将在 qemu 上重新种子 (CPRNG)(通过五分钟的周期性计时器)。我认为这是目前唯一在系统启动后进行重新种子的熵源。

首先,我们应该能够使用内核中内置的熵源(RdRand 和抖动熵)。定期运行这些实验可以改进我们的再播故事。请注意,每 5 分钟一次的频率可能比我们需要的频率多。

我们已经更频繁地讨论过从 CPRNG 提取大量数据(我认为大约为 2^48 位)后重新种子。

监控熵源

熵源有可能完全失败,也可能部分失败。

“设备未插接”或“设备对 I/O 没有响应”等总失败情况最好由硬件层报告。

部分失败(设备返回数据,但熵低于预期)则更为可怕。我们应运行简单的运行状况测试来尝试检测部分故障。如需查看示例,请参阅 NIST SP800-90B 第 4.4 节中的连续运行状况测试。其中的运行状况测试非常简单,只需极少的资源即可。它们需要存储一些有关近期熵源输出的统计信息,而这会带来一些安全风险。

NIST SP 还建议运行启动测试(当然需要,但我不了解目前是否有认证计划)。NIST 启动测试需要对至少 4096 个样本(请参阅第 4.3 节 #12)运行连续测试,之后这些样本可以重复用于为 CPRNG 播种。

完成监控后,我们需要确定如何应对熵源故障。如果六个不同的熵源中的一个发生故障,我们可能会将此视为会被记录下来的轻微硬件故障。如果系统只有一个熵源,并且其发生故障,则我们需要采取更剧烈的措施(以关闭 CPRNG 或中止系统)。

用户空间 RNG 驱动程序

一旦 DDK 稳定下来,我们就应添加并改进 RNG 驱动程序。目前,有两个与 RNG 相关的驱动程序:TPM 和 virtio-rng。

一个重要要求是通过 Resource 或类似机制来限制对 zx_cprng_add_entropy 系统调用的访问。我们还应使用此名称来区分提供熵的设备,以便进行监控。如果内核可以通过此资源向驱动程序发送启动/停止信号,再好不过了。

下面是一些当前未使用的熵来源,供您参考:

  • 已有一个 TPM 驱动程序,该驱动程序会在其 bind() 回调中调用 cprng_add_entropy。我们应添加对 TPM 2.0 的支持,以扩大覆盖面。

  • 市售的硬件 RNG 有很多,通常通过 USB 连接。我们可以为这些驱动程序添加驱动程序,但应该使用第三方驱动程序。

  • 根据 Raspberry Pi 论坛中的记录,Raspberry Pis 中的 SoC 中显然还内置了硬件 RNG。一般来说,我们可以检查硬件 RNG 的其他特定目标(即不是“pc-x86-64”),并将其连接起来。幸运的是,其中许多都可以从内核访问,以便在启动期间或启动后立即使用。

  • 最后,我们可以记录硬件 IRQ 的熵,尤其是对于硬盘、网卡、输入设备和其他传统熵源。虽然速度远没有专用硬件 RNG 快,但它很有吸引力,因为在我们的驱动程序堆栈中的正确位置添加几行代码应该支持从各种非常常见的设备进行熵收集。

抖动熵

用组装替换生成噪声的函数,并移除“-O0”

目前,抖动熵在优化级别 -O0 进行编译(根据作者的文档)。原因在于以下两个噪声生成函数:jent_lfsr_timejent_memaccess。我们应通过汇编代码(可能通过使用 -S -O0 标志进行编译)替换这些 C 函数,然后在启用优化的情况下编译抖动的其余部分。之后,我们应重新测试,以确保我们的熵估算值准确无误。

更全面地测试抖动熵

我一直在同一批实体设备上进行测试。我们应该在一些其他 PC、RPis 等设备上测试抖动熵。

在运行时测试抖动熵

目前,抖动熵仅在启动序列的单核部分运行(并且只经过了测试)。我们应该在 SMP 运行时期间测试抖动熵,并且考虑是否需要(例如)停用中断或将自己固定到抖动存在范围内的 CPU。

更多微调

请参阅调整文档。当前的通用硬编码参数似乎很不错,因此这可能不是特别紧急。尽管如此,由于抖动属于每次启动的关键路径,并且它也会在运行时(希望很快!)运行,因此在某个时候可能值得进行优化。

我们至少应该基于每个架构,最好针对每个目标调整抖动熵。请注意,目前 kernel/lib/crypto/entropy/jitterentropy_collector.cpp 中的 entropy_per_1000_bytes 统计信息是硬编码的,不依赖于架构/目标。这或许应该还可以进行配置。

克隆 NIST 测试套件

我们可能需要将 NIST 测试套件克隆到 Fuchsia third_party。这将帮助我们自动执行熵源(特别是抖动熵)的测试和分析。