AMDESE / AMDSEV

AMD Secure Encrypted Virtualization
272 stars 84 forks source link

Table of contents

Secure Encrypted Virtualization (SEV)

SEV is an extension to the AMD-V architecture which supports running encrypted virtual machine (VMs) under the control of KVM. Encrypted VMs have their pages (code and data) secured such that only the guest itself has access to the unencrypted version. Each encrypted VM is associated with a unique encryption key; if its data is accessed by a different entity using a different key, the encrypted guests data will be incorrectly decrypted, leading to unintelligible data.

SEV support has been accepted in upstream projects. This repository provides scripts to build various components to enable SEV support until the distros pick the newer version of components.

To enable SEV support we need the following versions.

Project Version
kernel >= 4.16
libvirt >= 4.5
qemu >= 2.12
ovmf >= commit (75b7aa9528bd 2018-07-06 )

To enable SEV-ES support we need the following versions.

Project Version/Tag
kernel >= 5.11
libvirt >= 4.5
qemu >= 6.00
ovmf >= edk2-stable202102
  • Installing newer libvirt may conflict with existing setups hence script does not install the newer version of libvirt. If you are interested in launching SEV guest through the virsh commands then build and install libvirt 4.5 or higher. Use LaunchSecurity tag https://libvirt.org/formatdomain.html#sev for creating the SEV enabled guest.

  • SEV support is not available in SeaBIOS. Guest must use OVMF.

SLES-15

SUSE Linux Enterprise Server 15 GA includes SEV support; we do not need to compile the sources.

SLES-15 does not contain the updated libvirt packages yet hence we will use QEMU command line interface to launch VMs.

Prepare Host OS

SEV is not enabled by default, lets enable it through kernel command line:

Append the following in /etc/defaults/grub

GRUB_CMDLINE_LINUX_DEFAULT=".... kvm_amd.sev=1"

Regenerate grub.cfg and reboot the host

# grub2-mkconfig -o /boot/efi/EFI/sles/grub.cfg
# reboot

Install the qemu launch script. The launch script can be obtained from this project.

# git clone https://github.com/AMDESE/AMDSEV.git
# cd AMDSEV/distros/sles-15
# ./build.sh

Prepare VM image

Create empty virtual disk image

# qemu-img create -f qcow2 sles-15.qcow2 30G

Create a new copy of OVMF_VARS.fd. The OVMF_VARS.fd is a "template" used to emulate persistent NVRAM storage. Each VM needs a private, writable copy of VARS.fd.

#cp /usr/share/qemu/ovmf-x86_64-suse-4m-vars.bin OVMF_VARS.fd 

Download and install sles-15 guest

# launch-qemu.sh -hda sles-15.qcow2 -cdrom SLE-15-Installer-DVD-x86_64-GM-DVD1.iso -nosev

Follow the screen to complete the guest installation.

Launch VM

Use the following command to launch SEV guest

# launch-qemu.sh -hda sles-15.qcow2

NOTE: when guest is booting, CTRL-C is mapped to CTRL-], use CTRL-] to stop the guest

RHEL-8

RedHat Enterprise Linux 8.0 GA includes SEV support; we do not need to compile the sources.

Prepare Host OS

SEV is not enabled by default, lets enable it through kernel command line:

Append the following in /etc/defaults/grub

GRUB_CMDLINE_LINUX_DEFAULT=".... kvm_amd.sev=1"

Regenerate grub.cfg and reboot the host

# grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg
# reboot

Install the qemu launch script. The launch script can be obtained from this project.

# git clone https://github.com/AMDESE/AMDSEV.git
# cd AMDSEV/distros/rhel-8
# ./build.sh

Prepare VM image

Create empty virtual disk image

# qemu-img create -f qcow2 rhel-8.qcow2 30G

Create a new copy of OVMF_VARS.fd. The OVMF_VARS.fd is a "template" used to emulate persistent NVRAM storage. Each VM needs a private, writable copy of VARS.fd.

#cp /usr/share/OVMF/OVMF_VARS.fd OVMF_VARS.fd 

Download and install rhel-8 guest

# launch-qemu.sh -hda rhel-8.qcow2 -cdrom RHEL-8.0.0-20190404.2-x86_64-dvd1.iso

Follow the screen to complete the guest installation.

Launch VM

Use the following command to launch SEV guest

# launch-qemu.sh -hda rhel-8.qcow2

NOTE: when guest is booting, CTRL-C is mapped to CTRL-], use CTRL-] to stop the guest

Fedora-28

Fedora-28 includes newer kernel and ovmf packages but has older qemu. We will need to update the QEMU to launch SEV guest.

Prepare Host OS

SEV is not enabled by default, lets enable it through kernel command line:

Append the following in /etc/defaults/grub

GRUB_CMDLINE_LINUX_DEFAULT=".... kvm_amd.sev=1"

Regenerate grub.cfg and reboot the host

# grub2-mkconfig -o /boot/efi/EFI/fedora/grub.cfg
# reboot

Build and install newer qemu

# cd distros/fedora-28
# ./build.sh

Prepare VM image

Create empty virtual disk image

# qemu-img create -f qcow2 fedora-28.qcow2 30G

Create a new copy of OVMF_VARS.fd. The OVMF_VARS.fd is a "template" used to emulate persistent NVRAM storage. Each VM needs a private, writable copy of VARS.fd.

# cp /usr/share/OVMF/OVMF_VARS.fd OVMF_VARS.fd

Download and install fedora-28 guest

# launch-qemu.sh -hda fedora-28.qcow2 -cdrom  Fedora-Workstation-netinst-x86_64-28-1.1.iso

Follow the screen to complete the guest installation.

Launch VM

Use the following command to launch SEV guest

# launch-qemu.sh -hda fedora-28.qcow2

NOTE: when guest is booting, CTRL-C is mapped to CTRL-], use CTRL-] to stop the guest

Fedora-29

Fedora-29 contains all the pre-requisite packages to launch an SEV guest. But the SEV feature is not enabled by default, this section documents how to enable the SEV feature.

Prepare Host OS

Prepare VM image

Create empty virtual disk image

# qemu-img create -f qcow2 fedora-29.qcow2 30G

Create a new copy of OVMF_VARS.fd. The OVMF_VARS.fd is a "template" used to emulate persistent NVRAM storage. Each VM needs a private, writable copy of VARS.fd.

# cp /usr/share/edk2/ovmf/OVMF_VARS.fd OVMF_VARS.fd

Download and install fedora-29 guest

# launch-qemu.sh -hda fedora-29.qcow2 -cdrom  Fedora-Workstation-netinst-x86_64-29-1.1.iso

Follow the screen to complete the guest installation.

Launch VM

Use the following command to launch SEV guest

# launch-qemu.sh -hda fedora-29.qcow2

NOTE: when guest is booting, CTRL-C is mapped to CTRL-], use CTRL-] to stop the guest

Ubuntu 18.04

Ubuntu 18.04 does not includes the newer version of components to be used as SEV hypervisor hence we will build and install newer kernel, qemu, ovmf.

Prepare Host OS

# cd distros/ubuntu-18.04
# ./build.sh

Prepare VM image

Create empty virtual disk image

# qemu-img create -f qcow2 ubuntu-18.04.qcow2 30G

Create a new copy of OVMF_VARS.fd. The OVMF_VARS.fd is a "template" used to emulate persistent NVRAM storage. Each VM needs a private, writable copy of VARS.fd.

# cp /usr/local/share/qemu/OVMF_VARS.fd OVMF_VARS.fd

Install ubuntu-18.04 guest

# launch-qemu.sh -hda ubuntu-18.04.qcow2 -cdrom ubuntu-18.04-desktop-amd64.iso

Follow the screen to complete the guest installation.

Launch VM

Use the following command to launch SEV guest

# launch-qemu.sh -hda ubuntu-18.04.qcow2

NOTE: when guest is booting, CTRL-C is mapped to CTRL-], use CTRL-] to stop the guest

openSUSE-Tumbleweed

Latest version of openSUSE Tumbleweed distro contains all the pre-requisite packages to launch an SEV guest. But the SEV feature is not enabled by default, this section documents how to enable the SEV feature.

Prepare Host OS

Launch SEV VM

The SEV support is available in the latest libvirt, follow the https://libvirt.org/kbase/launch_security_sev.html to use the libvirt to create and manage the SEV guest.

SEV Containers

Container runtimes that use hardware virtualization to further isolate container workloads can also make use of SEV. As a proof-of-concept, the kata branch contains an SEV-capable version of the Kata Containers runtime that will start all containers inside of SEV virtual machines.

For installation instructions on Ubuntu systems, see the README.

Additional Resources

SME/SEV white paper

SEV API Spec

APM Section 15.34

KVM forum slides

KVM forum videos

Linux kernel

Linux kernel

Libvirt LaunchSecurity tag

Libvirt SEV

Libvirt SEV domainCap

Qemu doc

FAQ

GRUB_CMDLINE_LINUX_DEFAULT=".... swiotlb=262144"

And regenerate the grub.cfg.

SEV firmware is part of the AMD Secure Processor and is responsible for much of the life cycle management of an SEV guest. Updates to the firmware can be made available outside the traditional BIOS update path.

On Linux, the AMD Secure Processor driver (ccp) is responsible for updating the SEV firmware when the driver is loaded. The driver searches for the firmware using the kernel's firmware loading interface. The kernel's firmware loading interface will search for the firmware, by name, in a number of locations (see fw_search_path.rst), with the traditional path being /lib/firmware.

The ccp driver searches for three different possible SEV firmware files under the "amd" directory, using the first file that is found. The first file that is searched for is a firmware file with a CPU family and model specific name, then a firmware file with a CPU family and model range name, and finally a generic name. The naming convention uses the following format:

For example, for an EPYC processor with a family of 0x19 and a model of 0x01, the search order would be::

  1. amd/amd_sev_fam19h_model01h.sbin
  2. amd/amd_sev_fam19h_model0xh.sbin
  3. amd/sev.fw

The level of firmware that is loaded can be viewed in the kernel log. For example, issuing the command "dmesg | grep ccp":

[   13.879283] ccp 0000:01:00.5: enabling device (0000 -> 0002)
[   13.887532] ccp 0000:01:00.5: sev enabled
[   13.899646] ccp 0000:01:00.5: psp enabled
[   14.560461] ccp 0000:01:00.5: SEV API:1.55 build:24
[   14.644793] ccp 0000:01:00.5: SEV-SNP API:1.55 build:24

Since, on Linux, the firmware is updated on driver load of the ccp module, it is possible to update the firmware level after the system has booted. At this time, all guests would need to be shutdown and the kvm_amd module unloaded before the ccp module could be unloaded and reloaded.

SEV firmware can be obtained from the AMD Secure Encrypted Virtualization web portal or through the Linux Firmware repository.