【技术干货】针对M2351系列故障注入攻击的软件防护措施
微控制器产品在设计之初,就会设定相应的产品规格以规范产品的执行条件,确保产品可以完成默认的任务。然而,若执行条件可不完全依照产品规格的情况下,就有可能会让系统无法如预期的方式运作,这样的特性,经常被恶意攻击者,运用做为寻找系统漏洞的工具,藉此绕过预设的安全机制或取得受保护的资料。这方法之所以被攻击者经常使用,其根本原因不外乎相关攻击设备简单、容易取得且成本低廉,并且其攻击具有一定的效果。本篇文章将介绍常见的故障注入攻击方式及其原理,并提出在不增加硬件成本下最有效益的软件防护方法,来防护这些攻击。
透过Fault Injection攻击可以做到什么
以硬件加解密引擎运作为例
当产品的执行条件,超出了原本预设的规范,将使产品的运行出错,如果能够限缩这样的执行条件出现在特定的时间,且只持续一段极短的时间,便足以能够让产品在执行特定指令的时候出错,而其它指令又能够正常的执行。也就是说,透过 Fault Injection,可以让特定指令的执行失效,例如让加密硬件系统错误的执行读取密钥的任务,使其加载空白密钥 (zero key) 来加密数据,如此一来只要再使用空白密钥,就能将密文还原成明文。
Figure 1. Skip Instruction Attack
Figure 2. Zero Key Attack
常见且低成本的Fault Injection方式
Fault Injection 攻击手段通常可区分为侵入式攻击和非侵入式攻击。
侵入式攻击所影响的是产品功能永久性的故障和异常,这手段通常是透过高精密的仪器对产品内部电路或数据做修改和破坏,因此所需的硬件成本和技术门坎都很高。
非侵入式攻击则是在产品运行中,注入攻击,使其短暂的影响产品当下运作行为,造成异常或功能故障,这类攻击手段常见的方式为攻击产品输入电压和频率。因为这样的攻击是针对电压及频率且持续时间短暂,我们称之为 Voltage Glitch 攻击与 Clock Glitch 攻击。这两种攻击方式,只需具备可以产生对 voltage 和 clock 讯号干扰的硬设备即可达成,因此实现所需成本比侵入式攻击低上许多,也更容易取得和实现。
Figure 3. Voltage Glitch Attack
因为 Voltage Glitch 和 Clock Glitch 的攻击都可以造成产品执行时,跳过某些指令或是影响某些操作的输出结果, 本章节接下来将以 Voltage Glitch 攻击范例来说明常见的 Fault Injection 影响。
Voltage Glitch 对
TrustZone 配置设定的攻击
在具备 TrustZone? 技术的微控制器产品中,都会具有 Secure Attribution Unit (SAU) 控制单元,用来将微控制器的所有资源,设置为 Secure 和Non-secure 区域,目的是为了透过隔离 Secure与 Non-secure 区域的方式,来保护 Secure 区域中的资源。
在针对 TrustZone? 技术的攻击中,攻击者会企图透过让 SAU 的设置无效化,来瓦解这样的隔离保护机制,此攻击主要是在系统程序配置 SAU 属性时进行 Voltage Glitch 的攻击, 让系统执行指令出现错误,造成 SAU 配置和系统原先规划的不一致,以期在这当中寻找到可利用的漏洞。
我们以试图攻击 M2351 微控制器在配置 SAU 过程中设定 Non-secure 区域为例,整个 M2351 的 Flash 内存大小为 512 KB,如果规划其中的 Secure 空间大小为 256 KB,那么剩下的 256 KB 空间,就属于 Non-secure ,其在内存空间中的地址如下图:
Figure 4. TrustZone? Secure, Non-secure Partition。
在这样的内存配置下, Secure代码与Non-secure代码被远远的区隔开来,实现了TrustZone?的硬件隔离,而想要进行这样的隔离配置,实际上所需要的设置有三个部分,一个是SAU的配置设定,一个是Flash Non-secure Boundary的设定,最后则是编译代码需要的设置。
SAU的配置,主要在指定Non-secure区域的起始地址与结束地址,这里设定的范围是由0x10040000到0x1007FFFF,至于其它未定义的区域,则默认为Secure区域。
Flash Non-secure Boundary的设定,是指Flash内存空间中,由哪里开始要划分给Non-secure使用,在这里其设定为0x40000,表示Flash后面的256KB,将划归给Non-secure使用,其余则是给Secure使用。Flash Non-secure Boundary的设定,是一出厂就设置好的,不会再改动 。
由Figure3可知,Secure区域跟Non-secure区域是分开的,因此在编译时,Secure代码与Non-secure 代码的RO Base就必定不同,也就是Secure的RO Base必须落在0x0到0x3FFFF的范围,而Non-secure的RO Base则是要落在0x10040000到0x1007FFFF的范围内,这里我们设定Secure RO Base为0x0,Non-secure RO base为0x10040000。
上述的三种设置,其中只有SAU的设置,会在系统运作中进行,因而有机会被Voltage Glitch攻击,如果系统在写入SAU区域设置时,遭到攻击,就有可能造成指令执行失败,因而使得SAU的设置不正确,也就是设置 SAU Non-secure Region的起始地址 0x10040000这行指令执行失败,这将造成SAU Non-secure Region的实际设定为 0x0,则系统的内存规划将变成如下图所示:
Figure 5. Secure, Non-secure Partition after Attack SAU Setting.
注意在Non-secure Region起始地址被窜改成0x0的情况下,0x0至0x0003_FFFF内存的属性并不会真的被改成Non-secure,这是因为另一个固定的属性设置单元Implementation Defined Attribution Unit (IDAU)所造成的影响,在SAU于0x0到0x0003_FFFF设置为Non-secure的情况下,最终的0x0到0x0003_FFFF的属性将依照较严格的IDAU设置,这表示,即使成功的攻击SAU,让Non-secure 起始地址设定为0x0,仍然无法让原来的Secure 区域改变为Non-secure区域,而是变成IDAU设置的Non-secure callable 区域,而Non-secure callable区域,其本质上仍是属于Secure区域的一部分。
另外,虽然成功的攻击SAU后,会让大部分的Secure区域,转变为Non-secure callable区域,但是因为这些区域缺乏SG (Secure Gateway)指令的缘故,Non-secure code是无法任意用Non-secure callable方式呼叫这区域的指令的。
值得注意的是,M2351微控制器SAU最多总共有8个区域可以设定, 可是这8个区域的范围,是不允许重迭的,重迭区域的设定,将导致该重迭区域强制为Secure属性,也就是说,若是原来的设定中,本来就有划定0x3F000至0x3FFFF为Non-secure callable区域,而因为此区域跟被攻击后的SAU区域0x0到0x1007FFFF重迭了,将使得0x3F000至0x3FFFF这个区域的设定直接成为Secure区域,这将造成所有的Non-secure callable API无法被Non-secure code呼叫。
因此,单纯的攻击SAU设置,并无法为Non-secure code取得额外的权限,甚至会失去原本可以呼叫Non-secure callable API权限,所以即使成功的攻击了SAU的设置,也并无法形成一个有效的攻击,不会有任何Secure区域信息的泄漏或被Non-secure code取得任何的Secure权限。
Voltage Glitch 对 AES 加密的攻击
此攻击方式主要是在代码执行AES加密相关处理时,使用Voltage Glitch攻击其运作,使其产生错误的密文。执行AES加密的基本流程如下图所示, 最终会产生密文 :
Figure 6. AES Encrypt Procedure.
例如在输入 AES Key操作时被Voltage Glitch攻击,可能出现输入密钥的动作被忽略或是输入错误的密钥值。如果是输入密钥的动作因为攻击而没有实际上的密钥值输入,那么接下来的加密过程,就会直接使用其缓存器内原来的值,通常这会是一组全部为0的密钥值,所以对于最后加密过后的秘文,只要使用全0的密钥来解密,就可以还原出正确的原文了。
Figure 7. Zero Key Fault Injection Attack.
另一种状况是在原文已知道情况下,攻击者利用Voltage Glitch造成输入错误的密钥,然后加密过后,得到对应的密文,以此重复多次,攻击者就可以根据原文、正确密钥加密后的密文、各种错误密钥加密后的密文,经过Differential Fault Analysis (DFA) 差分故障分析方法,就可以还原出正确的密钥。
Figure 8. Use Fault Injection to get N Encrypted Text for DFA.
如何透过软件来防护这些攻击
由上述几个采用Voltage Glitch攻击的例子可以发现,攻击者需要在正确的时间点,进行Fault Injection攻击,才有一些机会得到其想要达成的目的,因此让攻击者无法轻易的了解系统内部运作的时序,将会是一个有效的防护,最简单的方法就是建立不可预测的系统时序和处理流程, 让攻击者不容易找到合适的攻击时间点,也不容易持续攻击到同一个关键运行点,而这可以透过随机延迟和随机变化处理流程的顺序来实现。
Figure 9. Add Random Delay
Figure 10. Change Execution Procedure Randomly
但是只要无法挡住攻击的来源,攻击者总会达成他们所要的攻击目的。如果软件可以侦测到系统可能被攻击, 则可透过对应的处里程序将攻击损害程度降到最低。
本章节将依据前一章节提到的故障攻击范例来说明软件解决方案, 并实现可侦测出系统是否被攻击以及对应的处理。
关键设置攻击防护
在先前所举TrustZone?设定攻击的例子中,我们知道攻击者企图利用跳过SAU配置指令来影响Secure与Non-secure区域范围的设置,企图扩大Non-secure区域范围,藉此取得存取Secure资源的机会。虽然在之前的描述中提到,因为Secure与Non-secure范围设置,除了SAU,还需要搭配IDAU,所以单纯的攻击SAU,并无法取得有效的权限,但这里我们仍然为这样的攻击提出对应的策略,让攻击者连SAU的设置都无法攻击成功。
这个防护最主要原理,是侦测异常的SAU配置,并做复原SAU配置的处理, 让针对SAU设置的攻击无效化。
首先要侦测出异常的SAU设置,可针对所有的SAU设置进行冗余检查。
纪录有效的系统SAU设定值:
系统SAU设定值已预先被定义在partition_M2351.h内,需要将这些设定值预先记录下来, 可供后续步骤的使用。
计算出有效的系统SAU设定值总和 :
将有效的SAU相关设定例如: RBAR, RLAR和CTRL等设定值全部加起来做运算, 会得到一个Checksum值。
将有效的SAU设定值写入对应的SAU region :
将partition_M2351.h内定义有效的SAU设定值和属性写入各自的SAU区域内。
读出全部有被写入SAU region的设定值, 并做加总运算
判断写入SAU是否正确 :
在此比对Step 2和Step4计算出来的总和值是否一致,便可得知在写SAU设定值是否因遭到攻击而产生异常的设定结果。
上述步骤Step 1,2,4,5是针对侦测攻击所加的步骤, 而Step 3则是原来没有加防护代码时的SAU设置。如下图所示,
Figure 11. Fault Injection Countermeasure Flow.
接下来,侦测到错误后,必须要让系统能够自行回复,所以需要重复Step3的步骤再次写入SAU设定。
防护Zero Key攻击与AES加密攻击
Zero Key攻击与SAU设置攻击类似,都是让软件写入动作失效,也就是让系统无法写入正确地密钥到运算单元中,因而使用默认的空白数据,据此产生使用 空白密钥的效果。
对AES加密运算的攻击, 目的是影响密钥的加载使其加密出错误的密文,然后攻击者透过分析大量不同的错误密文和正确密文的关系, 透过DFA分析方法推导出系统内使用的加密密钥后, 再解密密文, 便可得到明文数据。
因此AES加密攻击的防护重点是让软件可以知道AES加密运算过中有受到攻击,避免使用到空白或错误的密钥,并且不能将被攻击后产生的密文回报给攻击者,使其有机会进行DFA分析。
攻击者再攻击密钥的加载前,需要先精确的定位到特定的时间点,因为配置密钥与输入明文的程序,是可以互换的,软件可以在这个部分进行随机的次序调换,如此可以增加攻击者定位密钥加载时间点的难度。
Figure 12. Random change the plaintext, Key input procedure.
由于对AES运算的攻击,重点在于使其密钥的加载出错,无论是Zero Key或是大量错误的Key,所以只要在加载密钥之后,再针对缓存器中的密钥做检查,即可保障密钥输入的正确性,而且如果运算中有使用到DMA的话,DMA的Source, Destination与Transfer Count都应该也纳入检查。
而加密运算使用密钥时的攻击,则可在加密完成后,直接把密文用同一把密钥解密,并与原来的明文做比对,即可验证在加密过程中是否有任何出错。
整个防护对策流程图如下:
Figure 13. AES Key Fault Injection Countermeasure Flow.
编辑:zzy 最后修改时间:2021-12-29