[libvirt PATCH 10/12] docs/kbase: describe attestation for SEV guests

Daniel P. Berrangé berrange at redhat.com
Fri Oct 7 11:43:05 UTC 2022

Expand the SEV guest kbase guide with information about how to configure
a SEV/SEV-ES guest when attestation is required, and mention the use of
virt-qemu-sev-validate as a way to confirm it.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
 docs/kbase/launch_security_sev.rst | 102 +++++++++++++++++++++++++++++
 1 file changed, 102 insertions(+)

diff --git a/docs/kbase/launch_security_sev.rst b/docs/kbase/launch_security_sev.rst
index 2734832487..a19a5a4b25 100644
--- a/docs/kbase/launch_security_sev.rst
+++ b/docs/kbase/launch_security_sev.rst
@@ -206,6 +206,20 @@ libvirt to the correct OVMF binary.
+If intending to attest the boot measurement, it is required to use a
+firmware binary that is stateless, as persistent NVRAM can undermine
+the trust of the secure guest. This is achieved by telling libvirt
+that a stateless binary is required
+   ...
+   <os type='efi'>
+     <type arch='x86_64' machine='q35'>hvm</type>
+     <loader stateless='yes'/>
+   </os>
+   ...
@@ -373,6 +387,94 @@ running:
    # dmesg | grep -i sev
    AMD Secure Encrypted Virtualization (SEV) active
+Guest attestation for SEV/SEV-ES from a trusted host
+Before a confidential guest is used, it may be desirable to attest to boot
+measurement. To be trustworthy the attestation process needs to be performed
+from a machine that is already trusted. This would typically be a physical
+machine that the guest owner controls, or could be a previously launched
+confidential guest that has already itself been attested. Most notably, it is
+**not** possible to securely attest a guest from the hypervisor host itself,
+as the goal of the attestation process is to detect whether the hypervisor is
+Performing an attestation requires that the ``<launchSecurity>`` element is
+configured with a guest owner DH certificate, and a session data blob. These
+must be unique for every guest launch attempt. Any reuse will open avenues of
+attack for the hypervisor to fake the measurement. Unique data can be generated
+using the ``sevctl`` tool.
+First of all the PDH for the hypervisor host needs to be obtained. The admin
+of the hypervisor can extract this using::
+  $ sevctl export --full ${hostname}.pdh
+Upon receiving the PDH associated with the hypervisor, the guest owner should
+validate its integrity::
+  $ sevctl verify --sev ${hostname}.pdh
+  PDH EP384 D256 008cec87d6bd9df67a35e7d6057a933463cd8a02440f60c5df150821b5662ee0
+   ⬑ PEK EP384 E256 431ba88424378200d58b6fb5db9657268c599b1be25f8047ac2e2981eff667e6
+     •⬑ OCA EP384 E256 b4f1d0a2144186d1aa9c63f19039834e729f508000aa05a76ba044f8e1419765
+      ⬑ CEK EP384 E256 22c27ee3c1c33287db24d3c06869a5ae933eb44148fdb70838019e267077c6b8
+         ⬑ ASK R4096 R384 d8cd9d1798c311c96e009a91552f17b4ddc4886a064ec933697734965b9ab29db803c79604e2725658f0861bfaf09ad4
+           •⬑ ARK R4096 R384 3d2c1157c29ef7bd4207fc0c8b08db080e579ceba267f8c93bec8dce73f5a5e2e60d959ac37ea82176c1a0c61ae203ed
+   • = self signed, ⬑ = signs, •̷ = invalid self sign, ⬑̸ = invalid signs
+Assuming this is successful, it is now possible to generate a unique launch
+data for the guest boot attempt::
+  $ sevctl export --name ${myvmname} ${hostname}.pdh ${policy}
+This will generate four files
+ * ``${myvmname}_tik.bin``
+ * ``${myvmname}_tek.bin``
+ * ``${myvmname}_godh.bin``
+ * ``${myvmname}_session.bin``
+The ``tik.bin`` and ``tek.bin`` files will be needed to perform the boot
+attestation, and must be kept somewhere secure, away from the hypervisor
+The ``godh.bin`` file contents should be copied into the ``<dhCert>`` field
+in the ``<launchSecurity>`` configuration, while the ``session.bin`` file
+contents should be copied into the ``<session>`` field.
+When launching the guest, it should be set to remain in the paused state with
+no vCPUs running::
+  $ virsh start --paused ${myvmname}
+With it launched, it is possible to query the launch measurement::
+  $ virsh domlaunchsecinfo ${myvmname}
+  sev-measurement: LMnv8i8N2QejezMPkscShF0cyPYCslgUoCxGWRqQuyt0Q0aUjVkH/T6NcmkwZkWp
+  sev-api-major  : 0
+  sev-api-minor  : 24
+  sev-build-id   : 15
+  sev-policy     : 3
+The techiques required to validate the measurement reported are beyond the
+scope of this document. Fortunately, libvirt provides a tool that can be used
+to perform this validation::
+  $ virt-qemu-sev-validate \
+      --measurement LMnv8i8N2QejezMPkscShF0cyPYCslgUoCxGWRqQuyt0Q0aUjVkH/T6NcmkwZkWp
+      --api-major 0
+      --api-minor 24
+      --build-id 15
+      --policy 3
+      --tik ${myvmname}_tik.bin
+      --tek ${myvmname}_tek.bin
+  OK: Looks good to me
+The `man page <../manpages/virt-qemu-sev-validate.html>`__ for
+``virt-qemu-sev-validate`` outlines a great many other ways to invoke this

More information about the libvir-list mailing list