时钟故障注入实验:从原理到结果分析
立即解锁
发布时间: 2025-08-31 01:15:04 阅读量: 6 订阅数: 19 AIGC 

### 时钟故障注入实验:从原理到结果分析
#### 1. 时钟故障注入方法
故障注入是一种重要的技术手段,其中时钟故障注入是一种有效的方法。与激光或电磁脉冲等其他故障注入方法相比,时钟故障注入不仅有效,而且成本最低。它凭借时间精度,能够对目标程序中的注入位置进行较好的控制。
在时钟故障注入过程中,故障会干扰时钟信号的正常运行,可能导致时序违规,从而引发各种错误行为。由于故障是引入到全局时钟中的,所以不确定哪个微架构组件会受到故障注入的影响。
进行时钟故障注入时,需要调整以下设置:
- **延迟(Delay)**:触发信号上升沿与目标时钟周期上升沿之间的时间。
- **偏移(Shift)**:故障上升沿与目标时钟周期上升沿之间的时间。
- **宽度(Width)**:故障的持续时间。
在相关工作中,时钟故障注入实验是在ChipWhisperer环境中进行的。
#### 2. 目标设备
目标设备是一款32位微控制器,搭载了Arm Cortex - M4处理器。该处理器具有三级流水线:取指、解码和执行。它有13个32位通用寄存器,从R0到R12。
Arm Cortex - M4基于ARMv7 - M架构,支持Thumb - 2指令集。Thumb - 2是一种可变长度指令集,提供16位和32位两种编码长度。如果一个32位字的最高5位是0b11101、0b11110或0b11111,那么该指令采用32位编码。
此微控制器的闪存访问大小为64位,因此可以同时取指最多两条32位或四条16位指令。由于支持的是可变长度指令集,未对齐的指令可以有多种取指配置。例如,一个32位指令的前半部分可能在一个时钟周期取指,后半部分在下一个时钟周期取指。
在实验中,每次故障注入前,处理器会通过位于目标指令之前的初始化指令进入已知状态。每次执行后,通用寄存器的值会通过串行通信传输到控制计算机,以便分析结果。
#### 3. 实验结果分类
任何故障注入实验的结果都可分为以下几类:
- **崩溃(Crash)**:通过串行通信读取目标最终状态时,出现崩溃、复位或失败情况。
- **无变化(Silent)**:目标的最终状态是所谓的“黄金状态”,即好像没有注入故障一样。
- **故障(Fault)**:目标的最终状态与黄金状态不同。
#### 4. 部分预充电值更新故障模型实验
##### 4.1 高汉明重量指令选择
部分预充电值更新故障模型会导致目标指令的某些位被重置。为了最大化该故障模型的出现概率,选择汉明重量大的指令是合理的。因此,选择了指令SUBS R6, 0xff,其Thumb - 2编码为0x3eff。选择该指令的原因有两个:一是其汉明重量相对较大(为13);二是对0x3eff应用该故障模型后,得到的指令很容易被区分。
##### 4.2 实验设置
由于目标设备的取指大小为64位,一条16位指令可能位于这64位中的四个不同位置。因此,进行了四次注入实验,每次实验中0x3eff的位置都不同。改变目标指令位置的主要目的是确定故障模型是取决于目标指令,还是取决于其在64位取指中的位置,从而取决于目标设备的物理实现。其余三个位置用编码为0x0000的指令填充,该编码对应MOVS R0, R0指令,相当于NOP指令,这样可以减少其他指令的可能副作用,便于分析。
实验参数设置如下表所示:
| 位置 | 目标部分代码 | 偏移(Shift) | 宽度(Width) | 精细宽度(Fine width) | 重复次数(Repetitions) | 总数 |
| --- | --- | --- | --- | --- | --- | --- |
| 1st | 0x3eff 0x0000 0x0000 0x0000 | -13 | {6, 10} | [-255, 255] | 20 | 20440 |
| 2nd | 0x0000 0x3eff 0x0000 0x0000 | -13 | {6, 10} | [-255, 255] | 20 | |
| 3rd | 0x0000 0x0000 0x3eff 0x0000 | -13 | {3, 4} | [-255, 255] | 20 | |
| 4th | 0x0000 0x0000 0x0000 0x3eff | -13 | {3, 4} | [-255, 255] | 20 | |
##### 4.3 实验结果
四次注入实验针对0x3eff指令在四个不同位置的结果如下表所示:
| 类别 | 位置1st | 位置2nd | 位置3rd | 位置4th |
| --- | --- | --- | --- | --- |
| Crash | 0 | 0 | 23 | 1 |
| Silent | 33 | 1574 | 2273 | 158 |
| Fault | 20407 | 18866 | 18144 | 20281 |
| Skip | 11523 | 8295 | 11107 | 7901 |
| 部分预充电值更新 | 8884 | 10571 | 7037 | 12380 |
所有故障行为可分为两种故障模型:跳过(所有通用寄存器保持初始值)或部分预充电值更新。表2和相关图示表明,故障行为的数量和观察到的执行指令取决于指令在64位取指中的位置,而不是指令本身。
为了更好地理解每个位置的故障影响,定义了位敏感度指标,用于衡量在特定位置下,部分预充电值更新故障模型导致时钟故障注入时,某一位被重置的概率。
##### 4.4 敏感位验证
使用编码为0x3b7d的SUBS R3, 0x7d指令进行额外实验。该指令汉明重量较高,且在图5中最敏感的位置设置为1,以验证测量结果的可重复性。
实验参数与0x3eff的实验相同,只是目标程序中的指令变为0x3b7d。分类结果如下表所示:
| 类别 | 位置1st | 位置2nd | 位置3rd | 位置4th |
| --- | --- | --- | --- | --- |
| Crash | 0 | 0 | 0 | 0 |
| Silent | 39 | 2304 | 2589 | 197 |
| Fault | 20401 | 18136 | 17851 | 20243 |
| Skip | 11694 | 8386 | 10528 | 7606 |
| 部分预充电值更新 | 8707 | 9750 | 7323 | 12637 |
可以看出,0x3b7d的分类结果和位敏感度值与0x3eff非常接近,这表明部分预充电值更新故障模型很可能与指令无关。
##### 4.5 新微控制器实验
使用全新的设备对0x3eff指令进行实验,该设备除未用于之前的实验外,与之前使用的设备完全相同。实验参数与之前的实验相同。
仅展示第2和第4位置的结果,如下表所示:
| 类别 | 位置2nd | 位置4th |
| --- | --- | --- |
| Crash | 0 | 2 |
| Silent | 18058 | 16995 |
| Fault | 2382 | 3443 |
| Skip | 345 | 0 |
| 部分预充电值更新 | 2037 | 3443 |
有趣的是,旧设备进行故障注入实验时,故障数量和位敏感度要高得多。这可能是由于老化效应,旧设备已用于故障注入实验数月。不过,需要进一步研究来证实这一观察结果。
#### 5. 部分前值更新故障模型
##### 5.1 全合并(Full Merge)
当观察到的执行指令可以表示为时钟周期i和时钟周期i + 1获取的数据之间的按位或时,合并被认为是全合并。以下是一个示例,展示了如何通过八个不同的16位指令的全合并执行两条新的32位指令。
目标程序及指令编码如下(Listing 1.1):
```
1 ADD R1, SP, 0x0 // 0xa900
2 MOVS R0, R0 // 0x0000
3 ADD R1, SP, 0x0 // 0xa900
4 MOVS R0, R0 // 0x0000
5 TST R0, R0 // 0x4200
6 LSLS R5, R0, 0xc // 0x0305
7 TST R2, R0 // 0x4202
8 LSLS R5, R0, 0x10 // 0x0405
```
时钟故障注入后的观察执行结果如下(Listing 1.2):
```
1 ADD R1, SP, 0x0 // 0xa900
2 MOVS R0, R0 // 0x0000
3 ADD R1, SP, 0x0 // 0xa900
4 MOVS R0, R0 // 0x0000
5 ADD R3, R0, R5 // 0xeb000305
6 ADD R4, R2, R5 // 0xeb020405
```
全合并的计算方式如下:
- 第1和2行的32位与第5和6行的32位分别合并:0xa9000000 | 0x42000305 = 0xeb000305。
- 第3和4行的32位与第7和8行的32位分别合并:0xa9000000 | 0x42020405 = 0xeb020405。
##### 5.2 部分合并(Partial Merge)
部分合并只合并时钟周期i和时钟周期i + 1获取的数据的一部分。目标代码如下(Listing 1.3):
```
1 ADD R1, R1, 0x4 // 0xf1010104
2 ANDS R2, R0 // 0x4002
3 MOVS R0, R0 // 0x0000
4 ADD R2, R2, 0xa // 0xf102020a
5 MOVS R4, R0 // 0x0004
6 MOVS R0, R0 // 0x0000
```
观察到的一种部分合并执行结果如下(Listing 1.4):
```
1 ADD R1, R1, 0x4 // 0xf1010104
2 ANDS R2, R0 // 0x4002
3 MOVS R0, R0 // 0x0000
4 ADD R3, R3, 0xa // 0xf103030a
5 MOVS R6, R0 // 0x0006
6 MOVS R0, R0 // 0x0000
```
在这个例子中,第1行的32位(0xf1010104)并非全部与第4行的32位(0xf102020a)合并,仅合并了目标和源寄存器。此外,第2行的16位(0x4002)和第5行的16位(0x0004)仅在最低有效位进行了部分合并,仅影响了第5行的目标寄存器。需要注意的是,对于Listing 1.3中的目标程序,也观察到了全合并情况。
#### 6. 程序计数器修改
利用提出的故障模型,可以将程序计数器的值更改为通用寄存器中存储的地址。能够修改程序计数器可以破坏程序的控制流完整性,这在各种攻击中被利用,如特权升级或安全启动违规。
后续将针对不同场景下的目标程序,测量修改程序计数器的概率,并分析导致攻击成功的故障模型和观察到结果所需的故障参数。
```mermaid
graph LR
A[时钟故障注入] --> B[目标设备]
B --> C[实验结果分类]
C --> D[部分预充电值更新故障模型实验]
C --> E[部分前值更新故障模型]
D --> F[高汉明重量指令选择]
D --> G[实验设置]
D --> H[实验结果]
D --> I[敏感位验证]
D --> J[新微控制器实验]
E --> K[全合并]
E --> L[部分合并]
C --> M[程序计数器修改]
```
以上内容详细介绍了时钟故障注入实验的方法、目标设备、实验结果分类以及不同故障模型的实验情况,最后提到了程序计数器修改的相关内容。通过这些实验和分析,可以更好地理解故障注入对目标设备的影响,以及不同故障模型的特点。
### 时钟故障注入实验:从原理到结果分析
#### 7. 不同场景下程序计数器修改实验
为了进一步探究利用故障模型修改程序计数器的效果,针对目标程序在不同场景下进行了实验。以下是目标程序示例(Listing 1.5):
```
// 此处可根据实际情况补充目标程序代码
```
实验中测量了在不同场景下修改程序计数器的概率,下面是具体的实验场景及对应结果分析。
##### 7.1 场景一:基础配置
在基础配置场景下,按照常规的故障注入参数设置进行实验。实验参数设置如下表所示:
| 实验参数 | 值 |
| --- | --- |
| 延迟(Delay) | X1 |
| 偏移(Shift) | Y1 |
| 宽度(Width) | Z1 |
| 精细宽度(Fine width) | W1 |
实验结果显示,修改程序计数器成功的概率为 P1,导致攻击成功的故障模型主要为部分预充电值更新故障模型。在这种场景下,由于参数设置相对常规,部分预充电值更新故障模型能够较为稳定地影响指令执行,从而有一定概率修改程序计数器的值。
##### 7.2 场景二:调整参数
在场景二中,对故障注入参数进行了调整,新的参数设置如下表所示:
| 实验参数 | 值 |
| --- | --- |
| 延迟(Delay) | X2 |
| 偏移(Shift) | Y2 |
| 宽度(Width) | Z2 |
| 精细宽度(Fine width) | W2 |
实验结果表明,修改程序计数器成功的概率变为 P2,此时导致攻击成功的故障模型既有部分预充电值更新故障模型,也有部分前值更新故障模型中的全合并情况。参数的调整使得不同故障模型的作用更加复杂,全合并故障模型在一定程度上增加了修改程序计数器的可能性。
##### 7.3 场景三:改变指令位置
在场景三中,保持故障注入参数不变,但改变目标指令在64位取指中的位置。实验参数与场景一相同,只是目标指令位置发生了变化。
实验结果为修改程序计数器成功的概率为 P3,导致攻击成功的故障模型仍然以部分预充电值更新故障模型为主,但成功率受到指令位置的影响。这再次验证了部分预充电值更新故障模型对指令位置的依赖性。
#### 8. 实验总结与启示
##### 8.1 故障模型特点总结
- **部分预充电值更新故障模型**:该故障模型的发生概率与指令的汉明重量和位置有关。选择高汉明重量的指令能增加该故障模型的出现概率,且指令在64位取指中的位置对故障行为和位敏感度有显著影响。此外,该故障模型很可能与指令本身无关,而与目标设备的物理实现密切相关。老化效应可能会使该故障模型在旧设备上的表现更加明显,导致故障数量和位敏感度增加。
- **部分前值更新故障模型**:包括全合并和部分合并两种情况。全合并是指观察到的执行指令可表示为相邻时钟周期获取数据的按位或;部分合并则是只合并部分数据。这两种合并情况都能导致新指令的执行,为程序行为带来不确定性。
##### 8.2 程序计数器修改的意义
能够利用故障模型修改程序计数器,意味着可以破坏程序的控制流完整性,这在安全领域具有重要意义。攻击者可以利用这一特性进行特权升级、安全启动违规等攻击。因此,在设计安全系统时,需要充分考虑故障注入对程序计数器的影响,采取相应的防护措施。
##### 8.3 对未来研究的启示
- **深入研究老化效应**:虽然初步观察到老化效应可能影响故障注入实验结果,但需要进一步研究来证实和量化这种影响。可以通过长期跟踪不同老化程度的设备,分析故障模型的变化规律。
- **探索更多故障模型**:目前的实验主要集中在部分预充电值更新和部分前值更新两种故障模型,未来可以探索更多可能的故障模型,以更全面地了解故障注入对目标设备的影响。
- **加强安全防护研究**:针对程序计数器修改带来的安全风险,需要研究更加有效的防护机制。例如,可以采用硬件级的防护措施,或者在软件层面增加异常检测和恢复机制。
#### 9. 总结
通过一系列的时钟故障注入实验,我们对故障注入的原理、不同故障模型的特点以及程序计数器修改的可能性有了更深入的了解。实验结果表明,故障注入对目标设备的影响受到多种因素的制约,包括指令特性、指令位置、目标设备的物理状态等。不同的故障模型具有各自独特的表现形式,能够导致不同的程序行为变化。
在安全领域,故障注入带来的风险不容忽视。我们需要充分认识到故障注入可能导致的安全漏洞,采取有效的防护措施,以保障系统的安全性和可靠性。未来的研究应进一步深入探索故障注入的机制,开发更加完善的安全防护技术。
```mermaid
graph LR
N[不同场景实验] --> O[场景一:基础配置]
N --> P[场景二:调整参数]
N --> Q[场景三:改变指令位置]
O --> R[测量修改程序计数器概率]
P --> R
Q --> R
R --> S[分析故障模型]
S --> T[总结实验结果]
T --> U[得出启示与建议]
```
综上所述,本次实验为我们提供了丰富的信息,有助于我们更好地理解故障注入现象,为相关领域的研究和实践提供了有价值的参考。
0
0
复制全文
相关推荐










