From: Dov Murik <dovmurik@linux.ibm.com>
To: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: "Tom Lendacky" <thomas.lendacky@amd.com>,
"Ashish Kalra" <ashish.kalra@amd.com>,
"Brijesh Singh" <brijesh.singh@amd.com>,
"James Bottomley" <jejb@linux.ibm.com>,
"Marcelo Tosatti" <mtosatti@redhat.com>,
qemu-devel@nongnu.org,
"Dr. David Alan Gilbert" <dgilbert@redhat.com>,
"Dov Murik" <dovmurik@linux.ibm.com>,
"Tobin Feldman-Fitzthum" <tobin@linux.ibm.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@redhat.com>
Subject: Re: [PATCH] docs: Add measurement calculation details to amd-memory-encryption.txt
Date: Thu, 16 Dec 2021 12:38:34 +0200 [thread overview]
Message-ID: <336cbad3-06da-f11c-8cd1-ca058dd9c6b0@linux.ibm.com> (raw)
In-Reply-To: <Ybjk6XJUNIyC/LX5@redhat.com>
On 14/12/2021 20:39, Daniel P. Berrangé wrote:
> On Tue, Dec 14, 2021 at 01:59:10PM +0000, Dov Murik wrote:
>> Add a section explaining how the Guest Owner should calculate the
>> expected guest launch measurement for SEV and SEV-ES.
>>
>> Also update the name and link to the SEV API Spec document.
>>
>> Signed-off-by: Dov Murik <dovmurik@linux.ibm.com>
>> Suggested-by: Daniel P. Berrangé <berrange@redhat.com>
>> ---
>> docs/amd-memory-encryption.txt | 50 +++++++++++++++++++++++++++++++---
>> 1 file changed, 46 insertions(+), 4 deletions(-)
>>
>> diff --git a/docs/amd-memory-encryption.txt b/docs/amd-memory-encryption.txt
>> index ffca382b5f..f97727482f 100644
>> --- a/docs/amd-memory-encryption.txt
>> +++ b/docs/amd-memory-encryption.txt
>> @@ -43,7 +43,7 @@ The guest policy is passed as plaintext. A hypervisor may choose to read it,
>> but should not modify it (any modification of the policy bits will result
>> in bad measurement). The guest policy is a 4-byte data structure containing
>> several flags that restricts what can be done on a running SEV guest.
>> -See KM Spec section 3 and 6.2 for more details.
>> +See SEV API Spec [1] section 3 and 6.2 for more details.
>>
>> The guest policy can be provided via the 'policy' property (see below)
>>
>> @@ -88,7 +88,7 @@ expects.
>> LAUNCH_FINISH finalizes the guest launch and destroys the cryptographic
>> context.
>>
>> -See SEV KM API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
>> +See SEV API Spec [1] 'Launching a guest' usage flow (Appendix A) for the
>> complete flow chart.
>>
>> To launch a SEV guest
>> @@ -113,6 +113,45 @@ a SEV-ES guest:
>> - Requires in-kernel irqchip - the burden is placed on the hypervisor to
>> manage booting APs.
>>
>> +Calculating expected guest launch measurement
>> +---------------------------------------------
>> +In order to verify the guest launch measurement, The Guest Owner must compute
>> +it in the exact same way as it is calculated by the AMD-SP. SEV API Spec [1]
>> +section 6.5.1 describes the AMD-SP operations:
>> +
>> + GCTX.LD is finalized, producing the hash digest of all plaintext data
>> + imported into the guest.
>> +
>> + The launch measurement is calculated as:
>> +
>> + HMAC(0x04 || API_MAJOR || API_MINOR || BUILD || GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)
>> +
>> + where "||" represents concatenation.
>> +
>> +The values of API_MAJOR, API_MINOR, BUILD, and GCTX.POLICY can be obtained
>> +from the 'query-sev' qmp command.
>> +
>> +The value of MNONCE is part of the response of 'query-sev-launch-measure': it
>> +is the last 16 bytes of the base64-decoded data field (see SEV API Spec [1]
>> +section 6.5.2 Table 52: LAUNCH_MEASURE Measurement Buffer).
>> +
>> +The value of GCTX.LD is SHA256(firmware_blob || kernel_hashes_blob || vmsas_blob),
>> +where:
>> +
>> +* firmware_blob is the content of the entire firmware flash file (for example,
>> + OVMF.fd).
>
> Lets add a caveat that the firmware flash should be built to be stateless
> ie that it is not secure to attempt to measure a guest where the firmware
> uses an NVRAM store.
>
* firmware_blob is the content of the entire firmware flash file (for
example, OVMF.fd). Note that you must build a stateless firmware file
which doesn't use an NVRAM store, because the NVRAM area is not
measured, and therefore it is not secure to use a firmware which uses
state from an NVRAM store.
>> +* if kernel is used, and kernel-hashes=on, then kernel_hashes_blob is the
>> + content of PaddedSevHashTable (including the zero padding), which itself
>> + includes the hashes of kernel, initrd, and cmdline that are passed to the
>> + guest. The PaddedSevHashTable struct is defined in target/i386/sev.c .
>> +* if SEV-ES is enabled (policy & 0x4 != 0), vmsas_blob is the concatenation of
>> + all VMSAs of the guest vcpus. Each VMSA is 4096 bytes long; its content is
>> + defined inside Linux kernel code as struct vmcb_save_area, or in AMD APM
>> + Volume 2 [2] Table B-2: VMCB Layout, State Save Area.
>
> Is there any practical guidance we can give apps on the way the VMSAs
> can be expected to be initialized ? eg can they assume essentially
> all fields in vmcb_save_area are 0 initialized except for certain
> ones ? Is initialization likely to vary at all across KVM or EDK2
> vesions or something ?
From my own experience, the VMSA of vcpu0 doesn't change; it is basically what QEMU
sets up in x86_cpu_reset() (which is mostly zeros but not all). I don't know if it
may change in newer QEMU (machine types?) or kvm. As for vcpu1+, in SEV-ES the
CS:EIP for the APs is taken from a GUIDed table at the end of the OVMF image, and has
actually changed a few months ago when the memory layout changed to support both TDX
and SEV.
Here are the VMSAs for my 2-vcpu SEV-ES VM:
$ hd vmsa/vmsa_cpu0.bin
00000000 00 00 93 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 f0 9b 00 ff ff 00 00 00 00 ff ff 00 00 00 00 |................|
00000020 00 00 93 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
*
00000060 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 82 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000080 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000090 00 00 8b 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000d0 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000140 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@.......|
00000150 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 |................|
00000160 00 04 00 00 00 00 00 00 f0 0f ff ff 00 00 00 00 |................|
00000170 02 00 00 00 00 00 00 00 f0 ff 00 00 00 00 00 00 |................|
00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000260 00 00 00 00 00 00 00 00 06 04 07 00 06 04 07 00 |................|
00000270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000310 10 0f 83 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000003e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
000003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
$ hd vmsa/vmsa_cpu1.bin
00000000 00 00 93 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000010 00 f0 9b 00 ff ff 00 00 00 00 80 00 00 00 00 00 |................|
00000020 00 00 93 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
*
00000060 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000070 00 00 82 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000080 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
00000090 00 00 8b 00 ff ff 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000000d0 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000140 00 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 |........@.......|
00000150 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 00 |................|
00000160 00 04 00 00 00 00 00 00 f0 0f ff ff 00 00 00 00 |................|
00000170 02 00 00 00 00 00 00 00 00 b0 00 00 00 00 00 00 |................|
00000180 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000260 00 00 00 00 00 00 00 00 06 04 07 00 06 04 07 00 |................|
00000270 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00000310 10 0f 83 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
00000320 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000003e0 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
000003f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
00001000
-Dov
next prev parent reply other threads:[~2021-12-16 10:40 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-14 13:59 [PATCH] docs: Add measurement calculation details to amd-memory-encryption.txt Dov Murik
2021-12-14 18:39 ` Daniel P. Berrangé
2021-12-16 10:38 ` Dov Murik [this message]
2021-12-16 16:09 ` Daniel P. Berrangé
2021-12-16 21:41 ` Dov Murik
2021-12-17 13:24 ` Daniel P. Berrangé
2022-01-07 20:18 ` Daniel P. Berrangé
2022-01-10 11:17 ` Dov Murik
2022-01-10 11:26 ` Daniel P. Berrangé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=336cbad3-06da-f11c-8cd1-ca058dd9c6b0@linux.ibm.com \
--to=dovmurik@linux.ibm.com \
--cc=ashish.kalra@amd.com \
--cc=berrange@redhat.com \
--cc=brijesh.singh@amd.com \
--cc=dgilbert@redhat.com \
--cc=jejb@linux.ibm.com \
--cc=mtosatti@redhat.com \
--cc=pbonzini@redhat.com \
--cc=philmd@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=thomas.lendacky@amd.com \
--cc=tobin@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).