AMD SEV基本原理

AMD SEV基本原理介绍 AMD 的机密解决方案 SEV 的硬件基础和软件 API amdsev

背景

  • 在云生成环境中,存在两个角色分别是Platform ower和Guest owner,Platform owner通常指云厂商,比如公有云厂商阿里、腾讯、华为等,或者企业云厂商VMware、SmartX、H3C等;Guest owner通常就是希望在云厂商提供的iass服务中运行自己业务的客户。
  • 传统模式下,Guest owner完全信任Platform owner提供的基础设置,将安全防护的工作交给Hypervisor来做,假如Hypervisor被恶意程序通过管理程序或其他软件中漏洞攻破,那么它就可以任意访问客户机内存。对于某些数据敏感的Guest owner,这样的安全事故是无法接受的,因此希望其业务数据受到保护。
  • 另一方面,Platform owner即云长商当然也想实现客户业务数据保护的需求,但提供的解决方案除了要解决用户的问题,也要考虑方案对传统计算资源管理方式的兼容,方案能够高效管理计算资源,可以做灵活的分配和释放。
  • SEV特性就是AMD为满足上述需求提供的硬件机密计算解决方案,它不仅支持机密虚机功能(对客户虚机数据加密),也很好地支持了传统虚机的生命周期(启动、热迁移、快照等),能够让虚机的管理方式平滑切换。

SME

  • SME(Secure Memory Encryption)是AMD内存加密硬件特性,AMD通过在SOC的内存控制器上增加加解密引擎,实现对内存数据的加解密。

Arch

  • SME内存加密原理如下图所示:
    在这里插入图片描述
  • AMD在其SOC的内存控制器中增加支持AES加解密的硬件引擎,当CPU向内存写数据时,数据首先被内存控制器中的加密引擎加密,然后写入到内存;当CPU从内存读数据时控制器做对应的解密处理并返回给CPU。

C-bit

  • 为支持对内存的加密并且兼容原有的MMU硬件设计,AMD将页表项中原来存放物理页地址的字段划分出1个bit作为C-bit(enCrypted bit),用于控制该表项指向的物理内存页是否需要加密。由于页表项的低12bit已经被用做传统的页表转换功能,因此C-bit只能放到存放物理页地址的字段,并且其具体位置和硬件架构相关,需要通过CPUID获取得到。注意,C-bit可以存在于PTE、PDE、PDPE甚至PML4E的表项中,因此C-bit既可以控制1个具体的物理页是否加密,可以控制整个PDE、PDPE、PML4E表包含的物理页是否加密。
  • 下图是AMD手册中1个4K页表项的字段描述,对于Hygon C86 7380 32-core Processor,其C-bit为bit 47。从硬件设计来看,AMD牺牲了至少1 bit物理地址位宽来支持内存页加密。
    在这里插入图片描述
  • AMD利用页表项中的物理地址来支持内存加密,势必会导致物理地址位宽减少,AMD没有给出计算减少物理地址位宽的方式,而是提供了CPUID指令让用户查询, AMD手册中查询C-bitPhysAddrReduction介绍如下图所示(Volume 3 Appendix E.4.17):
    在这里插入图片描述
  • 当EAX输入为0xF,执行CPUID指令后,EBX寄存器中存放了CbitPositionPhysAddrReduction相关信息:
  1. CbitPosition: C-bit在页表项中的位置,单位bit
  2. PhysAddrReduction:引入C-bit后页表项中物理地址减少的宽度,单位bit
  • C-bit既能在CPU的非虚拟化(non-vitualized)模式打开,也可以在虚拟化模式且SEV特性使能的时候打开。在虚拟化模式下,使用NPT实现硬件辅助的内存虚拟化时,AMD CPU支持通过在Guest的页表项中设置C-bit来控制是否对GPA对应的物理页是否加密。Guest页表项的C-bit控制物理页是否加密原理示意图如下所示:
    在这里插入图片描述
  • AMD NPT在检测到C-bit使能后,会在页地址转换时增加额外逻辑处理C-bit,具体为:
  1. 提取NPT的输入 — Guest页表项内容(GPA),根据CPUID查询得到的CbitPosition信息在页表项中定位C-bit的位置,提取其内容并保存。
  2. 将GPA作为硬件NPT页地址转换的输入,得到HPA
  3. 将C-bit内容和2中得到的HPA一道,作为页表项内容填入物理内存页表
  • 注意,通过CPUID查询得到的PhysAddrReduction,只对物理地址的宽度有影响,对Guest的GPA地址没有影响。假设查询得到PhysAddrReduction为5,那么原来52bit的物理地址HPA变为了52-5=47bit。对于GPA,其宽度只减少了1bit,即C-bit占用的那1bit。

SME-MK

  • C-bit的引入为系统软件提供了1个内存页加密的开关。在非虚拟化的应用场景下,为了让OS软件实现更细粒度的加密控制,AMD还设计了Multi-Key Secure Memory Encryption (SME-MK)特性,该特性允许OS软件将加密内存使用的密钥导入到SOC的内存控制器中,然后在内存加密时通过选择密钥ID(EncrKeyID)指定使用的密钥。SME-MK可以通过CPUID Fn8000_0023_EAX[MemHmk]来查询CPU是否支持,可以通过CPUID Fn8000_0023_EBX[MaxMemHmkEncrKeyID]查询EncrKeyID的最大值。
  • SME-MK特性可以支持OS上不同应用程序独立加密自己的内存,其设计并非支持机密虚拟化,因此SME-MKSME是互斥的。使能SME-MKSME需要关闭,下文介绍SEV时我们可以知道,SEV特性依赖SME的打开。因此可以理解为,SME-MK可以实现多个应用内存的独立加密,应用于非虚拟化场景,SME可以使多个虚机的内存独立加密,应用在虚拟化场景,即SEV场景。

Interface

SME

  • 软件可以通过CPUID探测CPU是否支持SME相关特性,同时通过写SYSCFG MSR(地址:0xc0010010)设置。
  • 通过CPUID Fn8000_001F[EAX],可以查询CPU是否支持SME,查询信息字段解释如下 :
    在这里插入图片描述
  • 通过写SYSCFG MSR可以使能SME,SYSCFG MSR字段解释如下:
    在这里插入图片描述
  • CPUID Fn8000_001F指令的EAX和EBX输出解释已在之前 介绍,这里贴出AMD手册中ECX和EDX中各字段含义,如下 :
    在这里插入图片描述
  • 以Hygon C86 7380 32-core Processor为例,并升级到Hygon支持机密计算的内核,通过cpuid工具查看CPU是否支持SME和SEV相关特性。
    在这里插入图片描述
  1. EAX:0xf,0b1111,支持SME、SEV、PageFlushMsr、SEV-ES
  2. EBX: 0x16f,0b,
    bit[0]-bit[5]为CbitPosition,二进制0b,十进制47,表示C-bit控制位 在页表项的bit 47
    bit[6]-bit[11]为PhysAddrReduction,二进制0b101,十进制5,表示CPU寻址物理内存空间使用的地址长度减少了5bit
  3. ECX:0xffff,15,SEV相关,参考SEV章节
  4. EDX:0x1,MinSevNoEsAsid,SEV相关,参考SEV章节
  • 通过rdmsr工具查看当前CPU的SYSCFG MSR输出:0xf40000 = 0b1111 0100 0000 0000 0000 0000
    在这里插入图片描述
  • 参考手册,解析上面MSR寄存器的输出字段含义如下:
  1. bit 18: MFDE enabled
  2. bit 20: MVDM enabled
  3. bit 21: TOM2 enabled
  4. bit 22: FWB enabled
  5. bit 23: MEME,MemEncryptionModeEn enabled,内存加密特性使能
  6. bit 26: HMKE,HostMultiKeyMemEncrModeEn disabled

SME-MK

  • 通过CPUID Fn8000_0023_EAX[MemHmk]指令可以查询CPU是否支持SME-MK,如果CPU支持 ,可以通过CPUID Fn8000_0023_EBX[MaxMemHmkEncrKeyID]查询CPU支持的密钥数上限;通过写SYSCFG MSR可以使能SME-MK。CPUID的输出信息如下图所示,使能SME-MKSYSCFG MSR位在上一节已介绍。
    在这里插入图片描述
  • 通过cpuid工具查看SME-MK的支持情况:
    在这里插入图片描述
  • 可以看到输出EAX为0,Hygon C86 7380不支持SME-MK

SEV

  • SEV:(Secure Encrypted Virtualization)是AMD设计的机密虚拟化硬件解决方案。SEV在内存加密的基础之上,引入了安全处理器(PSP - Platform Secure Processor)解决密钥管理的扩展性问题,支持为每个内存加密的虚机关联一个密钥。
  • 相比标准的X86虚拟化硬件方案,SEV最大的不同就是可以让Guest对其本身使用的主机上物理内存进行权限控制,Guest可以决定哪些内存可以暴露给hypervisor,哪些不可以暴露给hypervisor。更进一步,作为SEV的增强,SEV-ES特性还可以让Guest决定哪些寄存器可以暴露给hypervisor,哪些不可以暴露。

Arch

  • SEV整体架构示意图如下:
    在这里插入图片描述
  • 传统的虚拟化架构中有两个角色,分别是Hypervisor和Guest,Hypervisor负责了所有Guest的权限管理,可以对虚机的代码和数据进行查看和修改。具体表现为:
  1. Hypervisor可以访问虚机GPA对应的HPA内存内容。
  2. Hypervisor可以访问虚机使用的CPU寄存器内容。
  3. Hypervisor可以篡改虚机使用的镜像文件。
  4. Hypervisor可以根据需要修改启动虚机所使用的命令行参数。
  • SEV架构下新增了一个角色Guest Owner,将Hypervisor权限中的上述部分剥离出来,赋给了新角色Guest Owner。Hypervisor的CPU计算能力仍然被使用,但管理属性被削弱。SEV架构下,可以将Hypervisor的看成是提供计算虚拟化能力的虚机管理代理角色。
  • 在SEV架构下,每个机密虚机都关联了一个密钥,密钥管理由AMD Secure Processor负责;CPU与AMD Secure Processor之间基于厂商提供的SEV API实现SEV Driver,Hypervisor集成SEV Dirver后,进一步通过调用SEV API实现对机密虚拟机的生命周期管理。
  • AMD硬件逻辑中为每个机密虚机都关联一个密钥,作为加密该虚机内存的密钥,这是AMD Secure Processor的内部逻辑,那么Hypervisor软件如何指定虚机关联的密钥呢?AMD将VMCB结构中的ASID字段作为了机密虚机关联的密钥ID,当执行VMRUN指令运行虚机时,硬件读取VMCB结构中的ASID字段的值,作为密钥ID。当然,AMD能够支持的密钥个数有上限,上限值可以通过CPUID 8000_001F[ECX]查询得到,ASID作为密钥ID,其值也不能大于该上限。同时ASID在SEV使能,SEV-ES未使能的模式下,其取值还有1个下限,下限值通过CPUID 8000_001F[EDX]查询得到。

Interface

  • 在介绍SME的章节中,我们知道可以通过CPUID Fn8000_001F查询硬件对SME、SEV的支持情况,SEV相关字段总结如下:
  1. CPUID 8000_001F_EAX[SME]: 是否支持内存加密
  2. CPUID 8000_001F_EAX[SEV]: 是否支持机密虚拟化
  3. CPUID 8000_001F_EAX[SEV-ES]: 是否支持机密虚拟化且支持集存器的加密
  4. CPUID 8000_001F_EBX[CbitPosition]: C-bit在页表项中的位置
  5. CPUID 8000_001F_EBX[PhysAddrReduction]: 内存加密牺牲的物理地址位宽
  6. CPUID 8000_001F_ECX[NumEncryptedGuests]: 支持的最大机密虚机个数
  7. CPUID 8000_001F_EDX[MinSevNoEsAsid]: 使能SEV禁用SEV-ES的模式下,ASID的最小值
  • 我们再分析一下SME章节中CPUID指令查询得到的输出信息,现在我们知道了NumEncryptedGuestsMinSevNoEsAsid字段的含义,它确定了使能SEV禁用SEV-ES的模式下,ASID的取值范围是[1, 15]。
    在这里插入图片描述

SEV API

  • 从上述关于SEV的介绍中,我们知道AMD Secure Processor的主要功能是实现密钥管理,这是硬件的逻辑,当硬件具备这样的能力后,它通过MMIO Registers向外界暴露自己的API,包括平台管理API(Platform Management API)和虚机管理API(Guest Management API),SEV Driver通过对MMIO Registers的读写操作将API封装,最后供Hypervisor调用,整个架构示意图如下:
    在这里插入图片描述
  • AMD在提供SEV硬件机制的同时,也提供SEV API规范,开发者只要按照该规范实现SEV Driver并集成到Hypervisor,就可以支持SEV特性。因此SEV API才是指导开发者如何实现SEV虚拟化解决方案的标准参考文档,本章节简要介绍该规范涉及的内容。

Key Management

证书链

  • 机密虚拟化场景下,Guest Owner认为Hypervisor软件是不可信的,只有AMD安全处理器(内核源码中也称AMD Platform Security Processor)是可信的,但安全处理器的可信是需要第三方的权威机构来认证的,这个权威机构就是服务器厂商AMD,这有点类似PKI中的CA。安全处理器怎么证明自己是可信的呢,我们知道安全处理器通过SEV Firmware与外界交互,因此证明安全处理器可信就需要证明SEV Firmware是可信的,否则所有与Firmware的通信都将变得不可信,进而所有SEV API都将不可信,基于API开发的SEV Driver以及其提供的kernel ioctl都变得不可信。
  • 通过以上分析,我们知道认证AMD安全处理器可信的第一要务是认证固件可信,这个职责由一个叫PEK-Platform Endorsement Key的证书来完成,SEV Firmware提供一个APIPEK_GEN来创建PEK,另外还有一个API INIT也可能创建PEK。通常情况下,使能SEV特性服务器在启动的时候,DEV Driver会发起INIT,如果固件发现自己没有PEK,那么固件就会自动创建一个PEK;而PEK_GEN接口是单独的PEK创建接口,大部分场景不会使用,只在Policy要求的情况下才会设置。
  • PEK是由固件创建的,我们也讨论了PEK创建的场景,那么为什么PEK可以由固件随意创建呢?如果固件也不可信,是不是创建的PEK也不可信?如果说PEK创建的时候是自签名的,它就是根CA了(Root CA),也就是说Guest owner只能无条件信任固件了,这其实也不合理,因为固件也可能由其它攻击方提供并烧录到芯片中。
  • 这里的解释是,PEK在创建的时候是有被权威的第三方CA签名的,这就是CEK,而CEK怎么来的?它是服务器厂商AMD签发的,它的生成过程是,本地软件通过调用API GEN_ID查询得到CPU的ID信息,将ID信息与公司信息一起作为输入,在AMD提供的CA管理网站上提交CSR(Certificate Signing Request),CA验证CPU ID是否有效,如果有效,再检查该服务器是否由输入中提到的公司购买,最后,如果所有检查通过,CA会使用ASK的私钥对签名后颁发的,CEK被下载到本地后再导入到固件中,通过这样的方式才完成整个固件的可信认证,因此CEK成为了固件可信的起点。除此之外,PEK还会被OCA签名。参考下一段的描述。
  • 固件认证的整个证书链如下图所示:
    在这里插入图片描述

会话密钥

  • 上图中我们还看到PDH(Platform Diffe-Hellman Key),这是做什么的呢?当Guest owner想要与固件通信时,因为需要经过不可信的Hypervisor,所以消息需要做加密处理。因此Guest owner需要协商一个共享密钥用于消息加密的密钥。具体做法是Guest owner向固件请求用于计算共享密钥的PDH(通过API PDH_CERT_EXPORT),PSP导出的PDH用于Guest owner计算共享密钥,Guest owner提供的PDH用于PSP计算的共享密钥,两者最终计算得到相同的共享密钥。
  • 另外,Guest owner还会验证PDH是否可信,怎么证明这个PDH就是可信的固件发来的呢?其实PDH_CERT_EXPORT API不仅导出PDH,还会附带证书用于证明固件提供的PDH是可信的,这些证书包括PEK证书、CEK证书和OCA。Guest owner校验PDH的过程如下:
  1. 获取ASK证书,并使用ASK证书对验证CEK是否可信
  2. 如果1验证通过,使用CEK证书对PEK证书进行校验,验证其是否可信
  • 对PDH的可信验证通过后,使用PEK证书的公钥对PDH进行解密得到PDH的明文,根据AMD Firmware API的介绍,密钥交换算法使用Elliptic Curve Diffie-Hellman (ECDH) ,PDH的明文即为固件提供的用于计算共享密钥的公钥。Guest Owner拿到公钥后通过以下步骤实现共享密钥的协商:
  1. 根据PDH的明文获取椭圆曲线的参数,为计算要发送给固件的公钥做准备
  2. 随机生成私钥,结合椭圆曲线的参数,计算得到要发送给固件的公钥
  3. 根据随机生成的私钥,椭圆曲线参数和固件发来的PDH中包含的公钥数据,计算得到会话密钥,用做固件通信
  • 在固件初始化完成后的任何时间(通常是虚机启动前),Guest owner都可以请求Hypervisor将固件的PDH导出并发送给自己,Guest owner拿到PDH后通过上述步骤得到两个值,一是计算得到通信的会话密钥;一是要发送给固件的公钥(让固件可以计算得到会话密钥,与Guest owner计算得到的值相同),过程如下:
    在这里插入图片描述
  • 通过上述方式,虽然Guest owner与安全处理器之间的消息将不可信的Hypervisor作为传输通道,但因为两者通信是加密的,所以两者的数据传输仍然是安全的。

证书签发

  • 固件一经出厂,在第一次上电初始化后,首先要做的事就是证明自己的可信身份,通常做法是导出自己的芯片ID作为输入,请求厂商的CA对该信息进行签名并颁发证书,从而证明自己的可信根在厂商。但在实际使用固件及PSP时,除了将可信根与厂商挂钩,更普遍的策略是将可信根与Platform owner挂钩,这样只要Platform owner被Guest owner认证为可信的,那么Guest owner也可以放心的与PSP通信。这两种场景有所不同,第一种场景固件的owner即Platfor owner就是它自己,第二种场景固件的owner是其它实体,为了支持这两种场景,SEV还涉及了一个OCA证书,作为PSP平台的信任根,平台上产生的其它证书,其证书链的顶端就是OCA,当PSP是自包含的即Platform owner是自己,那么OCA证书的公钥和私钥都由PSP来维护,即第一种场景;当PSP属于其它实体,那么OCA证书的公钥由PSP维护,私钥Platform owner维护,OCA与平台的关系参考证书链示意图。
  • 为了支持第二种场景,PSP还提供一个接口输出CSR,该CSR包含的PEK的公钥以及Platform的信息,Platform owner将作为CA对CSR进行处理,即使用自己的私钥对CSR签名并生成PEK证书,最后通过PEK_CERT_IMPORT导入到PSP,完成PSP的平台认证,通过该步骤,PSP不仅可以被厂商证明是可信的,还可以被Platform owner证明是可信的。整个过程如下:
    在这里插入图片描述

Guest Policy

  • 机密虚拟化场景下,Hypervisor对虚机的管理需要调用SEV API完成,AMD向Guest owner提供了针对不同场景的权限配置(即Guest Policy),用来约束Hypervisor对虚机的操作权限。Guest owner通过配置Guest Policy可以达到控制Hypervisor行为的目录。当然这些行为只会与机密计算相关,不会涉及到Hypervisor的本旨工作(即计算资源的管理),因此Policy不会很多,如下图所示:
    在这里插入图片描述
  1. NODBG:不允许hypervisor对虚机进行debug
  2. NOKS:TODO
  3. ES:要求开启SEV-ES,即对寄存器进行加密
  4. NOSEND:TODO
  5. DOMAIN:TODO
  6. SEV:不允许虚机迁移到其它不支持SEV的平台
  7. API_MAJOR/API_MINOR:不允许虚机迁移到其它固件版本低于指定版本的平台

API

Mailbox Register Protocol

  • 我们提到AMD安全处理器可以为软件提供平台管理API(Platform Management API)和虚机管理API(Guest Management API),这通过一组MMIO寄存器来实现。软件可以通过读写这组软件向AMD安全处理器发送命令并获取命令返回结果,这组寄存器包括CmdResp Register、CmdBufAddr_Hi RegisterCmdBufAddr_Lo Register,格式如下:
    在这里插入图片描述
  • 在安全提供的API中,可以分为两类,一类是不需要传入参数的API(比如GET_ID);另一类需要传入参数(比如PEK_CSR、PEK_CERT_IMPORT)。当API不需传入参数时,直接写CmdResp Register即可;当需要传入参数时,在填写CmdResp Register之后,还需要将参数所在内存的物理地址填入CmdBufAddr_Hi Register/CmdBufAddr_Lo Register
  • 另外,软件通过写寄存器发送命令的工作模式也有两种,一种是Mailbox模式,这是最早支持的模式;另一种是Ring Buffer模式,这个模式在SEV Firmware 0.24版本开始支持,当以Mailbox模式向CmdResp Register写入特定的命令(RING_BUFFER)时其工作模式就会切换到Ring Buffer,而寄存器的含义也随之改变:CmdResp变为RBCtlCmdBufAddr_Hi变为RBTailCmdBufAddr_Lo变为RBHeadRing Buffer模式的工作方式不再介绍。感兴趣可以查看SEV API的4.2章节。

Platform Management API

  • SEV安全处理器提供的平台管理API主要功能就是支持Firmware和Platform的可信验证,当然也包括基本的平台生命周期API,所有API如下图所示:
    在这里插入图片描述
  • TODO

Guest Management API

  • SEV既要保证SEV虚机可以实现机密计算,又要兼容传统Hypervisor的资源管理方案,因此需要提供一组API来让Hypervisor实现SEV虚机的生命周期管理,这就是虚机管理API —— Guest Management API
  • SEV Driver基于Guest Management API,封装了支持虚机管理的一系列interface并集成到KVM中,KVM基于SEV Driver,封装了虚机管理的一系列IOCTL命令字供用户态程序(比如QEMU)使用,因此可以说Guest Management API才是虚拟化工程师支持SEV需要了解的核心内容:
    在这里插入图片描述
  • TODO
今天的文章 AMD SEV基本原理分享到此就结束了,感谢您的阅读。
编程小号
上一篇 2024-12-20 09:01
下一篇 2024-12-20 08:57

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/91747.html