xref: /openbmc/qemu/docs/system/i386/amd-memory-encryption.rst (revision b92b39af4219df4250f121f64d215506909c7404)
1.. _amd-sev:
2
3AMD Secure Encrypted Virtualization (SEV)
4=========================================
5
6Secure Encrypted Virtualization (SEV) is a feature found on AMD processors.
7
8SEV is an extension to the AMD-V architecture which supports running encrypted
9virtual machines (VMs) under the control of KVM. Encrypted VMs have their pages
10(code and data) secured such that only the guest itself has access to the
11unencrypted version. Each encrypted VM is associated with a unique encryption
12key; if its data is accessed by a different entity using a different key the
13encrypted guests data will be incorrectly decrypted, leading to unintelligible
14data.
15
16Key management for this feature is handled by a separate processor known as the
17AMD secure processor (AMD-SP), which is present in AMD SOCs. Firmware running
18inside the AMD-SP provides commands to support a common VM lifecycle. This
19includes commands for launching, snapshotting, migrating and debugging the
20encrypted guest. These SEV commands can be issued via KVM_MEMORY_ENCRYPT_OP
21ioctls.
22
23Secure Encrypted Virtualization - Encrypted State (SEV-ES) builds on the SEV
24support to additionally protect the guest register state. In order to allow a
25hypervisor to perform functions on behalf of a guest, there is architectural
26support for notifying a guest's operating system when certain types of VMEXITs
27are about to occur. This allows the guest to selectively share information with
28the hypervisor to satisfy the requested function.
29
30Launching (SEV and SEV-ES)
31--------------------------
32
33Boot images (such as bios) must be encrypted before a guest can be booted. The
34``MEMORY_ENCRYPT_OP`` ioctl provides commands to encrypt the images: ``LAUNCH_START``,
35``LAUNCH_UPDATE_DATA``, ``LAUNCH_MEASURE`` and ``LAUNCH_FINISH``. These four commands
36together generate a fresh memory encryption key for the VM, encrypt the boot
37images and provide a measurement than can be used as an attestation of a
38successful launch.
39
40For a SEV-ES guest, the ``LAUNCH_UPDATE_VMSA`` command is also used to encrypt the
41guest register state, or VM save area (VMSA), for all of the guest vCPUs.
42
43``LAUNCH_START`` is called first to create a cryptographic launch context within
44the firmware. To create this context, guest owner must provide a guest policy,
45its public Diffie-Hellman key (PDH) and session parameters. These inputs
46should be treated as a binary blob and must be passed as-is to the SEV firmware.
47
48The guest policy is passed as plaintext. A hypervisor may choose to read it,
49but should not modify it (any modification of the policy bits will result
50in bad measurement). The guest policy is a 4-byte data structure containing
51several flags that restricts what can be done on a running SEV guest.
52See SEV API Spec ([SEVAPI]_) section 3 and 6.2 for more details.
53
54The guest policy can be provided via the ``policy`` property::
55
56  # ${QEMU} \
57     sev-guest,id=sev0,policy=0x1...\
58
59Setting the "SEV-ES required" policy bit (bit 2) will launch the guest as a
60SEV-ES guest::
61
62  # ${QEMU} \
63     sev-guest,id=sev0,policy=0x5...\
64
65The guest owner provided DH certificate and session parameters will be used to
66establish a cryptographic session with the guest owner to negotiate keys used
67for the attestation.
68
69The DH certificate and session blob can be provided via the ``dh-cert-file`` and
70``session-file`` properties::
71
72  # ${QEMU} \
73       sev-guest,id=sev0,dh-cert-file=<file1>,session-file=<file2>
74
75``LAUNCH_UPDATE_DATA`` encrypts the memory region using the cryptographic context
76created via the ``LAUNCH_START`` command. If required, this command can be called
77multiple times to encrypt different memory regions. The command also calculates
78the measurement of the memory contents as it encrypts.
79
80``LAUNCH_UPDATE_VMSA`` encrypts all the vCPU VMSAs for a SEV-ES guest using the
81cryptographic context created via the ``LAUNCH_START`` command. The command also
82calculates the measurement of the VMSAs as it encrypts them.
83
84``LAUNCH_MEASURE`` can be used to retrieve the measurement of encrypted memory and,
85for a SEV-ES guest, encrypted VMSAs. This measurement is a signature of the
86memory contents and, for a SEV-ES guest, the VMSA contents, that can be sent
87to the guest owner as an attestation that the memory and VMSAs were encrypted
88correctly by the firmware. The guest owner may wait to provide the guest
89confidential information until it can verify the attestation measurement.
90Since the guest owner knows the initial contents of the guest at boot, the
91attestation measurement can be verified by comparing it to what the guest owner
92expects.
93
94``LAUNCH_FINISH`` finalizes the guest launch and destroys the cryptographic
95context.
96
97See SEV API Spec ([SEVAPI]_) 'Launching a guest' usage flow (Appendix A) for the
98complete flow chart.
99
100To launch a SEV guest::
101
102  # ${QEMU} \
103      -machine ...,confidential-guest-support=sev0 \
104      -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1
105
106To launch a SEV-ES guest::
107
108  # ${QEMU} \
109      -machine ...,confidential-guest-support=sev0 \
110      -object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x5
111
112An SEV-ES guest has some restrictions as compared to a SEV guest. Because the
113guest register state is encrypted and cannot be updated by the VMM/hypervisor,
114a SEV-ES guest:
115
116 - Does not support SMM - SMM support requires updating the guest register
117   state.
118 - Does not support reboot - a system reset requires updating the guest register
119   state.
120 - Requires in-kernel irqchip - the burden is placed on the hypervisor to
121   manage booting APs.
122
123Calculating expected guest launch measurement
124---------------------------------------------
125
126In order to verify the guest launch measurement, The Guest Owner must compute
127it in the exact same way as it is calculated by the AMD-SP.  SEV API Spec
128([SEVAPI]_) section 6.5.1 describes the AMD-SP operations:
129
130    GCTX.LD is finalized, producing the hash digest of all plaintext data
131    imported into the guest.
132
133    The launch measurement is calculated as:
134
135    HMAC(0x04 || API_MAJOR || API_MINOR || BUILD || GCTX.POLICY || GCTX.LD || MNONCE; GCTX.TIK)
136
137    where "||" represents concatenation.
138
139The values of API_MAJOR, API_MINOR, BUILD, and GCTX.POLICY can be obtained
140from the ``query-sev`` qmp command.
141
142The value of MNONCE is part of the response of ``query-sev-launch-measure``: it
143is the last 16 bytes of the base64-decoded data field (see SEV API Spec
144([SEVAPI]_) section 6.5.2 Table 52: LAUNCH_MEASURE Measurement Buffer).
145
146The value of GCTX.LD is
147``SHA256(firmware_blob || kernel_hashes_blob || vmsas_blob)``, where:
148
149* ``firmware_blob`` is the content of the entire firmware flash file (for
150  example, ``OVMF.fd``).  Note that you must build a stateless firmware file
151  which doesn't use an NVRAM store, because the NVRAM area is not measured, and
152  therefore it is not secure to use a firmware which uses state from an NVRAM
153  store.
154* if kernel is used, and ``kernel-hashes=on``, then ``kernel_hashes_blob`` is
155  the content of PaddedSevHashTable (including the zero padding), which itself
156  includes the hashes of kernel, initrd, and cmdline that are passed to the
157  guest.  The PaddedSevHashTable struct is defined in ``target/i386/sev.c``.
158* if SEV-ES is enabled (``policy & 0x4 != 0``), ``vmsas_blob`` is the
159  concatenation of all VMSAs of the guest vcpus.  Each VMSA is 4096 bytes long;
160  its content is defined inside Linux kernel code as ``struct vmcb_save_area``,
161  or in AMD APM Volume 2 ([APMVOL2]_) Table B-2: VMCB Layout, State Save Area.
162
163If kernel hashes are not used, or SEV-ES is disabled, use empty blobs for
164``kernel_hashes_blob`` and ``vmsas_blob`` as needed.
165
166Launching (SEV-SNP)
167-------------------
168Boot images (such as bios) must be encrypted before a guest can be booted. The
169``MEMORY_ENCRYPT_OP`` ioctl provides commands to encrypt the images:
170``SNP_LAUNCH_START``, ``SNP_LAUNCH_UPDATE``, and ``SNP_LAUNCH_FINISH``. These
171three commands communicate with SEV-SNP firmware to generate a fresh memory
172encryption key for the VM, encrypt the boot images for a successful launch. For
173more details on the SEV-SNP firmware interfaces used by these commands please
174see the SEV-SNP Firmware ABI.
175
176``SNP_LAUNCH_START`` is called first to create a cryptographic launch context
177within the firmware. To create this context, the guest owner must provide a
178guest policy and other parameters as described in the SEV-SNP firmware
179specification. The launch parameters should be specified as described in the
180QAPI schema for the sev-snp-guest object.
181
182The ``SNP_LAUNCH_START`` uses the following parameters, which can be configured
183by the corresponding parameters documented in the QAPI schema for the
184'sev-snp-guest' object.
185
186+--------+-------+----------+-------------------------------------------------+
187| key                       | type  | default  | meaning                      |
188+---------------------------+-------------------------------------------------+
189| policy                    | hex   | 0x30000  | a 64-bit guest policy        |
190+---------------------------+-------------------------------------------------+
191| guest-visible-workarounds | string| 0        | 16-byte base64 encoded string|
192|                           |       |          | for guest OS visible         |
193|                           |       |          | workarounds.                 |
194+---------------------------+-------------------------------------------------+
195
196``SNP_LAUNCH_UPDATE`` encrypts the memory region using the cryptographic context
197created via the ``SNP_LAUNCH_START`` command. If required, this command can be
198called multiple times to encrypt different memory regions. The command also
199calculates the measurement of the memory contents as it encrypts.
200
201``SNP_LAUNCH_FINISH`` finalizes the guest launch flow. Optionally, while
202finalizing the launch the firmware can perform checks on the launch digest
203computing through the ``SNP_LAUNCH_UPDATE``. To perform the check the user must
204supply the id block, authentication blob and host data that should be included
205in the attestation report. See the SEV-SNP spec for further details.
206
207The ``SNP_LAUNCH_FINISH`` uses the following parameters, which can be configured
208by the corresponding parameters documented in the QAPI schema for the
209'sev-snp-guest' object.
210
211+--------------------+-------+----------+-------------------------------------+
212| key                | type  | default  | meaning                             |
213+--------------------+-------+----------+-------------------------------------+
214| id-block           | string| none     | base64 encoded ID block             |
215+--------------------+-------+----------+-------------------------------------+
216| id-auth            | string| none     | base64 encoded authentication       |
217|                    |       |          | information                         |
218+--------------------+-------+----------+-------------------------------------+
219| author-key-enabled | bool  | 0        | auth block contains author key      |
220+--------------------+-------+----------+-------------------------------------+
221| host_data          | string| none     | host provided data                  |
222+--------------------+-------+----------+-------------------------------------+
223
224To launch a SEV-SNP guest (additional parameters are documented in the QAPI
225schema for the 'sev-snp-guest' object)::
226
227  # ${QEMU} \
228    -machine ...,confidential-guest-support=sev0 \
229    -object sev-snp-guest,id=sev0,cbitpos=51,reduced-phys-bits=1
230
231
232Debugging
233---------
234
235Since the memory contents of a SEV guest are encrypted, hypervisor access to
236the guest memory will return cipher text. If the guest policy allows debugging,
237then a hypervisor can use the DEBUG_DECRYPT and DEBUG_ENCRYPT commands to access
238the guest memory region for debug purposes.  This is not supported in QEMU yet.
239
240Snapshot/Restore
241----------------
242
243TODO
244
245Live Migration
246---------------
247
248TODO
249
250References
251----------
252
253`AMD Memory Encryption whitepaper
254<https://www.amd.com/content/dam/amd/en/documents/epyc-business-docs/white-papers/memory-encryption-white-paper.pdf>`_
255
256.. [SEVAPI] `Secure Encrypted Virtualization API
257   <https://www.amd.com/system/files/TechDocs/55766_SEV-KM_API_Specification.pdf>`_
258
259.. [APMVOL2] `AMD64 Architecture Programmer's Manual Volume 2: System Programming
260   <https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf>`_
261
262KVM Forum slides:
263
264* `AMD’s Virtualization Memory Encryption (2016)
265  <http://www.linux-kvm.org/images/7/74/02x08A-Thomas_Lendacky-AMDs_Virtualizatoin_Memory_Encryption_Technology.pdf>`_
266* `Extending Secure Encrypted Virtualization With SEV-ES (2018)
267  <https://www.linux-kvm.org/images/9/94/Extending-Secure-Encrypted-Virtualization-with-SEV-ES-Thomas-Lendacky-AMD.pdf>`_
268
269`AMD64 Architecture Programmer's Manual:
270<https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/programmer-references/24593.pdf>`_
271
272* SME is section 7.10
273* SEV is section 15.34
274* SEV-ES is section 15.35
275