功耗分析基础:从芯片的“呼吸”到攻击者的“听诊器”
各位同学,欢迎来到功耗分析的世界。说实话,我第一次接触这个领域时,也觉得挺玄乎的——不就是芯片耗电吗?能有什么秘密?直到我在实验室里,亲眼看着一条平平无奇的功耗曲线,把AES算法的密钥给“读”了出来。那一刻我才明白,功耗,就是芯片最诚实的“呼吸”。
这一章,我们先把功耗分析的底子打牢。你想想看,要听懂芯片的“呼吸”,总得先知道它是怎么喘气的吧?
CMOS电路功耗原理:芯片为什么会耗电?
现代数字芯片,绝大多数都是CMOS(互补金属氧化物半导体)工艺。它的基本单元就是反相器——一个PMOS管加一个NMOS管。
CMOS电路有个很优雅的特性:静态时几乎不耗电。为什么?因为PMOS和NMOS是“互补”的,一个导通时另一个必然截止,没有从电源到地的直流通路。
但一旦开始工作,情况就变了。我习惯把CMOS的功耗拆成两笔账:
- 动态功耗:电路翻转时产生的功耗。这是大头。
- 静态功耗:电路不翻转时,漏电流造成的功耗。工艺越先进,这问题越头疼。
核心观点:功耗分析攻击之所以能成立,根本原因在于CMOS电路的功耗与正在处理的数据强相关。这不是bug,是物理定律。
动态功耗与静态功耗:两笔账,都得算清楚
动态功耗
动态功耗又分两部分:
- 开关功耗:给负载电容充放电消耗的能量。公式是
P_sw = α · C_L · V_DD² · f。α是翻转率,C_L是负载电容,V_DD是供电电压,f是时钟频率。 - 短路功耗:翻转瞬间,PMOS和NMOS同时短暂导通,形成从V_DD到GND的短路电流。
我在项目中遇到过一件事:某款低功耗芯片,动态功耗优化得特别好,但攻击者反而更容易做SPA了。为什么?因为动态功耗小了,信噪比反而变差了?不对,恰恰相反——动态功耗的“数据相关性”特征更明显了。优化后的电路,每次翻转的电流尖峰更“干净”,攻击者看得更清楚。
个人经验:做功耗分析时,我一般先看动态功耗的波形。如果波形上每个时钟周期的电流尖峰都差不多,那说明数据相关性弱,攻击难度大。如果尖峰高低起伏很明显——嗯,密钥可能就藏在里面。
静态功耗
静态功耗主要是漏电流造成的。包括:
- 亚阈值漏电流:晶体管关不彻底,仍有微弱电流。
- 栅极漏电流:栅氧化层太薄,电子直接隧穿过去。
- PN结漏电流:反偏PN结的少子漂移。
静态功耗在先进工艺(28nm以下)中越来越严重。但有意思的是,它对功耗分析攻击也有影响——静态功耗也会携带数据信息。我记得有一篇论文专门研究过,利用静态功耗的温度依赖性来做攻击,效果还挺好。
| 功耗类型 | 来源 | 与数据相关性 | 攻击利用价值 |
|---|---|---|---|
| 动态开关功耗 | 负载电容充放电 | 强(翻转次数、数据值) | 高(DPA/CPA主要利用) |
| 动态短路功耗 | 翻转瞬间直通电流 | 中等(与翻转斜率相关) | 中(辅助分析) |
| 静态漏电流 | 亚阈值、栅极漏电等 | 弱-中(与数据状态相关) | 低-中(特殊场景可用) |
功耗与数据相关性:芯片的“小动作”
这是整个功耗分析的核心。说白了就是:芯片处理不同数据时,消耗的能量不一样。
为什么会这样?我举个例子:
一个8位的寄存器,从0x00变成0xFF,需要翻转8个bit(从0到1)。从0x00变成0x01,只翻转1个bit。翻转的bit越多,动态功耗越大。这就是汉明距离(Hamming Distance)模型的基础。
再比如,一个总线上的数据是0x55(01010101),另一个是0xAA(10101010)。虽然它们翻转的bit数可能一样,但每个bit的“0”和“1”状态不同,对应的漏电流也不同。这就是汉明重量(Hamming Weight)模型的基础。
避坑指南:我曾经犯过一个错误——直接用汉明重量模型去攻击一个带有预充电逻辑的总线。结果相关性分析出来全是噪声。后来才意识到,预充电逻辑会在每个时钟周期先把总线拉到固定电平,再写入数据。这时候应该用汉明距离模型,而不是汉明重量。嗯,这个坑我替你们踩过了。
下面这张图,是我自己总结的功耗与数据相关性的知识框架:
简单功耗分析(SPA)概念:用眼睛看出来的秘密
SPA,说白了就是直接观察功耗曲线,从中提取信息。不需要复杂的统计,不需要大量的样本,有时候一条干净的曲线就够了。
我见过最经典的SPA案例,是分析RSA算法的功耗曲线。RSA的模幂运算里,如果指数bit是1,就执行“平方+乘法”;如果是0,只执行“平方”。这两种操作的功耗特征明显不同。攻击者只要看一眼功耗曲线,就能把私钥的每一位读出来。
SPA的适用场景:
- 算法执行路径与数据相关(如条件分支)
- 操作码不同导致功耗特征差异明显
- 攻击者有足够的信号质量(高采样率、低噪声)
SPA的局限性也很明显:如果芯片加了噪声、用了双轨逻辑、或者操作时间被随机化了,单条曲线就很难看出东西。这时候,就得请出DPA了。
差分功耗分析(DPA)概念:统计学的力量
DPA和SPA最大的区别在于:SPA用眼睛看,DPA用统计学算。
DPA的基本思路是这样的:
- 采集大量功耗曲线(比如几千到几万条)。
- 根据一个假设的密钥,把曲线分成两组(比如“某bit为1”和“某bit为0”)。
- 计算两组曲线的平均差值。
- 如果假设的密钥正确,差值曲线上会出现明显的尖峰。
- 如果假设错误,差值曲线基本是平的(噪声)。
我刚开始做DPA时,总觉得这方法太“暴力”了——不就是穷举假设然后看统计结果吗?但实际跑起来才发现,DPA的美妙之处在于它能从海量噪声中把信号“挖”出来。哪怕单条曲线完全看不出任何特征,几千条平均下来,数据相关性就会浮现。
个人习惯:做DPA时,我一般先采集1000条曲线做预分析。如果能看到明显的尖峰,说明信号质量好,可以继续深入。如果看不到,我会增加到10000条。还看不到?那可能是假设模型有问题,或者芯片有防护措施。这时候我会回头检查功耗模型——是用汉明距离还是汉明重量?中间值选对了吗?
DPA的变种很多,最常用的是相关功耗分析(CPA)。CPA用皮尔逊相关系数代替了简单的均值差,对噪声的容忍度更高,需要的曲线数也更少。嗯,这个我们后面章节会详细讲。
| 对比维度 | SPA | DPA |
|---|---|---|
| 分析方法 | 直接观察单条/少量曲线 | 统计分析大量曲线 |
| 所需样本量 | 少(1~100条) | 多(1000~100000条) |
| 抗噪声能力 | 弱 | 强 |
| 适用场景 | 算法结构泄露、操作差异明显 | 数据相关性微弱、有防护措施 |
| 攻击者技能要求 | 波形分析经验 | 统计学+编程能力 |