内核 Random、CRNG 与用户接口

内核 Random、CRNG 与用户接口

1. 目标

random.c聚合不可信或不同质量的输入,维护cryptographic RNG状态,并向内核和用户空间提供随机字节。它不把某个HWRNG输出原样转交应用。

2. 输入来源

典型输入:

  • interrupt timing;
  • device/input timing;
  • bootloader seed;
  • CPU RNG;
  • hardware generator;
  • architecture/firmware randomness;
  • 用户向random/urandom写入的数据。

数据可以混入pool但不一定获得entropy credit。Credit决定CRNG何时被认为初始化。

3. 初始化阶段

系统早期CRNG可能未ready。代码维护初始化状态和waitqueue:

1
2
3
4
5
6
collect entropy
-> fast pool/input pool mixing
-> threshold reached
-> initialize CRNG key/state
-> wake random waiters
-> notify callbacks

密码、长期密钥和TLS随机数必须等待CRNG ready。

4. /dev/random

Linux 6.1中,CRNG初始化后/dev/random与urandom都基于同一安全生成器;主要差别是random在初始化前阻塞。

Read支持:

  • blocking;
  • O_NONBLOCK
  • signal中断;
  • iter I/O;
  • poll ready。

不要用“每读取一次就消耗固定entropy位”的旧模型解释现代实现。

5. /dev/urandom

初始化前历史上可返回早期输出,因此敏感程序更推荐getrandom(),它能显式等待ready且不依赖device node。

初始化后适合大多数随机需求。

6. getrandom

Flags包括:

  • GRND_NONBLOCK
  • GRND_RANDOM
  • GRND_INSECURE

默认调用在CRNG ready前等待。GRND_INSECURE允许早期输出,只适合明确不要求密码学安全的场景。

7. 内核API

  • get_random_bytes()
  • get_random_u32/u64()
  • get_random_long()
  • get_random_bytes_wait()
  • add_device_randomness()
  • add_hwgenerator_randomness()
  • wait_for_random_bytes()

Driver应使用API,不应自行read /dev/urandom

8. 写入语义

向random/urandom写数据会mix进状态,但普通write不会自动声明这些数据含有可信entropy。只有受控内核路径可credit entropy。

这防止任意用户通过可预测数据欺骗CRNG ready。

9. Reseed

CRNG按时间/生成量及新entropy reseed。Per-CPU batched random减少全局锁竞争,适合非密钥的频繁u32/u64使用。

10. Trust配置

RANDOM_TRUST_CPURANDOM_TRUST_BOOTLOADER控制CPU/boot seed是否被credit,而不是是否mix。

RK3588产品应评估:

  • Bootloader是否每次提供唯一高质量seed;
  • SMCCC/SoC TRNG是否可信;
  • 克隆镜像是否保存并更新random seed;
  • 安全启动链是否保护seed注入。

11. 并发

Random fast path使用per-CPU状态、锁、RCU和waitqueue降低竞争。Entropy输入可来自IRQ,不能在该路径睡眠。

用户read大buffer会分块生成并检查signal/reschedule。

12. 与HWRNG区别

/dev/random/urandom /dev/hwrng
内核CSPRNG输出 当前硬件源原始输出
混合多源、reseed 单一selected hwrng
适合密钥 需自行健康评估
初始化状态明确 可因硬件故障返回错误

应用通常不应直接用/dev/hwrng替代getrandom()

文章互动

阅读 --

留言

0 条留言

正在加载留言…