一、介绍
2016年10月,ARMV8.3-A指令集中加入了指针认证(Pointer Authentication)机制,在使用寄存器的值作为指针访问数据或代码之前验证其内容,目的是为了对抗ROP/JOP攻击。
在地址总线宽度为64位的处理器中,并不是所有位全部都使用了,例如,64位的linux使用低48位地址来表示虚拟地址空间,40位地址来表示物理地址和空间,高位地址空间是符号位的扩展。PA利用这一特性,通过特殊指令在寄存器的高位中存入一个验证码(Pointer Authentication Code,PAC),在寄存器内容使用之前进行验证,保证寄存器内容的完整性,并将寄存器中内容恢复原状。攻击者如果想修改寄存器中的内容必须同时正确的修改PAC(这和PAC的机制有关系,下一节详细说)。显然PA只能用在ARMV8.3-A的64位架构中。
二、指针认证的原理
指针认证机制的基本原理是利用特殊指令根据一个64位的上下文、指针的原始值和一个128位的密钥通过一个加密算法的运算之后得到一个64位的密文,对其进行截断之后作为PAC,在使用该指针之前利用特殊指令对指针值进行验证,验证通过之后将指针的高位恢复原状,否则在指针高位填入错误代码,在寻址阶段会触发例外。
1、特殊指令
PA机制提供了三类特殊的指令:
一类是PAC*指令,用来生成和向指针值中插入PAC。例如,PACIA X3,X4;X3寄存器中是指针的原始值,该指令把X4作为上下文,IA作为密钥,计算PAC,并将PAC添加到指针值中,最后将结果写回X3寄存器中。此时指针的值不可用
二类是AUT*指令,用来验证和从指针值中移除PAC。例如,AUTIA X3,X4;X3寄存器中是添加PAC之后的指针值,该指令以X4作为上下文,IA作为密钥再次计算PAC值,并与寄存器中的PAC进行比较,如果计算得到的PAC和寄存器中的PAC是相同的则代表验证通过,把PAC从指针值中去除掉,并将结果写回X3寄存器。
三类是XPAC* 类指令,该指令可以移除一个指针的 PAC 并且在不验证指针有效性的前提下恢复指针的原始值。
2、密钥
PA机制中有五类密钥,指令指针密钥IA、IB,数据指针密钥DA、DB和用于PACGA指令的特殊通用密钥GA。密钥是在进程创建时产生的随机值,在进程复制时子进程继承父进程的密钥值,当子进程执行exec()时,得到子进程自己的密钥。这些密钥存储在CPU内部的寄存器中,EL0特权级无法读取该寄存器,EL1特权级的密钥由更高特权级进行管理。
3、加密算法
理论上来说,使用什么加密算法是微体系结构设计者的工作,但是高通白皮书中推荐使用QARMA算法,这种算法是由高通设计的专门用于生成较短的tag的算法,加密时间短,并且安全性足够高。该算法的输入是指针值和上下文,PAC是截断之后的QARMA输出。截断长度取决于处理器虚拟地址的大小配置以及是否使用了“标记地址”功能。与PAC不同,“标记地址”功能允许软件在指针上添加8位标记而不会影响地址转换。如果未启用标记地址功能,则PAC可以使用这些位。由于虚拟地址的大小可以配置为介于32位和52位之间,并且一位(第55位)用于选择虚拟地址空间的高半部分或低半部分,因此当禁用标记地址时,PAC的大小范围为11到31位,启用标记地址时PAC大小范围是从3到23位。PACGA指令始终从QARMA输出截断32位PAC。
三、应用场景
1、软件栈防御
PA机制可以用来保护栈内存空间,防御栈溢出攻击和ROP/JOP攻击。如下示例代码所示,使用的PACIASP和AUTIASP指令是更通用的PACIA X30 SP和AUTIA X30 SP的专用版本。它们分别使用堆栈指针作为上下文标记和验证链接寄存器(X30)。这些专用指令位于NOP空间中,这意味着生成的代码与旧处理器保持二进制兼容。如果不需要向后兼容,则可以使用与AUTIASP + RET等效的组合指针认证指令RETAA来节省额外的指令。
在函数的装入代码中,利用PACIASP对函数的返回地址添加验证码之后再将其存入栈中,函数结束时排空代码中读出栈中的返回地址,对返回地址中的验证码进行验证,验证通过之后将返回地址恢复成原始值。攻击者如果想实施ROP攻击必须更改X30寄存器中的内容,也就必须拿到密钥和SP的值。构造一个相同的SP是容易的,但是,想要拿到密钥没有高权限是很难的。还有一种方法是暴力猜解PAC的值,这种攻击手段的难度取决于PAC的位数。
2、控制流完整性
利用编译时产生的位置信息和上下文,作为PA机制计算PAC时的上下文输入,可以实现控制流完整性。
参考文献
[1]ARM Connected Community Blog, 2016, “ARMv8-A architecture – 2016 additions”,https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/armv8-a-architecture-2016-additions
[2]googleprojectzero,看我如何绕过 iPhone XS 中指针验证机制 (上),https://www.anquanke.com/post/id/171358
[3]高通,https://www.qualcomm.com/media/documents/files/whitepaper-pointer-authentication-on-armv8-3.pdf