From nobody Mon Feb 9 19:31:03 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) client-ip=170.10.129.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1667832119; cv=none; d=zohomail.com; s=zohoarc; b=YVN8j+P4Y5qCPo307fxYMjfiBznhJuxTrZ8zfLWq0ymqWS1919AjMCD6OA41cULZMQrBHXzn0Sb1K16v0LS9/zMaqnO3bi6NoPjK94xTWNtJ/n3MHYAZD961eMICm+/ov4Mm6ovmQWlxnqEs1+GZeYCsPbTf7NlZtDjWGwpA6g8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1667832119; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=zmDFwD/ffZPwBMlLubdfoqkkP+dH3BKrGMuF8hepxh4=; b=f2+V0aIhMPj+SVra96c4Px1J1Yh31XV093OPkMt0x2IIvYuBwAa8j2Geng2wp3QIxoLV2hRsl6PUaiIwUQpzY+XZxr/md2HbG+qudhYF0PMIBi0dN2LiWJZ/albsSWBBIDYmccuxQSqowfX7XtT7xCx7u1AlBaUFWI4rxlHPEcw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.zohomail.com with SMTPS id 1667832119282266.48100465556445; Mon, 7 Nov 2022 06:41:59 -0800 (PST) Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-537-sk5N8oNfPQ2KH9WHm3En-Q-1; Mon, 07 Nov 2022 09:41:56 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 68845857FAC; Mon, 7 Nov 2022 14:41:53 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (unknown [10.30.29.100]) by smtp.corp.redhat.com (Postfix) with ESMTP id 55FB840C2143; Mon, 7 Nov 2022 14:41:53 +0000 (UTC) Received: from mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (localhost [IPv6:::1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id 4F6CA19465A2; Mon, 7 Nov 2022 14:41:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) by mm-prod-listman-01.mail-001.prod.us-east-1.aws.redhat.com (Postfix) with ESMTP id DC765194705D for ; Mon, 7 Nov 2022 14:41:38 +0000 (UTC) Received: by smtp.corp.redhat.com (Postfix) id CA81840C2144; Mon, 7 Nov 2022 14:41:38 +0000 (UTC) Received: from localhost.localdomain.com (unknown [10.33.36.58]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3312440C2064; Mon, 7 Nov 2022 14:41:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1667832118; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=zmDFwD/ffZPwBMlLubdfoqkkP+dH3BKrGMuF8hepxh4=; b=amsTiLCB/aj9bZ8evRUv+GWuIVxsvF7F4VjK8RT+df50cr45fQj/+oUrW7JmWrXIjyQ5Al KmnrbYNLJ0enlmAprjN9bRZWJTmnxemxyrV/Jj92TFOXfeoYJOd6v3FQ1+by6JxAf86pNd Yrqv+Cxwl/xDPLttscg9ZPEOLlH598U= X-MC-Unique: sk5N8oNfPQ2KH9WHm3En-Q-1 X-Original-To: libvir-list@listman.corp.redhat.com From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= To: libvir-list@redhat.com Subject: [libvirt PATCH v4 10/12] docs/kbase: describe attestation for SEV guests Date: Mon, 7 Nov 2022 14:41:25 +0000 Message-Id: <20221107144127.973324-11-berrange@redhat.com> In-Reply-To: <20221107144127.973324-1-berrange@redhat.com> References: <20221107144127.973324-1-berrange@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?J=C3=A1n=20Tomko?= Errors-To: libvir-list-bounces@redhat.com Sender: "libvir-list" X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1667832120550100001 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. Reviewed-by: J=C3=A1n Tomko Signed-off-by: Daniel P. Berrang=C3=A9 --- docs/kbase/launch_security_sev.rst | 105 +++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/docs/kbase/launch_security_sev.rst b/docs/kbase/launch_securit= y_sev.rst index 2734832487..7f692af748 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. ... =20 +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 + +:: + + ... + + hvm + + + ... + Memory ------ =20 @@ -373,6 +387,97 @@ running: # dmesg | grep -i sev AMD Secure Encrypted Virtualization (SEV) active =20 +Guest attestation for SEV/SEV-ES from a trusted host +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D + +Before a confidential guest is used, it may be desirable to attest the boot +measurement. To be trustworthy the attestation process needs to be perform= ed +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 itsel= f, +as the goal of the attestation process is to detect whether the hypervisor= is +malicious. + +Performing an attestation requires that the ```` element is +configured with a guest owner Diffie-Hellman (DH) certificate, and a sessi= on +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 `_ to= ol. + +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 the PDH using:: + + $ sevctl export --full ${hostname}.pdh + +Upon receiving the PDH associated with the hypervisor, the guest owner sho= uld +validate its integrity:: + + $ sevctl verify --sev ${hostname}.pdh + PDH EP384 D256 008cec87d6bd9df67a35e7d6057a933463cd8a02440f60c5df150821b= 5662ee0 + =E2=AC=91 PEK EP384 E256 431ba88424378200d58b6fb5db9657268c599b1be25f80= 47ac2e2981eff667e6 + =E2=80=A2=E2=AC=91 OCA EP384 E256 b4f1d0a2144186d1aa9c63f19039834e729= f508000aa05a76ba044f8e1419765 + =E2=AC=91 CEK EP384 E256 22c27ee3c1c33287db24d3c06869a5ae933eb44148f= db70838019e267077c6b8 + =E2=AC=91 ASK R4096 R384 d8cd9d1798c311c96e009a91552f17b4ddc4886a= 064ec933697734965b9ab29db803c79604e2725658f0861bfaf09ad4 + =E2=80=A2=E2=AC=91 ARK R4096 R384 3d2c1157c29ef7bd4207fc0c8b08d= b080e579ceba267f8c93bec8dce73f5a5e2e60d959ac37ea82176c1a0c61ae203ed + + =E2=80=A2 =3D self signed, =E2=AC=91 =3D signs, =E2=80=A2=CC=B7 =3D inv= alid self sign, =E2=AC=91=CC=B8 =3D invalid signs + +Assuming this is successful, it is now possible to generate a unique launch +data for the guest boot attempt:: + + $ sevctl session --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 ```` field +in the ```` configuration, while the ``session.bin`` file +contents should be copied into the ```` field. + +When launching the guest, it should be set to remain in the paused state w= ith +no vCPUs running:: + + $ virsh start --paused ${myvmname} + +With it launched, it is possible to query the launch measurement:: + + $ virsh domlaunchsecinfo ${myvmname} + sev-measurement: LMnv8i8N2QejezMPkscShF0cyPYCslgUoCxGWRqQuyt0Q0aUjVkH/T6= NcmkwZkWp + 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 u= sed +to perform this validation:: + + $ virt-qemu-sev-validate \ + --measurement LMnv8i8N2QejezMPkscShF0cyPYCslgUoCxGWRqQuyt0Q0aUjVkH/T= 6NcmkwZkWp + --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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 --=20 2.37.3