何 运, 贾晓启, 刘 鹏, 张伟娟
1中国科学院信息工程研究所 北京 中国 100093
2中国科学院大学网络空间安全学院 北京 中国 100049
3宾夕法尼亚州立大学 宾夕法尼亚 美国 16802
云计算作为一种新兴计算模式, 由于其低成本、灵活性、高度自动化等特点而备受关注。越来越多的企业将其应用程序和数据迁移到云平台, 文献[1]调查显示几乎有一半的公司表示其IT系统中有31%~60%是基于云平台进行部署的。此外, 预计到2024年全球云计算市场将突破1万亿美元[2]。然而, 云计算迅速发展的过程中也面临着诸多安全挑战。近期的调查报告[3-5]指出云计算安全问题已成为企业部署或使用云平台时首要考虑的因素。云安全联盟(Cloud Security Alliance, 简称CSA)发布的一份报告[6]归纳了云计算中的12大安全威胁, 其中恶意内部人员攻击(Insider Attacks)排名第六。此类攻击通常由某个组织中(如云服务提供商)的恶意内部人员发起。例如, DuPont公司的商业机密被一位前工程师偷走并泄露给竞争对手[7]。2016年美国网络犯罪状况调查发现, 27%的网络犯罪是由内部人士造成的[8], 该调查还显示, 30%的受访者认为内部人员攻击造成的损害比外部攻击造成的损害更加严重。针对云平台环境, 云服务提供商的恶意内部人员很容易窃取客户虚拟机的敏感数据[9-10]。考虑一个常见场景: 当客户虚拟机中的某个进程正在执行加密(或解密)操作, 此时云服务提供商的某些恶意内部人员, 如云平台运维人员(Cloud Operators), 可能会对客户虚拟机执行内存快照(Memory Dump)操作, 然后可以轻松地从内存快照文件中恢复密钥, 本文将此类攻击称作内存快照攻击(Memory Dump Attacks)。
针对恶意内部攻击, 文献[11-14]通过分析内部人员的行为记录来检测未经授权或非法访问云租户数据的异常事件。然而, 这些方法并不总是奏效, 因为客户虚拟机中的敏感数据已经被窃取, 即便后续发现了此类攻击行为。为了防止恶意内部人员对云租户数据进行窥探或篡改, TCCP[15]为客户虚拟机提供一个封闭的执行环境, 将客户虚拟机运行于该执行环境中。但TCCP尚未实现其方案的原型系统, 并且该方案需要依赖第三方信任代理。Overshadow[16]设计了一种mutli-shadowing机制, 该机制为物理内存的提供不同视图(view)。 具体而言, Overshadow为应用程序提供其内存页的明文视图, 而为客户操作系统提供加密视图, 其目的在于保护客户操作系统内运行的应用程序的机密性和完整性。然而, Overshadow机制中的加密计算过程都是在内存中完成, 用于加密的密钥也存储在内存中。换句话说, Overshadow也不能抵御内存快照攻击。
Intel SGX[17]是Intel CPU的一套指令集扩展, 它提供硬件支持的可信执行环境(被命名为Enclave)来运行受信任的代码。受信任的代码和数据驻留在受CPU保护内存区域中, 该内存区域为Enclave Page Cache(EPC)。SGX仅允许在Enclave中执行的受信任代码访问EPC。EPC内存区域受硬件加密引擎(Memory Encryption Engine)保护。即使是不受信任的操作系统或虚拟机管理程序(Virtual Machine Monitor, 也称作 Hypervisor)也不能破坏受硬件保护的Enclave。理论上, 内存快照攻击对SGX无效, 但将SGX应用到云平台时会存在一些限制, 主要有以下几个方面。a) 内存资源限制。为Intel SGX保留的物理内存最多为128MB, 而实际可用的为93MB。虽然可通过在EPC和非EPC之间执行内存换入/换出来支持Enclave访问超过128MB的虚拟地址空间。但这将导致代价高昂的上下文切换(即Enclave进入/退出操作), 并导致性能显著下降[18]。b) 侧信道攻击威胁。Intel SGX无法抵御侧信道攻击(side-channel)。例如, 在基于页面错误(page fault)的侧信道攻击[19]中, 不受信任的操作系统可以通过页面错误信息推测Enclave访问内存页面的规律进而窃取敏感数据。此外, 最近的研究[20-21]表明, Intel SGX也容易受到基于缓存的侧信道攻击。c) 实际部署限制。在客户操作系统中运行SGX应用程序需要虚拟机管理程序(Hypervisor)的支持。然而, 支持SGX的开源虚拟机管理程序, 如kvm-sgx[22]和xen-sgx[23]还处在研发阶段尚不能用于实际部署支持SGX的云虚拟机。
针对上述由恶意内部人员发起的内存快照攻击(Memory Dump Attacks), 本文提出并实现了一个名为HCoper(Hypervisor Cryptographic operations outside RAM)的解决方案, 该方案在内存外部执行加密算法, 整个加密运算过程仅在CPU内部完成, 只涉及CPU寄存器和缓存(Cache)的使用, 进而使得整个加密计算过程中不会将任何机密数据(如数据加密密钥)或中间结果导出到系统内存中。从而使得内存快照攻击无法从内存镜像文件中恢复出数据加密密钥。此外, HCoper不受侧信道攻击的影响(将在第6.2节中讨论), HCoper可方便地部署, 而无任何内存限制。具体地, HCoper采用一种通用的key-encryption- key结构, 主密钥存储在寄存器中, 数据加密密钥由主密钥加密后以密文状态存储在RAM中。本文中的主密钥特指用于加密其他密钥的密钥, 主密钥不用于数据加密用途。相应地, 数据加密密钥(也称加密密钥)特指用于数据加密用途的密钥, 数据加密密钥是主密钥加密的对象。执行加密(或解密)计算任务时, 密文状态的数据加密密钥会被动态解密后直接加载到寄存器中, 使得明文态的密钥永远不会被加载到RAM中。存储主密钥或数据加密密钥的寄存器属于特权资源, 只允许HCoper对其进行访问。对这些寄存器的任何读写操作都将被HCoper捕获并拦截(见4.2节)。此外, HCoper提供动态调度密钥的机制, 以支持多应用多密钥场景。
本文利用Intel AES-NI[24]机制实现了HCoper的原型系统, Intel AES-NI支持在CPU内完成加密算法(即AES)。特别地, HCoper将主密钥存储在MSR寄存器(即x86 Model Specific Registers)中。当HCoper运行时, 数据加密密钥临时加载到调试寄存器(Debug Registers)中完成加密运算。HCoper以一个内核模块的形式集成到开源虚拟机管理程序Xen[25]内核中, 并为客户虚拟机提供加密接口。理论上, 其他虚拟机管理程序(如kvm[26]也适用于HCoper。此外, 本文已经将HCoper提供的加密接口集成到OpenSSL库中, 以便于开发第三方应用程序。本文在Intel Core i7 4790 CPU上运行并评估HCoper原型系统。实验结果表明, HCoper能够有效防御内存快照攻击。与原始的加密实现方案(OpenSSL)相比, HCoper具有良好的加密运算性能。同时, HCoper对并发型应用程序性能的影响很小(不影响实用性)。
内部人员攻击通常指由内部人员滥用组织给予的信任和权力实施的非法活动[9], 如窃取、窥探用户隐私数据等。例如, 恶意的云平台运维人员(Cloud Operator)可能会实施精心策划的攻击, 以窃取客户的敏感数据。这种攻击通常比较隐秘且难以察觉, 但极具破坏性, 因为运维人员通常对云平台中不同的系统有着不同级别的访问权限, 并且他们对云平台的基础设施部署情况有比较详细的了解, 这使得恶意运维人员可以更加容易地实施窃密攻击。相对而言, 外部攻击者则需要花费很长时间才能探查出云平台基础设施的部署情况。
正如文献[10]所述, 恶意内部人员可以很轻易地破坏客户虚拟机内部数据的机密性而不需要实施任何高超的渗透手段。其中, 比较简单却有效的攻击手段通常是从客户虚拟机内存快照或内存镜像文件中提取敏感数据。实施此类攻击时, 恶意内部人员通常通过执行一些Hypervisor提供的管理指令(如Xen提供的“xl save”指令)先获取目标虚拟机的内存快照(Memory Dump)。接着, 可以使用简单的文本分析工具从内存快照文件中提取隐私数据(如明文口令等)。更进一步, 攻击者可以使用类似冷启动攻击[27]中介绍的攻击手段或工具从客户虚拟机内存快照文件中恢复出加密密钥, 如AES的加密密钥。文献[27]已证实可从内存快照文件中恢复出AES加密密钥。
在虚拟机克隆攻击[9](IaaS VM Cloning Attacks)中, 客户虚拟机本质上也是存储在磁盘上的文件, 可能会被备份、复制或转移到其他服务器上。相应地, 恶意内部人员可能会复制客户虚拟机对应的镜像文件, 并在外部私有的Hypervisor上重新加载和启动该虚拟机。利用暴力破解工具获得虚拟机登录口令后, 进入克隆虚拟机中窥探用户隐私数据。类似的, 针对DaaS(Data Storage as a Service)场景, 恶意内部人员可能会滥用权限非法访问客户文件, 再借助一些取证技术或工具从文件中盗取隐私数据(如口令, 密钥等), 此类攻击被称作DaaS File Copying Attacks[9]。本文将重点关注内存快照攻击(Memory Dump Attacks), 虚拟机克隆攻击(VM Cloning Attacks)和DaaS File Copying Attacks这三类攻击。
文献[28]分析了不同级别管理人员及其所对应的潜在安全威胁等级。文献[9]讨论了不同类型的内部攻击向量以及不同类型的恶意内部人员。针对恶意内部人员带来的安全威胁, 一些研究者提出基于内部人员行为分析来检测和识别内部威胁。如基于图的分析(Graph-based analysis)方案[12], 主动分析(Proactive analysis)方案[13]和蜜罐(Honeypot)分析方案[11]等。文献[14]通过记录系统调用(System call analysis)活动来分析用户行为特性进而检测出恶意内部人员实施的异常行为。在文献[29-30]中, 类似的度量和策略, 如心理分析(Psychological Profiling)、用户分类(User Taxonomy)被用于预测和检测潜在的恶意内部人员。在文献[31]中, 击键动态技术(keystroke dynamic technology)被用来检测恶意的内部人员。
TCCP[15]设计一个可信的云计算平台(trusted cloud computing platform, 简称TCCP), 使IaaS服务提供商能够为客户的虚拟机提供一个封闭的执行环境。即使IaaS服务提供商的管理人员也无权访问客户虚拟机内部的机密执行环境。然而, 该方案仅从理论层面提出TCCP构想, 并未实现原型系统。此外, TCCP需依赖于第三方可信机构。文献[32]得出结论: 将技术与有效的管理策略相结合才是缓解内部威胁的最好的解决方案。文章建议管理员在执行任何操作之前必须向参与管理的其他k个管理员提交申请许可。只有其他k个管理员都许可该操作时才能继续往下执行。但该方案需要较长的时间来响应客户的请求。
Fog Computing[33]利用诱骗信息(decoy information)技术对恶意内部人员进行虚假信息攻击(disinformation attacks), 使得攻击者无法区分出真实的敏感数据和虚假无用的数据。MyCloud[34]提出一种新的虚拟化架构削减云服务提供商的管理特权, 使控制域虚拟机(类似于Dom0)没有访问其他客户虚拟机资源(如内存)的特权。此外, MyCloud还提供了一个访问控制矩阵, 供客户根据需要配置隐私策略, 该矩阵定义了能够访问虚拟机的实体。理论上, MyCloud可以抵御内部威胁, 但MyCloud不具备和Xen一样的实用性。
表1将HCoper与其他现有的针对云环境内部威胁的缓解方案进行了比较。本文主要关注第2.1节中描述的三种类型的内部攻击(Memory Dump Attacks, VM Cloning Attacks, DaaS File Copying Attacks)。如表1所示, HCoper可以有效防御此三种内部攻击。此外, HCoper是一种适用于云平台的实用性解决方案。虽然TCCP[15]可以抵御这三类内部攻击, 但其无原型系统并需依赖第三方机构。MyCloud[34]实用性较弱。其他基于策略的[29-30,32]方法、行为分析方法[12-14,31]或基于蜜罐的[11]方法均专注于检测恶意内部人员, 但它们无法抵御内存快照攻击。
表1 三种典型攻击向量下的现有缓解方案对比 Table 1 Comparison of Mitigation under Three Attack Vectors
为了防御冷启动攻击[27], TRESOR[35]、AESSE[36]和Amnesia[37]通过将AES密钥存储在寄存器中来增强全盘加密的安全性。值得注意的是, 冷启动攻击本质上也是内存快照攻击。Copker[38]使用受TRESOR[35]保护的AES密钥作为主密钥来加密RSA的私钥, 并在CPU缓存中实现RSA算法。PRIME[39]与Copker类似, 它在AVX[40]寄存器中完成RSA中安全敏感(Security-sensitive)的操作, 将不影响安全性的中间值保存在RAM中, 实现一种memory-less的RSA方案。Mimosa[41]通过使用Intel TSX[42]机制进一步增强Copker的安全性, 以确保一旦检测到攻击者试图读取Cache中的密钥, 敏感数据将被自动清除。Mimosa的目的是阻止恶意线程窃取CPU缓存中的私钥。
基于寄存器的AES实现方案容易受到基于DMA的高级攻击[43], 这些攻击可以将恶意代码注入操作系统内核中, 然后访问存放密钥的寄存器。但是, BARM[44]提供了一种检测基于DMA的攻击的方法。另外, 还可以通过配置IOMMU[45]和SMM[46]来防御高级DMA攻击。
PixeValut[47]在GPU中执行整个加密计算过程, 所有敏感数据都存储在GPU的缓存和寄存器中。保证CPU上运行的恶意进程无法访问GPU上的数据, 即使恶意的或被攻陷OS内核也无法窃取任何敏感数据。CaSE[48]利用ARM处理器的TrustZone[49]技术创建了一个基于缓存的独立执行环境。将加密算法(例如, AES、RSA、SHA1)运行在该独立的执行环境中。CaSE能有效地防御软件级和硬件级内存泄漏攻击(如冷启动攻击)。
上述现有工作均主要集中在个人计算机或移动设备上实现抵御内存攻击的加密运算, 均需要进一步的扩展和改进, 因此无法直接适用于云计算平台。
如文献[50]所述, 云平台中的管理任务主要由三个不同组别的成员完成:
(1)云平台管理员(Cloud Administrator): 云管理员通常是云服务提供商指定的极少数高级别员工(人数少, 易受监控)。云服务提供商授予其配置、初始化和启动云平台的权限。云管理员负责创建云平台服务条款, 并监管、审查服务条款的执行情况。
(2)云平台运维人员(Cloud Operator): 云运维人员负责完成来自用户的配置请求(例如, 创建虚拟机等)。云运维人员负责管理和维护云平台的日常运营工作, 例如, 解决在资源调配或虚拟机运行过程中发生的错误。更重要的是, 它们通常代表客户执行一些敏感操作, 例如, 当执行云平台故障修复任务时, 云运维人员可能会暂停, 终止, 重启虚拟机; 该过程中会伴有获取和恢复虚拟机快照等操作。通常云运维人员的数量远超过云管理员的数量, 这使得云服务提供商难以监督所有云运维人员的日常操作行为。
(3)云用户(Cloud User): 或云租户, 他们向云服务提供商申请虚拟机资源, 并使用云服务提供商提供的用户管理接口来管理分配给他们的任何虚拟机。
显然, 我们可以区分受信任的云管理员和不受信任的云运维人员。云服务提供商通常只会委派少数且可信云管理员进行初始化云平台。云管理员最能代表云服务提供商的利益。通常云管理员(即代表云服务提供商)有责任保护客户的隐私, 以维护企业良好的形象和声誉。本文假设云平台管理员为可信的, 不会主动实施内存快照攻击。然而, 云平台启动结束后云平台运维工作交给其他运维人员, 云运维人员不可信且数量通常较多, 甚至运维工作可能会被外包给第三方人员。因此, 数目众多的(难监控的)云运维人员可能会恶意实施内存快照攻击, 窃取客户虚拟机中的敏感数据。本文主要目标是防御恶意云运维人员发起的内存快照攻击。
云运维人员通常有机会访问云平台设施(如Dom0), 其可能会有意滥用职权执行违规操作从而对云平台的保密性和完整性产生负面影响。例如, 借助专业工具, 如aeskeyfind[27], 从客户虚拟机的内存快照文件中提取隐私数据(如口令, 密钥等)。此外, 远程攻击者也有可能对客户虚拟机发起类似的内存攻击, 他们通常利用虚拟机管理程序的软件漏洞来攻击客户虚拟机, 然后对整个客户虚拟机的内存数据或者某一个受害进程作内存快照, 以从内存快照文件中提取敏感数据。此外, 硬件平台(如CPU)的漏洞也可能为攻击者提供一种可行的方法来转储(Dump)整个系统内存。如针对Intel CPU的meltdown[51]漏洞, 攻击者可以利用该漏洞转储系统内存以窃取隐私数据。
本文假设Hypervisor具备代码完整性, 且无任何漏洞可供攻击者利用以执行恶意代码来破坏Hypervisor的内核。本文假设恶意的云运维人员(其职责如第3.1节中所述)能够执行常规的维护管理shell命令(例如“xl save”)。此外, 本文还假设在密钥初始化期间(很短的时间), 整个Hypervisor系统都是安全的。在此期间, 获得云服务提供商授权的云管理员会初始化HCoper的主密钥和密钥。一旦密钥初始化完成, 即使在特权域(Dom0)内安装rootkit也无法窃取密钥。这是因为Dom0内核的CPU权限级别比Hypervisor低。因此, Dom0内核中的rootkit不可能篡改Hypervisor的内核内存(例如, hook超级调用表)。据本文所知, 在不利用Hypervisor内核漏洞的情况下无法直接将rootkit安装到Hypervisor(如Xen)中。而如何挖掘和修复Hypervisor的漏洞超出了本文的研究范围。
云平台场景中, 攻击者对云虚拟机作内存快照, 内存快照通常是无语义信息的二进制数据, 攻击者需要还原出二进制数据的语义信息才可获取到有价值的信息(如加密密钥等)。再次, 攻击者通常不会无休止地对云虚拟机作内存快照, 这一方面增大攻击成本(时间开销和存储开销), 另一方面, 频繁的内存快照操作容易暴露攻击行为。相反, 加密计算过程(如AES算法)通常表现出固定的规律, 加密算法使用的参数、密钥等会以某种特定的格式存储在内存中, 这使得攻击者能以可接受的攻击成本恢复出加密密钥的语义信息, 如文献[27]中根据AES加密密钥在内存中存储的特定规律和格式成功从内存快照中恢复出AES密钥。因此, 窃取加密密钥成为攻击者的首选目标。此外, 从云用户的角度来说, 通常采用加密处理(如加密传输)的数据都是少量但重要的隐私数据, 一旦攻击者获取到加密密钥, 再辅以其他攻击手段可获取到更多的隐私数据(如网站的登录凭证等)。因此, 针对云平台环境, 密钥泄露对云用户造成的破坏性更大。
为保护客户虚拟机在执行加密运算时, 其使用的加密密钥不被窃取。首要的设计目标是确保主密钥和加密密钥在任何时候都不会被加载到系统内存(RAM)中。此外, 加密计算过程中的中间结果也不能出现在RAM中。本文提出的方案中, 将主密钥永久存储在CPU寄存器中, 而加密密钥和计算过程的中间状态都只是临时暂存在寄存器中。然而, 虚拟化平台(如Xen)通常会允许虚拟机之间共享硬件资源, 目前Xen的实现方案默认允许虚拟机直接访问CPU的寄存器(如Debug寄存器)。因此, 另一个设计目标需要防止客户虚拟机(包括特权域Dom0)访问存储着密钥的寄存器以窃取密钥。总体而言, HCoper的目标是为云租户提供一个通用、高效的加密计算服务, 同时保证该加密运算服务使用的密钥不会被攻击者(特别是恶意内部人员)窃取。基于上述目标, HCoper的设计需要满足以下几个要求(准则):
(1)在执行数据块加密运算(通常是最小的加密运算执行单位)时, 该运算过程不能被中断。否则, 很可能在执行进程调度的过程中, 在将进程状态(包括寄存器状态)导出(swap)到RAM中时也将密钥或运算的中间结果导出到RAM中, 从而导致密钥被窃取。
(2)针对多核(multi-core)CPU, 同一个加密进程可能会被调度到不同的核(core)上去执行。而不同的CPU核内部维护着不同的寄存器状态。因此, 需要确保当同一个加密进程不同时刻运行在不同的CPU核上时, 其加密运算使用的加密密钥仍保持一致。
(3)客户虚拟机可能会有意访问存储着密钥的寄存器。因此, 需要确保客户虚拟机访问保存有密钥的寄存器的行为能被捕获并拦截。
为了满足原则(1), HCoper的块加密计算必须在 一个原子域中运行, 在该原子域中将暂时禁用所有中断, 并暂时禁用CPU抢占。同样, 加密密钥的加载和调度也需要放置在原子域中执行, 以确保数据加密密钥不被泄露, 同时保证在执行块加密之前数据加密密钥正确无误地被载入到寄存器中。需注意的是, 块加密运算(最小加密运算执行单位)通常很小, 如AES为16字节(128bit), 块加密计算的原子域是在极短暂的时间内完成, 完成块加密计算后会立即恢复中断和CPU抢占, 而不是在运行整个加密进程的过程中都禁用CPU抢占和中断。块加密(原子操作)计算完成后恢复中断和CPU抢占, 使得加密进程和其他进程一样处于同等的地位, 系统执行进程调度算法正常调度进程(包括加密进程)获取CPU执行权限, 对系统内其他进程的影响很小。在下一节(第3.4节)中, 将介绍满足原则(2)的设计细节。满足原则(3)所使用的技术实现细节将在第4.2节中给出。
如图1所示, HCoper主要由五个组件构成。同时, HCoper是一个三层模型结构: 用户层(User Space), 虚拟机内核层(Guest Kernel)和虚拟化平台层(Hypervisor)。位于用户层的应用程序通过ioctl接口将数据加密请求提交给虚拟机内核中的gCoper(guest Coper)模块, gCoper模块负责将接收到的加密请求通过调用Coper提供的超级调用(hypercall)接口提交给Hypervisor内核中的加密模块Coper。Coper模块在CPU内部完成相应的加密计算任务。HCoper的执行流程主要分为两个阶段: 初始化阶段(initialization phase)和数据加密阶段(data-encryption phase)。
图1 HCoper系统架构图 Figure 1 The Architecture of HCoper
在初始化阶段, 获得云服务提供商授权的云平台管理员在特权域(Dom0)中临时安装Key Initializer模块, 该模块的主要功能是负责接收管理员输入的长字符串(如password)并将该password提交该Hypervisor内核中的Key Generator模块。Key Generator模块利用收到的password生成主密钥和数据加密密钥。具体地, Key Generator首先生成主密钥, 并立即将主密钥加载到MSR寄存器中。HCoper中只有一份主密钥用于加密解密其他数据加密密钥, HCoper中维护着多个加密密钥(理论上加密密钥个数不受限制)。接着利用再次收到的password生成加密密钥, 加密密钥将会被主密钥加密后以密文的形式存储在系统内存(RAM)中。HCoper支持多应用多密钥场景, 因此在初始化阶段云管理员会输入多次password并相应的生成多个数据加密密钥。值得注意的是, 密钥初始化工作是在一个很短的时间内完成, 本文假设在此短暂的初始化期间, 整个Hypervisor平台是安全的。另外密钥的初始化工作通常在系统启动期间完成(即Boot阶段), 在此期间云平台管理员通过外设输入password, 在此短暂期间内password会暂留RAM, 一旦根据password生成主密钥或数据加密密钥后, RAM中的password会被彻底清除。密钥初始化阶段通常是Hypervisor平台的启动阶段, 此时平台尚未启动完成, 云虚拟机尚未启动, 通过云虚拟机的攻击在此阶段无效。此外, 系统启动工作尚未结束使得无法实施内存快照攻击, 因为内存快照执行过程中需要调用Hypervisor向外提供的接口。
Key Initializer模块是云平台管理员临时安装到Dom0中的, 只有云管理员有权限使用该模块。该模块调用Key Generator提供的隐式hypercall完成密钥的初始化工作, 该hypercall不对外公开, 即云运维人员不知道该hypercall的任何细节。需注意的是, 该hypercall每次被调用时都会先执行合法性验证, 验证调用者是否运行在特权域(Dom0)中, 如果是非特权域的调用则直接拒绝, 若是来自特权域的调用还需要进一步判断调用者是否是Key Initializer模块, 具体地当Key Initializer模块调用隐式hypercall时, HCoper能捕获到调用者EIP寄存器信息, 进而可以获取调用者执行hypercall时, 控制流上下文信息, HCoper预先保存了一份Key Initializer调用该隐式hypercall时的控制流上下文信息, 每次都以同样的方式获取调用者执行hypercall时的控制流上下文信息, 然后再进行对比(匹配)进而判断调用者是否是Key Initializer模块。云管理员后续可以随时在重新安装Key Initializer模块更新主密钥和数据加密密钥。另外, 在完成密钥初始化工作之后, Key Initializer模块会被从Dom0中卸载并移除。Key Generator模块生成密钥时, 对收到的password执行一定次数(在本方案中至少计算2000次)的SHA-256哈希计算后获得的摘要值(digest)作为最终的密钥。HCoper将主密钥存储在原本用于硬件性能计数[52](hardware performance counter)的MSR寄存器(涉及4个MSR寄存器)中。本文选择该组MSR寄存器时主要考虑到硬件性能计数特性并不是大多数软件必需依赖的特性。存储主密钥仅占用4个用于硬件性能计数功能的MSR寄存器而不是所有的MSR寄存器。另外, 部署在云场景中的业务很少使用该组MSR寄存器, 在云虚拟机内部进行性能评测(如, 评测虚拟机内程序运行时间开销)是不推荐的。这是由于云虚拟机运行在Hypervisor之上, 云虚拟机占用的资源均由Hypervisor调度, 云虚拟机性能受云平台整体负载情况的影响。因此, 即使HCoper关闭了硬件计数功能也不会对大多数软件的正常运行造成影响。数据加密密钥的初始化过程和主密钥基本一致, 不同点在于生成主密钥后直接加载到MSR寄存器中, 而数据加密密钥生成后先被主密钥加密后以密文形式存储在系统内存中。只有在执行加密运算时才会被解密后加载到Debug寄存器内(该加载过程是寄存器之间的数据拷贝行为, 不涉及内存的读写)。数据加密密钥的解密过程也是在CPU内部完成, 因此, 不会造成密钥泄露的风险。HCoper同样独占了Debug寄存器, 使得硬件调试功能被禁用, 软件调试功能不受影响。对于大多数软件来言, 硬件调试也不是必需的功能, 因此, HCoper并不会破坏大多数软件的兼容性。总体而言, HCoper的密钥初始化工作可以简要的归纳为三个步骤, 如图2所示: (1)Key Generator利 用password生成主密钥(master key)并立即将其载入MSR寄存器; (2)Key Generator利用再次收到的password生成数据加密密钥, 接着使用MSR寄存器中的主密钥对数据加密密钥进行加密处理; (3)密文态的数据加密密钥被存储到系统内存中。
图2 密钥初始化 Figure 2 Initialization of Keys
数据加密阶段, 用户层应用程序通过ioctl接口提交加密请求, 该请求中包含待加密明文的内存地址, 密文存储地址以及所使用的加密密钥标识符。HCoper对每个加密密钥都用唯一的key-id进行标识。gCoper将加密请求提交该Coper模块后, Coper根据key-id载入对应的数据加密密钥并完成相应的加密运算。数据加密密钥的载入与调度工作实际上是由Key Scheduler模块完成。
加密密钥调度, 为了支持多应用多密钥场景, Key Scheduler模块维护了一个加密密钥使用记录列表。该列表记录了最近被使用过的加密密钥, 列表记录的只是加密密钥对应的key-id, 而列表的索引值为CPU核序号(core-id)。例如, 某一时刻, CPU 核2上运行的加密进程使用的加密密钥的key-id为3, 则该列表中索引值(或下标)为2的元素值为3。当在处理某个加密请求时, Key Scheduler首先需要获取当前加密进程所在的CPU核的core-id, 然后以此core-id为索引到列表中进行查询获得最近被载入到该CPU核上的加密密钥的key-id(记为L-key-id)。再将L-key-id与用户提交的加密请求中指定的加密密钥的key-id(记为R-key-id)进行对比。若L-key-id与R-key-id一致, 则直接使用该CPU核中存留在Debug寄存器中的加密密钥, 需注意的是, 为了减少从系统内存解密并载入加密密钥的次数, 存储在Debug寄存器中的加密密钥在加密运算任务结束后依旧存留而不会被清除。若L-key-id与R-key-id不一致, 则需要使用MSR寄存器中主密钥解密系统内存中的密文态的加密密钥, 并将解密后的加密密钥直接载入Debug寄存器。由于整个解密(或加密)运算过程都是在CPU内部完成, 具体而言, 均使用CPU内存的寄存器来暂存密钥、中间状态值以及最后的解密结果都是暂存在寄存器中。因此, 解密后的加密密钥也是暂存在寄存器中, 在将其载入Debug寄存器时也仅仅是寄存器之间的数据拷贝而不会涉及任何内存读写操作。因此, 解密后的加密密钥被直接拷贝到Debug寄存器而不会泄漏到系统内存中。
图3简要地归纳了数据加密阶段中的密钥调度过程: 1)当L-key-id和R-key-id不一致时, Key Scheduler模块使用MSR寄存器中的主密钥解密加密密钥。加密密钥的密文存储在RAM中, 本质上是一个密文列表, 使用key-id(如R-key-id)为索引载入对应加密密钥的密文。2)解密后的加密密钥被直接载入Debug(简记为db)寄存器, 该过程不涉及任何内存读写操作。3)Coper完成最后的加密计算任务, 从内存中载入待加密数据(Input), 将加密结果写回内存中(Output)。在完成加密计算后, Coper会将计算过程中使用到的寄存器(如Streaming SIMD Extensions[53], 简称SSE)的状态值都清零, 只保留Debug寄存器中加密密钥以备下一次使用。
图3 动态密钥调度 Figure 3 Dynamic Scheduling of Keys
本文基于开源虚拟化平台Xen 4.4.0实现HCoper原型系统。HCoper利用Intel AES-NI指令集在CPU内实现加密计算, 利用x86架构的调试寄存器(Debug Registers)存储数据加密密钥, 利用MSR寄存器存储主密钥。Intel AES-NI利用SSE[53]寄存器存储加密密钥、中间状态和AES轮次密钥, 从而确保不会将任何中间状态或密钥加载到RAM中。HCoper通过超级调用(hypercall)机制向客户虚拟机的内核提供加密计算服务。客户虚拟机的用户空间进程通过ioctl接口调用加密计算服务。本文已将ioctl接口集成到openssl-1.1.0g[54]和polarssl-2.6.0[55]中, 作为通用API为其他第三方应用程序提供开发接口。
超级调用(hypercall)是从虚拟机到Hypervisor的软件级陷入(software trap)操作。虚拟机通过超级调用请求特权操作(例如, 更新页表等)。类似地, HCoper为虚拟机内核提供了两个超级调用, 用于调用加密和解密服务。在Xen的实现中每个超级调用都有全局唯一的超级调用号与之对应。相应的, 在HCoper的实现中, 在Xen内核中扩展了两个超级调用, 其超级调用号分别为41、42。此外, HCoper还定义了用来封装加解密请求的结构体, 如下图所示:
图4 加密请求结构体 Figure 4 Structure of Encryption Request
用户层应用程序需要将加密请求封装为该结构体, 再提交到HCoper内部。其中src表示待加密(或解密)的数据, dst用于存储加密(或解密)的结果, msglen指示待加密(或解密)的数据大小, key-id指明本次加密计算所使用的加密密钥。
HCoper作为Hypervisor的一个内核模块运行, 因此, 位于上层的客户虚拟机访问MSR寄存器或Debug寄存器的行为均能被HCoper捕获并拦截, 以保证主密钥和加密密钥不会被客户虚拟机窃取。Intel虚拟化机制(Intel VT)允许在Hypervisor层定义敏感操作, 当上层客户虚拟机执行敏感操作时会陷入(trap)到Hypervisor内核中, 即执行权限被转交给Hypervisor。例如, 客户虚拟机读写CR3寄存器以更新页表为典型的敏感操作。在虚拟化场景下客户虚拟机也需要Hypervisor的辅助才能访问物理内存。因此, 更新CR3须陷入到Hypervisor中进行处理。具体地, Intel VT虚拟化技术提供虚拟机执行控制域字段[56](VM execution control filed)来定义敏感操作。HCoper通过该字段将MSR寄存器和Debug寄存器的访问操作定义为敏感操作, 当客户虚拟机访问这两组寄存器时被HCoper截获。具体过程如下:
(a)对于Debug寄存器, 将VM execution control 字段上MOV-DR标志位设置为1, 使得虚拟机执行mov指令读写Debug寄存器时, 触发VM-exit事件陷入到Hypervisor内核, HCoper处理该事件并阻止访问Debug寄存器。
(b)类似的, 在VM execution control字段上将RDMSR和WRMSR标志位设置为1, 截获上层虚拟机访问MSR的行为。
(c)针对半虚拟化场景, 不能使用上述步骤中的方法。本文修改(patch)了Hypervisor(即Xen)中原本用于访问MSR寄存器和Debug寄存器的超级调用, 将对MSR寄存器和Debug寄存器的读写操作重定向到一块固定内存区域, 使得半虚拟化虚拟机不能读写真实的硬件寄存器, 从而保证密钥的机密性。
本节首先进行有效性验证实验, 以证明恶意的云运维人员(Cloud operator)在HCoper执行加密计算期间无法从内存快照文件中恢复出加密密钥和主密钥。然后, 本节通过比较OpenSSL-1.1.0g中的原始加密函数与HCoper实现的加密函数之间的性能差异来评估HCoper的实用性。本次实验环境部署在Intel Core i7 4790 CPU(8核)的工作站上, 其运行的Hypervisor为Xen 4.4.0版本。
HCoper的加密接口被集成到三个常见的加密库中: GnuPG 1.4.22[57]、OpenSSL-1.1.0g[54]和polarssl-2.6.0[58]。安全功能验证实验主要分为3个步骤: (1)首先, 在实验虚拟机内部执行这三个加密工具中的AES加密函数对测试文件进行加密(解密)操作, 在执行加密函数的过程中, 在特权虚拟机(Dom0)中执行“xl save”命令获取实验虚拟机的内存快照; (2)使用文献[27]中的aeskeyfind工具从内存快照中提取AES加密密钥; (3)在实验虚拟机内执行HCoper加密计算进程, 同时在此期间获取虚拟机快照, 再次使用aeskeyfind工具从内存快照中尝试提取AES加密密钥。
此外, 本节中还模拟了外部攻击者获取客户虚拟机内存快照并从内存快照中恢复出AES加密密钥。本次模拟外部攻击者实验中, 在虚拟机中运行加密计算进程时, 通过虚拟机内部的/dev/mem设备接口来获取虚拟机的内存镜像, 再使用同样的工具尝试从内存快照中提取AES加密密钥。两个实验的结果均一致表明攻击者(内部或外部攻击者)无法从内存快照中获取HCoper使用的主密钥和加密密钥, 而运行常规加密库中的原始加密函数时能成功从内存快照中恢复出加密密钥, 实验结果如表2所示。另外,
表2 密钥恢复结果对比 Table 2 Comparison of Recovering Keys
由于HCoper使用的密钥不会存在于内存中, 也不会出现在虚拟机镜像文件和普通的文件中, 进一步表明了HCoper不受冷启动攻击(Cold-boot)、VM克隆攻击(VM Cloning)和DaaS文件复制攻击(DaaS File Copying)的威胁。
图5 总时间开销 Figure 5 Real Time Overhead
系统时间开销(sys time)是指某个进程在内核态(内核模式)中执行的时间。如图6所示, openssl-xen- aes-ni的内核态执行时间开销明显高于openssl-ecb- aes。当加密同一个文件(例如900MB)时, openssl-ecb- aes(2.1248s)在内核模式下的平均开销仅为openssl- xen-aes-ni(6.9544s)的30.6%(2.1248/ 6.9544)。这可以归因于HCoper大部分加密计算操作是在Hypervisor的内核中执行的。仅有少部分的操作是在用户模式下完成, 比如用户层应用程序简单地构造加密请求, 然后将加密请求提交给客户操作系统内核。此外, 从图6中还可以看到, 随着文件大小的持续增长, openssl-xen-aes-ni的系统时间开销相比于openssl- ecb-aes增长速度要较快些。
图6 系统时间开销 Figure 6 Sys Time Overhead
相应地, 实验结果还表明 openssl-xen-aes-ni的用户态时间开销(即在用户模式下的开销)比openssl-ecb-aes低很多, 并且openssl-xen-aes-ni的用户态时间开销几乎不随文件大小的增加而增长, 如图7所示。对于相同大小的文件(例如, 100MB), openssl-xen-aes-ni(0.042s)在用户模式下的平均开销 仅为openssl-ecb-aes(0.6588s)的6.4%(0.042/0.6588)。这与我们所期望的一致, 内核模式时间开销越高, 用户态时间开销越低, 两者的总和即是总时间开销(real time)。总之, 尽管openssl xen-aes-ni(或HCoper)的平均内核模式时间开销要高于openssl-ecb-aes, 但openssl-xen-aes-ni的整体加密运算性能甚至比openssl-ecb-aes要快一点。换言之, HCoper的加密运算效率与OpenSSL库中的加密实现方案一样具备实用性。
图7 用户态时间开销 Figure 7 User Time Overhead
5.2.2 并发性能影响评估
由于HCoper在执行块加密计算期间, HCoper会短暂地禁用CPU抢占, 因此被分配到同一CPU核上运行的其他任务的性能可能会受到影响。本次实验使用SysBench[60]工具来衡量HCoper短时间独占CPU核对其他并发型应用程序造成的影响, Sys-Bench是一个通用的系统性能(如内存访问速度, CPU运算性能)度量工具。本节实验部署时先将HCoper集成到Apache Web服务器中, 具体地, 在PHP文件中调用HCoper执行加密运算。在客户机端, 本次实验启动了多个客户线程来并发地提交加密8KB数据的请求。在服务器端(HCoper和SysBench都运行在服务器端, 即同一台机器上), 使用SysBench启动4个线程向本地CPU核发出10K个请求, 每个请求都涉及高达40K的素数计算, 即求出40K个素数。我们收集了当客户端线程以不同的速率(requests/second)发出加密请求时(即此时HCoper需要响应客户的加密请求), 记录SysBench(在服务器端运行)所发起的每个素数计算任务的平均运行时间。
如图8所示, 基准值(baseline)是在没有执行任何加密进程的干净环境中测量的。对于相同的加密速率(requests/sec), 相对于openssl-xen-aes-ni而言, 原来的openssl-ecb-aes对Sysbench启动的素数计算进程性能的影响较低一些, 但实验结果表明, HCoper对其他并发型应用程序性能造成的影响是可以接受的。例如, 当加密速率为 400(requsets/sec)时, openssl-xen-aes-ni导致执行素数计算任务的并发进程的性能下降了1.8%, 而openss-ecb-aes导致素数计算性能下降了1.3%。相比之下, openssl-xen-aes-ni带来的并发性能影响和openssl-ecb-aes造成的并发性能影响还处于同一个数量级(仅高了0.5%)。这主要是因为当HCoper执行块加密运算时, 它将暂时地禁止CPU抢占, 使得CPU密集型的运算任务的性能会受到影响。然而实验结果表明, 与openssl-ecb-aes相比, HCoper引起附加开销是可以接受的, 即不影响实用性。
图8 对并发型程序的性能影响 Figure 8 Impact on Concurrent Processes
如第5节所示, 实验结果已验证了HCoper的功能正确并且在执行加密运算时不会将加密密钥泄漏到RAM中。在本节中, 本节将分析HCoper针对Hypervisor级攻击的防御能力。然后讨论HCoper可能会面临的来自硬件层面的攻击方式以及相关防御措施。
HCoper的安全性基于Hypervisor安全可靠的假设之上。然而在真实的云环境中, Hypervisor不可能没有任何安全缺陷。不可避免地, 攻击者可能会利用Hypervisor的漏洞窃取密钥。例如, 在虚拟机逃逸攻击[61]中, 攻击者可以使用虚拟机逃逸漏洞向Hypervisor的内核中注入恶意代码, 然后设计精妙的攻击手段(如ROP)来执行恶意代码。由于恶意代码与Hypervisor内核的执行权限级别相同, 因此攻击者可以轻松读取或写入寄存器(即Debug或MSR)以获取密钥。类似的, 利用XSA-148[62]漏洞利用也能实现任意读取和写入Xen的物理内存。此外, 恶意的半虚拟化客户虚拟机中可以通过此漏洞篡改(Hook)Xen内核中的超级调用表(hypercall table), 进而实现在Hypervisor内核级别执行任意代码[63]。本文使用最新的安全补丁来提高HCoper对抗Hypervisor内核级别攻击的能力。如何增Hypervisor内核的安全性以及发现Hypervisor的漏洞超出了本文的研究范围。
云服务提供商内部的恶意运维人员(Cloud operator)可能会有机会物理接触到部署云计算平台的物理机器。考虑一个简单的场景: 恶意运维人员有可能使用恶意启动设备(例如, 外部USB启动设备)重新启动计算机, 以读取CPU内部寄存器(例如, DR和MSR)中残存的数据内容。幸运的是, 这种攻击是无效的, 因为在重新启动物理机器时, CPU内部的所有寄存器都将被重置为零[35]。
基于CPU缓存(Cache)的侧信道(side-channel)攻击[64-65]对很多加密系统而言的是一大安全威胁。但是这种攻击对HCoper中是无效的, 因为Intel AES- NI提供的硬件加密指令集对timing-attacks[24]免疫。即Intel AES-NI指令执行加密运算时没有表现出规律性的时间差异, 攻击者不能根据执行时间差异性逆推出加密运算执行的细节。另外, HCoper的执行控制流中没有输入依赖性(input dependent)的执行分支(branch), 使得攻击者不能使用侧信道攻击的手段(通过监控、窥探目标代码内跳转分支的执行情况, 逆推出执行分支代码时的输入值)来推测加密密钥以及加密计算得中间状态值等。因此HCoper能防御侧信道攻击。
攻击者还可能会发起基于DMA的高级攻击[43], 将恶意代码注入Hypervisor内核, 然后访问调Debug存器和MSR寄存器中的密钥。幸运的是, 我们可以通过配置IOMMU[45]或使用BARM[44]来监视系统总线活动以检测、揭露从外围设备(peripherals)访问内存的恶意行为, 从而抵御这种攻击。最后, 通过物理访问(接触)云平台中的真实机器, 恶意的内部人员(例如高级电气工程师)可能会通过使用示波器等专业设备测量CPU周围的电磁信号来变向读取正在运行的CPU的寄存器。但是这种攻击实施条件异常严苛并且实施过程高度复杂, 据本文所知, 目前暂时还没公开过这种高难度攻击手段成功的案例。如何防御此种攻击已不在HCoper研究的范围。
本文提出了一种在CPU内执行加密运算(CPU- bound)的解决方案HCoper, 目的在于保护云租户的密钥免受恶意运维人员发起的内存快照攻击。HCoper适用于真实云计算平台。同时, 所有的密码计算都在CPU寄存器内完成, 因此HCoper也不受冷启动攻击(Cold-boot)、VM克隆攻击(VM Cloning)和DaaS文件复制攻击(DaaS File Copying)的威胁。通过执行动态密钥调度, HCoper支持多个应用程序使用多个密钥。此外, HCoper已经集成到其他第三方密码库中(如OpenSSL-1.1.0g、polarssl-2.6.0、GnuPG 1.4.22), 使得开发新应用程序变得容易。HCoper原型系统作为Xen4.4.0的核心模块实现, 体现其具备实际部署价值。安全功能验证实验表明, 恶意运维人员无法从客户虚拟机的内存快照文件中提取数据加密密钥或主密钥。此外, 性能评估表明, HCoper的效率与传统的加密计算实现方案相当, 对其他并发型应用程序性能的影响在可接受范围(即HCoper带来的性能损失不足以影响其实用性)。
目前HCoper只针对Intel CPU实现了对称加密算法(AES)。理论上, HCoper的架构思想可以部署在其他类型处理器上, 只要这些处理器也提供指令集支持实现加密算法(如AES、RSA)的加密操作。将来, HCoper可以扩展到非对称加密计算(如RSA)。然而, 完全在CPU内实现非对称加密计算极具挑战性, 因为RSA计算需要更大的存储空间, 而寄存器(如SSE)暂时不支持RSA所需要的存储空间。HCoper方案比较适用于加密计算的中间变量或参数占用空间较小的算法(如AES算法等)。而其他算法(如RSA)计算过程中使用到的参数占用空间较大远超过SSE寄存器的空间, 针对此类算法, 可将一部分加密过程交给HCoper来完成或者使用HCoper来加密此类算法运行过程中重要参数达到加密密钥保护的目标, 这将是HCoper未来的优化工作。另外, HCoper基于这样一个假设: Hypervisor是安全的, 没有任何安全缺陷。另一个未来的工作可在硬件支持的可行执行环境(如Intel SGX提供的Enclave)中实现加密计算, SGX对不受信任或遭受攻击的Hypervisor发动的攻击免疫。然而, Intel SGX只为Enclave保留128M物理内存, 如何使用有限的RAM加密大文件是一个挑战。