掌桥专利:专业的专利平台
掌桥专利
首页

保护程序逻辑一致性的协处理器架构及程序保护方法

文献发布时间:2024-04-18 20:01:23


保护程序逻辑一致性的协处理器架构及程序保护方法

技术领域

本发明涉及程序保护技术领域,尤其涉及一种保护程序逻辑一致性的协处理器架构及程序保护方法。

背景技术

随着对计算机系统攻击手段的普及和演化,保证系统中程序安全的必要性正逐渐上升,因为程序中可能包含对数据处理和分析等各种敏感的操作。如果这些数据和操作在系统中被泄露或破坏,将会带来巨大的风险和损失。对计算机系统中程序保护的概念最早来源于文献[Lampson B W.Protection[J].ACM SIGOPS Operating Systems Review,1974,8(1):18-24.]和[Wilkes M V.Hardware support for memory protection:Capability implementations[C]//International Symposium on ArchitecturalSupport for Programming Languages&Operating Systems.ACM,1982.],经过半个世纪的发展,该领域涌现出众多优秀的保护方案,特别是对细粒度的控制流保护,如在程序执行期间监控控制流传输以执行安全策略的program shepherding[Kiriansky V,Bruening D,Amarasinghe S P.Secure Execution via Program Shepherding[C]//USENIX Securitysymposium.2002,92:84.];显著提高计算系统安全性,性能开销可忽略不计的dynamicinformation flow tracking[Suh G E,Lee J W,Zhang D,et al.Secure programexecution via dynamic information flow tracking[J].ACM Sigplan Notices,2004,39(11):85-96.]等。然而,目前已有工作大多集中于突出程序生成、存储或运行的某一阶段或若干阶段,研究者找寻其中可能存在的安全漏洞或给出防护策略,但对程序全流程的安全性尚未提出统一定义和防护策略。

为了保护程序全流程的安全性,我们首先需要分析程序执行的本质。一个程序的执行可视为一个状态机从初始状态出发遵循某种逻辑,不断地通过指令的执行进行状态变更的过程。因此程序的正常执行是依赖于其固有逻辑实现的。换言之,逻辑不仅是程序本身意义的一部分,也贯穿了其生成、存储和运行的全流程,对程序逻辑的保护意味着保护程序全流程的安全性。特别地,目前已有的攻击方式如:软件升级攻击、基于硬件的密钥窃取攻击、算法替换攻击、基于软硬件和操作系统的漏洞挖掘利用等攻击等,本质上都是为了寻找可以触发篡改原本程序功能和意图的逻辑的可能性。篡改程序逻辑可能会将敏感流程、系统、网络和数据置于攻击者手中,从而可用于攻击传统IT资产。因此,程序逻辑的安全性是至关重要的。

发明内容

针对当前程序面临的逻辑安全现实威胁,本发明提出程序的逻辑一致性(logicconsistency,LC)这一安全定义,该概念是指程序实际的执行结果与指令的预定逻辑保持一致,不能被恶意用户或第三方篡改、伪造或破坏。这是一种保证程序逻辑机密和正确的重要安全属性。程序的逻辑一致性旨在从更细粒度的指令/数据流层次来刻画从程序生成到静态存储再到动态执行的连续逻辑安全性,该概念可被抽象为一种全流程的系统整体安全。

目前学界尚未提出保护程序LC的相关架构。考虑到LC刻画了程序全流程的安全性,参考已有策略可知,为有效达成保护系统整体安全的目的,在片上增加协处理器的方案通常是合适的选择。例如Jintide通过架构状态记录、回放、分析CPU的IO和内存行为,同时验证记录是否正确回放指令集架构或涉及恶意行为。更为重要的是,我们必须保证当系统的外部安全组件失效或被屏蔽/绕过时,攻击者仍然无法篡改程序逻辑。将系统安全性紧密归约到CPU内核硬件层次。此外,我们希望在对程序运行流程改动尽可能小的前提下,利用操作系统已有的策略实现指令/数据流粒度的程序内容保护。因此,我们需要利用硬件底层设计并结合软件架构实现以保护程序LC。

进一步地,采用密码学原语保护程序LC也是必须的,因为通过加密方式可以在源头上阻断敌手篡改程序执行逻辑的途径。特别地,作为存储程序指令和数据的关键载体,对内存的加密具有重要意义。内存加密技术是一种保护内存中指令和数据免遭未授权敌手窥探或篡改的技术,其直接目的是增加与制造漏洞和窃取敏感信息相关的攻击者的工作负载。由于内存加密仅与执行期间数据和代码的机密性有关,因此我们的方案需要对传统的ME技术进行补充和扩展以确保程序逻辑在运行之前的安全性。此外,对于已有的程序加密框架具体实现方案,提供可证明安全的相关工作较少。而对于程序LC安全性的理论扩展而言,该证明是重要且必须的。

基于以上考虑,在本发明中我们设计了一种基于密码学原语保护程序逻辑一致性(LC)的协处理器架构ECP(encrypting core processing)及程序保护方法,对程序全生命周期安全性进行系统地描述。本发明的贡献主要包含以下三个方面:

1.本发明研究了一个以前未被探索的程序保护安全问题——对程序全生命周期的安全性尚未提出统一的定义和保护策略。本发明提出程序的逻辑一致性(LC)概念,从细粒度的指令/数据流层次来刻画从程序生成到静态存储再到动态执行的连续安全性。

2.本发明设计了用于保护程序LC的协处理器架构ECP,使用密码学原语对程序的全流程安全进行保护。通过可证明安全理论将敌手破坏程序LC的能力归约到密码算法本身的安全性上,并分析该架构抵御不同攻击能力敌手的有效性。

3.在ECP具体实现细节方面,本发明提出CTRn分组加密模式,基于程序指令和数据相对段基址的偏移值实现加解密。同时,ECP基于x64架构采用轻量级密码算法,既节约了硬件成本,也有效避免了分组对齐和重复存取等预处理操作,从而提高了实现效率。

为了实现上述目的,本发明采用以下技术方案:

本发明一方面提出一种保护程序逻辑一致性的协处理器架构,该架构部署在CPU内部,包括LWC加密单元,NUM计算单元,Ctr表,Ctr生成单元,程序和进程的编号单元;

所述LWC加密单元用于在内部预置轻量级密码算法,同时存储加密参数三元组(K,Ctr,NUM),其中K表示密钥,Ctr表示计数器,NUM表示加密序号;

所述NUM计算单元用于存储程序/进程各段基地址并计算加密序号NUM;

所述Ctr表用于存放程序编号ID,该ID下的若干进程编号PID以及应用于各段加解密的计数器Ctr;

所述程序和进程的编号单元用于生成程序编号ID及该程序的若干进程编号PID;

所述Ctr生成单元用于生成应用于各段加解密的计数器Ctr;

所述LWC加密单元与CPU的存储器数据寄存器交互,NUM计算单元与CPU的存储器地址寄存器交互,Ctr表通过程序和进程的编号单元、Ctr生成单元与CPU中的控制单元交互。

进一步地,所述密钥K默认是固定的,若更换则需要对已加密的程序解密后重新加密。

进一步地,所述LWC加密单元内部预置SIMON算法,将三元组(K,Ctr,NUM)视为加密参数。

进一步地,加密时NUM计算单元存储PE文件文字段和数据段的基地址,根据待加密指令/数据相对基地址的偏移计算NUM;解密时NUM计算单元中存储该进程内存映射中指令段和数据段的基地址,根据从内存中取得的密文指令/数据相对基地址的偏移计算NUM。

进一步地,所述Ctr表中,程序加密过程中的Ctr

本发明二方面提供一种利用上述协处理器架构对可执行文件生成时的保护方法,包括:

步骤A1:由用户编辑源代码;

步骤A2:由编译程序将用户源代码编译成若干个目标模块;

步骤A3:由链接程序将编译后形成的一组目标模块以及所需库函数采用静态链接方式链接在一起,逐条指令/数据用0填充至64比特,并记录PE文件头、PE可选头及节表中相关参数,形成一个完整的装入模块,并在其中生成一个明文形式存储的程序编号及随机数,用于此次加密的指令加密计数器Ctr

步骤A4:将形成的装入模块逐条指令/数据传入所述协处理器架构,每条指令/数据为一个加密分组,协处理器架构组件实时记录该行为,首先将文件中的Ctr

步骤A5:用户运行.exe*文件后,操作系统将加密后的程序置入内存,当程序入口点地址交由CPU的PC寄存器时,程序开始执行,首先将程序编号及Ctr

本发明三方面提供一种利用上述协处理器架构对可执行文件运行时的保护方法,包括取指令操作保护和调用函数操作保护。

进一步地,所述取指令操作保护包括:

步骤B1:由程序计数器PC将其中存储的指令X对应地址Addr

步骤B2:MAR将其内容传至地址总线及协处理器架构,协处理器架构内部查询该进程/程序编号,之后根据Addr

步骤B3:控制单元CU发出控制信号,传至控制总线;

步骤B4:控制总线启动内存,开启读信号;

步骤B5:地址总线将MAR中地址送入内存代码段;

步骤B6:内存将MAR所指代码段地址中的内容C

步骤B7:数据总线将该内容送入ECP;

步骤B8:将协处理器架构中的指令解密后传入存储器数据寄存器MDR中;

步骤B9:将MDR中的内容送入指令寄存器随后译码,此时译码单元根据指令实际长度将对齐加密时补充的0删去;

步骤B10:CU发出控制信号,形成下一条指令地址传入PC。

进一步地,所述调用函数操作保护包括:

步骤C1:CPU通过译码得到目标指令为调用函数时,将内存中下一条指令地址压入堆栈;

步骤C2:寄存器RSP将修改后的地址Addr

步骤C3a:MAR将其中内容传至地址总线;

步骤C4a:CU发出控制信号,传至控制总线;

步骤C5a:控制总线启动主存做写操作;

步骤C6a:地址总线将MAR中地址送入栈区;

步骤C7a:虚拟内存中堆栈段开辟8个字节的存储单元用于存储即将到来的数据;

步骤C3b:MAR将其中内容传至协处理器架构,协处理器架构根据此时程序编号、进程编号PID查询Ctr表,若此时对应的Ctr

步骤C4b:CU将此时PC的内容送入MDR;

步骤C5b:MDR将其中的内容送入协处理器架构加密,得到密文;

步骤C6b:协处理器架构将密文传入数据总线;

步骤C7b:数据总线将加密内容送入栈区已开辟的地址Addr

步骤C8:将目标函数的入口地址标记为PC_

步骤C9:按照步骤B1-B10,PC执行取指令操作;

步骤C10:按照步骤C1至步骤C7b,完成压栈操作;

步骤C11:取下一条指令并解密,按照上述相同方式完成压栈操作;

步骤C12:取下一条指令并解密,在新栈帧中预留N字节空位以供目标函数访问,完成目标函数栈帧创建的指令级保护流程。

与现有技术相比,本发明具有的有益效果:

1.现有保护方案的设计各有优点,但缺陷也是明显存在的。问题的本质反映在这些架构只能保护程序运行流程的某个关键阶段,无法对全生命周期进行保护。上述缺陷将在特定场景下无法确保程序指令和数据在内存中的安全性。本发明的方案对传统内存加密场景进行了补充和扩展,在将程序静态保护和动态保护有机整合的基础上,我们创造性地提出程序逻辑一致性的概念,结合“强绑定安全”的ECP架构对程序全生命周期安全性进行系统地描述。

2.已有的程序保护架构主要考虑在软件和硬件层次上正向的实现,站在攻击者视角对整体方案安全性进行理论证明和抵御现实攻击的系统评估工作较少。本发明在敌手具备一定攻击能力的条件下,利用可证明安全理论对ECP加密程序的方案进行证明,说明其满足IND-CPA安全性;并对不同类别的现实攻击方式展开具体分析论证,说明本方案在加密程序生成阶段和运行阶段均一致保持LC。

3.在x64架构中,内存最多操作64bit长分组。而已有加密方案大都采用AES标准算法,在AES算法中每个块至少为128位。因此在每次内存操作期间,需要收集目标内容附近的128位对齐数据并需要后续处理。本发明基于x64架构特点采用轻量级分组密码算法对指令和数据加密,可保证单个加密分组和系统处理指令/数据流分组相等。从而避免了对齐和重复存取等辅助操作,在节约硬件成本基础上提升了体系结构效率。

4.已有架构的加密粒度大多为特定大小的分组或分页,目前从更细粒度的指令层次分析执行流的安全性方案较少,且多使用序列密码。另一方面,目前广泛应用的基于Split Counter Mode Encryption方案[Yan C,Englender D,Prvulovic M,etal.Improving cost,performance,and security of memory encryption andauthentication[J].ACM SIGARCH Computer Architecture News,2006,34(2):179-190.]使用了若干7-bit微计数器,在已知明文攻击条件下这些计数器受到攻击将会影响系统的总体安全性。本发明对计数器递增的传统CTR加密模式进行改进,设计了基于程序section中地址偏移来计算加密参数三元组(K,Ctr,NUM)的加密模式CTRn,并在加密各指令/数据分组的基础上实现程序更细粒度的动态安全分析。

附图说明

图1为本发明实施例提供的ECP架构示意图;

图2为本发明实施例提供的CTR加密模式示意图;

图3为本发明实施例提供的PE文件加载至内存的对应结构关系;

图4为本发明实施例提供的ECP加密可执行文件流程图;

图5为本发明实施例提供的ECP取指令流程图;

图6为本发明实施例提供的ECP调用函数流程图。

具体实施方式

下面结合附图和具体的实施例对本发明做进一步的解释说明:

1.ECP架构

本发明提出的ECP芯片是具备一定存储和加密能力的嵌入式协处理器,可视为软硬件融合的底层安全防护架构。虽然部署在CPU内部,但其实现的功能和内存息息相关,ECP建立了基于“内存+系统+进程”的实时分析防护体系,基于密码学保护程序的执行逻辑安全可信,进而保证用户按照预期执行程序实现相应功能。与数据按顺序存储以供访问的硬盘不同,内存中数据的存取方式是多种多样的非连续的动态访问。关于ECP实现内存中程序(进程)加密的诸多细节,如采用的加密算法、加密粒度、加解密时机、加密参数数量等因素,必须在预期实现的保护程度和系统可用性之间做出一系列权衡。

1.1ECP整体结构

由于加密可能被绕过,所以ECP架构作用的位置相当重要。一个系统级漏洞可能对应用级的加密进行降级,从而实现敌手对加密行为与数据安全的解耦。基于此,我们提出使用“强绑定安全”保护程序LC,即当系统的外部安全组件失效或被屏蔽/绕过时,攻击者仍然无法篡改程序执行逻辑,系统安全性紧密归约到CPU内核硬件层次。

密码硬件安全技术的核心功能是密钥存储及安全密码运算,其优点是信任基较小,但保护范围较为局限,我们考虑在此技术上扩展安全防护的范围,以达到保护所有通用计算的能力。这就决定了一方面必须将ECP组件置于能够处理所有通用计算的系统“路口”,另一方面,考虑到攻击者可以访问除CPU以外的系统任意区域,信任基应置于最底层次的安全位置。对比参照SGX的MEE部件,Jintide CPU协处理器及其他协处理器所实现的功能及部署位置,我们考虑在CPU内部部署ECP芯片,以完成对出入CPU指令和数据的快速加解密。基于此,我们在ECP安全架构的设计中,对所有需保护的程序在加密完毕后依次发布供用户使用。用户只能在装载ECP芯片的CPU上运行这些程序的加密版本。加密密钥K位于整个系统信任基最深处,因此对他们而言是透明的。

根据以上表述可知ECP芯片与CPU内部结构的信息交互是必须的,我们将ECP划分为三个主要区域,它们分别与CPU控制部分的相应组件交互从而实现不同的功能:

区域1:LWC加密单元。该区域内部预置轻量级密码算法,同时存储加密参数三元组(K,Ctr,NUM)。默认密钥K是固定的(若更换则需要对已加密的程序解密后重新加密),计数器Ctr和加密序号NUM在程序加密过程中获得。

区域2:NUM计算单元。该区域存储程序/进程各段基地址并计算加密序号NUM。程序加密时,基于exe各部分Header中section基地址和指令/数据在各section中的偏移计算NUM;程序运行(解密)时,基于指令/数据在内存虚拟地址各Segment中的相对偏移计算NUM。

区域3:Ctr表。该区域存储加密参数计数器Ctr。在整体Table中,ECP为每个程序维持一个独立数据结构,分别存放程序的ID,该ID下的若干进程编号PID以及应用于各Segment加解密的计数器Ctr,该数据结构是动态可扩展的。

ECP芯片的其他部分还包括Ctr生成单元,程序和进程的编号单元等等,区域3通过这些单元与CPU中的控制单元(Control Unit,CU)交互,区域1与CPU的存储器数据寄存器(Memory Data Register,MDR)交互,区域2与CPU的存储器地址寄存器(Memory AddressRegister,MAR)交互。每个区域的架构原理,实现细节及交互流程将在后文详细介绍。ECP芯片的结构示意图如图1所示。

1.2LWC加密单元的设计

ECP架构的重要创新点是放弃了之前大多数ME方案采用的AES算法。在协处理器运载的x64平台中,CPU寄存器大小和总线数据传输单元均为64bit,因此考虑采用分组长为64bit的加密算法以避免数据对齐等预处理操作。本方案选择使用轻量级分组密码算法,此类密码算法可在微型元器件上实现数据的保护,其安全性也得到了充分论证。由于算法设计必须考虑实现时所需的物理资源,如芯片大小、能量消耗的平均值和峰值等,故需要在安全强度与资源占用方面加以折中。基于此,大部分轻量级分组密码算法的分组长度相对较短(64比特),密钥长度适中(80比特),密钥扩展算法简单,迭代轮数较多。下面给出常见轻量级分组密码算法参数,其中等效门电路(Gates Equivalent,GE)是衡量硬件实现成本的重要指标。

表1常见轻量级分组密码算法参数

观察上表可知,SIMON算法在硬件上的实现效率均优于现有大多数的轻量级分组密码,且整体结构和轮函数设计都非常简单,仅使用了适合硬件实现的基本算术运算:异或、移位和比特与运算,因此在计算速度和资源消耗上更有优势,更能适应硬件条件受限的情况。更重要的是,SIMON算法支持32bit块分组的简化版本,这意味着在x86平台中ECP架构同样能够保持加密分组与CPU处理分组长度相等。综合以上考虑,我们可采用SIMON作为内置LWC加密单元的加密算法。

在确定选用的加密算法之后,我们必须考虑采用一种合适的分组密码加密模式。众所周知,分组密码有五种加密模式,分别是电子密码本模式(Electronic Codebook,ECB),密码分组链接模式(Cipher Block Chaining,CBC),密码反馈模式(CipherFeedback,CFB),输出反馈模式(Output Feedback,OFB)和计数器模式(Counter,CTR)。考虑到我们预期实现的功能,即对程序进行指令/数据流粒度的加密,将上述加密模式的优缺点列举如下:ECB模式会导致相同明文加密成相同的密文,攻击者通过对密文的简单分析即可提取相关的明文信息;CBC和CFB模式存在更改(错误)扩散特点,当内存中某一地址的密文内容发生改变后,其后所有的内容均需重新加密,造成大量的资源浪费;OFB模式与CTR模式原理类似,由于不支持并行计算,在大多数场合下被CTR模式取代。特别地,在CTR模式中先对Ctr加密生成密钥流,再将密钥流与明文异或生成密文,解密时使用相同的密钥流,对密文异或即可得到明文。因此,对Ctr进行一次加密操作即可完成数据的加密和解密。在LWC加密单元中只设计加密算法模块即可,节约了一半硬件实现成本。综合以上考虑,我们采用CTR模式加密,如图2所示。

ECP架构中LWC加密单元采用的CTRn加密模式对传统CTR加密模式进行改进,将三元组(K,Ctr,NUM)视为加密参数,在尽可能少占用CPU内部存储资源的前提下,确保程序中指令/数据在非顺序存取时的加解密操作可以正常执行。此外,由于对不同程序加密时CPU随机生成秘密的Ctr,因此LWC加密单元使用相同K可确保系统安全性,我们可以将SIMON算法的128比特长密钥预先写入LWC加密单元中。考虑到LWC加密单元更改密钥K后需对已加密程序解密后重新加密,因此在出现加密参数泄露的风险前,该操作一般是不建议的。

1.3NUM计算单元的设计

传统CTR模式加密中,每当加密新的分组时计数器Ctr递增。虽然这是效率较高的操作,但却无法应用于ECP中实现对程序LC的保护,原因在于程序指令/数据解密时的分组顺序与加密时的分组顺序不可能相同(指令和数据的非顺序存取是普遍的),为每个加密分组设置Ctr理论上是可行的,但是耗费的存储成本非常巨大,将直接导致系统的不可用。

我们提出的CTRn模式加密的改进方案是引入加密序号NUM,将逐次递增的Ctr转化为加一个需要计算的NUM(无特殊说明情况下本发明加法均为模2

在Windows操作系统中,用户对源代码编译链接后形成一个完整的待装入模块,即可执行程序exe文件。exe具备PE文件格式,PE文件结构包含PE文件头和PE文件体两部分。其中PE文件头包含DOS头、PE头和section表;PE文件体包含程序代码.text段、已初始化以及静态数据.data段、未初始化数据.bss段、其他数据.rdata段、.edata段、.idata段以及.rsrc段等,此外还包括一些不能映射至内存的部分(如调试信息)。由于PE文件头部分中各HEADERS和table存储的相关参数反映了程序指令或数据在内存中的加载地址,因此考虑到维护程序的可用性,本架构不对除程序指令和数据之外的部分加密。同时,为后文架构的描述方便,我们将.bss段、诸.data段及其他存储数据相关段合并为data section(并不是物理意义上的合并,因为还需满足各段对齐即进行段间填充)。

当exe文件加载至内存中,系统运行动态的程序,即进程。内存中exe文件的textsection(文本部分)映射为Code Segment(指令段),data section(数据部分)映射为DataSegment(数据段),各段内部均保持致密性,即指令和数据的相对存储顺序维持不变。但程序在磁盘中存储和内存空间中加载时各段有不同的对齐粒度,各段间填充的数据长度不同。另一方面,与PE文件不同,进程生成时会在内存中分配Stack空间(系统分配)和Heap空间(用户分配)用于存储临时创建的局部变量,并且分配固定的高地址段作为内核空间。特别地,因为内存布局按照严格的规则摆放,各段很容易被敌手恶意访问。通过加入随机偏移,每个进程的栈空间起始位置稍有不同,使得敌手确定栈空间起始位置具有一定难度。堆段的Random brk offset等参数设置同理。因此,PE文件中各section和内存映像中各Segment保持各自独立的映射关系,exe文件映射至(虚拟)内存的对应关系如图3所示。

虽然同一指令/数据在PE文件和内存映射中的地址可能毫无关系,但其相对各自段基址的偏移是固定的。我们所需要的就是这样一个在加解密过程中保持不变的参数来计算NUM,这也是ECP架构基于section中的指令/数据offset加密的核心思想。具体而言,加密时NUM计算单元需要存储PE文件text段和data段的基地址,根据待加密指令/数据相对基地址的偏移计算NUM

进一步地,在NUM计算单元中需要存储程序/进程的5个不同的段基址Addr

1.4Ctr表的设计

Ctr表作为ECP芯片中一个专门的参数存储区域,用于存储随机生成的计数器Ctr。本架构主要考虑在确保系统安全的基础上尽量降低存储成本。

首先,在我们设计的ECP架构中,需要对程序的指令段和数据段分别加密,即我们必须确保程序加密过程中的Ctr

2.ECP对程序行为逻辑一致性的保护

如前文所述,我们考虑使用ECP架构对程序的内容加解密,目的是为了保护程序的逻辑一致性,进而保证程序全生命周期的安全。程序的LC体现在两个方面,一是程序静态代码的机密性,二是程序动态进程的正确性。基于此,本章分为两个部分介绍ECP架构对程序的具体保护流程:

i.可执行文件生成时的保护流程

ii.可执行文件运行时的保护流程

虽然当今汇编语言远非大规模软件开发的首选,但考虑到我们将从CPU视角解读出真实程序的运行流程,本章我们主要研究指令级的汇编语言加密实例。需要特别说明的是,程序保护者将ECP芯片提供给用户时,除了已写入LWC加密单元的密钥K以外,不需要在ECP中预留任何加密参数。诸如Ctr和NUM等参数将在程序运行时经提取或计算后加载至ECP对应区域,该做法是为了保证安全性的前提下节约片上存储成本。

2.1ECP对可执行文件生成时的保护

在程序运行之前应当完成指令与数据的加密,通过合理地设置CTR模式加密相关参数,确保程序运行时指令和数据得以安全高效地解密。我们创造性地通过指令在PE文件中和映射到虚拟内存中偏移量的关系确定加密参数NUM,并给出完整加密流程。特别地,对于本发明提出的ECP架构而言,程序生成过程默认是在安全的开发环境中。即从用户编辑代码至程序被加密后发布为exe*之前,攻击者无法实施诸如窥屏(编辑代码信息泄露)、安装编译/链接器后门(编译链接过程中程序信息泄露)、探测内存(加密过程中程序信息泄露)等行为。当所有需保护的程序被加密完毕,程序保护方将处理后的诸程序发布,连同部署ECP芯片的CPU提供给用户。用户只能使用改造过的CPU运行加密程序。

2.1.1基于section中的代码/数据offset加解密

在1.2小节中,我们讨论了ECP芯片采用分组密码加密模式CTR的可行性。在经典的CTR模式中,对明文分组P使用二元组(K,Ctr)加密即可得对应的密文C。当加密可执行文件时,考虑到指令在可执行文件中的相对顺序和加载至内存后的执行顺序不同,故采用传统的逐分组Ctr递增方式会导致同一指令/数据加解密对应的Ctr不同。因此ECP架构为每个明文分组设置一个加密序号NUM与计数器Ctr相加。显然的,加密序号NUM的存储也是额外的资源开销。为了使ECP上的存储资源得以最大程度地约简,同时结合可执行文件的架构特点,我们提出了基于section中的代码offset加密方法。

用户编写完成源代码后,经过编译和链接过程生成exe可执行文件。首先需要说明的是,本发明所使用的轻量级分组密码算法加密分组(基本单元)为64比特,若明文指令/数据长度小于64比特,需要在其后补0,待解密后由CPU中的译码单元IR删去分组中多余的0。特别的,鉴于64位操作系统中总线传输单元和CPU处理单元长度均为64比特,在我们的设计中避免了存取指令/数据不对齐的情况,这很大程度上节省了CPU的运算资源。

可执行文件中的section可视为连续的字节流,offset是其中某字节在该段字节流中的相对偏移。同理,每条指令/数据均有相对section起始地址的offset,由上述补0规则可知该offset均为8的整数倍。为了得到定义在自然数集上的NUM,在加密之前需要对offset进行除以8的转化操作。例如:当指令A进入ECP加密时,ECP中NUM计算单元根据PE文件头中的相关信息求得A相对.text section起始地址的offset,并记为PE_off

2.1.2生成exe*的具体流程

用户使用ECP组件对程序进行加密,需要执行以下流程。

Step11:由用户编辑源代码。

Step12:由编译程序将用户源代码编译成若干个目标模块(将高级语言翻译为机器语言)。

Step13:由链接程序将编译后形成的一组目标模块以及所需库函数采用静态链接方式链接在一起,逐条指令/数据用0填充至64比特(8字节对齐),并记录PE文件头、PE可选头及section table(节表)中相关参数,形成一个完整的装入模块,并在其中生成一个明文形式存储的程序编号及随机数(用于此次加密的指令加密计数器Ctr

Step14:将形成的装入模块(exe文件)逐条指令/数据传入ECP,每条指令/数据为一个加密分组。ECP组件实时记录该行为,首先将文件中的Ctr

Step15(在用户本地环境中的预备工作):用户运行.exe*文件后,操作系统将加密后的程序置入内存,当程序入口点地址交由CPU的PC寄存器时,程序开始执行。假设此时启动的是隶属于程序A的进程1,运行后首先将程序编号及Ctr

ECP架构整体加密流程示意图如图4所示。

2.2ECP对可执行文件运行时的保护

程序运行时其动态进程的正确性是程序逻辑行为一致性的主要体现,因此本部分是整个保护流程的核心。任何程序都是由若干指令和数据构成,接下来我们将以汇编指令为单元分析CPU执行加密程序时的指令级交互过程。

当操作系统运行一个加密.exe*文件时,它会先读取DOS头和PE头,然后根据可选头中的镜像基址将整个文件分散映射到虚拟内存中,之后再根据节表中的信息将每个section复制到相应的虚拟地址,最后根据入口点地址开始执行代码。需要特别说明的是,此时相关加密参数已被提取或生成后置于ECP内部组件中,默认后文的讨论步骤中加密参数均已在Ctr table及NUM生成单元部署完毕。

根据前文分析可知,在虚拟内存中,虽然节与节之间的偏移量发生改变,但节内指令/数据间的相对顺序保持不变,因此可根据指令/数据相对基址偏移量RBA_off计算出用于解密的参数NUM。另一方面,参数NUM根据指令在内存虚拟地址中的偏移量得到,因此整个加解密流程与指令/数据在DRAM上存储的物理地址无关。为了简化体系结构的相关描述,我们对CPU中的地址翻译部件MMU进行透明化处理,同理,对TLB和Cache等提升CPU运行效率的部件也进行了透明化处理,虽然在程序实际运行过程中,这些组件是必要的且起到至关重要的作用。

2.2.1取指令

在程序运行过程中,取指令操作是执行任何指令之前的必须步骤,我们先分析CPU从内存中取一条完整指令X的流程,如图5所示。

Step21:由程序计数器(Program Counter,PC)将其中存储的指令X对应地址Addr

Step22:MAR将其内容传至地址总线及ECP,ECP内部查询该进程/程序编号,之后根据Addr

Step23:控制单元CU发出控制信号,传至控制总线;

Step24:控制总线启动内存,开启读信号,记作:1→R;

Step25:地址总线将MAR中地址送入内存代码段;

Step26:内存将MAR所指代码段地址中的内容C

Step27:数据总线将该内容送入ECP记作:M(MAR)→ECP;

Step28:将ECP中的指令解密后传入存储器数据寄存器MDR中,明文指令即

Step29:将MDR中的内容送入指令寄存器(Instruction Register,IR)随后译码,此时译码单元根据指令实际长度将对齐加密时补充的0删去,记作:(MDR)→IR;

Step210:CU发出控制信号,形成下一条指令地址传入PC,记作:PC_

2.2.2调用函数

一个程序成功运行过程中,函数的调用是必不可少的。在函数调用过程中涉及到指令的转移/中断,数据在CPU和内存之间的交互,以及对堆栈段的操作等。下面我们给出调用一个函数时ECP模块的具体保护流程,如图6所示。为方便说明,我们采用函数的C调用约定,假设fun函数相关参数已赋给CPU若干寄存器或事先压入栈中(已用ECP中相关参数加密),直接从汇编指令call fun开始执行。

Step1:CPU通过译码得到该条指令为call fun时,需要将内存中下一条指令地址压入堆栈。首先应在堆栈中开辟存放指令地址的位置,控制器CU将寄存器RSP的值减8,记作:(RSP)-8→RSP;

Step2:寄存器RSP将修改后的地址Addr

Step3a:MAR将其中内容传至地址总线;

Step4a:CU发出控制信号,传至控制总线;

Step5a:控制总线启动主存做写操作,记作:1→W;

Step6a:地址总线将MAR中地址送入栈区;

Step7a:(虚拟内存中)堆栈段开辟8个字节的存储单元用于存储即将到来的数据;

Step3b:MAR将其中内容传至ECP,ECP根据此时程序编号、进程号PID查询Ctr表,若此时对应的Ctr

Step4b:CU将此时PC的内容P

Step5b:MDR将其中的内容送入ECP模块加密,密文即

Step6b:ECP模块将密文传入数据总线;

Step7b:数据总线将加密内容送入栈区已开辟的地址Addr

Step8:将函数fun的入口地址Addr

Step9:按照2.2.1节步骤,PC执行取指令操作。此时代码段地址Addr

Step10:按照Step1至Step7b步骤,完成push RBP(压栈)操作;

Step11:取下一条指令并解密,完成mov RBP,RSP操作;

Step12:取下一条指令并解密,完成sub RSP,N操作,即在新栈帧中预留N字节空位,fun函数可以使用(RSP+n)或(RBP-n)的形式访问(引用)空位。至此,完成函数fun栈帧创建的指令级保护流程。

当系统不切换进程及线程时,内存中维持一个固定的堆栈,此时使用Ctr表中固定的Ctr

2.2.3其他情形

·进程/线程切换

当系统运行多个程序,或一个进程内部开启多线程时,加密参数需要频繁地切换,在此过程中NUM生成单元和Ctr表起到至关重要的作用。由于NUM生成单元在每个进程产生时维护一条关于该进程各段基地址的信息,因此发生进程切换时可根据PID和线程控制块TCB精确匹配当前进程/线程参数所属段,从而根据MAR寄存器中的地址计算对应NUM;另一方面,ECP可根据PID定位Ctr表中对应参数,K固定情况下确定加密参数Ctr和NUM后即可成功实现指令/数据的加解密。

·堆段保护

在上一小节中,我们介绍了程序运行时对堆栈段数据的保护,由于堆段区域和堆栈段都是程序运行时临时开辟的内存区域,因此保护原理类似。更进一步地,由于同一进程使用共有的堆段,因此不需要考虑类似堆栈段的线程级切换,在需要向开辟堆区域中写入数据P

·内核空间保护

考虑到将内核空间所有代码加密对整个体系结构带来的效率负担是显著的,我们仅对内核空间中与CPU交互的相关参数和数据进行加密保护。当某进程发生系统调用、异常或外围设备的中断使系统陷入ring 0(内核态)时,需确保从ring 3(用户态)压入ring 0(内核态)栈的参数是秘密的。例如:Linux操作系统运行系统调用函数system_call()时首先要把系统调用号sysno(保存在寄存器RAX中)和所有相关cpu寄存器的值保存到ring 0的内核栈中,即执行SAVE_ALL宏操作。我们使用三元组(K,Ctr

3.ECP安全性分析

我们的目的是基于密码学保护程序行为逻辑的一致性,即保证用户安全可信地按预期执行程序,主要体现为程序指令和数据的机密性。因此,我们要确保任何ring 3进程的指令和数据都以加密形式存储在DRAM中。这样,驻留在主内存中或在不受信任域的不同组件之间移动的敏感数据将始终受到保护。在此前提下,我们需要对攻击者的能力做出一定假设,具体而言,首先应假设CPU的执行逻辑被屏蔽,这个屏蔽区域包括CPU原有的内部结构,如各寄存器,MMU,Cache等,也包括ECP及其所有内部组件,从而我们可以在CPU内部进行安全的加解密操作。进一步地,我们假定处理器之外的所有组件都容易受到攻击,包括RAM及其互连,如数据和内存总线、I/O设备等。在此基础上,我们可以基于敌手能力描述威胁模型中的相应攻击类别。形式上,敌手A可以读取片外存储器中的任何内容,并采用一系列被动攻击和主动攻击手段。

由于ECP中加密模块所使用的轻量级分组密码算法均为IND-CPA安全的公开加密方案,因此受益于已有的底层方案安全证明,可将所选用的轻量级分组密码算法视为与随机函数f等价,从而对后文IND-CPA的证明过程进行约简(即省去了规约证明的步骤)。

3.1 IND-CPA的安全性证明

根据ECP内部基本架构可知,当每个加密程序生成时首先使用对应的加密参数K,Ctr

在这里我们首先给定基于ECP对程序生成时加密保护方案Π的IND-CPA

1.挑战者C使用ECP随机生成唯一安全的加解密密钥

2.敌手A向C提交程序exe明文,C通过ECP模块生成一组独立的Ctr

3.步骤2重复p次(称为敌手查询p次不同程序的密文);

4.A向C提交和步骤3中查询程序代码段与数据段均不同的两个挑战程序明文exe

5.C选择一个随机比特

6.A根据

下面证明该保护方案Π的IND-CPA安全性。

定理1:ECP对程序生成时的加密保护策略Π具备IND-CPA安全性。

证明:ECP分别使用Ctr

现允许敌手A向ECP提出共p(上限为多项式P(n))次的问询,同时令其为问询明文程序和挑战明文程序代码段和数据段的最大长度。令

这l

这l

情况1:不

该情况下,说明第一阶段ECP加密任何敌手的问询时,无论是加密代码段还是数据段,都不可能使用和第二阶段加密挑战程序代码段相同的密钥流。因此,当ECP加密挑战程序明文时,使用的流

情况2:

此时,有

进一步地,如果挑战程序和问询程序的代码段和数据段分组足够大,情况2发生的概率可达到最大。假设

固定

因为

于是有

同理,敌手成功区分出挑战程序数据段的优势概率也为Pr[Overlap],我们令Bad表示挑战程序代码段发生Overlap或挑战程序数据段发生Overlap事件。进一步地,可继续由布尔不等式得到

因为P(n)是多项式,因此

(证毕)

在ECP的基本架构中,我们规定加密算法LWC_f分组长为64比特,因此当P(n)的值等于2

3.2针对具体攻击的安全性分析

与上一小节不同,本小节将论证exe*运行过程中所面临的实际安全威胁,即所谓的动态安全性。首先,针对ECP模块内存加密架构的敌手A主要分为两种类型:被动窃听对手和主动伪造对手。下面列举出两类攻击的目的:

1.被动攻击目的:敌手A通过直接读取DRAM或监视密文指令流在DRAM和CPU之间的交互以收集相关信息,得到明文指令和数据。(例:冷启动攻击)

2.主动攻击目的:敌手A通过破坏DRAM中密文指令和数据的存储结构,通过更改DRAM某些区域内容,导致程序按照A的预想状态运行。(例:缓冲区溢出攻击)。

根据前文对程序行为逻辑一致性的定义,结合两类攻击目的可知,无论是被动攻击还是主动攻击,均破坏了程序的行为逻辑一致性,因此需要对抵御具体攻击的安全性展开分析。

3.2.1被动攻击

敌手A采用冷启动攻击直接读取内存中部分内容的做法是收效甚微的,因为针对内存地址中某个密文分组,需要三元组(K,Ctr,NUM)才能将其解密得到对应明文。一方面,K存储在ECP内部的轻量级加密模块中,对攻击者而言是透明的。另一方面,根据前文介绍,我们是根据exe各section映射到虚拟地址中的offset来计算NUM的。A通过冷启动攻击获取到的是内存数据对应的实际物理地址,需要访问CPU内部的MMU组件才可以完成虚拟地址的转化。而MMU组件也在信任基内部,因此A无法得到NUM。在三元组(K,Ctr,NUM)中,A唯一能得到的参数是记录在程序中的Ctr,因此A无法完成对加密消息的解密。任何A读取DRAM内容的尝试都会导致无意义的垃圾数据,由此确保了程序的行为逻辑一致性。同理可知,敌手A实施总线窃听攻击获取指令流和数据流在DRAM与CPU之间的交互也将是徒劳的,原因仍是A无法完全掌握参数三元组(K,Ctr,NUM)对获取到的信息解密。

3.2.2主动攻击

更有威胁的一种攻击方式是敌手A通过某种手段更改DRAM的某些内容以达到自己的目的,通常基于软件实现。其中的代表性攻击方法是缓冲区溢出攻击,主要有两种实现方式,现场注入和预先植入:

对于现场注入方式,攻击者一般会在程序运行过程中输入恶意代码即“恶意代码二进制表示+填充数据+恶意代码起始地址Addr

对于预先植入方式,即攻击者在程序运行之前植入恶意代码。首先根据相关知识,攻击者无法在源代码形成或编译链接过程中植入恶意代码。因为在编译链接过程中,编译器和链接器会对程序进行检查,以确保程序的安全性和正确性。编译器会检查程序中的语法错误和类型错误,而链接器会检查程序中的符号和库的链接。如果程序中包含恶意代码,编译器和链接器会在编译链接过程中发现这些代码,并报告错误。因此,如果程序员想写一段包含恶意代码的程序,那么这段代码很可能会在编译链接过程中被发现。另一方面,假如攻击者试图在已生成完毕的exe

为保证程序执行逻辑与用户预期一致,本发明将程序在系统中的静态安全与动态安全有机整合,提出基于程序全生命周期安全的行为逻辑一致性概念。我们开发了内置于CPU的轻量级加密协处理器ECP芯片,基于密码学原语对程序生成至程序运行的整体流程提供指令粒度的防护。我们对ECP芯片所支持的程序加密功能提供了可证明安全,并给出该架构在程序运行阶段抵御不同类型攻击的具体安全性分析。未来工作将对ECP架构中已有的功能进一步优化,对未实现的其他安全模块展开深入研究。另一方面,我们持续聚焦系统整体层次安全,并将密码学手段与其他新型防护架构不断融合扩展。

以上所示仅是本发明的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本发明的保护范围。

相关技术
  • 一种方控数据处理方法、装置、电子设备及存储介质
  • 一种材质的数据处理方法、装置、电子设备及存储介质
  • 一种数据处理方法、装置、电子设备及存储介质
  • 一种消息处理方法、装置、电子设备及存储介质
  • 一种应用程序处理方法、装置、电子设备及可读存储介质
  • 数据加密处理方法、数据解密处理方法、装置、电子设备及可读存储介质
  • 一种数据存储系统、数据处理方法、电子设备和存储介质
技术分类

06120116551461