TRNG
1. 简介
TRNG 是一种真随机数发生器,提供32位高质量随机数。它由两部分组成:活动噪声源(物理部分)和后处理单元。
噪声源内部有多个振荡器,采用不同类型的机制。振荡器的输出存在抖动,这是随机性的来源。它被采样、后处理,然后形成存储在输出缓冲区中的32位数据。
这是一个轻量级、低功耗的TRNG,适用于中等吞吐量应用。
2. 主要特性
本设备支持以下特性。
符合 NIST SP 800-90B 和 AIS-31 的熵源。
随机数通过 NIST SP 800-22 测试套件。
集成 1 种物理随机源:RO。
每个都可以通过软件启用/禁用。
通过客户指定的工艺实现随机源的自动数字流程。(无需模拟设计。)
输出 32 位随机数
可配置输出缓冲区大小(默认 4×32 位)
硬件调理组件
可编程:启用/禁用
使用基于 AES 的分组密码推导函数 (BC_df)。(符合 NIST SP 800-90B)
可配置和可编程的 AES 密钥长度 128/192/256。
可编程输入长度。高级用户可以根据原始样本的质量确定此长度,以调整随机数的吞吐量。
内置健康测试。
启动测试和连续测试。
窗口大小和阈值可编程。
支持两种范围:线路/聚合。在线路范围内,对单个线路(由特定输出位形成的流)进行测试。在聚合范围内,对所有线路集体进行测试。
提供两种测试套件。
符合 NIST SP 800-90B)重复计数测试和自适应比例测试。
符合 AIS-31)单比特测试、游程测试和扑克测试。
每个测试可以通过软件启用/禁用。
可配置。可以移除测试套件以节省资源。
低功耗。
设备在空闲一段时间后可进入睡眠状态。睡眠期间噪声源关闭。
健康测试警报或致命错误时自动关闭。
中断
用于数据就绪、健康测试警报、错误等的多个中断。
一个中断输出信号,电平信号。
可配置的系统总线接口(如 AXI/AHB/APB)。数据宽度为 32 位。
可配置的外部数据端口数量。
除了寄存器外,还提供多个硬件接口供其他设备获取随机性。
假定其他设备位于异步时钟域。
RISC-V seed CSR 接口。(定义于 RISC-V Cryptography Extensions Volume I - Scalar & Entropy Source Instructions 第 4 章熵源。)
带有 req/ack 握手机制的简单外部接口。
启动阶段
为启动时应用快速提供一批非FIPS随机性
健康测试较为宽松。
提供软件数据输入端口,除了噪声源。
接收用户提供的原始噪声样本。
执行已知答案测试 (KAT)。
使用收集的数据重现错误。
调试模式。提供调试端口以收集来自噪声源和中间节点的数据进行离线分析。
安全措施。
调理结果重复检查
只有在读取发生时数据才可见。
一个端口获取的数据对其他端口不可见。
两个异步时钟域:(噪声源)采样时钟域和主时钟域。
3. 功能描述
符号与约定
符号
此处使用以下符号。
健康测试 包含检查噪声源质量的统计测试的功能块。可能有多个测试套件。有时也可能指一个统计测试。
KAT 已知答案测试
线路 通常噪声源输出样本有几位。每个位的序列形成一条线路。例如,具有4位输出的噪声源有4条线路。
噪声源 本文档中指负责生成随机信号的整个组件。
OFFO 输出 FIFO 或输出缓冲区。
振荡器 本文档中指噪声源内部生成随机信号的具体实例。
后处理 使用批准算法对采样数据进行数字处理以增强随机性。
RO 环形振荡器。
RO_GRP RO 组,一组 RO。
原始数据 由噪声源产生的样本或用户通过软件端口提供的数据。
软件端口 用户提供源数据的寄存器。
TRNG 真随机数发生器。通常由噪声源、调理组件和健康测试组成。正式称为熵源。
测试 更准确地说,统计测试。它是检查噪声某方面统计特性的一段程序或算法。有时也称为健康测试。
测试统计量 零假设中使用的量。从样本计算得出,用于确定测试是否失败。
测试套件 由某个组织批准的一组测试程序。
如果上下文清晰且不会引起混淆,以下术语可以互换使用。
模块、功能块、设备。
随机性、熵。
随机数、随机数据。
随机源、噪声源。
熵源、TRNG。
流、线路。
原始样本、原始数据。
软件数据输入端口、软件端口,
(统计)测试、健康测试。
测试统计量、测试值。
调理器、调理组件。
睡眠、睡眠模式。
输出缓冲区、OFIFO。
约定
此处澄清一些术语。
TRNG的随机性来自一个源。源内部有几个电路实例,每个都是一个具体源。封装这些实例的整个源称为 噪声源 ,而实例称为 振荡器 。尽管有些实例不采用振荡机制,但仍称它们为振荡器。
周期可能用作时间单位。通常周期指主时钟周期。
框图
图 3.1 为本设备的框图。
图 3.1: TRNG 模块框图
TRNG 是总线上的一个从设备。它包含以下组件。
Bus_inf: 总线接口,CPU 通过它访问寄存器文件。总线宽度为 32 位。
Register file:配置和状态寄存器的集合。它是本设备的编程接口。
Interrupt:到 CPU 的中断。
Noise source:噪声源,一个物理/模拟模块,随机性的来源。内部包含多个振荡器。
Software port:软件端口,图中,sw_port 是用于用户输入数据的软件端口。它是噪声源之外的另一个原始数据来源。
post-processing:后处理,一系列数字处理。随机数由此产生。
OFIFO:输出缓冲区。它存储由后处理产生的随机数。
health test:支持多个测试套件。它们在启动测试和连续测试中运行。
External ports:有 2 种类型的硬件接口供设备获取随机数:到 RISC-V seed CSR 的接口和到其他设备的接口。
以下是关于系统及其工作原理的简单描述。
本设备有两个异步时钟:主时钟和采样时钟。主时钟来自系统总线时钟。它是设备的主要数字时钟。采样时钟驱动噪声源输出端的采样逻辑。
用户通过寄存器文件控制设备。提供了几种获取随机数的方式:通过读取寄存器和通过外部端口。
设备支持停止和睡眠。停止类似于软件复位。睡眠可节省功耗。
噪声源产生随机信号,由采样时钟采样。采样数据经过后处理。最终,生成随机数并存储在 OFIFO 中。
TRNG 提供的随机数具有不可预测的特性。基于产生的数据,无法得知 TRNG 的内部状态、预测未来数据或预测未来数据的统计特性。
使用 TRNG 的基本步骤如下。
配置并启动 TRNG。
TRNG 经过初始化。然后开始生成随机数。
通过轮询或中断等待随机数就绪。
就绪后,读取随机数。
注意:模式和配置是静态配置,除非另有说明。在设备工作时不能动态更改,否则行为未定义。可以在硬件复位后或设备已停止时更改。
图 3.2 为设备的主状态机。
图 3.2: 主状态机
具有以下状态。
ST_IDLE。空闲状态。设备复位或停止时,返回此状态。
ST_SLEP。睡眠,低功耗状态。
ST_INIT。噪声源初始化。
ST_WAKE。同 ST_INIT。
ST_STARTUP。执行启动测试。
ST_RGEN。在连续阶段生成随机数。
ST_BGEN。在启动阶段生成随机数。
ST_BEND。当启动阶段结束时,将停留在此状态。
ST_ALRT。健康警报状态。
ST_FERR。致命错误状态。
(保留状态。供内部使用。)
(其他。其余为非法状态。)
状态机转换的一些典型路径。
启动。ST_IDLE -> ST_INIT -> ST_STARTUP -> ST_RGEN
睡眠与唤醒。ST_RGEN -> ST_SLEP -> ST_WAKE -> ST_STARTUP -> ST_RGEN
启动阶段。ST_IDLE -> ST_INIT -> ST_BGEN -> (若重试) ST_BGEN -> ST_BEND
关于一些特殊状态的说明。
任何 -> ST_IDLE。当用户停止设备时,从任何状态进入 ST_IDLE。
任何 -> ST_FERR。此路径有一些限制。状态机在以下情况下进入 ST_FERR (1) 从除 ST_IDLE、ST_ALRT 和 Others 之外的任何状态,(2) 当致命错误(不包括健康警报)发生时。
-> ST_ALRT。当健康警报发生时,状态机从 ST_STARTUP 和 ST_RGEN 进入 ST_ALRT。
模式与阶段
本设备有两种模式:正常模式和调试模式。
正常模式是设备的典型工作模式。在此模式下,设备正常工作并产生随机数。用户获取随机数。所有功能均可用。健康测试正常工作。设备可以启用、停止(禁用)或进入睡眠。
调试模式是诊断模式。在此模式下,噪声源的原始样本通过数据路径到达 OFIFO。用户收集它们并使用供应商提供的工具进行离线分析。这是对噪声源的探测(某种后门)。在以下情况下很有用:(1) 找出噪声源故障的根本原因,(2) 评估噪声质量。更多细节请参考第 “调试模式” 节。
本设备有两个阶段:启动阶段和连续阶段。
启动阶段用于在系统启动后快速收集少量随机数。这些随机数不符合 FIPS。
连续阶段是设备的正常工作状态。随机数符合 FIPS。
模式与阶段的合法组合是
正常模式 + 启动阶段
正常模式 + 连续阶段
调试模式 + 连续阶段
注意:虽然睡眠通常被称为睡眠模式,但它并非与此处的模式并列。它是正常模式下的一种状态。
图 3.3: 模式与阶段
初始化
噪声源在启用后必须经过初始化。刚启动时,振荡器处于某种确定性状态,其输出远非随机。一段时间后,它进入随机状态。这段时间称为初始化。在初始化期间,噪声源的输出被丢弃。
在以下情况下,设备进入初始化。
启用噪声源后立即。
从睡眠中唤醒。
初始化期间的行为
噪声源开启,但样本被丢弃。
数字逻辑没有数据可处理。没有样本流向下游(健康测试或后处理)。
初始化的持续时间为 t_init = TRNG_CTRL_init × tick_period。最小持续时间为 t_init_min。在调试模式下,为了在振荡器启动后立即收集数据,用户可以将初始化设置得非常短。
停止
停止相当于软件复位。它优雅地停止设备。
它执行以下工作。
关闭噪声源。
刷新数据路径。
清除内部状态。
清除错误标志。
然后设备返回到空闲状态。
在以下情况下使用停止。
设备不再需要工作。
设备处于致命错误状态。软件将其恢复正常。
异常。如果在空闲状态遇到致命错误,停止将不起作用。这种情况下需要硬件复位。
停止由 TRNG_CTRL_trng_en 1->0 启动,可以在任何时候发生。
定时器
所有定时器都基于 tick 计数。当 tick 到达时,计数器(定时器的)加 1。
Tick 的周期为 \(tick\_period = 2^{4(tick\_scale + 1)}\) 个周期,其中 tick_scale 是 TRNG_CTRL_tick_scale。
噪声源
噪声源是一个物理/模拟模块。它是熵或随机性的来源。噪声源的输出信号实际上由其内部的振荡器产生。
在当前设计中,有 1 种类型的振荡器 – RO_GRP。相同类型的实例在电路上是相同的,而输出信号不相关。
内部有 8 个插槽,索引为 0-7,用于实例化振荡器。在当前设计中,并非所有索引都有实际的振荡器实例化。从 0 到 7 的索引分别是 RO_GRP0、RO_GRP1、RO_GRP2、RO_GRP3、Other_2、Other_3、Other_0 和 Other_1,其中 Other_* 是空插槽,保留供将来使用。(图 3.4 噪声源示意图)
最多允许启用 4 个振荡器。否则,行为未定义且不会发出错误信号。
一个样本可能包含多个位。每个位的序列形成一条线路。例如,具有4位输出的噪声源有4条线路。
图 3.4: 噪声源示意图
RO_GRP
ro_grp 内部总共有 7 个 RO。每个都可以单独启用或禁用。
软件端口
除了噪声源,设备还有一个替代的原始数据来源 – 用户提供的原始数据。数据通过软件端口进入设备。
这是一个非常有用的特性。典型应用包括
使用用户提供的(原始)数据生成随机数。
使用收集的数据重现问题。
执行已知答案测试。
执行自测试。
当 OFIFO 满时,软件端口将被阻塞。
当选择软件端口时,噪声源会自动关闭。因此启用睡眠没有意义。选择软件端口并禁用睡眠可以确保每个原始数据位都到达后处理,这对于某些应用(如已知答案测试)是必要的。
注意:(建议)使用软件端口时,禁用睡眠。
健康测试
最终(全熵)输出必须通过 [SP800-22] 中的测试套件,该套件深入彻底地检查输出数据,由几个在软件中实现的高复杂度算法组成。设备内部有一些内置测试在运行并实时监控噪声源的质量,这些测试更简单并在硬件中实现,称为健康测试。
噪声源的健康状态至关重要。有缺陷的样本泄漏到下游将损害随机数的质量。因此,使用一个健康测试块来持续监控噪声源的原始样本,它检测序列中的简单和明显错误并快速捕捉它们。当检测到错误条件时,会报告错误中断。
测试套件
一个测试套件有多个测试,它们具有相同的窗口大小和范围。
健康测试块内部实现了以下测试套件。
NIST SP 800-90B。包括重复计数测试和自适应比例测试,如 [SP800-90B] 中所定义。
AIS-31。包括单比特测试、游程测试和扑克测试,如 [AIS31] 中所定义。窗口大小应大于或等于 WIN_MIN_AIS。
多个测试套件独立运行。虽然它们共享一些公共参数(如范围、fail2alert_th),但每个都有其自己的配置参数(如窗口大小)。
范围
范围指定测试应用于窗口中数据线路的方式。在线路范围内,测试逐条检查每条线路。在聚合范围内,测试集体检查所有线路。
不同范围的阈值不同。
例如,单比特测试计算”1”的数量。假设噪声源有 N 条线路。在线路范围内,测试逐行检查数据。并产生 N 个结果, \(t_i\) (0<i<N) 是线路 i 的”1”的数量。如果任何 \(t_i\) 超过阈值,则当前窗口测试失败。否则,成功。在聚合范围内,测试一起检查所有线路。并产生一个结果, \(t = ∑t_i\) 是所有线路的”1”的数量。如果 t 超过阈值,则当前窗口测试失败。否则,成功。
统计测试
使用以下符号。
w - 窗口大小。
N - 线路数。
W - 每个窗口进入测试的数据量。如果在线路范围内,W=w;如果在聚合范围内,W=Nw。
α - 可接受的假阳性概率,或显著性水平。
H - 每个噪声源样本的最小熵估计。
\(t_l\) - 低阈值。
\(t_h\) - 高阈值。
设 T 为测试统计量。决策规则是,如果 \(T < t_l\) 或 \(t_h < T\) ,则测试失败。(或者将 < 替换为 ≤,或两者都替换)。有时从方程计算的阈值不是整数,而编程值是整数。在这种情况下,决策规则中的不等式(无论 < 或 ≤)被转换为 \(T < |t_{l}|\) 或 \(|t_{h}| < T\) 。
重复计数测试
此测试在 [SP800-90B] 的第 4.4.1 节中定义。它仅具有线路范围。
测试统计量 B 是重复计数。阈值 \(t_h\) 由 α 和 H 使用如下公式确定。如果 \(B > t_h\) ,测试失败。
原文中截止值 \(C = ⌈t_h⌉ + 1\) ,如果 B ≥ C,则发出失败信号。
各种 α 和 H 的阈值如表 3.1 重复计数测试阈值示例 所示。
H |
\(t_h\) |
α |
|---|---|---|
0.1 |
200 |
\(2^{-20}\) |
0.125 |
160 |
\(2^{-20}\) |
0.25 |
80 |
\(2^{-20}\) |
0.5 |
40 |
\(2^{-20}\) |
1 |
20 |
\(2^{-20}\) |
4 |
5 |
\(10^{-6}\) |
8 |
5 |
\(10^{-12}\) |
自适应比例测试
此测试定义于[SP800-90B]标准的第4.4.2节。它有两种判定范围。
测试统计量 B 是样本中”1”的个数。低阈值和高阈值由 α、H 和 W 通过如下公式确定,其中 BINOM.INV(.) 是 Microsoft Excel 的函数。如果 \(B < t_l\) 或 \(B > t_h\) ,则测试失败。
其中, \(α_0, α_1 ≥ 0, α_0 + α_1 ≤ α\) 。
BINOM.INV(.) 返回使累积二项分布大于或等于给定准则值的最小值。 \(BINOM.INV(n, p, α) = min \{ k|\sum_{i=0}^{k}(^{n}_i)p^{i}(1-p)^{n-i} ≥ α\}\)
设置阈值的两种常用方式如下:
(右尾) \(α_0 = 0, α_1 = α\) 。此时 \(t_l = 0, t_h = C - 1\) 。(C 是原始文档中的截止值。如果 B ≥ C,则发出失败信号。)
(双尾) \(α_0 = α_1 = α/2\)
当 \(α_1 = α = 2 ^ {-20}\) 时,不同 H 和 W 下的阈值如表 3.2 自适应比例测试示例阈值表 所示。
H |
\(t_h\) |
W |
|---|---|---|
0.05 |
1013 |
1024 |
0.06 |
1009 |
1024 |
0.07 |
1004 |
1024 |
0.075 |
1002 |
1024 |
0.08 |
1000 |
1024 |
0.09 |
995 |
1024 |
0.1 |
990 |
1024 |
0.2 |
940 |
1024 |
0.4 |
839 |
1024 |
0.6 |
747 |
1024 |
0.8 |
663 |
1024 |
1 |
588 |
1024 |
0.5 |
409 |
512 |
1 |
310 |
512 |
2 |
176 |
512 |
4 |
61 |
512 |
8 |
12 |
512 |
单比特测试
这是在 [AIS31] 第 2.4.3 节中定义的测试 1。此测试类似于自适应比例测试。它有两种范围。
测试统计量 \(T_1\) 是”1”的数量。低阈值和高阈值由 α 和 W 通过如下公式确定。如果 \(T_1 < t_l\) 或 \(T_1 > t_h\) ,则测试失败。
对 \(t_l\) 和 \(t_h\) 的一个恰当选择是它们关于 W/2 对称,即满足 \((t_l + t_h) / 2 = W / 2\) 。例如,在行范围内,窗口大小 W=20000。若 \(t_l = 9000\) 则 \(t_h = 11000\) 。
当 w=20000 时,各种 α 和范围的阈值如表3.3 扑克测试阈值示例 所示。
右尾 |
线路范围 |
线路范围 |
聚合范围, N = 4 |
聚合范围, N = 4 |
|
|---|---|---|---|---|---|
α |
\(T_1'\) |
\(t_l\) |
\(t_h\) |
\(t_l\) |
\(t_h\) |
0.05 |
3.841459 |
9861.409614 |
10138.59039 |
39722.81923 |
40277.18077 |
0.01 |
6.634897 |
9817.861358 |
10182.13864 |
39635.72272 |
40364.27728 |
0.001 |
10.827566 |
9767.324625 |
10232.67537 |
39534.64925 |
40465.35075 |
0.0001 |
15.136705 |
9724.893611 |
10275.10639 |
39449.78722 |
40550.21278 |
0.00001 |
19.511421 |
9687.658672 |
10312.34133 |
39375.31734 |
40624.68266 |
0.000001 |
23.928127 |
9654.108926 |
10345.89107 |
39308.21785 |
40691.78215 |
0.0000009922 |
23.9432 |
9654 |
10346 |
39308 |
40692 |
游程测试
这是在 [AIS31] 第 2.4.3 节中定义的测试 3。它有两种范围。
测试统计量 \(^2 T_3(λ, p)\) 是长度为 λ 的 p-run 的数量,其中 p ∈ {0, 1}, λ ∈ [1, w]。 低阈值和高阈值由 α、w、范围和 N 确定。如果 \(T_3 < t_l\) 或 \(T_3 > t_h\) ,则测试失败。
\(^2\) 原始文档中 \(T_3\) 的表达式有误。正确的表达式是:
各种 α、w 和范围的阈值如表 3.4 游程测试阈值示例 所示。
线路范围 |
线路范围 |
聚合范围, N = 2 |
聚合范围, N = 2 |
聚合范围, N = 3 |
聚合范围, N = 3 |
聚合范围, N = 4 |
聚合范围, N = 4 |
|||
|---|---|---|---|---|---|---|---|---|---|---|
游程长度 |
\(t_l\) |
\(t_h\) |
\(t_l\) |
\(t_h\) |
\(t_l\) |
\(t_h\) |
\(t_l\) |
\(t_h\) |
ω |
α |
1 |
/ |
/ |
\(2^{16} - 4\) |
\(10^{-6}\) |
||||||
2 |
/ |
/ |
\(2^{16} - 4\) |
\(10^{-6}\) |
||||||
3 |
/ |
/ |
\(2^{16} - 4\) |
\(10^{-6}\) |
||||||
4 |
/ |
/ |
\(2^{16} - 4\) |
\(10^{-6}\) |
||||||
5 |
/ |
/ |
\(2^{16} - 4\) |
\(10^{-6}\) |
||||||
≥ 6 |
/ |
/ |
\(2^{16} - 4\) |
\(10^{-6}\) |
||||||
1 |
2267 |
2733 |
20000 |
\(10^{-6}\) |
||||||
2 |
1079 |
1421 |
20000 |
\(10^{-6}\) |
||||||
3 |
502 |
748 |
20000 |
\(10^{-6}\) |
||||||
4 |
223 |
402 |
20000 |
\(10^{-6}\) |
||||||
5 |
90 |
223 |
20000 |
\(10^{-6}\) |
||||||
≥ 6 |
90 |
223 |
20000 |
\(10^{-6}\) |
||||||
1 |
/ |
/ |
1024 |
\(10^{-6}\) |
||||||
2 |
/ |
/ |
1024 |
\(10^{-6}\) |
||||||
3 |
/ |
/ |
1024 |
\(10^{-6}\) |
||||||
4 |
/ |
/ |
1024 |
\(10^{-6}\) |
||||||
5 |
/ |
/ |
1024 |
\(10^{-6}\) |
||||||
≥ 6 |
/ |
/ |
1024 |
\(10^{-6}\) |
||||||
1 |
/ |
/ |
512 |
\(10^{-6}\) |
||||||
2 |
/ |
/ |
512 |
\(10^{-6}\) |
||||||
3 |
/ |
/ |
512 |
\(10^{-6}\) |
||||||
4 |
/ |
/ |
512 |
\(10^{-6}\) |
||||||
5 |
/ |
/ |
512 |
\(10^{-6}\) |
||||||
≥ 6 |
/ |
/ |
512 |
\(10^{-6}\) |
||||||
1 |
/ |
/ |
256 |
\(10^{-6}\) |
||||||
2 |
/ |
/ |
256 |
\(10^{-6}\) |
||||||
3 |
/ |
/ |
256 |
\(10^{-6}\) |
||||||
4 |
/ |
/ |
256 |
\(10^{-6}\) |
||||||
5 |
/ |
/ |
256 |
\(10^{-6}\) |
||||||
≥ 6 |
/ |
/ |
256 |
\(10^{-6}\) |
||||||
1 |
/ |
/ |
128 |
\(10^{-6}\) |
||||||
2 |
/ |
/ |
128 |
\(10^{-6}\) |
||||||
3 |
/ |
/ |
128 |
\(10^{-6}\) |
||||||
4 |
/ |
/ |
128 |
\(10^{-6}\) |
||||||
5 |
/ |
/ |
128 |
\(10^{-6}\) |
||||||
≥ 6 |
/ |
/ |
128 |
\(10^{-6}\) |
||||||
128 |
\(10^{-5}\) |
|||||||||
128 |
\(10^{-4}\) |
|||||||||
3 |
128 |
\(10^{-3}\) |
||||||||
4 |
128 |
\(10^{-2}\) |
||||||||
5 |
128 |
\(10^{-1}\) |
扑克测试
这是在 [AIS31] 第 2.4.3 节中定义的测试 2。它有两种范围。窗口大小必须是 4 的倍数。
每个 4 比特块称为一张牌,可能值为 0-15。这里的测试统计量与原始文档中的略有不同。
\(S_2 = ∑_{i=0}^{W/4} f[i]^2\) , 其中 f[i] 是值为 i 的牌的数量。低阈值和高阈值由 α 和 W 如下公式确定。如果 \(S_2 < t_l\) 或 \(S_2 > t_h\) ,则测试失败。
当 w = 20,000 时,各种 α 和范围的阈值如表 3.5 扑克测试阈值示例 所示。
左尾 |
右尾 |
线路范围 |
线路范围 |
聚合范围, N = 4 |
聚合范围, N = 4 |
|
|---|---|---|---|---|---|---|
α |
\(T_2'\) |
\(T_2'\) |
\(t_l\) |
\(t_h\) |
\(t_l\) |
\(t_h\) |
0.05 |
7.26094 |
24.99579 |
1564769.044 |
1570311.184 |
25009076.18 |
25031244.74 |
0.01 |
5.22935 |
30.57791 |
1564134.172 |
1572055.597 |
25006536.69 |
25038222.39 |
0.001 |
3.48268 |
37.69730 |
1563588.338 |
1574280.406 |
25004353.35 |
25047121.63 |
0.0001 |
2.40819 |
44.26322 |
1563252.559 |
1576332.256 |
25003010.24 |
25055329.03 |
0.00001 |
1.70028 |
50.49301 |
1563031.338 |
1578279.066 |
25002125.35 |
25063116.26 |
0.000001 |
1.21600 |
56.49344 |
1562880.000 |
1580154.200 |
25001520.00 |
25070616.80 |
0.000000701845 |
57.4 |
1580437.500 |
25071750.00 |
|||
0.0000007 |
57.40672 |
1580439.600 |
25071758.40 |
|||
0.00000031237 |
1.03 |
1562821.875 |
25001287.50 |
|||
0.0000003 |
1.02412 |
1562820.038 |
25001280.15 |
状态
每个测试套件都有一个状态机,其转换由底层测试的结果驱动。它反过来反映了噪声源的部分健康状况。
图 3.5: 测试套件状态机
它有 3 个状态:
ST_OVCA:失败阴天状态,或简称阴天状态。噪声源可能有问题,但当前不确定。可能它正在经历暂时的不稳定状态。需要更多测试来找出(在后续窗口中)。
ST_SUNY:晴天状态。噪声源健康状况良好。
ST_ALRT:警报状态。噪声源遇到故障。它被定义为致命错误。
当一个窗口中的测试失败时,测试套件被视为失败,状态机转换到阴天状态。
当一个窗口中的所有测试都成功时,测试套件被视为成功。当它连续成功 SUNNY_TH 个窗口时,状态机从阴天状态转换到晴天状态。
健康测试警报在以下情况下发出信号:
当测试套件连续失败 n 个窗口时,其中 n = TRNG_HT_CTRL.fail2alert_th。一个特殊情况是 n = 1,在这种情况下,状态机将在任何测试失败时立即转换到警报状态。
当状态机在阴天状态下停留了 OVERCAST_MAX 个窗口时。它无法在给定的长时间内成功转换到晴天状态。
设备的健康测试也有这 3 种状态,根据以下规则从所有测试套件的状态映射而来:
当任何测试套件处于阴天状态时,健康测试或设备处于阴天状态。
当所有测试套件都处于晴天状态时,健康测试或设备处于晴天状态。
当任何测试套件处于警报状态时,健康测试或设备处于警报状态。
错误处理请参考第 “错误处理” 节。
启动测试
在启动测试期间,样本流向健康测试,而不流向后处理。
当所有测试套件连续成功 SUNNY_TH 个窗口时,设备通过启动测试并转换到连续测试。
注意:被测试的序列是原始数据,而不是经过处理后的序列。
注意:除了中断,不提供关于错误的更多信息。要找出根本原因以及哪个振荡器有缺陷,请在调试模式下收集数据并进行离线分析。
后处理
这是一系列数字处理,用于消除偏置并提高随机比特的质量(白化)。数据首先经过一些简单方法(简单翻转和VNC),然后经过一个经过验证的调理器。
固定偏置
这里的固定偏置是一些处理数据的简单方法,包括简单翻转和VNC。它们可以在单条线路上启用或禁用。
简单翻转 只是反转一条线路的每隔一个比特。
VNC 是冯·诺依曼校正器。它根据以下规则处理一对比特。
输入比特对 |
输出比特 |
|---|---|
00 |
无输出 |
11 |
无输出 |
10 |
1 |
01 |
0 |
调理
调理算法是基于 AES 的分组密码推导函数 (BC_df),已在 [SP800-90B] 中得到验证。
支持所有 AES 密钥长度。结果长度与密钥长度相同。
它接收大量数据作为输入,输出较小量的数据。它挤压数据中的熵,从而增加每比特的熵。
输入到调理器的长度是 TRNG_PP_CTRL.cond_blk_len。必须根据最小熵并遵循 [SP800-90A]、[SP800-90B]、[SP800-90C] 中的一些要求来设置,以便调理器能够生成全熵输出。
调理器可以通过软件禁用。
重复检查
对于一个好的调理器,两个连续的结果相同的可能性极低,除非输入相同。如果发现这样的结果,则发生重复错误。这是一个致命错误。设备可能有问题。
当调理器启用时,结果长度由密钥长度指定。一个结果与上一个结果进行比较。如果相等,则发生重复错误。两个结果中的第一个可能已经输出,第二个被阻止输出。在本设计中,仅比较前 64 位,因为这在统计上是显著的。
当调理器禁用时,输出是一个 32 位数据流。将它们分组以形成根据密钥长度的结果,并像上述情况一样进行比较。例如,当密钥长度为 128 位时,四个 32 位数据块形成一个结果;比较 128 位结果的前 64 位。
通过设置 TRNG_PP_CTRL.cond_dup_chk_en=0 来动态禁用重复检查,这将解除对重复结果的阻塞,这仅用于调试目的。
在调试模式下,应禁用重复检查。
输出
随机数存储在 OFIFO 中。数据通过数据寄存器或外部数据端口输出。数据寄存器从 OFIFO 获取数据的优先级高于外部数据端口。
OFIFO 输出将在以下情况下停止/阻塞:
发生致命错误时。
用户通过 TRNG_CTRL.stop_output 控制。
数据寄存器
数据寄存器通过软件读取向用户提供随机数。
在不同的情况下,有几组用于数据输出的寄存器:
在启动阶段,数据进入寄存器 TRNG_DAT_NF,并有一个关联的寄存器 TRNG_DAT_V_NF。
在连续阶段,数据进入寄存器 TRNG_DAT,并有一个关联的寄存器 TRNG_DAT_V。
在调试模式下,数据进入 TRNG_DBG_DAT,并有一个关联的寄存器 TRNG_DBG_DAT_V。
读取数据寄存器的通用流程
在每个寄存器集中有 3 个字段:
字段 data_ready 指示至少有一个随机数可用。
字段 pre_read_st 是自上次读取以来先前读取数据的累积状态。如果任何先前(多次)读取字段 data 无效,它将被设置。
字段 data 是随机数。
方法 A - 逐个读取数据
轮询直到 data_ready=1,或接收 data_ready 中断。
读取 data 一次。
检查 pre_read_st 是否为 1。
如果是,读取的数据有效。
如果不是,读取的数据无效。
方法 B - 读取多个数据
轮询直到 data_ready=1,或接收 data_ready 中断。
用户知道(至少)有 k 个数据可用。读取 data k 次。
检查 pre_read_st 是否为 1。
如果是,所有读取的数据都有效。
如果不是,至少有一个读取的数据无效。(但不知道是哪一个)
字段 pre_read_st 旨在解决由轮询 data_ready=1 和读取 data 之间的时间差引起的竞态条件。例如,如果在这之间发生了停止输出的致命错误,则返回的读取数据无效。字段 pre_read_st 有助于告知读取数据的真实状态。
外部数据端口
(硬件)外部数据端口向系统上的其他设备提供随机数。
外部数据端口在以下情况下停止/阻塞:
在调试模式下。
当 OFIFO 输出停止/阻塞时。
用户通过 TRNG_CTRL.stop_ext_inf 控制。
有几种类型的端口可用。端口数量可配置。有关端口时钟域的更多细节,请参考第 “时钟” 节。
RISC-V Seed CSR 接口
这是 RISC-V 加密扩展熵源的 seed CSR 接口。更多细节请参考 [RISCV-KS] 的第 4.1 节。
此接口直接连接到 CPU。设备内部状态映射到 OPST 中定义的四种状态。
CPU 通过断言 riscv[n]_req 启动对 seed CSR 的读取请求,设备在当前周期响应 OPST 和 entropy。如果 riscv[n]_req 断言多个周期,则每个周期发生一次事务。
riscv[n]_bist_alarm 是一个额外的信号,用于通知 RISC-V CPU BIST 状态。当端口处于 BIST 状态时,它被断言。CPU 可以监控它,并立即知道发生了 BIST,而无需启动对 seed CSR 的读取。
这样的 BIST 警报必须被锁存,直到至少被轮询一次,以便软件能够记录其发生。 ———— [RISCV-KS] 第 4.1 节中的 BIST 状态描述。
RISC-V Seed CSR 寄存器
寄存器文件中有一个特殊的 seed CSR 接口 TRNG_RISCV,它始终存在且位于主时钟域。(尽管在寄存器文件中,它实际上属于外部数据端口。)它适用于没有硬件 seed CSR 接口但希望通过软件读取模拟一个的 CPU。
简单外部接口
它使用简单的 req/ack 握手机制。
睡眠
噪声源包含在主动工作时消耗大量能量的组件,因此当设备暂时不需要生成更多随机数时(称为睡眠前的空闲超时期),将其关闭,并在需要时打开,这是一种良好的实践。例如,OFIFO 已满一段时间且用户未读取。当这段时间达到阈值(超时)时,设备进入睡眠状态。
超时阈值应设置在合理范围内。设置过短会导致波动。(频繁进入和退出。随后的初始化和启动测试也需要时间。)设置过长则不利于节能。
超时时,设备关闭噪声源并进行一些清理。然后主状态机转换到 ST_SLEP 状态。睡眠选项指定将清理什么。
当退出睡眠时,设备打开噪声源。然后重新启动初始化和启动测试。
启动阶段的睡眠在几个方面有所不同。超时时,它不进行清理(相当于睡眠选项 SLP_OPT_LEV0)。当退出睡眠时,它进行初始化但不进行启动测试。
启动阶段
启动阶段旨在系统启动后快速收集少量随机数。这些随机数不符合 FIPS。用户指定数据量。
设置要求如下:
调理器被禁用。允许固定偏置。
数据量和 OFIFO 大小无关。
数据量和健康测试窗口大小无关。
启动阶段支持睡眠。
为了加速收集,启动测试被跳过。初始化后,设备开始第一轮数据收集过程,在此期间健康测试和后处理也运行。如果失败,设备将清理数据并重试。总共允许 10 轮(或 9 次重试)。最终状态记录在寄存器文件中。如果失败,则未获得有效数据。如果任何一轮成功,则启动阶段立即结束并获得有效数据。
应通过降低置信度来放宽健康测试。因此,输出数据可能不是全熵的,其质量取决于噪声源。用户可以对数据进行额外的处理。
在每一轮中,健康测试连续窗口进行,直到数据收集完成。窗口的跨度覆盖收集的数据。如果任何窗口中的测试失败,则认为此轮失败。
如果数据量小于或等于 OFIFO 大小加上 32 比特,设备可以容纳所有数据,并且启动阶段无需软件干预即可完成。否则,需要用户及时读取数据。设备没有足够的空间容纳所有数据。如果用户不读取,设备会卡住并超时进入睡眠。当用户来读取时,空间再次可用,数据收集继续进行。有关启动阶段睡眠的更多细节,请参考第 “睡眠” 节。
在离开启动阶段之前,应读取所有数据。否则,它将阻塞连续阶段的数据。
调试模式
在调试模式下,振荡器的原始样本未经处理即到达 OFIFO。
为了正确收集数据,必须满足一些要求:
调理器应被禁用。
启动测试可被禁用。在启动测试期间,样本不流向数据输出端口。如果用户需要收集噪声源启动后的那部分数据,请跳过启动测试。
用户应及时读取数据并本地保存。 噪声源持续生成样本,无法进行反压。如果样本未及时读取,新的样本将覆盖旧的样本。因此,收集的数据不完整。
如果用户在数据尚未有效时读取数据,则会触发 OFIFO 下溢错误。在这种情况下,返回零值,并且 TRNG_DBG_DAT_V.pre_read_st_src 将被设置为 1。
如果用户未能及时读取数据(新数据到达时 OFIFO 已满),则会触发 OFIFO 上溢错误。最新数据覆盖 OFIFO 中最旧的数据。
设备永远不会进入睡眠状态,因为新数据总是可以进入 OFIFO。实际上,睡眠是不希望的,因为用户正在等待故障发生,应保持噪声源开启。
模式与软件端口一起提供了许多有用的方式进行调试和测试。一些典型应用列于表 3.7 模式典型应用。
模式 |
源 |
后处理 |
结果 / 输出 |
调试/测试场景 |
|---|---|---|---|---|
D |
NS |
fix_bias_en=0, cond_en=0 |
用户必须及时读取数据,否则被覆盖。 |
从噪声源收集原始数据 |
N |
SW |
fix_bias_en=0, cond_en=0, stop_ext_inf=1 |
用户应读取数据,否则软件端口将被阻塞。 |
通过软件端口收集数据 |
N |
SW |
fix_bias_en=0, cond_en=1, stop_ext_inf=1 |
用户应读取数据,否则软件端口将被阻塞。 |
调理器已知答案测试 (KAT) |
N |
SW |
fix_bias_en=1, cond_en=0, stop_ext_inf=1 |
用户应读取数据,否则软件端口将被阻塞。 |
固定偏置已知答案测试 (KAT) |
N |
SW |
fix_bias_en=1, cond_en=1, stop_ext_inf=1 |
用户应读取数据,否则软件端口将被阻塞。 |
固定偏置 + 调理器已知答案测试 (KAT) |
D |
SW |
cond_en=0 |
用户可以忽略输出数据。检查健康测试的统计数据。 |
健康测试已知答案测试 (KAT) |
D |
NS |
cond_en=0 |
用户可以忽略输出数据。检查健康测试的统计数据。 |
长时间监控噪声源并检查其质量 |
注:N - 正常模式;D - 调试模式;NS - 噪声源;SW - 软件端口;fix_bias_en - 启用 fix_bias;cond_en - 启用 cond;stop_ext_inf - 停止外部接口。
格式
数据在寄存器 TRNG_DBG_DAT 中。数据有效性由 TRNG_DBG_DAT_V.src_dat_vld 指示。
TRNG_DBG_DAT = {raw_data[27:0], cnt[3:0]},其中:
cnt[3:0] 是一个伴随计数。每个数据递增 1,范围 0-15。它像一个序列号,保证顺序并帮助识别缺失或重复的项目。
raw_data[27:0] 保存振荡器的原始样本。索引较低的振荡器的比特在前。比特紧凑地打包到其中并对齐到 LSB。如果没有足够的空间容纳传入的比特,部分比特填充它,剩余比特填充下一个数据。
以下是一些例子:
启用 1 个振荡器,索引 [1]。样本序列是 {a[1][t]},其中 t ≥ 0 是时间。然后它们按以下方式打包。
cnt=0, raw_data[27:0] = {a[1][03], a[1][02], a[1][01], a[1][00], a[1][07], a[1][06], a[1][05], a[1][04], a[1][11], a[1][10], a[1][09], a[1][08], a[1][15], a[1][14], a[1][13], a[1][12], a[1][19], a[1][18], a[1][17], a[1][16], a[1][23], a[1][22], a[1][21], a[1][20], a[1][27], a[1][26], a[1][25], a[1][24]} cnt=1, raw_data[27:0] = {a[1][31], a[1][30], a[1][29], a[1][28], a[1][35], a[1][34], a[1][33], a[1][32], a[1][39], a[1][38], a[1][37], a[1][36], a[1][43], a[1][42], a[1][41], a[1][40], a[1][47], a[1][46], a[1][45], a[1][44], a[1][51], a[1][50], a[1][49], a[1][48], a[1][55], a[1][54], a[1][53], a[1][52]} cnt=2, …
启用 2 个振荡器,索引 [1] 和 [5]。样本序列是 {a[5][t], a[1][t]},其中 t ≥ 0 是时间。然后它们按以下方式打包。
cnt=0, raw_data[27:0] = {a[5][01], a[1][01], a[5][00], a[1][00], a[5][03], a[1][03], a[5][02], a[1][02], a[5][05], a[1][05], a[5][04], a[1][04], a[5][07], a[1][07], a[5][06], a[1][06], a[5][09], a[1][09], a[5][08], a[1][08], a[5][11], a[1][11], a[5][10], a[1][10], a[5][13], a[1][13], a[5][12], a[1][12]} cnt=1, raw_data[27:0] = {a[5][15], a[1][15], a[5][14], a[1][14], a[5][17], a[1][17], a[5][16], a[1][16], a[5][19], a[1][19], a[5][18], a[1][18], a[5][21], a[1][21], a[5][20], a[1][20], a[5][23], a[1][23], a[5][22], a[1][22], a[5][25], a[1][25], a[5][24], a[1][24], a[5][27], a[1][27], a[5][26], a[1][26]} cnt=2, …
启用 3 个振荡器,索引 [0]、[1] 和 [5]。样本序列是 {a[5][t], a[1][t], a[0][t]},其中 t ≥ 0 是时间。然后它们按以下方式打包。
cnt=0, raw_data[27:0] = {a[0][01], a[5][00], a[1][00], a[0][00], a[1][02], a[0][02], a[5][01], a[1][01], a[5][03], a[1][03], a[0][03], a[5][02], a[0][05], a[5][04], a[1][04], a[0][04], a[1][06], a[0][06], a[5][05], a[1][05], a[5][07], a[1][07], a[0][07], a[5][06], a[0][09], a[5][08], a[1][08], a[0][08]} cnt=1, raw_data[27:0] = {a[1][10], a[0][10], a[5][09], a[1][09], a[5][11], a[1][11], a[0][11], a[5][10], a[0][13], a[5][12], a[1][12], a[0][12], a[1][14], a[0][14], a[5][13], a[1][13], a[5][15], a[1][15], a[0][15], a[5][14], a[0][17], a[5][16], a[1][16], a[0][16], a[1][18], a[0][18], a[5][17], a[1][17]} cnt=2, …
启用 4 个振荡器,索引 [0]、[1]、[5] 和 [6]。样本序列是 {a[6][t], a[5][t], a[1][t], a[0][t]},其中 t ≥ 0 是时间。然后它们按以下方式打包。
cnt=0, raw_data[27:0] = {a[6][00], a[5][00], a[1][00], a[0][00], a[6][01], a[5][01], a[1][01], a[0][01], a[6][02], a[5][02], a[1][02], a[0][02], a[6][03], a[5][03], a[1][03], a[0][03], a[6][04], a[5][04], a[1][04], a[0][04], a[6][05], a[5][05], a[1][05], a[0][05], a[6][06], a[5][06], a[1][06], a[0][06]} cnt=1, raw_data[27:0] = {a[6][07], a[5][07], a[1][07], a[0][07], a[6][08], a[5][08], a[1][08], a[0][08], a[6][09], a[5][09], a[1][09], a[0][09], a[6][10], a[5][10], a[1][10], a[0][10], a[6][11], a[5][11], a[1][11], a[0][11], a[6][12], a[5][12], a[1][12], a[0][12], a[6][13], a[5][13], a[1][13], a[0][13]} cnt=2, …
错误处理
有两种类型的错误:可恢复错误和致命错误。
通常可恢复错误是由用户行为的轻微错误或设计可容忍的错误引起的。设备可以在有或没有少量干预的情况下继续正常工作。详细的错误标志记录在寄存器 TRNG_RECOV_ERR 中。它有一个源中断位 TRNG_INTSRC.rint_recover。
致命错误是由严重问题引起的,整个设备无法再工作。通常需要复位。详细的错误标志记录在寄存器 TRNG_FATAL_ERR 中。它有一个源中断位 TRNG_INTSRC.rint_fatal_err。
当致命错误发生时,设备自动停止 OFIFO 的输出。
健康测试警报属于致命错误。这是一个如此重要的错误,它有一个专用的源中断位,TRNG_INTSRC.rint_health_alert。其错误标志记录在 TRNG_FATAL_ERR.health_alert 中。
有 3 种致命错误状态 – ST_ALRT、ST_FERR 和非法状态。当致命错误发生时,主状态机转换到特定状态并停留在那里。当健康警报发生时,它转换到 ST_ALRT。它可能因噪声而意外转换到非法状态。当其他致命错误发生时(包括其他状态机转换到非法状态),它转换到 ST_FERR。需要软件干预(停止)或硬件复位才能使其恢复正常,在此之前,软件应检查或保存一些相关信息以进行调试。
重复错误 (cond_dup_err)
当重复错误发生时,重复数据被阻止输出。
用户可以简单地停止设备或应用硬件复位。
开发人员可以解除阻塞并读取重复数据进行离线分析。这仅用于调试目的。(步骤请参考第 “读取重复数据” 节。)
状态机处于非法状态 (*_fsm_err)
用户可以简单地停止设备或应用硬件复位。
开发人员可以读取寄存器 TRNG_DBG_ST 并检查它处于哪个状态。
健康警报 (health_alert)
用户可以简单地停止设备或应用硬件复位。
开发人员可以读取相关寄存器以获取更多信息。寄存器是 TRNG_DBG_ST、TRNG_DBG_HT_ST_FIPS 和 TRNG_DBG_HT_ST_AIS。
安全性
输出数据在读取发生之前不可见。
一个端口获取的数据对其他端口不可见。
输出数据重复检查。更多细节请参考第 “重复检查” 节。
当发生致命错误或健康警报时,设备中的数据被清除。
中国标准
硬件 TRNG 的中国标准是 [GMT0005-2021]、[GMT0062-2018]、[GMT0078-2020] 和 [GMT0103-2021]。
它还来自 [GMT0008-2012] 的额外要求,如下文引用。文本说明扩展算法的数据必须进行异或。然而,它没有说明扩展算法是什么,或者健康测试的数据是否必须进行异或。
一些寄存器字段用于满足此要求:
当 TRNG_NOISRC_0.combine_pp=1 时,到后处理的数据进行异或。
当 TRNG_NOISRC_0.combine_ht=1 时,到健康测试的数据进行异或。
是否设置 combine_ht 取决于开发人员对要求的理解。
警告:禁止设置 TRNG_NOISRC_0.combine_pp=0 和 TRNG_NOISRC_0.combine_ht=1,因为它不符合任何标准。
关于安全等级,摘自[GMT0008-2012]:
安全等级1
安全芯片必须提供至少2个相互独立的物理随机源,直接生成随机数或生成随机数扩展算法的初始输入。物理随机源直接生成的随机数或此类随机数扩展算法的初始输入必须通过对所有物理随机源的输出进行异或操作来生成。
安全等级2
安全芯片必须提供至少4个相互独立的物理随机源,直接生成随机数或生成随机数扩展算法的初始输入。物理随机源直接生成的随机数或此类随机数扩展算法的初始输入必须通过对所有物理随机源的输出进行异或操作来生成。
安全等级3
安全芯片必须提供至少8个相互独立且分散分布的物理随机源,直接生成随机数或生成随机数扩展算法的初始输入。物理随机源应采用至少两种设计原则实现。物理随机源直接生成的随机数或此类随机数扩展算法的初始输入必须通过对所有物理随机源的输出进行异或操作来生成。
操作流程
复位
本设备有两个异步(硬件)复位,没有同步复位。
这两个异步复位分别对应主时钟域和采样时钟域。要复位设备,必须同时置位这两个复位。仅置位一个将导致设备故障。
(异步复位从外部生成,通常来自时钟和复位单元。遵循那里的指南完成复位过程。)
外部端口
外部端口将此设备连接到另一设备。此端的复位和另一端的复位都会影响端口。这两个复位可以独立应用。也就是说,复位端口时,可以复位任一端。(有时在系统中复位端口的两端是不可行的。)
停止
停止相当于软件复位。
步骤
禁用设备:在任何时候通过 TRNG_CTRL.trng_en = 0 禁用它。
等待设备返回到空闲状态:轮询直到 TRNG_DBG_ST.post_proc_fsm = ST_IDLE。(轮询超时)如果轮询在 4 × t_stop_max 后没有成功,设备故障并应用硬件复位。
结束。
启动阶段
有两种情况:
情况1:OFIFO深度 + 1 ≥ TRNG_BTPH_DLEN.data_len_btph
情况2:OFIFO深度 + 1 < TRNG_BTPH_DLEN.data_len_btph
在情况1中,OFIFO能够容纳所有收集的数据。用户可以等待完成然后读取数据,或者使用情况2的方法。
在情况2中,OFIFO无法容纳所有收集的数据。用户应及时读取数据,以便为传入数据腾出空间。
情况1的步骤
等待启动阶段完成。
(检查完成)检查启动阶段是否结束。读取 TRNG_ST.btph_done。
(轮询超时)如果轮询(检查完成)在 4 × t_btph_max 后没有成功,那么返回空数据和 ERROR 状态。设备故障并应用硬件复位。结束。
读取收集的数据。
读取 TRNG_DAT_NF n 次并将数据本地保存。(n = TRNG_BTPH_DLEN.data_len_btph)
读取 TRNG_DAT_V_NF.pre_read_st_nfips 以检查读取数据的状态。
如果 pre_read_st_nfips=1,读取的数据无效。返回空数据和 INVALID 状态。
如果 pre_read_st_nfips=0,读取的数据有效。返回数据和 VALID 状态。
结束。
正常模式
将设备编程为在正常模式下工作。
步骤
选择正常模式:TRNG_CTRL.dbg_mode_en = 0
在设备中设置基本控制。
设置 tick 比例
TRNG_TIMER.tick_scale
设置初始化周期:
TRNG_TIMER.init_t.
注:如果 init_t=0,初始化(快速)跳过。但是,FSM 仍会在 ST_INIT 状态停留几个周期。)
设置睡眠超时阈值:
TRNG_TIMER.pp_rd_th < 0xff
如果 pp_rd_th=0xff,则禁用睡眠模式。
配置噪声源
这里使用噪声源作为原始数据源。也可以使用软件端口。参考第 “软件端口” 节
选择噪声源作为原始数据源:TRNG_CTRL.raw_sel = RAW_NS
启用噪声源:TRNG_NOISRC_0 / TRNG_NOISRC_1
配置后处理
如果需要,启用简单翻转和 VNC:TRNG_FIX_BIAS
如果需要,配置调理器:TRNG_PP_CTRL
配置健康测试
选择测试套件和测试。测试套件/测试的通用配置步骤如下:
选择所需的测试并启用它们:TRNG_HT_CTRL.test_*_en
设置测试范围、失败到警报阈值和窗口大小:
TRNG_HT_CTRL.test_scope
TRNG_HT_CTRL.fail2alert_th
TRNG_HT_WIN
设置每个测试的阈值(s):
TRNG_TEST_TH_*
TRNG_TEST_THLO_*
TRNG_TEST_THHI_*
如果需要,启用中断:TRNG_INTEN
启动 TRNG。启用 TRNG 后初始化开始:TRNG_CTRL.trng_en = 1
结束。
注:TRNG_CTRL.trng_en 应最后设置。其他配置的顺序无关紧要。TRNG_CTRL 的字段可以一次全部设置。
软件端口
使用软件端口输入原始数据。
步骤
配置设备。
使用与第 “正常模式” 节相同的流程,但有以下例外。
在步骤(配置噪声源)中,设置 TRNG_CTRL.raw_sel=RAW_SW(此设置会自动禁用噪声源)。
将数据馈送到软件端口。
轮询直到 TRNG_SWPORT_ST.sw_in_empty=1。
向 TRNG_SWPORT 写入一条数据。
(可选)通过读取 TRNG_SWPORT_ST.pre_write_st_sw 来双重检查写入数据的状态。
如果 pre_write_st_sw=1,前一次写入未成功,数据被丢弃。
如果 pre_write_st_sw=0,前一次写入成功。
读取随机数
提供两种读取随机数的方法:通过轮询和中断。
通过轮询读取
一次读取一条数据。
(检查就绪状态)检查数据是否就绪。读取 TRNG_DAT_V.data_ready。
(轮询超时)如果轮询(检查就绪状态)在 4 × t_rnd_gen_max 后没有成功,那么返回空数据和 ERROR 状态。设备故障并应用硬件复位。结束。
如果 data_ready=0 并且返回随机数是强制性的,跳转到(检查就绪状态)。
如果 data_ready=0 并且返回随机数不是强制性的,那么返回空数据和 INVALID 状态。用户可以在一段时间后发起另一次读取。结束。
如果 data_ready=1,从寄存器读取数据:TRNG_DAT.data
读取 TRNG_DAT_V.pre_read_st 以检查先前读取数据的状态。
如果 pre_read_st=1,最近一次读取的数据无效。返回空数据和 INVALID 状态。
如果 pre_read_st=0,最近一次读取的数据有效。返回数据和 VALID 状态。
结束。
通过中断读取
接收中断后读取多个数据。(前提:中断 data_ready 已正确设置。)
设置中断。
设置中断 data_ready 的阈值:TRNG_TIMER.data_ready_cnt_th
启用中断 data_ready:TRNG_INTEN.inten_data_ready = 1
读取数据。
当接收到中断时,检查中断 data_ready 是否设置。如果没有,结束。TRNG_INTST.intst_data_ready
屏蔽中断:TRNG_INTEN.inten_data_ready = 0
读取随机数据。现在至少有 n 条数据可用,其中 n = TRNG_TIMER.data_ready_cnt_th。读取数据可通过轮询读取 或以下过程:
从寄存器 TRNG_DAT.data 读取多个数据并本地保存。读取次数不应大于 n。
读取 TRNG_DAT_V.pre_read_st 以检查先前读取数据的状态。
如果 pre_read_st=1,部分读取的数据无效。丢弃所有本地保存的数据。返回空数据和 INVALID 状态。
如果 pre_read_st=0,所有读取的数据都有效。返回数据和 VALID 状态。
清除并重新启用中断:TRNG_INTSRC(写 1 清除),TRNG_INTEN.inten_data_ready = 1
结束。
调试模式
这是调试模式。以下是两种典型应用:
收集噪声源启动一段时间后的数据。
收集噪声源刚启动时的数据。
步骤
选择调试模式:TRNG_CTRL.dbg_mode_en = 1
在设备中设置基本控制。
设置 tick 比例:TRNG_TIMER.tick_scale
设置初始化周期:TRNG_TIMER.init_t. 注:如果 init_t=0,初始化(快速)跳过。然而,FSM 仍会在 ST_INIT 状态停留几个周期。)
(可选)禁用睡眠:TRNG_TIMER.pp_rd_th = 0xff
如果需要,禁用启动测试:TRNG_DBG_CTRL.startup_test_dis = 1
配置噪声源:参考 “配置噪声源”。
禁用设备中的功能。
禁用简单翻转和 VNC:TRNG_FIX_BIAS.simple_flip_en = 0,TRNG_FIX_BIAS.vnc_en = 0
禁用调理器:TRNG_PP_CTRL.cond_en = 0
禁用中断:TRNG_INTEN = 0
如果需要,禁用健康测试:TRNG_HT_CTRL.test_*_en = 0
启动 TRNG:TRNG_CTRL.trng_en = 1
收集数据。
如果用户想在 trng_en=1 一段时间后开始收集数据,请等待数据收集的起点。
(收集)使用以下任一方式及时收集数据:
轮询直到 TRNG_DBG_DAT_V.src_dat_vld = 1。然后从 TRNG_DBG_DAT 读取 1 个数据。重复此操作。(无超时)
轮询直到 TRNG_ST.buf_full = 1。然后从 TRNG_DBG_DAT 读取 CFG_TRNG_OFIFO_DEP 个数据。重复此操作。(无超时)(推荐)
检查数据的完整性。
如果 TRNG_RECOV_ERR.ofifo_overflow = 1,则有些数据缺失。(伴随计数不连续。)
如果 TRNG_RECOV_ERR.ofifo_underflow = 1,则保存的某些数据无效(零值)。
结束。
读取重复数据
(当重复错误发生时,开发人员可以解除阻塞并读取重复数据。参考第 “错误处理” 节了解全面的重复错误处理。)
步骤
除了重复错误,通过读取寄存器 TRNG_FATAL_ERR 检查是否发生其他致命错误。如果是,数据无法从 OFIFO 排出。结束。
禁用外部接口。不要让重复数据流出:TRNG_CTRL.stop_ext_inf = 1
清除 cond_dup_err 标志:TRNG_FATAL_ERR.cond_dup_err = 1(写 1 清除)
禁用重复检查:TRNG_PP_CTRL.cond_dup_chk_en = 0
从 TRNG_DAT 读取数据,直到 OFIFO 为空。
停止设备或应用硬件复位。参考第 “停止” 节。
结束。
参数
参数 |
值/范围 |
单位 |
描述 |
|---|---|---|---|
f_clk |
(可配置) |
MHz |
主时钟频率 |
t_clk |
1/f_clk |
µs |
主时钟周期 |
f_smp |
(可配置) |
MHz |
采样时钟频率 |
t_smp |
1/f_smp |
µs |
采样时钟周期 |
N |
1 ≤ N ≤ 4 |
1 |
启用的振荡器数量,也是线路数 |
\(H_{bitstring}\) |
\(0 ≤ H_{bitstring} ≤ 1\) |
bit |
噪声源输出每个物理比特的熵量 |
H (最小熵) |
\(N \cdot H_{bitstring}\) |
bit |
|
keysize |
128/192/256 |
bit |
调理器密钥长度 |
L |
\(\left\lceil \frac{keysize \cdot N}{16min-entropy} \right\rceil\) |
32-bits |
调理器输入块长度 (L = TRNG_PP_CTRL.cond_blk_len) |
L_btph |
< 64 |
32-bits |
启动阶段要收集的数据长度 (L_btph = TRNG_BTPH_DLEN.data_len_btph) |
tick_period |
\(2^{4(tick\_scale + 1)}\) |
周期 |
定时器/超时的 Tick 周期 (tick_scale = TRNG_TIMER.tick_scale) |
t_init |
init_t × tick_period |
周期 |
噪声源初始化时间 (init_t = TRNG_TIMER.init_t) |
t_init_min |
100 |
µs |
t_init 的最小值 |
win_m |
\(< 2^{16}\) |
采样周期 |
所有测试套件窗口大小的最大值 |
t_startup |
s × win_m (SUNNY_TH ≤ s ≤ OVERCAST_MAX) |
采样周期 |
启动测试时间 |
th_slp |
(pp_rd_th+1) × tick_period |
周期 |
进入睡眠的超时阈值 (pp_rd_th = TRNG_TIMER.pp_rd_th) |
t_wake |
t_init |
周期 |
唤醒时间 |
t_rnd_gen |
(32 × L) / N |
采样周期 |
当设备处于 ST_RGEN 状态且调理器启用时,生成一个随机数(长度等于 keysize)所需的时间。 |
t_rnd_gen_max |
t_rnd_gen × t_smp + t_init × t_clk + t_startup × t_smp |
µs |
从启动或唤醒到生成第一个随机数所需的最大时间 |
t_stop_max |
t_init |
采样周期 |
停止设备的最大转换时间 |
t_btph_max |
≈ TRY_BTPH × max(win_m, (32 × L_btph)/N) |
采样周期 |
当 fix_bias 禁用时,启动阶段的最大时间 |
SUNNY_TH |
2 |
1 |
测试套件状态机转换到晴天状态所需的连续成功窗口数。 |
OVERCAST_MAX |
8 |
1 |
测试套件状态机在转换到警报状态前允许停留在阴天状态的最大窗口数。 |
TRY_BTPH |
10 |
1 |
启动阶段数据收集的最大尝试次数。 |
WIN_MIN_AIS |
100 |
1 |
AIS-31 测试套件的最小窗口大小。 |
(吞吐量) |
\(≤ 6.25^{3}\) |
Mbps |
吞吐量 |
硅数据
工艺 |
频率 (MHz) |
总面积 (µm²) |
非组合面积 (µm²) |
组合面积 (µm²) |
总单元数 |
时序单元 |
组合单元 |
时钟门控率 |
带 DFT |
注释 |
|---|---|---|---|---|---|---|---|---|---|---|
SMIC |
300 |
67001 |
29599 |
37402 |
33059 |
3915 |
27654 |
95.42% (3419:332) |
是 |
DC 模式,未展平 |
吞吐量
吞吐量取决于许多因素。给定启用 N 个振荡器,采样频率 f_smp,VNC 禁用,调理器启用,并满足第 “时钟约束” 节中指定的时钟约束,吞吐量 T 为:
吞吐量下限:假设质量较低。在一个工艺下,最小反相器产生波形。抖动与周期之比为 a。保守估计 a = 1/1000,吞吐量为 0.22 kbps。
吞吐量上限:假设质量较高。采样频率为 50MHz,H_bitstring = 1/16(N=4,keysize=128,L=128),吞吐量为 6.25 Mbps。
时钟约束
f_smp ≤ 100 MHz
f_clk ≥ f_smp
编程约束
一些对设备寄存器编程的约束和建议。
约束:
在调试模式下,必须禁用调理器。
在启动阶段,禁用调理器。
在启动阶段,使用正常模式。
AIS-31 测试套件的窗口大小必须大于或等于 WIN_MIN_AIS。
当启用扑克测试时,窗口大小必须是 4 的倍数。
禁止设置 TRNG_NOISRC_0.combine_pp=0 和 TRNG_NOISRC_0.combine_ht=1。
建议:
使用软件端口时,禁用睡眠。
在调试模式下,应禁用重复检查。
4. 中断
本设备有一个中断信号。它是一个电平中断。
中断是可屏蔽的。提供以下中断:
data_ready:数据就绪中断。
sw_in_empty:软件端口数据输入就绪中断。
health_alert:健康警报中断。
recov_err:可恢复错误中断。
fatal_err:致命错误中断(不包括健康警报)。
更多细节请参考寄存器描述。相关寄存器是 TRNG_INTEN、TRNG_INTSRC、TRNG_INTST 和 TRNG_INTSET。
5. 寄存器
TRNG 寄存器
表5.1 TRNG 寄存器偏移地址。
偏移量 |
寄存器名称 |
功能描述 |
|---|---|---|
0x0 |
IP_VER |
IP 版本号 |
0x4 |
GIT_VER |
Git 版本号 |
0x8 |
TRNG_CAP |
TRNG 能力寄存器 |
0xC |
TRNG_CTRL |
控制寄存器 |
0x10 |
TRNG_TIMER |
定时器与阈值寄存器 |
0x14 |
TRNG_NOISRC_0 |
噪声源寄存器 0 |
0x18 |
TRNG_NOISRC_1 |
噪声源寄存器 1 |
0x24 |
TRNG_FIX_BIAS |
偏置校正寄存器 |
0x28 |
TRNG_PP_CTRL |
后处理控制寄存器 |
0x30 |
TRNG_ST |
状态寄存器 |
0x34 |
TRNG_RECOV_ERR |
可恢复错误标志寄存器 |
0x38 |
TRNG_FATAL_ERR |
致命错误标志寄存器 |
0x3C |
TRNG_SWPORT_ST |
软件端口状态寄存器 |
0x40 |
TRNG_SWPORT |
原始数据输入软件端口 |
0x44 |
TRNG_DAT_V_NF |
非FIPS数据有效寄存器 |
0x48 |
TRNG_DAT_NF |
非FIPS数据寄存器 |
0x4C |
TRNG_DAT_V |
数据有效寄存器 |
0x50 |
TRNG_DAT |
数据寄存器 |
0x54 |
TRNG_RISCV |
RISC-V seed CSR 寄存器 |
0x60 |
TRNG_INTEN |
中断使能寄存器 |
0x64 |
TRNG_INTSRC |
中断源寄存器 |
0x68 |
TRNG_INTST |
中断状态寄存器 |
0x6C |
TRNG_INTSET |
中断置位寄存器 |
0x70 |
TRNG_DBG_DAT_V |
数据有效调试寄存器 |
0x74 |
TRNG_DBG_DAT |
数据调试寄存器 |
0x78 |
TRNG_DBG_ST |
状态调试寄存器 |
0x7C |
TRNG_DBG_HT_ST |
健康测试状态调试寄存器 |
0x80 |
TRNG_DBG_HT_ST_FIPS |
健康测试状态调试寄存器 - 用于 FIPS 测试套件 |
0x84 |
TRNG_DBG_HT_ST_AIS |
健康测试状态调试寄存器 - 用于 AIS 测试套件 |
0x88 |
TRNG_DBG_CTRL |
控制调试寄存器 |
0x8C |
TRNG_DBG_HTEJ_FIPS |
健康测试错误注入调试寄存器 - 用于 FIPS 测试套件 |
0x90 |
TRNG_DBG_HTEJ_AIS |
健康测试错误注入调试寄存器 - 用于 AIS 测试套件 |
0xA0 |
TRNG_HT_CTRL |
健康测试控制寄存器 |
0xA4 |
TRNG_BTPH_DLEN |
启动阶段数据长度寄存器 |
0xA8 |
TRNG_HT_WIN |
健康测试窗口寄存器 |
0xB0 |
TRNG_TEST_TH_REPCNT |
重复计数健康测试 - 阈值寄存器 |
0xB8 |
TRNG_TEST_THLO_ADPPRP |
自适应比例健康测试 - 低阈值寄存器 |
0xBC |
TRNG_TEST_THHI_ADPPRP |
自适应比例健康测试 - 高阈值寄存器 |
0xC4 |
TRNG_TEST_THLO_MONBIT |
单比特健康测试 - 低阈值寄存器 |
0xC8 |
TRNG_TEST_THHI_MONBIT |
单比特健康测试 - 高阈值寄存器 |
0xE4 |
TRNG_TEST_TH_RUNS_1 |
游程健康测试 - 游程长度 1 阈值寄存器 |
0xE8 |
TRNG_TEST_TH_RUNS_2 |
游程健康测试 - 游程长度 2 阈值寄存器 |
0xEC |
TRNG_TEST_TH_RUNS_3 |
游程健康测试 - 游程长度 3 阈值寄存器 |
0xF0 |
TRNG_TEST_TH_RUNS_4 |
游程健康测试 - 游程长度 4 阈值寄存器 |
0xF4 |
TRNG_TEST_TH_RUNS_5 |
游程健康测试 - 游程长度 5 阈值寄存器 |
0xF8 |
TRNG_TEST_TH_RUNS_6 |
游程健康测试 - 游程长度 6 阈值寄存器 |
0x100 |
TRNG_TEST_THLO_POKER |
扑克健康测试 - 低阈值寄存器 |
0x104 |
TRNG_TEST_THHI_POKER |
扑克健康测试 - 高阈值寄存器 |
IP 版本号寄存器
地址偏移:0x0
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
IP_VER |
23:0 |
RO |
0x020007 |
IP 版本号 |
Reserved |
31:24 |
/ |
0x0 |
/ |
Git 版本号寄存器
地址偏移:0x4
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
GIT_VER |
31:0 |
RO |
32’h0000_0000 |
Git 版本号 |
TRNG 能力寄存器 (TRNG_CAP)
地址偏移:0x8
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
auto_boot_ph |
0 |
RO |
0x0 |
|
保留 |
7:1 |
/ |
0x0 |
/ |
source_ind |
15:8 |
RO |
8’b0000_1111 |
|
保留 |
31:16 |
/ |
0x0 |
/ |
控制寄存器 (TRNG_CTRL)
地址偏移:0xC
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
trng_en |
0 |
RW |
0x0 |
|
boot_ph_en |
1 |
RW |
0x0 |
|
dbg_mode_en |
2 |
RW |
0x0 |
|
保留 |
3 |
/ |
0x0 |
/ |
raw_sel |
4 |
RW |
0x0 |
|
stop_output |
5 |
RW |
0x0 |
|
stop_ext_inf |
6 |
RW |
0x0 |
|
保留 |
27:7 |
/ |
0x0 |
/ |
clr_cnt |
28 |
RW |
0x0 |
清除计数器。(在当前设计中此字段无用。) |
clr_flag |
29 |
RW |
0x0 |
清除标志。相关寄存器是 TRNG_RECOV_ERR、TRNG_FATAL_ERR 和 TRNG_INTSRC。 |
保留 |
31:30 |
/ |
0x0 |
/ |
定时器与阈值寄存器 (TRNG_TIMER)
地址偏移:0x10
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
tick_scale |
2:0 |
RW |
0x0 |
|
保留 |
3 |
/ |
0x0 |
/ |
init_t |
11:4 |
RW |
0x0 |
|
sleep_opt |
13:12 |
RW |
0x1 |
|
保留 |
15:14 |
/ |
0x0 |
/ |
pp_rd_th |
23:16 |
RW |
0x1 |
|
保留 |
27:24 |
/ |
0x0 |
/ |
data_ready_cnt_th |
29:28 |
RW |
0x0 |
警告: 如果设置 data_ready_cnt_th × 2 ≥ OFIFO深度,RISC-V 端口和外部硬件端口将无法获取数据) |
保留 |
31:30 |
/ |
0x0 |
/ |
噪声源寄存器 0 (TRNG_NOISRC_0)
地址偏移:0x14
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
src_en |
7:0 |
RW |
0x0 |
|
combine_pp |
8 |
RW |
0x0 |
|
combine_ht |
9 |
RW |
0x0 |
警告:(不要使用值 {combine_ht, combine_pp} = 2’b10) |
保留 |
15:10 |
/ |
0x0 |
/ |
rings_0_en |
22:16 |
RW |
0x0 |
|
保留 |
23 |
/ |
0x0 |
/ |
rings_1_en |
30:24 |
RW |
0x0 |
ro_grp1 的 RO 使能。用法请参考 rings_0_en |
保留 |
31 |
/ |
0x0 |
/ |
噪声源寄存器 1 (TRNG_NOISRC_1)
地址偏移:0x18
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
15:0 |
/ |
0x0 |
/ |
rings_2_en |
22:16 |
RW |
0x0 |
ro_grp2 的 RO 使能。用法请参考 rings_0_en |
保留 |
23 |
/ |
0x0 |
/ |
rings_3_en |
30:24 |
RW |
0x0 |
ro_grp3 的 RO 使能。用法请参考 rings_0_en |
保留 |
31 |
/ |
0x0 |
/ |
偏置校正寄存器 (TRNG_FIX_BIAS)
地址偏移:0x24
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
vnc_en |
3:0 |
RW |
0x0 |
|
simple_flip_en |
7:4 |
RW |
0x0 |
|
保留 |
31:8 |
/ |
0x0 |
/ |
后处理控制寄存器 (TRNG_PP_CTRL)
地址偏移:0x28
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
cond_en |
0 |
RW |
0x0 |
|
cond_dup_chk_en |
1 |
RW |
0x0 |
|
保留 |
3:2 |
/ |
0x0 |
/ |
cond_keysize |
5:4 |
RW |
0x0 |
|
保留 |
7:6 |
/ |
0x0 |
/ |
cond_blk_len |
15:8 |
RW |
0x0 |
|
保留 |
31:16 |
/ |
0x0 |
/ |
状态寄存器 (TRNG_ST)
地址偏移:0x30
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
offo_empty |
0 |
RO |
0x1 |
|
offo_full |
1 |
RO |
0x0 |
|
affo_empty |
2 |
RO |
0x1 |
|
unpk_fifo_empty |
3 |
RO |
0x1 |
|
unpk_fifo_full |
4 |
RO |
0x0 |
|
保留 |
7:5 |
/ |
0x0 |
/ |
failure_overcast_fips |
8 |
RO |
0x1 |
检测到任何 FIPS 健康测试失败或已在之前几个窗口中持续存在。如果一个窗口内所有测试都通过,它将被清除。意味着噪声源目前不稳定。 |
failure_overcast_ais |
9 |
RO |
0x1 |
检测到任何 AIS 健康测试失败或已在之前几个窗口中持续存在。如果一个窗口内所有测试都通过,它将被清除。意味着噪声源目前不稳定。 |
保留 |
15:10 |
/ |
0x0 |
/ |
offo_data_cnt |
18:16 |
RO |
0x0 |
OFIFO 中存储的数据数量(单位:32 位) |
保留 |
23:19 |
/ |
0x0 |
/ |
busy |
24 |
RO |
0x0 |
|
保留 |
28:25 |
/ |
0x0 |
/ |
btph_cmpl_st |
29 |
RO |
0x0 |
|
btph_done |
30 |
RO |
0x1 |
启动阶段已完成。 |
init_done |
31 |
RO |
0x0 |
噪声源初始化完成。 |
可恢复错误标志寄存器 (TRNG_RECOV_ERR)
地址偏移:0x34
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
offo_overflow |
0 |
W1C |
0x0 |
OFIFO 上溢 |
offo_underflow |
1 |
W1C |
0x0 |
OFIFO 下溢。在无数据可用时读取了寄存器 TRNG_DAT_NF / TRNG_DAT / TRNG_DBG_DAT。 |
swport_overflow |
2 |
W1C |
0x0 |
软件端口上溢。在 TRNG_SWPORT 非空时向其写入数据。它也是解包器 FIFO 上溢。 |
保留 |
30:3 |
/ |
0x0 |
/ |
test_recov |
31 |
W1C |
0x0 |
这是通过 TRNG_DBG_CTRL.inj_err_code 软件注入的错误。仅用于测试目的。不与任何特定错误关联。 |
致命错误标志寄存器 (TRNG_FATAL_ERR)
地址偏移:0x38
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
2:0 |
/ |
0x0 |
/ |
cond_dup_err |
3 |
W1C |
0x0 |
调理组件产生重复结果。与寄存器 TRNG_PP_CTRL.cond_dup_chk_en 相关联。 |
health_alert |
4 |
RO |
0x0 |
健康测试失败已达到阈值并触发警报。 |
main_fsm_err |
5 |
RO |
0x0 |
主状态机处于非法状态 |
cond_fsm_err |
6 |
RO |
0x0 |
调理组件状态机处于非法状态 |
bedf_fsm_err |
7 |
RO |
0x0 |
Block_Cipher_df 状态机处于非法状态 |
ht_fsm_err_fips |
8 |
RO |
0x0 |
健康测试状态机 (FIPS) 处于非法状态 |
ht_fsm_err_ais |
9 |
RO |
0x0 |
健康测试状态机 (AIS) 处于非法状态 |
保留 |
30:10 |
/ |
0x0 |
/ |
test_fatal |
31 |
W1C |
0x0 |
这是通过 TRNG_DBG_CTRL.inj_err_code 软件注入的错误。仅用于测试目的。不与任何特定错误关联。 |
软件端口状态寄存器 (TRNG_SWPORT_ST)
地址偏移:0x3C
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
2:0 |
/ |
0x0 |
/ |
sw_in_empty |
3 |
RO |
0x1 |
|
保留 |
10:4 |
/ |
0x0 |
/ |
pre_write_st_sw |
11 |
RC |
0x0 |
|
保留 |
31:12 |
/ |
0x0 |
/ |
原始数据输入软件端口 (TRNG_SWPORT)
地址偏移:0x40
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
sw_din |
31:0 |
WO |
0x0 |
|
非FIPS数据有效寄存器 (TRNG_DAT_V_NF)
地址偏移:0x44
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
0 |
/ |
0x0 |
/ |
data_ready_nfips |
1 |
RO |
0x0 |
|
err_dout |
2 |
W1C |
0x0 |
实际输出数据过长的错误标志状态清除。只写,读回始终为 0 |
保留 |
8:2 |
/ |
0x0 |
/ |
pre_read_st_nfips |
9 |
RC |
0x0 |
|
保留 |
31:10 |
/ |
0x0 |
/ |
非FIPS数据寄存器 (TRNG_DAT_NF)
地址偏移:0x48
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
data_nfips |
31:0 |
RO |
0x0 |
在启动阶段生成的非FIPS随机数。TRNG_DAT_V_NF.data_ready_nfips 指示其是否有效。 |
数据有效寄存器 (TRNG_DAT_V)
地址偏移:0x4C
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
data_ready |
0 |
RO |
0x0 |
|
保留 |
7:1 |
/ |
0x0 |
/ |
pre_read_st |
8 |
RC |
0x0 |
|
保留 |
31:9 |
/ |
0x0 |
/ |
数据寄存器 (TRNG_DAT)
地址偏移:0x50
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
data |
31:0 |
RO |
0x0 |
在连续阶段生成的随机数。TRNG_DAT_V.data_ready 指示其是否有效。 |
RISC-V SEED CSR 寄存器 (TRNG_RISCV)
这是 RISC-V 加密扩展熵源的 seed CSR。更多细节请参考 [RISCV-KS] 的第 4.1 节。
地址偏移:0x54
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
entropy |
15:0 |
RO |
0x0 |
16 位随机性,仅在 opst=ES16 时有效 |
保留 |
29:16 |
/ |
0x0 |
/ |
opst |
31:30 |
RO |
0x3 |
|
中断使能寄存器 (TRNG_INTEN)
地址偏移:0x60
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
inten_data_ready |
0 |
RW |
0x0 |
对应于原始中断 rint_data_ready 的中断使能。更多细节请参考 TRNG_INTSRC。 |
inten_sw_in_empty |
1 |
RW |
0x0 |
对应于原始中断 rint_sw_in_empty 的中断使能。更多细节请参考 TRNG_INTSRC。 |
保留 |
3:2 |
/ |
0x0 |
/ |
inten_health_alert |
4 |
RW |
0x0 |
对应于原始中断 rint_health_alert 的中断使能。更多细节请参考 TRNG_INTSRC。 |
inten_recov_err |
5 |
RW |
0x0 |
对应于原始中断 rint_recov_err 的中断使能。更多细节请参考 TRNG_INTSRC。 |
inten_fatal_err |
6 |
RW |
0x0 |
对应于原始中断 rint_fatal_err 的中断使能。更多细节请参考 TRNG_INTSRC。 |
保留 |
31:7 |
/ |
0x0 |
/ |
中断源寄存器 (TRNG_INTSRC)
地址偏移:0x64
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
rint_data_ready |
0 |
W1C |
0x0 |
|
rint_sw_in_empty |
1 |
W1C |
0x0 |
|
保留 |
3:2 |
/ |
0x0 |
/ |
rint_health_alert |
4 |
RO/W1C |
0x0 |
|
rint_recov_err |
5 |
W1C |
0x0 |
|
rint_fatal_err |
6 |
RO/W1C |
0x0 |
|
保留 |
31:7 |
/ |
0x0 |
/ |
中断状态寄存器 (TRNG_INTST)
地址偏移:0x68
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
intst_data_ready |
0 |
RO |
0x0 |
对应于原始中断 rint_data_ready 的中断状态。更多细节请参考寄存器 TRNG_INTSRC。 |
intst_sw_in_empty |
1 |
RO |
0x0 |
对应于原始中断 rint_sw_in_empty 的中断状态。更多细节请参考寄存器 TRNG_INTSRC。 |
保留 |
3:2 |
/ |
0x0 |
/ |
intst_health_alert |
4 |
RO |
0x0 |
对应于原始中断 rint_health_alert 的中断状态。更多细节请参考寄存器 TRNG_INTSRC。 |
intst_recov_err |
5 |
RO |
0x0 |
对应于原始中断 rint_recov_err 的中断状态。更多细节请参考寄存器 TRNG_INTSRC。 |
intst_fatal_err |
6 |
RO |
0x0 |
对应于原始中断 rint_fatal_err 的中断状态。更多细节请参考寄存器 TRNG_INTSRC。 |
保留 |
31:7 |
/ |
0x0 |
/ |
中断置位寄存器 (TRNG_INTSET)
此寄存器仅用于测试目的。向某位写入 1 将强制设置相应的原始中断。虽然中断被设置,但事件并未发生。
地址偏移:0x6C
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
intset_data_ready |
0 |
WO |
0x0 |
对应于原始中断 rint_data_ready 的中断注入。更多细节请参考寄存器 TRNG_INTSRC。 |
intset_sw_in_empty |
1 |
WO |
0x0 |
对应于原始中断 rint_sw_in_empty 的中断注入。更多细节请参考寄存器 TRNG_INTSRC。 |
保留 |
3:2 |
/ |
0x0 |
/ |
intset_health_alert |
4 |
WO |
0x0 |
对应于原始中断 rint_health_alert 的中断注入。更多细节请参考寄存器 TRNG_INTSRC。 |
intset_recov_err |
5 |
WO |
0x0 |
对应于原始中断 rint_recov_err 的中断注入。更多细节请参考寄存器 TRNG_INTSRC。 |
intset_fatal_err |
6 |
WO |
0x0 |
对应于原始中断 rint_fatal_err 的中断注入。更多细节请参考寄存器 TRNG_INTSRC。 |
保留 |
31:7 |
/ |
0x0 |
/ |
数据有效调试寄存器 (TRNG_DBG_DAT_V)
地址偏移:0x70
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
1:0 |
/ |
0x0 |
/ |
src_dat_vld |
2 |
RO |
0x0 |
|
保留 |
9:3 |
/ |
0x0 |
/ |
pre_read_st_src |
10 |
RC |
0x0 |
|
保留 |
31:11 |
/ |
0x0 |
/ |
数据调试寄存器 (TRNG_DBG_DAT)
地址偏移:0x74
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
src_dat |
31:0 |
RO |
0x0 |
从噪声源收集的新数据。TRNG_DBG_DAT_V.src_dat_vld 指示其是否有效。仅用于调试模式。 |
状态调试寄存器 (TRNG_DBG_ST)
地址偏移:0x78
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
post_proc_fsm |
3:0 |
RO |
0x0 |
|
cond_fsm |
7:4 |
RO |
0x0 |
调理组件状态机 |
bedf_fsm |
11:8 |
RO |
0x0 |
Block_Cipher_df 状态机 |
ht_fsm_fips |
13:12 |
RO |
0x0 |
|
ht_fsm_ais |
15:14 |
RO |
0x0 |
健康测试状态机 (AIS), 用法请参考 ht_fsm_fips。 |
保留 |
31:16 |
/ |
0x0 |
/ |
健康测试状态调试寄存器 (TRNG_DBG_HT_ST)
地址偏移:0x7C
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
23:0 |
/ |
0x0 |
/ |
btph_attempt |
27:24 |
RO |
0x0 |
在启动阶段结束前,它尝试了多少轮。 |
保留 |
31:28 |
/ |
0x0 |
/ |
健康测试状态调试寄存器 - 用于 FIPS 测试套件
地址偏移:0x80
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
win_stay_overcast_fips |
3:0 |
RO |
0x0 |
在最新的失败阴天条件下(针对 FIPS 测试套件)停留了多少个窗口。 |
保留 |
7:4 |
/ |
0x0 |
/ |
result_fail_fips |
15:8 |
RO |
0x0 |
|
win_cnt_fips |
23:16 |
RO |
0x0 |
窗口计数模 256 |
保留 |
31:24 |
/ |
0x0 |
/ |
健康测试状态调试寄存器 - 用于 AIS 测试套件
地址偏移:0x84
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
win_stay_overcast_ais |
3:0 |
RO |
0x0 |
在最新的失败阴天条件下(针对 AIS 测试套件)停留了多少个窗口。 |
保留 |
7:4 |
/ |
0x0 |
/ |
result_fail_ais |
15:8 |
RO |
0x0 |
|
win_cnt_ais |
23:16 |
RO |
0x0 |
窗口计数模 256 |
保留 |
31:24 |
/ |
0x0 |
/ |
控制调试寄存器 (TRNG_DBG_CTRL)
地址偏移:0x88
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
startup_test_dis |
0 |
RW |
0x0 |
|
保留 |
2:1 |
/ |
0x0 |
/ |
inj_err_en |
3 |
WO |
0x0 |
|
inj_err_code |
9:4 |
WO |
0x0 |
注意: 它对那些寄存器中具有 RO 访问属性的字段(如 TRNG_FATAL_ERR 中的 main_fsm_err/cond_fsm_err/…)没有影响。 |
保留 |
31:10 |
/ |
0x0 |
/ |
健康测试错误注入调试寄存器 - 用于 FIPS 测试套件
地址偏移:0x8C
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
htej_en_fips |
0 |
RW |
0x0 |
|
htej_st_l_fips |
1 |
RO |
0x0 |
|
htej_mode_fips |
2 |
RW |
0x0 |
|
保留 |
3 |
/ |
0x0 |
/ |
htej_len_fips |
7:4 |
RW |
0x0 |
将注入多少个窗口,或将更改多少个结果。确切数字是 (htej_len_fips + 1)。 |
htej_idx_fips |
11:8 |
RO |
0x0 |
正在注入的窗口编号(从0开始),或当前用于注入的 htej_vec_fips 索引。 |
保留 |
15:12 |
/ |
0x0 |
/ |
htej_vec_fips |
31:16 |
RW |
0x0 |
错误向量。结果将从位 [0] 到位 [k] 用这些位更改,其中 k = htej_len_fips - 1。 |
健康测试错误注入调试寄存器 - 用于 AIS 测试套件
地址偏移:0x90
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
htej_en_ais |
0 |
RW |
0x0 |
参考 TRNG_DBG_HTEJ_FIPS 的用法 |
htej_st_l_ais |
1 |
RO |
0x0 |
参考 TRNG_DBG_HTEJ_FIPS 的用法。 |
htej_mode_ais |
2 |
RW |
0x0 |
参考 TRNG_DBG_HTEJ_FIPS 的用法。 |
保留 |
3 |
/ |
0x0 |
/ |
htej_len_ais |
7:4 |
RW |
0x0 |
参考 TRNG_DBG_HTEJ_FIPS 的用法 |
htej_idx_ais |
11:8 |
RO |
0x0 |
参考 TRNG_DBG_HTEJ_FIPS 的用法 |
保留 |
15:12 |
/ |
0x0 |
/ |
htej_vec_ais |
31:16 |
RW |
0x0 |
参考 TRNG_DBG_HTEJ_FIPS 的用法 |
健康测试控制寄存器 (TRNG_HT_CTRL)
地址偏移:0xA0
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
test_repcnt_en |
0 |
RW |
0x1 |
重复计数健康测试使能 |
test_adpprp_en |
1 |
RW |
0x1 |
自适应比例健康测试使能 |
保留 |
7:2 |
/ |
0x0 |
/ |
test_monbit_en |
8 |
RW |
0x0 |
单比特健康测试使能 |
test_runs_en |
9 |
RW |
0x0 |
游程健康测试使能 |
test_poker_en |
10 |
RW |
0x0 |
扑克健康测试使能 |
保留 |
11 |
/ |
0x0 |
/ |
test_scope |
12 |
RW |
0x0 |
|
保留 |
15:13 |
/ |
0x0 |
/ |
fail2alert_th |
16 |
RW |
0x2 |
|
保留 |
31:19 |
/ |
0x0 |
/ |
启动阶段数据长度寄存器 (TRNG_BTPH_DLEN)
地址偏移:0xA4
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
15:0 |
/ |
0x0 |
/ |
data_len_btph |
21:16 |
RW |
0x3 |
在启动阶段要收集的数据量(单位:32 位字) |
保留 |
31:22 |
/ |
0x0 |
/ |
健康测试窗口寄存器 (TRNG_HT_WIN)
一个样本可能包含多个比特。一个窗口中的数据量等于窗口大小乘以每个样本的比特数。
地址偏移:0xA8
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
win_fips |
15:0 |
RW |
1024 |
FIPS 测试套件的测试窗口大小。(单位:样本) |
win_ais |
31:16 |
RW |
20000 |
|
重复计数健康测试 - 阈值寄存器
如果测试统计量 ≥ 阈值,则测试失败。
地址偏移:0xB0
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
15:0 |
/ |
0x0 |
/ |
repcnt_th |
21:16 |
RW |
0x3f |
重复计数健康测试的阈值。 |
保留 |
31:22 |
/ |
0x0 |
/ |
自适应比例健康测试 - 低阈值寄存器
如果测试统计量 ≤ 低阈值 或 测试统计量 ≥ 高阈值,则测试失败。
地址偏移:0xB8
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
11:0 |
/ |
0x0 |
/ |
adpprp_th_lo |
28:12 |
RW |
0x0 |
自适应比例健康测试的低阈值。 |
保留 |
31:29 |
/ |
0x0 |
/ |
自适应比例健康测试 - 高阈值寄存器
如果测试统计量 ≤ 低阈值 或 测试统计量 ≥ 高阈值,则测试失败。
地址偏移:0xBC
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
11:0 |
/ |
0x0 |
/ |
adpprp_th_hi |
29:12 |
RW |
0x3ffff |
自适应比例健康测试的高阈值。 |
保留 |
31:30 |
/ |
0x0 |
/ |
单比特健康测试 - 低阈值寄存器
如果测试统计量 ≤ 低阈值 或 测试统计量 ≥ 高阈值,则测试失败。
地址偏移:0xC4
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
11:0 |
/ |
0x0 |
/ |
monbit_th_lo |
28:12 |
RW |
0x0 |
单比特健康测试的低阈值。 |
保留 |
31:29 |
/ |
0x0 |
/ |
单比特健康测试 - 高阈值寄存器
如果测试统计量 ≤ 低阈值 或 测试统计量 ≥ 高阈值,则测试失败。
地址偏移:0xC8
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
保留 |
11:0 |
/ |
0x0 |
/ |
monbit_th_hi |
29:12 |
RW |
0x3ffff |
单比特健康测试的高阈值。 |
保留 |
31:30 |
/ |
0x0 |
/ |
游程健康测试 - 游程长度 1 阈值寄存器
如果测试统计量 < 低阈值 或 测试统计量 > 高阈值,则测试失败。
地址偏移:0xE4
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
runs_th_lo_1 |
15:0 |
RW |
2267 |
游程健康测试中长度为 1 的 0-run(或 1-run)的低阈值。对于线路范围,仅使用阈值的低 14 位进行比较 |
runs_th_hi_1 |
31:16 |
RW |
2733 |
游程健康测试中长度为 1 的 0-run(或 1-run)的高阈值。对于线路范围,仅使用阈值的低 14 位进行比较。 |
游程健康测试 - 游程长度 2 阈值寄存器
如果测试统计量 < 低阈值 或 测试统计量 > 高阈值,则测试失败。
地址偏移:0xE8
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
runs_th_lo_2 |
14:0 |
RW |
1079 |
游程健康测试中长度为 2 的 0-run(或 1-run)的低阈值。对于线路范围,仅使用阈值的低 13 位进行比较。 |
保留 |
16 |
/ |
0 |
/ |
runs_th_hi_2 |
30:16 |
RW |
1421 |
游程健康测试中长度为 2 的 0-run(或 1-run)的高阈值。对于线路范围,仅使用阈值的低 13 位进行比较。 |
保留 |
31 |
/ |
0 |
/ |
游程健康测试 - 游程长度 3 阈值寄存器
如果测试统计量 < 低阈值 或 测试统计量 > 高阈值,则测试失败。
地址偏移:0xEC
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
runs_th_lo_3 |
13:0 |
RW |
502 |
游程健康测试中长度为 3 的 0-run(或 1-run)的低阈值。对于线路范围,仅使用阈值的低 12 位进行比较。 |
保留 |
15:14 |
/ |
0 |
/ |
runs_th_hi_3 |
29:16 |
RW |
748 |
游程健康测试中长度为 3 的 0-run(或 1-run)的高阈值。对于线路范围,仅使用阈值的低 12 位进行比较。 |
保留 |
31:30 |
/ |
0 |
/ |
游程健康测试 - 游程长度 4 阈值寄存器
如果测试统计量 < 低阈值 或 测试统计量 > 高阈值,则测试失败。
地址偏移:0xF0
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
runs_th_lo_4 |
12:0 |
RW |
233 |
游程健康测试中长度为 4 的 0-run(或 1-run)的低阈值。对于线路范围,仅使用阈值的低 11 位进行比较。 |
保留 |
15:13 |
/ |
0 |
/ |
runs_th_hi_4 |
28:16 |
RW |
748 |
游程健康测试中长度为 4 的 0-run(或 1-run)的高阈值。对于线路范围,仅使用阈值的低 11 位进行比较。 |
保留 |
31:29 |
/ |
0 |
/ |
游程健康测试 - 游程长度 5 阈值寄存器
如果测试统计量 < 低阈值 或 测试统计量 > 高阈值,则测试失败。
地址偏移:0xF4
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
runs_th_lo_5 |
11:0 |
RW |
90 |
游程健康测试中长度为 5 的 0-run(或 1-run)的低阈值。对于线路范围,仅使用阈值的低 10 位进行比较。 |
保留 |
15:12 |
/ |
0 |
/ |
runs_th_hi_5 |
27:16 |
RW |
223 |
游程健康测试中长度为 5 的 0-run(或 1-run)的高阈值。对于线路范围,仅使用阈值的低 10 位进行比较。 |
保留 |
31:28 |
/ |
0 |
/ |
游程健康测试 - 游程长度 6 阈值寄存器
如果测试统计量 < 低阈值 或 测试统计量 > 高阈值,则测试失败。
地址偏移:0xF8
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
runs_th_lo_6 |
11:0 |
RW |
90 |
游程健康测试中长度为 6 的 0-run(或 1-run)的低阈值。对于线路范围,仅使用阈值的低 10 位进行比较。 |
保留 |
15:12 |
/ |
0 |
/ |
runs_th_hi_6 |
27:16 |
RW |
233 |
游程健康测试中长度为 6 的 0-run(或 1-run)的高阈值。对于线路范围,仅使用阈值的低 10 位进行比较。 |
保留 |
31:28 |
/ |
0 |
/ |
扑克健康测试 - 低阈值寄存器
如果测试统计量 < 低阈值 或 测试统计量 > 高阈值,则测试失败。
地址偏移:0x100
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
poker_th_lo |
28:0 |
RW |
0x0 |
扑克健康测试的低阈值。 |
保留 |
31:29 |
/ |
0 |
/ |
扑克健康测试 - 高阈值寄存器
如果测试统计量 < 低阈值 或 测试统计量 > 高阈值,则测试失败。
地址偏移:0x104
字段 |
位 |
访问 |
复位值 |
描述 |
|---|---|---|---|---|
poker_th_hi |
28:0 |
RW |
0x1fffffff |
扑克健康测试的高阈值。 |
保留 |
31:29 |
/ |
0 |
/ |