LXR | KVM | PM | Time | Interrupt | Systems Performance | Bootup Optimization

OpenWRT(9):随机数发生器urngd,以及/dev/random

urngd是一个基于时间jitter的非物理随机数发生器。urngd为Linux的/dev/random设备提供熵源,当/dev/random熵不足时,它会向其注入熵。

它会向其中注入熵。这确保了/dev/urandom也能从注入的熵中受益,尤其是在系统启动时,Linux的熵较低的情况下,urngd提供了足够的熵源

1 urngd:基于timer jitter的非物理RNG

1.1 urngd配置和启动

urngd配置:

Base system
    urngd

package/system/urngd/files/urngd.init中定义了启动urngd的启动脚本:

#!/bin/sh /etc/rc.common

START=00

USE_PROCD=1
NAME=urngd
PROG=/sbin/urngd

start_service() {
    procd_open_instance
    procd_set_param command "$PROG"
    procd_close_instance
}

reload_service() {
    procd_send_signal $PROG
}

1.2 urngd流程

urngd主要功能是为 Linux 系统的随机数生成器提供高质量的熵源:

  • urngd使用基于 CPU 时序抖动的算法来收集熵。
  • 当系统的熵池熵值不足时,urngd 可以将收集到的熵注入到/dev/random设备。
  • urngd 是一种非物理的随机数生成器,它依赖于软件算法来生成随机性。
  • urngd 可以检测到系统熵池中的熵水平,并在熵水平较低时自动增加熵,从而避免/dev/random 阻塞读取操作。
  • urngd 利用 OpenWrt 的 uloop 事件循环来处理熵的收集和注入。
main
  uloop_init
  urngd_init
    jent_entropy_init--进行随机数生成器的初始化,包括健康测试(比如重复计数测试和自适应比例测试)和配置内部定时器(如果需要)。
    jent_entropy_collector_alloc--为随机数生成器的实例分配内存,并配置过采样率和标志。
    open--只写打开/dev/random设备。
    uloop_fd_add--当有对/dev/random设备写ULOOP_WRITE时,调用回调函数。
      low_entropy_cb
        gather_entropy--收集新的熵,并将这些熵写入到/dev/random设备,从而提高系统的熵值。
          jent_read_entropy
          write_entropy
            ioctl--文件描述符,指向/dev/random设备。RNDADDENTROPY是ioctl调用的命令码,用于指示内核将额外的熵添加到熵池中。
  gather_entropy
    jent_read_entropy--从随机数生成器中读取随机数。如果检测到健康测试失败,将返回错误代码。
    write_entropy
      ioctl
  uloop_run
  uloop_done
  urngd_done--在程序退出时清理和释放urngd服务使用的资源。

2 /dev/random

2.1 /dev/random

点击链接查看和 Kimi 智能助手的对话 https://kimi.moonshot.cn/share/cqud11bdf0j055dm7r7g

chr_dev_init
  device_create--遍历devlist创建设备。
    random_fops--random设备的操作函数集,major为1,minor为8。

/dev/random的ioctl支持命令如下: 

  • RNDGETENTCNT:用于获取熵池中的熵计数或熵的总量。
  • RNDADDTOENTCNT:用于修改熵池数量。
  • RNDGETPOOL:用于获取当前熵池的状态或内容。
  • RNDADDENTROPY:用于向随机数生成器添加熵。这可能包括来自硬件源的熵或其他形式的随机数据。
  • RNDZAPENTCNT:用于清除熵计数器为0。
  • RNDCLEARPOOL:用于清空熵池和计数置为0.
  • RNDRESEEDCRNG:用于reseeding加密随机数生成器(CRNG)。

2.1 /proc/sys/kernel/random

 点击链接查看和 Kimi 智能助手的对话 https://kimi.moonshot.cn/share/cqud16cjot6qv0gkpnng

random_sysctls_init--创建/proc/sys目录下kernel/random目录,并创建random_table中节点。
  random_table

random_table中包含一系列与随机数生成器相关参数,具体如下:

  • boot_id:包含系统启动时生成的唯一标识符(boot ID)。它是基于系统启动时的多种因素(如时间、内存状态等)生成的,可用于确定随机数生成器的状态是否未被篡改。
  • entropy_avail:显示当前熵池中的熵数量。熵是一个度量,表示随机源的不可预测性。/dev/random 在熵不足时会阻塞读取操作,直到熵池中的熵足够。
  • poolsize:定义了熵池的大小,即熵池可以存储的熵的最大值。熵池的大小可能会影响到随机数生成器的性能和熵的收集速度。
  • uuid:包含系统启动时生成的全局唯一标识符(UUID)。它类似于 boot ID,但用于更广泛的身份验证和识别目的。
  • urandom_min_reseed_secs:设置了 /dev/urandom 自动重播种(reseeding)的最小时间间隔,单位为秒。重播种是指向熵池中注入新的熵以保证随机性的强度。这个设置防止 /dev/urandom 在短时间内过度重播种。
  • write_wakeup_threshold:定义了当熵池中的熵低于某个阈值时,/dev/random 将触发写入唤醒(write wakeup)。这是一个回调机制,用于在熵池需要更多熵时通知系统。

2.3 /dev/random和/dev/urandom区别

/dev/random 和 /dev/urandom 是Linux和其他类Unix操作系统中的两个特殊的文件,它们提供了访问系统随机数生成器(RNG)的接口。这两个设备文件的主要区别在于它们生成随机数的方式和特性:

/dev/random

这是一个阻塞设备,当系统认为熵池(entropy pool)中的熵不足时,它会阻塞读取操作,直到收集到足够的熵来生成高质量的随机数。
/dev/random 被认为是一个更安全的随机数源,因为它确保了随机数的生成依赖于真正的熵,这使得随机数更难被预测。
由于它可能阻塞,所以它更适合用于需要高安全性的场合,如生成密钥或密码。

/dev/urandom

这是一个非阻塞设备,即使熵池中的熵不足,它也会继续生成随机数,但这些随机数的质量可能不如 /dev/random。
/dev/urandom 从Linux 2.6.26 开始,通过使用一个基于Yarrow算法的加密随机数生成器(CSPRNG)来提供更好的随机性,即使在熵不足的情况下也能继续生成随机数。
它适合大多数应用程序使用,因为它不会阻塞,可以提供足够的随机性,除非对随机数的安全性有极高的要求。


在实际使用中,大多数应用程序不需要 /dev/random 的阻塞特性,因此 /dev/urandom 通常是首选。然而,如果你需要生成极其敏感的数据,例如用于加密通信的密钥,那么使用 /dev/random 可能更合适。

posted on 2024-08-17 23:59  ArnoldLu  阅读(81)  评论(0编辑  收藏  举报

导航