Fuchsia OS 随机数生成器浅析

Fuchsia OS 随机数生成器浅析

众所周知,Fuchsia OS是Google针对IoT设备推出的操作系统。之所以选择它的RBG(随机bit生成器)来研究,是因为相对Linux的RBG而言要简单一些。

0. 背景知识

  • RBG(Random Bit Generator,随机bit生成器) :一个软件、硬件或者固件模块,负责生成一段随机bit序列,用于序列号、密钥、session ID等等。大家可能更习惯随机数生成器(Random Number Generator,RNG)的叫法,但NIST这些年改用了RBG的叫法。我觉得RBG确实更准确,因为RBG生成的既不是数字也不是字符而是bit序列。
  • DRBG(Deterministic Random Bit Generator,确定性随机比特生成器) :DRBG其实就是用我们熟悉的密码算法改造而成,比如:HASH-DRBG就是用HASH算法改造而成。DRBG只是熵的搬运工,主要起到bit序列展宽等作用,它并不产生熵。
  • Seed随机数种子:一段从环境噪声中提取和转换得到的bit序列,从概率统计上看完全随机(满熵)或者部分随机(不满熵)。
    (注:理解熵需要一些信息论知识,有兴趣可以查看相关资料。)

Seed与DRBG的关系类似火种与炉灶、酒曲与粮食之间的关系,前者的量很少,但却构成了后者的灵魂(随机性)。进一步,我们可以简单地理解为:RBG = DRBG + seed。 实际上还需要很多处理才能构成RBG,但这样简单理解RBG原理没问题。

1. DRBG功能模型

为了分析Fuchsia RBG,需要先了解DRBG的功能模型(下图)。
RBG功能模型

图源:美国NIST(国家标准与技术研究所)标准SP800-90A

DRBG的设计为了达到密码学上的安全性,涉及很多技术细节,我也不全了解。我们只是为了弄清楚Fuchsia的RBG,因此,这里只需要了解DRBG的基本构成:

  • 内部状态机Internal State:这是DRBG里的一个内部状态机,不同时刻不一样,而且对DRBG系统多次上电后,其内部状态也应该不一样。它决定了DRBG输出bit序列的不可预测性,因此必须保密。
  • 输入Entropy、Nonce、Personalization String、Additional Input
    • Entropy是一段随机序列,就是我们所说的熵。它非常关键,决定了DRBG输出bit序列的随机性。前面说过DRBG只是熵的搬运工,自身并不产生熵。而熵又决定了随机比特序列的随机性。DRBG利用密码学算法,对输入的随机序列seed进行处理。
    • Nonce、Personalization String、Additional Input这些相对没那么重要,先简单理解为人为输入或者初始化的一段事先确定的数字或者字符串。
  • 输出Pseudorandom Output:提供给应用程序使用的随机bit序列。
  • 功能逻辑由五部分构成:
    1. Instantiate Fuction获取熵输入,并可以将其与nonce和个性化字符串组合以创建一个种子,从该种子创建初始内部状态
    2. Generate Function根据请求生成伪随机比特,使用当前的内部状态和可能的额外输入;还会生成下一个请求的新内部状态。
    3. Reseed Function获取新的熵输入,并将其与当前内部状态和任何其他额外输入相结合,以创建新的种子和新的内部状态。
    4. Uninstantiate Fuction将内部状态归零(即擦除)。
    5. Test为健康度测试功能,以确定DRBG机制是否继续正常运行。
      重要的是前三个功能,后两个功能可以暂时忽略。

2. Fuchsia OS RBG的原理图

我根据Fuchsia开发者网站上的资料,画出了Fuchsia OS RBG的大致原理图。
Fuchsia OS RBG原理图

Draw( )和AddEntropy( )是用户空间的两个函数,分别对应zx_cprng_draw( )和zx_cprng_add_entropy( )两个系统调用。
可能会有一些细节上的出入,但大差不大,不会影响理解。如果要开发,那就需要与代码核对。

有了本文第1节的铺垫,理解上图就容易多了:

  • Internal State: 可以简单理解为Key
  • Instantiate Fuction:zx_cprng_add_entropy(也可能是另一个函数,文档未明确)
  • Reseed Function:zx_cprng_add_entropy
    Uninstantiate Fuction、Test功能在开发者网站资料未提及,但应该有,具体得看代码确认了。

(1)开发者需要做的工作:
需要通过内核启动参数kernel.entropy-mixin设定一个初始种子,并根据需要对Jitter Entropy库进行基本配置或调整配置、以及将硬件RNG(如果有)产生的随机bit输入到zx_cprng_add_entropy过程中。
(2)系统运行的过程:
系统上电后,内核启动时先将kernel.entropy-mixin、硬件RNG的输出序列、Jitter Entropy提取到的序列合并起来作为初始种子,生成Key,nonce初始化为0。并且初始化好定时调用AddEntropy( )的定时线程。

接下来应用就可以调用Draw( )来获取需要的随机数。如果调用成功(没有被阻塞),说明系统熵池中的随机bit序列满足安全要求。

3. 其他说明

(1)关于Jitter Entropy

Jitter Entropy库的原理是通过多次执行软件访问内存块等操作,利用CPU每次处理时间必然存在的不一致(抖动)以获取随机序列,相当于对环境噪声提取的软实现。顺便说一下,该库的作者Stephan Mueller是德国Atsec公司的一位专家,他多年专注于研究随机数生成器。

(2)应优先使用硬件RNG

如果硬件能提供RNG那么要优先考虑使用它。因为软件提取环境噪声虽然有成熟的实现,但是毕竟产生的熵率较低。如果要大量产生随机数,就有可能导致熵池亏空而不能及时获得足够的随机比特。在Linux下有可能体现为获取随机数的系统调用被阻塞。虽然从Fuchsia的开发者文档来看,Fuchsia的RBG设计为非阻塞式,那么如果熵池亏空可能导致获得的随机bit序列熵率不高。在一般的应用中也问题不大,但在一些安全性要求较高的业务场景(如电子密码锁)或者产品要通过FIPS 140-3安全认证的时候,实测熵率就可能会达不到要求。

2024.5.18更新:增加“模型与技术架构来源”一小节

(3)模型与技术架构来源

Fuchsia OS 随机数生成器的设计并非Google自创,它来源于Boaz Barak和Shai Halevi 2005年发表的一篇题为“A model and architecture for pseudo-random generation with applications to /dev/random”的论文。该论文提出了一个健壮的伪随机生成模型和架构,即使在攻击者对生成器的熵源有部分控制的情况下,也能保持输出的随机性。
该随机数生成器模型和架构具有以下特性:

  • 弹性(Resilience) :即使攻击者完全控制用于刷新内部状态的数据,生成器的输出对没有内部状态知识的观察者看起来也是随机的。
  • 前向安全性(Forward security) :即使攻击者后来知道了内部状态,生成器的过去输出对观察者看起来也是随机的。
  • 后向安全性/入侵恢复(Backward security/Break-in recovery) :只要生成器使用足够熵的数据刷新,即使攻击者知道当前状态,生成器的未来输出对观察者看起来也是随机的。

如果想进一步深入研究,该论文的链接放在参考资料中的参考3。

4. 参考资料

  • 13
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值