Project | LXD |
Status | Implemented |
Author(s) | @gabrielmougard |
Approver(s) | @stgraber |
Release | 5.13 |
Abstract
We’d like to add support for enabling AMD SEV (SEV stands for Secure Encrypted Virtualization ; it is an extension of SME (Secure Memory Encryption) for virtual machines; SME is an x86 instruction set introduced by AMD for page-granular memory encryption support using a single ephemeral key) on LXD VMs.
This will have LXD instruct QEMU to encrypt guest memory as well as restrict some features.
Rationale
Enabling AMD SEV for a LXD VM would allow a user to get work done in a virtual machine in a context of Zero-Trust computing (you don’t necessarily trust your cloud provider for keeping your data safe). Also, this new feature allows a user to resist a “cold boot attack” : with the advent of persistent memory like NVDIMM, it is now possible to literally yank a memory module out and plug it somewhere else in order to analyse it. With AMD SEV, the memory is encrypted and the attacker would need the certificate’s key to decipher it.
Specification
Design
-
Detecting if the host supports SEV
First, we want to validate the presence of SME and SEV in the CPU flags. Also, we want to check if SEV-ES (ES stands for Encrypted State and it allows the encryption of the CPU register state as well as the memory) is supported, again reading the CPU flag. Once the CPU flags are validated, we need to validate QEMU’s support for SEV through QMP’squery-sev-capabilities
command -
We need a new set of user config keys to specify is SEV is enabled or not
A not-too-complex proposal could look like this :
- security.sev (bool) // is SEV enabled for this VM
- security.sev.policy.es (bool) // is SEV-ES enabled for this VM
- security.sev.session.dh (string) // guest owner\'s base64-encoded Diffie-Hellman key
- security.sev.session.data (string) // guest owner\'s base64-encoded session blob
- Launch SEV/SEV-ES guest VM
Given a successful harware validation (1) and a proper user config (2), we launch the SEV/SEV-ES guest VM through QEMU’s command line. Here is an example of a QEMU command :
qemu-system-x86_64 \
-enable-kvm \
-cpu EPYC-Milan-v2,stepping=0 \
-smp 4,maxcpus=64 \
-m 2048M,slots=5,maxmem=100G \
-no-reboot \
-drive if=pflash,format=raw,unit=0,file=/home/amd/sev-release-2022-02-10/usr/local/share/qemu/OVMF_CODE.fd,readonly \
-drive if=pflash,format=raw,unit=1,file=/home/amd/sev-release-2022-02-10/ubuntu-18.04.fd \
-device virtio-net-pci,disable-legacy=on,iommu_platform=true,netdev=netdev0,romfile= \
-netdev tap,script=/home/amd/qemu-ifup,id=netdev0 \
-drive file=/home/amd/sev-release-2022-02-10/ubuntu-18.04.qcow2,if=none,id=disk0,format=qcow2 \
-device virtio-scsi-pci,id=scsi0,disable-legacy=on,iommu_platform=true \
-device scsi-hd,drive=disk0 \
-object memory-backend-memfd-private,id=ram1,size=2G,share=true \
-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1 \
-machine q35,confidential-guest-support=sev0,memory-backend=ram1,kvm-type=protected \
-nographic -monitor pty -monitor unix:monitor,server,nowait \
-qmp unix:./qmp_sock-exp,server
- Through QEMU’s QMP, query that the launched VM has SEV enabled and running and get some information
Withquery-sev
andquery-sev-capabilities
, we’re able to fetch the some information on the SEV/SEV-ES running guest likeCBitPos
(if it is of any interest for us) so that maybe we’d want to store it somewhere.
API changes
The following keys
- security.sev (bool) // is SEV enabled for this VM
- security.sev.policy.es (bool) // is SEV-ES enabled for this VM
- security.sev.session.dh (string) // guest owner\'s base64-encoded Diffie-Hellman key
- security.sev.session.data (string) // guest owner\'s base64-encoded session blob
will be added to the Config
map :
type InstancePut struct {
...
// Instance configuration (see doc/instances.md)
Config map[string]string `json:"config" yaml:"config"`
...
}
CLI changes
No CLI changes. First, I think that we could simply add the config keys listed above through the lxc config edit <instance>
command.
Database changes
No database change.
Upgrade handling
No data migration required a priori.