APP下载

一种基于影子页表+ 的软件型vTPM 密钥秘密信息保护方案*

2019-07-16舒红梅

密码学报 2019年3期
关键词:客户机完整性度量

谭 良, 王 闪, 宋 敏, 舒红梅

1.四川师范大学计算机科学学院, 成都610101

2.中国科学院计算技术研究所, 北京100190

1 引言

云计算的主要目的在于帮助租户摆脱纷杂的硬件管理与维护, 实现系统资源的深度整合.通过统一管理模式提高资源利用率的同时, 满足各类租户的个性化需求.其实现方式决定了租户的数据信息势必会存储在公用数据中心, 数据的读取完全依赖于网络传输.因此, 云计算系统不仅面临着传统网络和信息系统等已有的安全问题, 还面临着由其运营特点所产生的一些新的安全威胁[1–4].其中, 云租户怎样确定云平台提供的资源和服务是安全的, 怎样确保云平台是可信的, 这是一个至关重要的问题.而可信计算是保障计算平台可信的基础手段, 它通过提供数据保护、身份证明以及完整性测量、存储与报告等功能提高计算平台整体的可信性[5].因此, 将可信计算技术融入虚拟平台已成为云安全研究领域的一大热点[6–22].

TPM (trusted platform module, TPM)是可信计算的核心, 提供平台完整性度量、远程证明、密封存储、平台唯一身份标识、硬件级的密钥保护等基本安全功能, 为可信计算提供基础硬件支撑.2009年TPM1.2 规范被接受为ISO 标准(ISO/IEC 11889)[23].TPM1.2 芯片内部是一个完整的安全计算环境, 内部结构包括低功耗的32 位RISC CPU、CPU 访问片内外围模块的通道、中断控制器(interrupt controller)、时钟发生器(clock generator)、对外IO 端口、RAM、ROM、Flash、SHA/HMAC 模块、RSA 协处理器模块、真随机数产生模块等模块, 通过LPC 总线接口放置在主板上.2014年TCG 发布了TPM2.0 规范[24], 在密码算法支持、密钥、授权、签名、平台配置寄存器PCRs、虚拟化以及芯片使用方式等方面均有些新的特点.但无论是TPM1.2 还是TPM2.0 均是一个资源受限的芯片, 其本质上是一个低速的外设.然而随着云计算的推广和普及, 云租户逐渐增多, 云平台上运行的用户虚拟机也越来越多, 云平台上的所有虚拟机和云租户都通过共享方式来使用TPM 提供的完整性度量、远程证明、密封存储、硬件级密钥保护等安全功能是很困难的, 性能上也是难以接受的.因此, 当前不少云平台在对TPM虚拟化时采用软件仿真方式, 如XEN、KVM、VMWare、VirutalBox、Hyper-V 等, 即用软件vTPM来模拟TPM 功能, 使用得到最多的TPM 模拟器是tpm_emulator.

值得注意的是, 一方面, 云平台的运行环境严重影响软件仿真型vTPM 的安全.Gartner 云安全报告中指出, 云平台的最大的安全威胁来自于特权用户对于租户隐私数据的非法访问[3], 显然软件型vTPM 运行时的密钥和证书信息也不例外.当然非特权用户也可以采用包括恶意代码注入攻击(malware injection attack)、交叉虚拟机边信道攻击(cross VM side channels attack)和定向共享内存攻击(targeted shared memory)等[2]来窃取和破坏vTPM 的密钥和证书信息, 其中恶意代码注入攻击是使用恶意实例代替系统服务实例处理正常的服务请求, 进而获得特权访问能力, 非法盗取vTPM 的密钥和证书信息; 交叉虚拟机边信道攻击是攻击者首先借助恶意虚拟机访问共享硬件和缓存, 然后执行预定的安全攻击, 最终导致目标虚拟机内vTPM 的秘密数据泄露; 定向共享内存攻击是以物理机或虚拟机的共享内存或缓存为攻击目标, 是恶意代码注入攻击与边信道攻击的基础, 结合内部攻击访问虚拟机的内存转储数据导致vTPM 密钥信息的泄露.另一方面, 即使采用硬件TPM 安全存储vTPM 的密钥信息,vTPM 在进行加解、解密、完整性验证等操作时, 也必须把vTPM 密钥信息加载到内存中, 特别在全虚拟化和硬件虚拟化平台环境中, 整个虚拟机均处于VMM (virtual machine monitor, VMM)的用户空间中, vTPM 的密钥和证书更容易遭到攻击, 这将严重影响虚拟机和vTPM 的安全.

为此,本文提出了一种基于影子页表+的vTPM 密钥秘密信息保护方案,该方案主要是在全虚拟化或硬件虚拟化平台中通过新增影子页表管理模块MMU-vTPM 来保护vTPM 的密钥和证书.MMU-vTPM包括两个部分, 其一是vTPM 密钥私有内存管理, 其二是vTPM 密钥私有内存访问控制, 该管理模块通过对vTPM 密钥私有内存页表的访问控制阻止其他进程访问和破坏vTPM 密钥私有内存.此外, 为了防止恶意用户对MMU-vTPM 模块进行篡改, 本文采用TPM 的静态度量机制和动态度量机制对该模块进行完整性保护.最后, 基于Xen 实现了该方案, 测试结果表明, 该方案能够在保证vTPM 的vEK 和vSRK 等关键密钥秘密信息的安全性, 而且不会带来严重的性能损失.

2 相关工作

可信计算技术与虚拟化技术结合的vTPM 一直以来都受到国内外学者的广泛关注.目前已经有涌现出较多研究成果[6–31].在国外, 早在2006年S Berger 等人就提出了一种软件仿真型的vTPM 架构[25].如图1 所示, 该系统架构包括vTPM、vTPM manager、Client-side TPM driver、Server-side TPM driver、TPM 等实体, 其中, vTPM、vTPM manager 和Server-side TPM driver 在特权域, Client-side TPM driver 在虚拟机域, TPM 在整个虚拟系统的底层硬件层.vTPM 为虚拟机提供大部分可信计算功能, vTPM manager 负责所有vTPM 的生命周期管理, 包括创建、挂起、恢复、删除vTPM 实例,转发虚拟机对其绑定的vTPM 实例请求并返回对应的响应, 每个vTPM 可通过vTPM manager 与硬件TPM 产生关联, 关联的内容主要包括PCR 映射和证书链扩展.Server-side TPM driver 是特权域端TPM 驱动, Client-side TPM driver 是虚拟机端TPM 驱动, Server-side TPM driver 与Client-side TPM driver 通过VMM 进行通信.文献[31]是TPM 半虚拟化的奠基之作, 后来该方向的多数研究均基于这一思路.

文献[26]也提出了TPM 虚拟化的一个通用系统架构GVTPM, 文献[25,26]的基本思路是一致的.文献[27]基于Xen 首次把vTPM 实例从特权域中分离, 但vTPM manager、vTPMD 守护进程仍然运行在Domain0.文献[28]对vTPM manager、vTPM 实例与特权域进一步分离, 将特权域中的一个重要功能——域管理功能分离出来, 基于MiniOS 构建Domain Builder 域, 简称为DomB, 并将vTPM manager 和vTPM 实例从特权域中分离到DomB.2009年, 欧盟委员会赞助的一个可信计算项目OpenTC 提出了一个有关TPM 虚拟化架构的研究报告[29], 将vTPM 基于属性的证明和迁移功能增加到vTPM 架构中, 并在Xen 平台上提出了双隔离域系统架构, 进一步分离了文献[28]中的DomB的功能.在该系统架构中包括两个域, 其一是DomB, 该DomB 与文献[28]中的DomB 类似; 其二是DomU-vTPM, DomU-vTPM 域运行vTPM 实例.除此以外, 通过隔离域来增强vTPM 安全性的文献还包括文献[11,30–34]等.这里不再一一分析.

在国内, 类似的文献出现在2010年, 文献[35]认为, 将整个特权域都看成TCB 会威胁到vTPM 的安全, 因为TCB 太大容易产生漏洞.为了解决这个问题, 文献[35]提出了一种新的vTPM 架构.通过创建一个新的管理域Dom A, 将原来在特权域中的vTPM、vTPM manager 以及TPM 原生驱动分离到管理域DomA 中.创建管理域有两个目的, 其一是使得vTPM 及其相关组件免受非法访问和调用, 其二是修改TPM 的访问流程, 并通过TPM 来保护DomA, 提高vTPM 及其相关组件的安全性.为了防止云环境中攻击者可能利用虚拟机的回滚机制(一种重要和常用的功能)发起攻击, 文献[36]基于Xen提出了抵御回滚的可信虚拟平台模块(rollback-resilient TPM, rvTPM)系统架构, 并在Xen 中实现了rvTPM 原型系统.

图1 vTPM 系统架构Figure 1 vTPM architecture

通过以上分析发现, 关于vTPM 架构的研究虽然能够在一定程度上提高vTPM 的安全性, 但并不能有效保护软件型vTPM 的密钥等秘密信息.

目前, 国内外关于vTPM 密钥的安全存储主要依赖硬件TPM.Pearson 等人[37]提出将密钥与平台绑定的方案, 主要利用物理TPM 的硬件保护功能来安全存储关键密钥, 这样使得密钥只可以在绑定的平台上使用, 其他平台上不可用, 以达到保护数据机密性的目的, 但是这种方案很显然缺乏灵活性.Yang 等人[38]设计了一个基于物理TPM 的云存储系统架构, 首先用对称密钥加密数据, 然后用非对称密钥加密该对称密钥, 最后利用物理TPM 来安全存储非对称密钥, 从而实现密钥的有效管理, 这种方法比较复杂,加密解密必然会耗费大量系统空间和时间.王丽娜等[39]提出的基于硬件TPM 的密钥使用次数管理方法在保护云存储中数据的机密性的同时控制密钥的使用次数, 从而能够安全有效地存储和保护密钥.文献[40]基于现有的虚拟TPM 架构提出一种用于vTPM 的安全改进方案, 在KVM 虚拟机上通过在硬件和软件方面实现TPM2.0 规范, 增加了使用TPM 的非对称加密算法对vTPM 的保护, 并且能够支持TPM 密钥的安全迁移以及VM-vTPM 的迁移.上述研究成果均基于硬件TPM 的加密保护, 虽然能够达到安全存储vTPM 密钥的效果, 但是仍具有如下不足: (1)由于vTPM 密钥的频繁使用必然会使硬件TPM 频繁加密解密, 不仅占用系统资源, 而且密钥传输以及加解密均需要耗费时间, 从而增加系统的响应时间和TPM 性能负担; (2)当vTPM 在进行加解、解密、完整性验证等安全操作时, vTPM 密钥等敏感信息也必须首先加载到内存中, 这些敏感信息仍然容易遭到窃取和破坏.

3 基于影子页表+ 的软件型vTPM 密钥保护方案

对于普通的可信计算平台, TPM 内部的密钥存储了EK、SRK、TPM 所有者和SRK 的授权数据等, 其他密钥存放在TPM 外部, 外部存储的密钥形成以SRK 为根的多级密钥树[41].由于TPM 内部具有平台软件无法直接访问的独立的存储空间, 因此普通的可信计算平台其密钥或证书是安全的.然而对于虚拟平台中的仿真型vTPM, 其作为运行在用户空间的应用程序并没有直接的硬件保护, 其对应的vEK、vSRK、vTPM 所有者和vSRK 的授权数据以及由此而保存在外设上的密钥树等很容易受到窃取和破坏.本节基于全虚拟化方式或硬件辅助虚拟化, 通过在VMM 中增加MMU-vTPM 管理模块对vTPM 域中vEK、vSRK、vTPM 所有者和vSRK 授权数据等秘密数据的存储空间进行保护, 系统框架如图2 所示.

图2 vTPM 保护系统框架Figure 2 vTPM protection system framework

如图2 所示, 运行在VMM 层的MMU-vTPM 对vTPM 密钥信息的保护起到关键作用.MMUvTPM 分为两个部分: vTPM 密钥私有内存管理和vTPM 密钥私有内存访问控制, 它能够对来自虚拟机操作系统以及应用程序的vTPM 内存访问进行监控, 通过建立vTPM 密钥的私有页表, 实现vTPM 内存隔离, 以防止任意进程对vTPM 受保护内存进行非法访问和破坏.主要原理如下:

(1)增加一个管理vTPM 密钥私有内存的超级调用.vTPM 管理程序创建vTPM 子实例的时候通过该超级调用申请内存用来存储生成的vEK 和vSRK 等秘密数据.该内存会受到MMU-vTPM 模块保护, 只能由该vTPM 子实例访问, 其他任何进程均不能访问.

(2)当发生访问vTPM 受保护内存的操作时, 会陷入到vTPM 密钥保护模块中MMU-vTPM, 由MMU-vTPM 对申请的私有内存保护.

(3)MMU-vTPM 通过验证访问vTPM 密钥私有内存的进程身份来进行访问控制.

值得注意的是, 本方案与采用Intel 的SGX 来实现可信保护是不同的.SGX 是Intel 开发的新的处理器技术, 可以在计算平台上提供一个可信的空间, 保障用户关键代码和数据的机密性和完整性.本方案是用软件模块MMU-vTPM 来保护vTPM 的内存空间, 而MMU-vTPM 又收到物理硬件TPM 的保护.而SGX 是对因特尔体系(IA)的一个扩展, 用于增强软件的安全性.这种方式是将合法软件的安全操作封装在一个enclave 中, 保护其不受恶意软件的攻击, 特权或者非特权的软件都无法访问enclave, 也就是说, 一旦软件和数据位于enclave 中, 即便操作系统或者和VMM 也无法影响enclave 里面的代码和数据.Enclave 的安全边界只包含CPU 和它自身.SGX 创建的enclave 也可以理解为一个可信执行环境TEE(trusted execution environment).

3.1 MMU-vTPM 的基本架构

在全虚拟化方式或硬件辅助虚拟化下, 各种虚拟平台均采用影子页表(shadow page table, SPT)[42]机制来实现虚拟地址到机器地址的转换, 它提供给每个Guest OS 一个Guest 页表, 但实际上客户机是通过影子页表SPT 来访问真实的机器物理地址的.如图3 所示, Guest 页表是Guest 虚拟地址到Guest 物理地址之间的映射, 而影子页表SPT 是Guest 物理地址与宿主机物理地址之间的映射.Guest 物理地址与宿主机物理地址之间可以通过哈希表和P2M 两种方式进行对应.其中, 哈希表对某一个非最低级客户机页表中的页表项而言, 以该客户机页表项中的物理地址和该页表项的类型作为哈希表的键值, 在哈希表中可以查找到相应的影子页表项中的机器物理地址; P2M 表是客户机物理地址到机器物理地址的转换表.此影子页表可以采用硬件支持的内存虚拟化, 如AMD 的NPT (nested page tables, NPT)和Intel EPT(extended page tables, EPT)技术实现[43].

在图3 中, 我们增加了特有的vTPM 内存管理模块MMU-vTPM, 用于保护vTPM 的密钥等敏感信息.MMU-vTPM 实际上是在影子页表的基础上构建影子页表+(shadow_plus)的映射机制, 即在同步客户机页表和影子页表的缺页异常中增加访问监控接口shadow_plus, 如图4 所示.下面我们将对vTPM内存管理模块MMU-vTPM 进行详细介绍.

图3 影子页表与客户机页表之间的关系Figure 3 Relationship between shadow page table and client page table

图4 访问监控接口shadow_plus 结构图Figure 4 Structure of shadow_plus access monitoring interface

3.2 vTPM 密钥私有内存管理

MMU-vTPM 的功能之一是vTPM 密钥私有内存的管理, 主要包括vTPM 密钥私有内存的申请和vTPM 密钥私有内存的回收.无论是vTPM 密钥私有内存的申请和vTPM 密钥私有内存的回收, 均需要提供用户空间的接口以及内核空间的接口, 用户可以通过使用这些接口为vTPM 分配或回收私有空间.

定义1 vTPM 密钥私有内存.vTPM 密钥私有内存是在vTPM 子实例创建时, 由vTPM 管理程序为vTPM 子实例申请的一段只允许vTPM 进程访问的物理内存, 用于存储vTPM 的vEK 和vSRK 等密钥.其数据结构vTPM_pmdomain 的具体描述为:

定义2vTPM 密钥私有内存保护列表.vTPM 密钥私有内存保护列表用于记录vTPM 密钥私有内存页的PFN(客户物理页框号)的链表.其数据结构vTPM_protected_list 的具体描述如下:

struct vTPM_protected_list

{

unsigned int vTPM_page_id; //vTPM 密钥私有内存id

unsigned long gfn; //vTPM 密钥私有内存页的客户机物理页框号

unsigned long mfn; //vTPM 密钥私有内存页的机器页框号

struct vTPM_protected_list *next;}

typedef struct vTPM_protected_list *vTPM_pm_list; //定义vTPM_pm_list * 指针类型

定义3malloc_vTPM_pages(), 即vTPM 密钥私有内存申请函数, 作为vTPM 密钥私有内存申请接口.实现如算法1 所示.

算法1 vTPM 密钥私有内存申请接口实现算法malloc_vTPM_pages()Input: struct vTPM_protected_list *vTPM_pm_list Output: *vTPM_pm_list 1 var item ←vTPM_pm_list;2 while item do 3Set item.gfn; 4page ←Get page; 5item.mfn ←Get mfn(item.gfn); 6Item ←item.next;7 end 8 return * vTPM_pm_list;

算法1 中Get、Set 方法为VMM 系统调用.Page 为VMM 分页机制下的内存页.gfn 内存页的客户机物理页框号.mfn 内存页的机器页框号.该算法是为了实现vTPM 私有内存申请, 首先通过系统调用Set 申请物理内存页, 并为其设置客户机物理页框号, 同时写入vTPM 密钥私有内存保护列表, 然后通过系统调用Get 为申请到的物理内存页分配机器页框号mfn, 并写入vTPM 密钥私有内存保护列表中gfn相应的mfn, 最后返回申请到的vTPM 密钥私有内存保护列表.

定义4drop_vTPM_pages(), 即vTPM 密钥私有内存回收函数, 作为vTPM 密钥私有内存回收接口.实现如算法2 所示.

算法2 vTPM 密钥私有内存回收接口drop_vTPM_pages()Input: struct vTPM_protected_list *vTPM_pm_list Output: NULL 1 for each item in ∗vTPM_pm_list do 2page.drop(item.gfn, item.mfn); 3p2m.drop(item.gfn, item.mfn); 4SPT.drop(item.gfn, item.mfn);5 end 6 FLUSH;

算法2 中page.drop 方法为VMM 中用于释放内存页的系统调用.p2m.drop 是VMM 中用于删除p2m 表项的系统调用.SPT.drop 是VMM 中用于清空影子页表表项的系统调用.FLUSH 是刷新系统TLB 表项的命令, 使得快表中的vTPM 密钥私有内存地址相关映射失效.该算法是为了实现vTPM 密钥私有内存回收, 首先遍历整个vTPM 私有内存列表*vTPM_pm_list, 然后通过VMM 内存管理系统调用的内存释放函数page.drop 释放vTPM 私有内存页, 同时通过VMM 内存管理系统调用p2m.drop删除P2M 表中的相关表项以及通过VMM 内存管理系统调用SPT.drop 影子页表中的相关表项, 最后执行系统刷新命令, 使系统TLB 中相关表项失效.

3.3 vTPM 密钥私有内存的访问控制

MMU-vTPM 的另一功能是对vTPM 密钥私有内存实施访问控制, 它监控所有访问vTPM 密钥私有内存空间的进程, 提供异常处理.首先, 当vTPM 进程首次访问vTPM 密钥私有内存空间时, 由于影子页表中没有关于vTPM 密钥私有内存的地址映射, 所以产生缺页异常, VMM 捕获该异常, 建立vTPM密钥私有内存的影子页表映射, 并且将其影子页表访问权限设置为只读.然后, MMU-vTPM 对vTPM密钥私有内存进行访问控制, 具体实现流程如下:

(1)VMM 可以捕获任何写CR3 寄存器的操作, 通过CR3 寄存器中存储的页目录的起始物理地址, VMM 可以得知该进程的所有页表[36].由此可以记录vTPM 进程的基地址并保存到vTPM_base_address 中.

(2)由于影子页表权限为只读, 当发生对vTPM 密钥秘密信息私有内存的操作时, VMM 同步客户机页表和影子页表时会发生缺页异常.

(3)VMM 捕获到缺页异常后, 首先要查找此进程的客户机页表, 确定发生缺页异常的客户机虚拟地址所对应的客户机物理地址; 然后进入到VMM 的影子页表缺页处理入口函数sh_page_fault(),sh_page_fault()调用vTPM 密钥私有内存异常处理接口shadow_plus 来进行处理.

vTPM 密钥私有内存异常处理接口如定义5 所示.

定义5shadow_plus(), 即vTPM 密钥私有内存异常处理接口.该接口是在同步客户机页表和影子页表缺页异常处理中增加的对vTPM 密钥私有内存异常的处理方法.

在异常处理的过程中, shadow_plus 首先获取发生缺页异常的客户机物理地址, 然后通过p2m 表获得发生缺页异常的 对, 并判断其pfn 是否是vTPM 密钥私有内存列表中的机器物理地址.然后, 获取该进程的客户机物理基地址与事先保存的vTPM 进程基地址进行比较.若为vTPM 进程, 则不做处理, 正常更新影子页表; 否则, 影子页表更新失败, 转由客户机处理.实现如算法3 所示.

算法3 vTPM 密钥私有内存异常处理接口shadow_plus()实现算法Input: Page Fault 缺页异常Output: 除vTPM 进程外访问vTPM 密钥私有内存的进程1 Get_Page_Fault(gva);2 pfn ←search in guest_page_table(gva); 3 ←get mfn from p2m;4 if < mfn,pfn > in vTPM_protected_list then 5bas ←Get CR3;6if bas! = vTPM_base_address then 7 goto not_a_shadow_fault;8end 9 end

算法3 中, Get_Page_Fault 表示VMM 捕获缺页异常的方法.guest_page_table 表示客户机页表,保存客户机虚拟地址gva 与客户机物理页框号gfn 的映射.p2m 保存客户机物理页框号与机器页框号的映射, 即 对.bas 保存当前进程的基地址.

至此, 我们可以设计vTPM 密钥私有内存的访问控制完整实现过程.如算法4 所示.

在算法4 中, Get_modify 表示VMM 捕获CR3 寄存器操作的方法.Get_Page_Fault 表示VMM捕获缺页异常.

算法4 vTPM 密钥私有内存访问控制接口access_vTPM_key()算法Input: 任意进程Output: 除vTPM 进程外访问vTPM 密钥私有内存的进程1 vTPM_base_address ←Get_modify(CR3);2 if Get_Page_Fault then 3shadow_plus();4 end

4 MMU-vTPM 模块的完整性验证保护

内存管理模块是VMM 的核心功能模块,通常作为虚拟平台的可信基TCB(trusted computing base,TCB), MMU-vTPM 模块作为VMM 内存管理模块的一部分, 也应看作是虚拟平台TCB 的一部分.然而, 当前的许多攻击, 如通过篡改VMM 代码段和数据段以及其它静态、持久化的数据而破坏完整性的攻击[44,45], 都会破坏TCB.为了防止恶意用户对MMU-vTPM 模块进行篡改, 我们采用TPM 的静态度量机制和动态度量机制对MMU-vTPM 模块进行完整性保护, 确保MMU-vTPM 模块完全可信.

4.1 MMU-vTPM 模块的静态完整性度量

虚拟平台的静态度量通常发生在整个虚拟平台重新启动时, 为了保证MMU-vTPM 可信, 我们扩展虚拟机的信任传递过程CRTM →BIOS →BootLoader →VMM →DOM OS →Apps, 将其中的VMM分为两部分, 一部分VMM-MMU-vTPM, 另一部分是MMU-vTPM, 则扩展后的信任链变为CRTM →BIOS →BootLoader →VMM-MMU-vTPM →MMU-vTPM →DOM OS →Apps.如图5 所示, 将MMU-vTPM 作为可信平台链式度量的重要一环.这种方式是可行的, MMU-vTPM 的静态度量可由VMM-MMU-vTPM 主导完成.

图5 扩展后的信任链传递过程Figure 5 Extended trust chain delivery process

4.2 MMU-vTPM 模块的动态完整性度量

在虚拟平台运行过程中需要对MMU-vTPM 模块进行动态完整性度量, 以便及时发现恶意程序对其的破坏和篡改, 保证虚拟平台上服务的稳定性和连续性.MMU-vTPM 模块动态完整性度量架构如图6所示.

图6 中, MMU-vTPM 模块动态完整性度量架构包括3 个部分: MMU-vTPM 度量代理、MMUvTPM 度量程序和MMU-vTPM 的备份和恢复程序.其中MMU-vTPM 度量代理位于特权域中, 主要功能就是获取并解析对MMU-vTPM 模块的度量请求, 并将请求发送到MMU-vTPM 度量程序;MMU-vTPM 度量程序位于VMM 中, 负责MMU-vTPM 模块的动态完整性度量; MMU-vTPM 备份和恢复程序也位于VMM 中, 负责对MMU-vTPM 进行备份, 当发现MMU-vTPM 被恶意篡改后对其进行恢复.MMU-vTPM 度量程序是整个架构的核心, 主要包括如下功能模块:

图6 MMU-vTPM 模块动态完整性度量架构Figure 6 MMU-vTPM dynamic metrics architecture

(1)构建度量环境.目前, 处理器厂商AMD 提供的安全虚拟机(secure virtual machine, SVM)和Intel 提供的可信执行技术(trusted execution technology, TXT)均可构建安全加载模块(secure loader block, SLB)作为动态信任根(dynamic root of trust for measurement, DRTM)[45], 通过执行特定的CPU 指令构建安全隔离的可信执行环境, 完成对MMU-vTPM 自身的完整性度量.本文利用Intel TXT技术中新引入的CPU 指令——SENTER, 利用动态信任根完成对MMU-vTPM 的完整性度量, 并创建一个受控和可证明的可信执行环境, 之后再加载运行MMU-vTPM 模块度量程序.

(2)MMU-vTPM 提取模块, 该模块主要功能是提取出需要完整性度量的MMU-vTPM 模块代码段数据, 具体如定义6 所示.

定义6extract_MMU-vTPM()即MMU-vTPM 模块提取接口, 主要实现如算法5 所示。

算法5 MMU-vTPM 模块提取extract_MMU-vTPM()算法Input: 可信度量环境Output: MMU-vTPM 模块代码段1 length ←MMU-vTPM.length(); 2 offset ←Get_offset_of_VMM(); 3 virtual_address ←Get_virtual_address(symbol_table); 4 physical_address ←virtual_address–offset; 5 MMU-vTPM ←Get_data_memory(physical_address, length); 6 return MMU-vTPM;

在算法5 中, 首先通过分析MMU-vTPM 模块代码段的数据量length; 由于, VMM 一般以内核的方式加载到内存特定物理地址开始的连续地址空间中, 并将该内存地址空间以直接映射的方式映射到VM 的虚拟地址空间, 所以VMM 中特定信息的虚拟地址和物理地址之间有一个固定的差值offset, Get_offset_of_VMM()获取VMM 的offset; symbol_table 表示编译VMM-vTPM 模块产生的符号表, 通过symbol_table 可以得到MMU-vTPM 模块代码段在内存中的虚拟地址virtual_address;physical_address 表示MMU-vTPM 模块的虚拟地址对应的物理地址; 最后Get_data_memory()表示按照物理地址和数据量, 直接从内存中读取MMU-vTPM 模块的代码段数据, 然后返回该值作为完整性度量DIM_MMU-vTPM()的输入.

(3)完整性度量, 该模块主要是对上一个模块提取到的数据进行完成性度量, 以保证度量结果的一致性, 完整性度量一般采用TPM 的完整性度量机制, 将度量结果存储到TPM 的平台配置寄存器(PCR)中.将该模块功能封装为完整性度量接口, 如定义7 所示.

定义7DIM_MMU-vTPM(), 即MMU-vTPM 模块的完整性度量接口.该接口的实现算法如算法6所示.

算法6 完整性度量DIM_MMU-vTPM()算法Input: MMU-vTPM 模块代码段Output: 度量值1 TPM_SHA1Start(); 2 TPM_SHA1Update(MMU-vTPM); 3 pcr_MMU-vTPM ←TPM_SHA1Complete(); 4 Tspi_TPM_PcrExtend(pcr_MMU-vTPM); 5 return pcr_MMU-vTPM;

完整性度量模块采用TPM 的完整性度量机制, 算法6 中, TPM_SHA1Start()表示TPM 中开始计算一个摘要的过程, 即开始完整性度量.然后调用TPM_SHA1Update()输入需要完整性度量的MMU-vTPM 模块代码段, 最后调用TPM_SHA1Complete()计算摘要值.完整性度量值的存储通过调用TSP 层的Tspi_TPM_PcrExtend()函数来完成, 将摘要值pcr_MMU-vTPM 扩展更新到指定的平台配置寄存器PCR 的值.

(4)度量报告, 该模块主要是获取完整性度量值, 并将新的度量值与存储的度量值进行匹配, 以检测完整性, 然后将完整性度量的结果返回给度量请求程序.

4.3 MMU-vTPM 模块的备份与恢复

为了在MMU-vTPM 模块被篡改时能够及时恢复, 我们首先通过MMU-vTPM 模块备份接口对MMU-vTPM 模块备份, 由TPM 的存储密钥加密存储在平台外存中.之后根据完整性度量结果判断是否需要恢复MMU-vTPM 模块,如果需要则要通过MMU-vTPM 模块恢复接口通过解密恢复MMU-vTPM模块.其中, MMU-vTPM 模块备份接口和MMU-vTPM 模块恢复接口的定义与实现算法如下.

定义8MMU-vTPM_Backup(), 即MMU-vTPM 模块的备份接口, 该接口的实现算法如算法7 所示.

算法7 MMU-vTPM 模块备份接口实现算法MMU-vTPM_Backup()Input: MMU-vTPM 模块代码Output: MMU-vTPM 模块备份地址Backup_Address 1 MMU-vTPM_copy ←Copy(MMU-vTPM); 2 MMU-vTPM_copy′ ←Tspi_Data_Bind(MMU-vTPM_copy); 3 Backup_Address ←&MMU-vTPM_copy′; 4 return Backup_Address;

算法7 中, MMU-vTPM_copy 表示MMU-vTPM 模块的备份文件, Copy()表示复制一份MMUvTPM 模块源码作为备份, 然后使用TPM 的Tspi_Data_Bind 命令加密MMU-vTPM_copy, 接着存储加密后的文件, 最后获取存储地址Backup_Address 并返回.

定义9MMU-vTPM_Recovery(), 即MMU-vTPM 模块的恢复接口, 该接口的实现算法如算法8 所示.

算法8 MMU-vTPM 模块恢复接口实现算法MMU-vTPM_Recovery()Input: MMU-vTPM 模块备份地址Backup_Address Output: MMU-vTPM 模块1 MMU-vTPM_copy′ ←*Backup_Address; 2 MMU-vTPM_copy ←TPM_Unbind(MMU-vTPM_copy′); 3 MMU-vTPM ←MMU-vTPM_copy; 4 REBOOT;

算法8 中, 首先根据MMU-vTPM 模块备份接口返回的备份地址Backup_Address 读取加密后的MMU-vTPM 模块备份文件, 然后使用TPM 的TPM_Unbind 命令对Tspi_Data_Bind 命令处理过的数据块进行解密并输出, 最后用上一步中输出的MMU-vTPM 模块备份文件替换系统中不可信的MMU-vTPM 模块.重启系统完成MMU-vTPM 模块恢复的更新操作.

5 基于XEN 的MMU-vTPM 实现

目前, 本方案已经在Xen 4.3.4 实现了上述功能, 能够保护vTPM 密钥私有内存空间不被其他任何进程访问或破坏并且可以保证MMU-vTPM 模块不被篡改.

5.1 vTPM 密钥私有内存管理实现

为了实现vTPM 密钥私有内存的管理, 对Xen 虚拟机的源码做出了相应的修改, 添加了一个vTPM私有内存列表和一个超级调用, 并对系统中相应的处理函数做出修改.

首先, 根据定义1, 在//xen/include/asm-x86/domain.h 中添加Xen_vTPM_pmdomain 结构用于描述vTPM 密钥私有内存.

其次, 根据定义2, 在//xen/include/asm-x86/domain.h 中定义vTPM 密钥私有内存保护列表的数据结构Xen_vTPM_protected_list.

第三, 根据定义3 和算法1, 在//xen/common/memory.c 中定义vTPM 密钥私有内存申请接口Xen_malloc_vTPM_pages()函数.

第四, 根据定义4 和算法2, 在//xen/common/memory.c 中定义vTPM 密钥私有内存回收接口Xen_drop_vTPM_pages()函数.

最后, 增加一个用于管理 vTPM 密钥私有内存的超级调用, 增加的超级调用为_HYPERVISOR_vTPMprotected_mm, 该超级调用封装了Xen_malloc_vTPM_pages()函数和Xen_drop_ vTPM_pages()函数, 其功能是管理vTPM 密钥私有内存空间, 它有一个参数op,_HYPERVISOR_vTPMprotected_mm 将根据该参数的值, 采取相应的操作.当op = 0 时, 表示对vTPM 密钥私有内存空间采取初始化操作.当op = 1 时, 表示申请vTPM 密钥私有内存.当op = 2时, 表示销毁vTPM 密钥私有内存相关数据并回收内存.

至此, Xen 中虚拟机的vTPM 管理程序通过超级调用_HYPERVISOR_vTPMprotected_mm 为新创建的vTPM 子实例分配和回收vTPM 密钥私有内存空间.

5.2 vTPM 密钥私有内存的访问控制实现

为了实现vTPM 密钥私有内存的访问控制, 对Xen 虚拟机的源码做出了相应的修改, 添加了一个vTPM 密钥私有内存异常处理接口shadow_plus()和vTPM 密钥私有内存的访问控制接口access_vTPM_key(), 并对系统中相应的处理函数做出修改.

首先, 根据算法3, 在//xen/arch/x86/mm/shadow/multi.c 中增加vTPM 密钥私有内存异常处理接口Xen_shadow_plus()函数.

其次, 根据算法4, 在//xen/arch/x86/mm.c 中增加vTPM 密钥私有内存的访问控制接口Xen_access_vTPM_key()函数.

至此, Xen 中虚拟机的 vTPM 管理程序通过 Xen_shadow_plus()函数和 Xen_access_vTPM_key()函数实现vTPM 密钥私有内存的访问控制.

5.3 MMU-vTPM 模块完整性度量实现

MMU-vTPM 模块完整性度量包括静态度量和动态度量, 对于静态度量, Xen 中的TPM 模拟器tpm_emulator 已经实现, 这里就不再阐述.下面介绍动态完整性度量.

由4.2 节可知, 要实现对MMU-vTPM 模块的动态完整性度量必须依赖CPU 支持而且要进行复杂设置.由于我们的目的仅仅是通过动态完整性度量来判定MMU-vTPM 是否可信, 我们选用了另外的替代办法, 采用在特权域中通过度量代理对MMU-vTPM 模块进行动态度量, 此方法同样可以达到我们的目标.为此, 我们增加了MMU-vTPM 度量程序各模块的实现函数.

首先, 在构建度量环境模块执行完SENTER 指令之后, 程序陷入到硬件层, 其加载执行的MMUvTPM 模块度量程序将运行于Ring0, 系统处于实地址模式, 根据定义6 和算法5, 增加MMU-vTPM 模块提取接口的实现函数extract_MMU-vTPM().

其次, 根据定义7 和算法6, 增加 MMU-vTPM 模块完整性度量接口的实现函数DIM_MMU_vTPM().

最后, 增加一个实现MMU-vTPM 模块度量程序的超级调用_HYPERVISOR_DIM_MMUvTPM(), 该超级调用封装了extract_MMU-vTPM()函数和DIM_MMU-vTPM()函数, 其功能是完成对MMU-vTPM 模块代码段的提取并进行完整性度量.

6 基于XEN 的MMU-vTPM 实验评估

目前, 本文的基于影子页表+ 的vTPM 保护方案已经在Xen 4.3.4 作为底层的VMM 的虚拟平台上实现.本节将设计两方面实验对本文提出的方案进行验证.一方面是vTPM 密钥私有内存的访问控制实验, 验证MMU-vTPM 对vTPM 密钥的保护; 另一方面是对MMU-vTPM 的完整性度量和相关安全验证, 包括静态度量、动态度量以及对度量程序的攻击等.

6.1 vTPM 密钥私有内存的访问控制实验

6.1.1 实验环境

本文实验环境为: 宿主机CPU 为Intel Core-i3 处理器, 主频3.40 GHz, 4 G 内存; 底层VMM 为Xen 4.3.4; 虚拟域操作系统为Ubuntu 14.04; TPM 使用TPM_emulator 0.7.3; TSS 使用Trousers 0.3.4.

6.1.2 实验步骤

为了评估本文提出的方案对vTPM 存储私钥等关键数据的私有内存的保护效果, 在测试中分别定义如下Shadow-Native 和shadow_plus 两种测试环境.

(1)Shadow-Native: 运行未修改的Xen 的测试环境.

(2)Shadow_plus: 运行采用本文方法修改过的Xen 的测试环境.

具体实验步骤如下:

(1)本实验首先在创建vTPM 实例时使用超级调用_HYPERVISOR_vTPMprotected_mm 为vTPM 申请受保护的私有内存页.

(2)将vTPM 的关键密钥存储到vTPM 密钥私有内存中, 并由vTPM 进程读取显示.

(3)编写测试程序, 在shadow_plus 测试环境中, 分别从以下四个方面进行测试: vTPM 进程正常访问测试, 其他进程访问测试, 用户态代码注入攻击测试, 内核态代码注入攻击测试.

(4)记录并分析上述四个测试结果.

(5)多次记录Shadow-Native 和shadow_plus 两种测试环境中进程运行时间并进行对比分析.

6.1.3 功能测试及实验

本方案的重要目标是通过对进程影子页表更新的监控来限制其他进程对vTPM 私有受保护内存空间的访问, 达到保护vTPM 密钥等关键数据的目的.

首先, 通过超级调用_HYPERVISOR_vTPMprotected_mm 为vTPM 申请受保护的私有内存页.调用_HYPERVISOR_vTPMprotected_mm 传入参数op = 1, 申请vTPM 密钥私有内存, 将vTPM管理程序为vTPM 子实例创建的关键密钥存储到vTPM 密钥私有内存中.如图7 所示.

图7 vTPM 密钥私有内存中的vTPM 密钥Figure 7 vTPM key in vTPM key private memory

其次, 测试vTPM 进程是否可以正常读取vTPM 密钥私有内存中的vTPM 密钥.在vTPM 源码中增加输出接口编写程序vtpm 显示输出结果, 由图8 可知, vTPM 进程可以正常访问vTPM 密钥私有内存中的vRSK 等关键密钥.

图8 vTPM 进程访问vTPM 密钥私有内存Figure 8 vTPM process access vTPM key private memory

除此之外, 我们在shadow_plus 测试环境中, 设计了对比的攻击实验, 以测试本文方案安全性.

第一种: 其他进程访问测试.本次实验编写名为test 的测试程序, 作为外部进程访问vTPM 密钥私有内存, 实验结果如图9 所示.

图9 其他进程访问测试结果Figure 9 Other process access test results

图10 用户态代码注入攻击测试结果Figure 10 User mode code injection attack test result

第二种: 用户态代码注入攻击测试.本次实验的用户态是指与vTPM 所在虚拟机同一用户空间的进程.编写一段访问vTPM 密钥私有内存空间的攻击代码, 注入用户态空间进程中进行访问攻击, 本次实验的入口程序名为us_injection.实验结果如图10 所示.

第三种: 内核态代码注入攻击测试.本次实验的内核态指的是在Xen VMM 空间运行的进程.通过内核注入攻击的方式将访问vTPM 密钥私有内存空间的攻击代码运行于内核态.实验结果同样返回“Permission denied” 的错误代码.

其中关于错误代码EACCES 的描述在/xen/include/xen/errno.h 头文件中, 如图11 所示.

表1 功能测试结果Table 1 Functional Test Results

综上所述, 本文功能测试结果如表1 所示:

从表1 的实验结果中可以看出, 只有vTPM 进程能够正常访问vTPM 受保护私有内存页.本次实验结果表明本文基于影子页表+ 的vTPM 密钥保护方案能够达到保护vTPM 密钥的目的.6.1.4 性能测试及实验

本文vTPM 保护方案对系统的性能影响主要包括两种行为: 处理改写CR3 寄存器的格外操作时间和处理缺页异常的额外操作时间.这两种额外增加的操作在系统中所有的进程执行都会产生一定的影响.编写测试进程多次实验, 在Shadow-Native 和shadow_plus 两种测试环境中运行时间进行记录, 结果如图12 所示.

图11 Xen 系统错误代码Figure 11 Xen system error code

图12 性能测试结果Figure 12 Performance test resultse

从图12 可以看出, 在vTPM 受保护私有内存大小较小的时候增加了vTPM 保护模块的shadow_plus 测试环境和没有对进行修改的原始系统在统一进程的运行时间差别不大, 在用户可以接受的范围内, 而随着受保护内存页面的增多, 两种测试环境的性能发生明显变化, 增加了vTPM 保护模块的shadow_plus 测试环境的性能随着受保护内存页的增加而下降.本次实验结果表明: 由于vTPM 保护方案需要保护的vTPM 数据主要包括vEK 和vSRK 等关键数据, 所需要的受保护内存较小, 所以, 增加的vTPM 保护模块对系统性能影响不大.

6.2 MMU-vTPM 完整性度量测试实验

6.2.1 实验环境和准备工具

本节的软件实验环境与6.1 节相同, 而动态完整性度量实验需要利用Intel TXT 构建SLB 作为DRTM, 保证起点可信, SLB 构建封闭隔离的执行环境来执行度量程序, 保证度量程序自身可信, 完成对MMU-vTPM 模块代码的完整性度量.所以本次实验需要CPU 支持Intel TXT 功能, 保证可以执行SENTER 命令.如图13 所示, 开启Intel TXT 功能.

6.2.2 实验步骤

为了对本文软件仿真型vTPM 密钥保护方案中的MMU-vTPM 模块进行完整性保护, 分别从静态完整性度量和动态完整性度量两个方面设计实验完成对功能和性能的测试.

实验步骤如下:

(1)静态完整性度量: 基于MMU-vTPM 模块的扩展信任链, 在系统启动时进行静态完整性度量.按照本文扩展的信任链的传递过程进行度量, 并将MMU-vTPM 度量结果保存到PCR(17), 然后读取PCR寄存器的值.

图13 开启Intel TXTFigure 13 Turn on Intel TXT

(2)动态完整性度量: MMU-vTPM 模块的动态完整性度量实验, 首先调用超级调用_HYPERVISOR_DIM_MMU-vTPM()以驱动MMU-vTPM 模块度量程序完成构建度量环境、MMUvTPM 模块提取和完整性度量等一系列过程.

(3)设计对MMU-vTPM 度量程序自身的攻击实验, 修改MMU-vTPM 模块动态完整性度量程序部分代码, 验证实验度量结果值是否发生改变.

(4)设计对MMU-vTPM 模块代码段的攻击实验, 修改MMU-vTPM 模块代码段中部分程序代码,验证实验度量结果值是否发生改变.

(5)执行MMU-vTPM 度量程序进行动态完整性度量, 并记录运行时间.

6.2.3 功能测试

首先, 在系统启动时进行静态完整性度量, 按照本文扩展的信任链的传递过程进行度量, 并将MMU-vTPM 度量结果保存到PCR(17), 然后读取PCR 寄存器的值, 实验结果如图14 所示.

图14 静态完整性度量后PCR 的值Figure 14 Post-PCR value after static integrity measurement

其次, 为了验证本文的MMU-vTPM 模块动态完整性度量架构能够有效的对MMU-vTPM 模块进行动态的完整性度量, 本次实验首先调用超级调用_HYPERVISOR_DIM_MMU-vTPM()以驱动MMU-vTPM 模块度量程序完成构建度量环境、MMU-vTPM 模块提取和完整性度量等一系列过程, 如图15 所示.

再次, 设计对MMU-vTPM 度量程序自身的攻击实验, 修改MMU-vTPM 模块动态完整性度量程序部分代码, DIM_MMU-vTPM′表示修改后的MMU-vTPM 度量程序.实验结果显示度量结果值发生改变, 与存储在TPM PCR[18]中的MMU-vTPM 度量程序摘要值不同, 结果如图16 所示.验证本文动态完整性度量程序自身的安全性.

最后, 设计对MMU-vTPM 模块代码段的攻击实验, 修改MMU-vTPM 模块代码段中部分程序代码,MMU-vTPM′表示修改后的MMU-vTPM 模块.实验结果显示度量结果值发生改变, 与存储在TPM PCR[17]中的MMU-vTPM 模块的静态完整性度量值度量不同, 结果如图17 所示.验证本文动态完整性度量的有效性.

图15 MMU-vTPM 模块动态完整性度量过程Figure 15 MMU-vTPM module dynamic integrity measurement process

图16 MMU-vTPM 度量程序自身攻击实验对比Figure 16 MMU-vTPM metrics own attack experiment results

图17 MMU-vTPM 模块代码段攻击实验对比Figure 17 Comparison of attack results of MMU-vTPM module code segment

由上述实验对比结果可知, 本文的MMU-vTPM 模块动态完整性度量架构能够在保证度量程序自身安全性的同时, 识别出对MMU-vTPM 模块代码段的攻击, 从而保证了MMU-vTPM 模块的安全性.

6.2.4 性能测试

为了对本文的MMU-vTPM 模块动态完整性度量架构的性能进行测试, 执行MMU-vTPM 度量程序进行动态完整性度量, 并记录运行时间.为了保证本文实验数据的可靠性, 本文性能测试共进行了6次实验, 经过测试, 动态完整性度量需要读取MMU-vTPM 模块的数据量大小为2.94 KB, 采用本文的MMU-vTPM 模块动态完整性度量架构度量时间性能第一次测试结果为0.39 ms, 第二次为0.44 ms, 第三次为0.37 ms, 第四次为0.51 ms, 第五次为0.34 ms, 第六次为0.36 ms.如图18 所示.

图18 MMU-vTPM 度量程序自身的攻击实验对比结果Figure 18 MMU-vTPM metrics own attack experiment results

综上所示, 本文的MMU-vTPM 模块动态完整性度量架构度量时间性能约为0.40 ms, 在用户可接受范围内.

7 结论

本文针对仿真型vTPM 的vEK 和vSRK 等关键密钥秘密信息存储在虚拟域的用户空间缺乏相应的保护机制, 容易受到攻击而使得软件型vTPM 的安全性降低的问题, 提出了一种基于影子页表+ 的vTPM 保护方案并在Xen 虚拟平台上实现.首先在创建vTPM 实例时使用超级调用_HYPERVISOR_vTPMprotected_mm 为vTPM 申请受保护的私有内存页.其次将vTPM 域内页表设置为只读, 当监控到页表修改行为发生缺页异常时, 使用vTPM 私有内存访问控制实现的shadow_plus 算法, 捕获除vTPM 进程以外的任何访问vTPM 受保护私有内存的进程的异常, 最后返回客户机进行处理.实验结果表明了本文提出方案的可靠性, 而且不会带来严重的性能损失.此外, 在本文相关工作中已经指出, 近年来不断有对提高vTPM 的安全性的研究, 这些大都基于硬件TPM, 针对软件仿真型的vTPM 密钥保护问题至今没有解决, 本文的实验及结果证明了本文提出的软件仿真型vTPM密钥保护方案的可靠性和可行性.

目前, 本方案只能对vTPM 的vEK 和vSRK 等较少的数据进行保护, 下一步将研究如何在不影响系统性能的情况下增加受保护内存的大小,以及vTPM 迁移时vTPM 保护模块如何有效的工作等问题.

猜你喜欢

客户机完整性度量
鲍文慧《度量空间之一》
关于防火门耐火完整性在国标、英标、欧标和美标中的比对分析
ELM及IS/OS完整性对年龄相关性黄斑变性预后视力的影响
更正说明
代数群上由模糊(拟)伪度量诱导的拓扑
突出知识本质 关注知识结构提升思维能力
度 量
隔山亦能打牛,本本巧变远控利器
升腾瘦客户机借神码翱翔“云端”
基于Web数据提高访问速度的方法