AMD EPYC(霄龙)处理器引入了两个硬件安全组件:
- AES-128硬件加密引擎:嵌入在内存控制器内,用于对内存数据进行加解密。
- AMD Secure Processor(AMD-SP):负责安全密钥的生成和管理。
Secure Memory Encryption (SME):AMD在DRAM的控制器中添加了加解密模块,用来控制内内存数据的加密和解密。
Secure Encrypted Virtualization (SEV) :将主内存加密功能与现有的AMD-V虚拟化体系结构来支持加密的虚拟机。 加密虚拟机不仅可以让虚拟机免受物理威胁,还可以免受其他虚拟机甚至是hypervisor本身。 因此,SEV代表了一种新的虚拟化安全范例,特别适用于虚拟机不需要完全信任其主机的hypervisor和管理员的云计算系统。 与SME一样,不需要修改应用程序软件即可支持SEV。
linux-4.16,Libvirt-4.5,qemu-2.12已经合入对SEV的支持。
SME介绍
每个内存控制器包含高性能的高Advanced Encryption Standard(AES)引擎,可在将数据写入DRAM时对其进行加密,并在读取时将其解密,如图1所示。数据加密使用了额外的基于物理地址的调整方式,以防止密文块移动攻击。
SME的AES引擎使用的加密密钥是在每次系统重置时随机生成的,并且对软件不可见。密钥由集成在AMD SOC上的微控制器AMD Secure Processor(AMD-SP)(32位ARM Cortex A5)进行管理。密钥是由板载的符合SP 800-90的硬件随机数生成器生成,并存储在专用的硬件寄存器中,永远不会暴露在SOC之外。与稍后描述的SEV模同,SME不需要软件参与密钥管理。
OS或者Hypervisor可以指定哪些页进行加密。启动内存加密后,物理地址的第47位(又名C-bit,C代表enCrypted)用于标记该页是否被加密,对加密页进行访问时,加密和解密将由AES引擎自动完成。
通过AES引擎对内存进行加密和解密确实会导致DRAM存储器访问的额外延迟。这种延迟对软件的影响主要取决于系统负载,但估计对系统性能的总体影响很小。如果仅对一部分内存进行加密,则对性能的影响将较小,因为通常未加密的访问不会产生额外的延迟。
SME使用场景
- 全部内存加密
- 部分内存加密:在云计算场景下,可以仅将虚拟机使用的内存进行加密。
Transparent SME
SME需要OS或Hypervisor的支持。AMD提供了叫Transparent SME(TSME)的模式,该模式下,所有内存都被加密(不管C-bit位是否为1)。TSME可以通过BIOS进行设置,当TSME开启时,其余的内存加密特性(包括SEV)均不可用。
SEV介绍(2016年)
SEV主要的思想是为虚拟机内存进行加密保护,而且不同虚拟机之间以及宿主机不能直接读取或者窃取到虚拟机内存数据。SEV提供的虚拟机内存数据的加密功能,可以保护虚拟机内存免受物理攻击,跨虚拟机和来自Hypervisor的攻击。SEV功能使能后,物理地址的43 bit至47 bit分别用来标志Address Space ID(ASID)和C-bit,在通过页表访问虚拟机内存时,虚拟机的物理地址会携带与虚拟机对应的ASID的Tag,用来判断是访问哪个虚拟机的数据,或者是操作哪个虚拟机的数据。虚拟机的ASID在页表遍历时使用,用来区分TLB。在缓存(Cache)中,C-bit和ASID用来区分Cache Line。内存控制器中ASID用来区分虚拟机加密密钥(VEK),由于物理地址中的ASID是由硬件自动添加,软件无法直接修改,因此,从内存中读取的数据由内存控制器使用与之对应的VEK进行加解密。SEV模型如下图所示:
开启SEV功能的同时,要求Host使能SME功能,且虚拟机的VMCB中开启NPT功能,这是为了保证Nest Paging的工作过程中C-bit的控制不被软件干扰。由于有两级页表,因此会存在两级页表中PTE的C-bit组合,决定如何对最终的虚拟机内存页如何进行加解密,过程如下图所示:
需要注意的是,SEV对hypervisor和Guest都有要求。Guest必须适配SEV硬件特性,需要对C-bit进行控制;不允许对加密内存进行DMA操作,因此DMA只能使用gue st共享内存。特别是,与SME一样,使用不同的C-bit访问页之前,必须将该页从高速缓存中flush到内存。另外,在更换硬件内存加密密钥之前,hypervisor必须执行完整的高速缓存flush动作。
SEV-ES介绍(2017年)
SEV-ES:Secure Encrypted Virtualization - Encrypted State
- Guest寄存器状态也由安全密钥加密保护
- Guest需要显式与hypervisor共享寄存器状态(使用Guest-Hypervisor Communication Block(GHCB))
SEV-ES工作原理:
SEV-ES导致VMCB分为两部分:VMCA(Control Area)和VMSA(Save Area),VMSA可以保存更多的状态。现在的VMSA包含:Segment State, Control State, GPR State, FPU State。
SEV-ES引入了新的VMEXIT类型:
- Automatic Exit(AE):不需要hypervisor模拟
-
- 异步事件(如中断)
- 不需要guest寄存器状态的事件(如HLT指令)
- Non-Automatic Exit(NAE):需要hypervisor模拟
-
- 产生VMM Communication Exception(#VC)
- guest通过GHCB确定共享的寄存器状态
- guest执行新的VMGEXIT指令(导致AE,退出码为0X403)
- guest通过hypervisor提供的结果更新寄存器状态
AE事件会导致CPU硬件保存加密后的guest寄存器状态,并读取hypervisor状态,待hypervisor处理完退出事件后,使用VMRUN命令再次让guest运行。
NAE事件是由guest执行特定指令,如读取模拟设备的寄存器等。NAE事件发生时,会产生一个新的异常(VMM Communication Exception(#VC)),且该异常由guest处理。
trap新的控制寄存器写入
- 对CR0-CR15, EFER的写入后会产生AE
- EXITINFO1中保存了寄存器的新值
- hypervisor可以据此跟踪控制寄存器的变化
- 只有SEV-ES guest支持
Guest-Hypervisor Communication Block(GHCB)
- 允许guest与hypervisor进行寄存器状态的通信
- 使用共享页(非加密)
-
- guest将GHCB的物理地址写入MSR
- hypervisor通过VMCB Control Area获取guest物理地址
GHCB位于共享内存中,因此guest和hypervisor都可以访问。
新的VMM Communication Exception(#VC)
- SEV-ES guest发生NAE事件时触发
- 错误码与NAE事件中的VMEXIT码相同
#VC handler
- 根据错误码准备GHCB
-
- 将需要的寄存器状态拷贝到GHCB
- 设置SW_EXITCODE, SW_EXITINFO1等
- 通过VMGEXIT指令触发AE事件(REP VMMCALL)
- VMGEXIT完成时检查GHCB
-
- 检查SW_EXITINFO以判断成功或者失败
-
-
- 失败时触发异常(如RDMSR of un-supported MSR)
-
-
- 从GHCB中拷贝寄存器状态
新的VMGEXIT(Virtual Machine General Exit)指令会导致一个AE退出,CPU硬件会保存加密后的guest state并读取hypervisor状态,把控制权转交给hypervisor。
SEV-SNP介绍
SNP(Secure Nested Paging)用于防止integrity attack。SEV-SNP一致性的基本原则是:如果VM能够读取一个加密的页,则VM总是能够读取到上次写入的值。就是说如果VM向地址X写入了值A,之后任意时刻读取地址X,要么能够读取到A,要么获取到一个内存不可读的异常。SEV-SNP就是用来保证这种一致性的。
SEV,SEV-ES,SEV-SNP能够防范的威胁见下表:
SEV-SNP提供的一致性保护包括四个方面,见下表:
SEV-SNP提供的Reverse Map Table(RMP)确保了内存页的拥有者才能写该页,以及同一时刻一个物理页仅能被一个guest的页映射。RMP可以防范replay attack, data corruption attack, memory aliasing attack。
SEV-SNP提供的Page Validation确保了同一时刻一个guest的页仅能映射到一个物理页。
Reverse Map Table(RMP)介绍
RMP是一种数据结构,其中的每项代表了可以被VM使用的4k页,用以跟踪每页的拥有者(拥有者可能是hypervisor,VM,AMD-SP),只有拥有者可以写该页。RMP与x86的页表一起完成该任务。
非虚拟化场景下,虚拟地址转换成物理地址之后,通过物理地址检索到对应的RMP项,通过RMP项检测页的拥有者身份是否相符,如果不相符则产生一个#PF异常并拒绝访问。
虚拟化场景下,GVA转成GPA,GPA转成HPA后,使用HPA检索到对应的RMP项。RMP项中包含了GPA映射信息,硬件检测GPA信息是否匹配,不过不匹配则产生异常并拒绝访问。
并非所有的内存访问都会触发RMP检查。比如:开启AES保护时,hypervisor和非SEV-SNP的虚拟机读取内存时不会触发RMP检查。软件不能直接访问RMP表,而是由hypervisor通过新的CPU指令负责处理RMP表。
Page Validation介绍
在RMP项中有一个Validated位,该位在RMP项被创建时由CPU硬件置0。guest要使用内存页之前,需要通过新的CPU指令PVALIDATE将RMP项的Validated位置1,且每个guest只能对自己的内存调用该指令。
现在向guest添加页需要两个步骤:
- hypervisor使用新的RMPUPDATE指令将页赋予guest,此时页会变为Guest-Invalid状态。
- guest使用新的PVALIDATE指令将页状态转为Guest-Valid,之后可以正常使用该页。
为了满足SEV-SNP的一致性要求,guest只能对同一物理页Validate一次。
以下是一个使用RMP+Page Validation防止re-mapping攻击的例子:
- GPA A最初映射到HPA X,guest使用PVALIDATE指令将HPA X对应的RMP项的Validated位置1。
- hypervisor恶意的将A重映射到HPA Y,此时会重新创建一个RMP项并使用RMPUPDATE指令将GPA A->HPA Y的映射通知guest。
- hypervisor恶意的修改NPT,将GPA A重映射到HPA Y。
- guest访问到HPA Y,因为HPA Y对应的RMP项的Validated位为0(RMP项创建的时候Validated位初始化是0),导致guest收到#VC异常。
- guest本身知道GPA A->HPA X的映射才是合法的,因此不应该收到#VC异常,但此时收到了#VC异常,说明遭受到了攻击。此时,guest可以选择关闭或者其他必要的保护手段。
页的状态
AMD-SP提供了虚拟机生命周期和页面管理的API,为了安全考虑,在实际执行这些API之前,AMD-SP即将操作的页必须处于Immutable的状态,处于Immutable状态的页除了AMD-SP之外,即不能被软件(包括hypervisor和guest)写入也不能修改其RMP项。
页的状态总共8种,见下表:
页的状态转换如下图所示:
虚拟机特权等级
SEV-SNP支持Virtual Machine Privilege Levels(VMPLs)虚拟机特权等级特性,该特性是一个可选特性,主要用于嵌套虚拟化的场景,此处不做介绍。
中断/异常保护
略
可信平台信息
略
TCB版本
略
虚拟机启动和认证
略
虚拟机迁移
所有的SEV都支持虚拟机迁移,SEV-SNP又对迁移的灵活性进行了增强。
SEV和SEV-ES中,在迁移之前AMD-SP需要认证目标机器的AMD-SP来执行迁移策略(虚拟机是否可迁移,迁移的目标系统类型)。在SEV-SNP中,则由Migration Agent(MA)来执行迁移策略。MA是运行在迁移源主机上的一台虚拟机。虚拟机启动时可以选择绑定到有且仅有的一个MA,但是一个MA可以管理多个虚拟机的迁移。
在典型的云场景下,MA本身不可迁移,每台物理主机上运行一个MA。当虚拟机需要迁移时,源主机上的MA先认证目的主机上的MA,然后建立守保护的连接,之后通过该连接将虚拟机信息传输到目的主机,之后虚拟机可以在目的主机上启动。
注意:因为引入了MA,迁移时不需要源主机和目的主机同时在线。虚拟机被暂停后,其状态可以传送给MA,MA可以在在线迁移或者讲虚拟机状态保存在持久化存储上。之后MA可以选择在同一台主机或者其他主机上重建虚拟机。