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

Daniel P. Berrangé posted 12 patches 3 years, 4 months ago
There is a newer version of this series
[libvirt PATCH 10/12] docs/kbase: describe attestation for SEV guests
Posted by Daniel P. Berrangé 3 years, 4 months ago
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@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.
    </os>
    ...
 
+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>
+   ...
+
 Memory
 ------
 
@@ -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
+malicious.
+
+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
+host.
+
+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
+tool.
+
 Limitations
 ===========
 
-- 
2.37.3

Re: [libvirt PATCH 10/12] docs/kbase: describe attestation for SEV guests
Posted by Kashyap Chamarthy 3 years, 3 months ago
On Fri, Oct 07, 2022 at 12:43:05PM +0100, Daniel P. Berrangé wrote:

The doc reads well; and is a strict improvement.  I only have a couple
of small nits inline.

[...]

>  Memory
>  ------
>  
> @@ -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

nit: "attest to" --> "attest the"

> +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
> +malicious.
> +
> +Performing an attestation requires that the ``<launchSecurity>`` element is
> +configured with a guest owner DH certificate, and a session data blob. These

nit: "DH certificate" --> "Diffie-Hellman (DH) certificate"?

> +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.

Might want to mention that the ``sevtool`` needs to be installed
separately (or link to its GitHub repo?).  I see it packaged at least in
Fedora.

> +
> +First of all the PDH for the hypervisor host needs to be obtained. 

Might want to expand the "PDH" on first use: PDH (Platform
Diffie-Hellman key).  It would also be nice to define what this key
actually is (there are at least 11 keys, looking at AMD's SEV API doc).
Consider rephrasing the above to something like:

    "First of all the Platform Diffie-Hellman key (PDH) for the
    hypervisor host needs to be obtained.  The PDH is used to negotiate
    a master secret between the SEV firmware and external entities."

> 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::

[...]

> +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

Nice!

I'm going to give this a try on an SEV-ES box.  Regardless, the rest of
the doc reads well.  Thank you for documenting!

Feel free to choose what nits to address from the above.  With or without
the nits addressed:

Reviewed-by: Kashyap Chamarthy <kchamart@redhat.com>    

> +The `man page <../manpages/virt-qemu-sev-validate.html>`__ for
> +``virt-qemu-sev-validate`` outlines a great many other ways to invoke this
> +tool.
> +
>  Limitations
>  ===========
>  
> -- 
> 2.37.3
> 

-- 
/kashyap