| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243 |
- .. SPDX-License-Identifier: GPL-2.0
- ===================================================================
- The Definitive SEV Guest API Documentation
- ===================================================================
- 1. General description
- ======================
- The SEV API is a set of ioctls that are used by the guest or hypervisor
- to get or set a certain aspect of the SEV virtual machine. The ioctls belong
- to the following classes:
- - Hypervisor ioctls: These query and set global attributes which affect the
- whole SEV firmware. These ioctl are used by platform provisioning tools.
- - Guest ioctls: These query and set attributes of the SEV virtual machine.
- 2. API description
- ==================
- This section describes ioctls that is used for querying the SEV guest report
- from the SEV firmware. For each ioctl, the following information is provided
- along with a description:
- Technology:
- which SEV technology provides this ioctl. SEV, SEV-ES, SEV-SNP or all.
- Type:
- hypervisor or guest. The ioctl can be used inside the guest or the
- hypervisor.
- Parameters:
- what parameters are accepted by the ioctl.
- Returns:
- the return value. General error numbers (-ENOMEM, -EINVAL)
- are not detailed, but errors with specific meanings are.
- The guest ioctl should be issued on a file descriptor of the /dev/sev-guest
- device. The ioctl accepts struct snp_user_guest_request. The input and
- output structure is specified through the req_data and resp_data field
- respectively. If the ioctl fails to execute due to a firmware error, then
- the fw_error code will be set, otherwise fw_error will be set to -1.
- The firmware checks that the message sequence counter is one greater than
- the guests message sequence counter. If guest driver fails to increment message
- counter (e.g. counter overflow), then -EIO will be returned.
- ::
- struct snp_guest_request_ioctl {
- /* Message version number */
- __u32 msg_version;
- /* Request and response structure address */
- __u64 req_data;
- __u64 resp_data;
- /* bits[63:32]: VMM error code, bits[31:0] firmware error code (see psp-sev.h) */
- union {
- __u64 exitinfo2;
- struct {
- __u32 fw_error;
- __u32 vmm_error;
- };
- };
- };
- The host ioctls are issued to a file descriptor of the /dev/sev device.
- The ioctl accepts the command ID/input structure documented below.
- ::
- struct sev_issue_cmd {
- /* Command ID */
- __u32 cmd;
- /* Command request structure */
- __u64 data;
- /* Firmware error code on failure (see psp-sev.h) */
- __u32 error;
- };
- 2.1 SNP_GET_REPORT
- ------------------
- :Technology: sev-snp
- :Type: guest ioctl
- :Parameters (in): struct snp_report_req
- :Returns (out): struct snp_report_resp on success, -negative on error
- The SNP_GET_REPORT ioctl can be used to query the attestation report from the
- SEV-SNP firmware. The ioctl uses the SNP_GUEST_REQUEST (MSG_REPORT_REQ) command
- provided by the SEV-SNP firmware to query the attestation report.
- On success, the snp_report_resp.data will contains the report. The report
- contain the format described in the SEV-SNP specification. See the SEV-SNP
- specification for further details.
- 2.2 SNP_GET_DERIVED_KEY
- -----------------------
- :Technology: sev-snp
- :Type: guest ioctl
- :Parameters (in): struct snp_derived_key_req
- :Returns (out): struct snp_derived_key_resp on success, -negative on error
- The SNP_GET_DERIVED_KEY ioctl can be used to get a key derive from a root key.
- The derived key can be used by the guest for any purpose, such as sealing keys
- or communicating with external entities.
- The ioctl uses the SNP_GUEST_REQUEST (MSG_KEY_REQ) command provided by the
- SEV-SNP firmware to derive the key. See SEV-SNP specification for further details
- on the various fields passed in the key derivation request.
- On success, the snp_derived_key_resp.data contains the derived key value. See
- the SEV-SNP specification for further details.
- 2.3 SNP_GET_EXT_REPORT
- ----------------------
- :Technology: sev-snp
- :Type: guest ioctl
- :Parameters (in/out): struct snp_ext_report_req
- :Returns (out): struct snp_report_resp on success, -negative on error
- The SNP_GET_EXT_REPORT ioctl is similar to the SNP_GET_REPORT. The difference is
- related to the additional certificate data that is returned with the report.
- The certificate data returned is being provided by the hypervisor through the
- SNP_SET_EXT_CONFIG.
- The ioctl uses the SNP_GUEST_REQUEST (MSG_REPORT_REQ) command provided by the SEV-SNP
- firmware to get the attestation report.
- On success, the snp_ext_report_resp.data will contain the attestation report
- and snp_ext_report_req.certs_address will contain the certificate blob. If the
- length of the blob is smaller than expected then snp_ext_report_req.certs_len will
- be updated with the expected value.
- See GHCB specification for further detail on how to parse the certificate blob.
- 2.4 SNP_PLATFORM_STATUS
- -----------------------
- :Technology: sev-snp
- :Type: hypervisor ioctl cmd
- :Parameters (out): struct sev_user_data_snp_status
- :Returns (out): 0 on success, -negative on error
- The SNP_PLATFORM_STATUS command is used to query the SNP platform status. The
- status includes API major, minor version and more. See the SEV-SNP
- specification for further details.
- 2.5 SNP_COMMIT
- --------------
- :Technology: sev-snp
- :Type: hypervisor ioctl cmd
- :Returns (out): 0 on success, -negative on error
- SNP_COMMIT is used to commit the currently installed firmware using the
- SEV-SNP firmware SNP_COMMIT command. This prevents roll-back to a previously
- committed firmware version. This will also update the reported TCB to match
- that of the currently installed firmware.
- 2.6 SNP_SET_CONFIG
- ------------------
- :Technology: sev-snp
- :Type: hypervisor ioctl cmd
- :Parameters (in): struct sev_user_data_snp_config
- :Returns (out): 0 on success, -negative on error
- SNP_SET_CONFIG is used to set the system-wide configuration such as
- reported TCB version in the attestation report. The command is similar
- to SNP_CONFIG command defined in the SEV-SNP spec. The current values of
- the firmware parameters affected by this command can be queried via
- SNP_PLATFORM_STATUS.
- 2.7 SNP_VLEK_LOAD
- -----------------
- :Technology: sev-snp
- :Type: hypervisor ioctl cmd
- :Parameters (in): struct sev_user_data_snp_vlek_load
- :Returns (out): 0 on success, -negative on error
- When requesting an attestation report a guest is able to specify whether
- it wants SNP firmware to sign the report using either a Versioned Chip
- Endorsement Key (VCEK), which is derived from chip-unique secrets, or a
- Versioned Loaded Endorsement Key (VLEK) which is obtained from an AMD
- Key Derivation Service (KDS) and derived from seeds allocated to
- enrolled cloud service providers.
- In the case of VLEK keys, the SNP_VLEK_LOAD SNP command is used to load
- them into the system after obtaining them from the KDS, and corresponds
- closely to the SNP_VLEK_LOAD firmware command specified in the SEV-SNP
- spec.
- 3. SEV-SNP CPUID Enforcement
- ============================
- SEV-SNP guests can access a special page that contains a table of CPUID values
- that have been validated by the PSP as part of the SNP_LAUNCH_UPDATE firmware
- command. It provides the following assurances regarding the validity of CPUID
- values:
- - Its address is obtained via bootloader/firmware (via CC blob), and those
- binaries will be measured as part of the SEV-SNP attestation report.
- - Its initial state will be encrypted/pvalidated, so attempts to modify
- it during run-time will result in garbage being written, or #VC exceptions
- being generated due to changes in validation state if the hypervisor tries
- to swap the backing page.
- - Attempts to bypass PSP checks by the hypervisor by using a normal page, or
- a non-CPUID encrypted page will change the measurement provided by the
- SEV-SNP attestation report.
- - The CPUID page contents are *not* measured, but attempts to modify the
- expected contents of a CPUID page as part of guest initialization will be
- gated by the PSP CPUID enforcement policy checks performed on the page
- during SNP_LAUNCH_UPDATE, and noticeable later if the guest owner
- implements their own checks of the CPUID values.
- It is important to note that this last assurance is only useful if the kernel
- has taken care to make use of the SEV-SNP CPUID throughout all stages of boot.
- Otherwise, guest owner attestation provides no assurance that the kernel wasn't
- fed incorrect values at some point during boot.
- 4. SEV Guest Driver Communication Key
- =====================================
- Communication between an SEV guest and the SEV firmware in the AMD Secure
- Processor (ASP, aka PSP) is protected by a VM Platform Communication Key
- (VMPCK). By default, the sev-guest driver uses the VMPCK associated with the
- VM Privilege Level (VMPL) at which the guest is running. Should this key be
- wiped by the sev-guest driver (see the driver for reasons why a VMPCK can be
- wiped), a different key can be used by reloading the sev-guest driver and
- specifying the desired key using the vmpck_id module parameter.
- Reference
- ---------
- SEV-SNP and GHCB specification: developer.amd.com/sev
- The driver is based on SEV-SNP firmware spec 0.9 and GHCB spec version 2.0.
|