244 lines · plain
1.. SPDX-License-Identifier: GPL-2.02 3===================================================================4The Definitive SEV Guest API Documentation5===================================================================6 71. General description8======================9 10The SEV API is a set of ioctls that are used by the guest or hypervisor11to get or set a certain aspect of the SEV virtual machine. The ioctls belong12to the following classes:13 14 - Hypervisor ioctls: These query and set global attributes which affect the15 whole SEV firmware. These ioctl are used by platform provisioning tools.16 17 - Guest ioctls: These query and set attributes of the SEV virtual machine.18 192. API description20==================21 22This section describes ioctls that is used for querying the SEV guest report23from the SEV firmware. For each ioctl, the following information is provided24along with a description:25 26 Technology:27 which SEV technology provides this ioctl. SEV, SEV-ES, SEV-SNP or all.28 29 Type:30 hypervisor or guest. The ioctl can be used inside the guest or the31 hypervisor.32 33 Parameters:34 what parameters are accepted by the ioctl.35 36 Returns:37 the return value. General error numbers (-ENOMEM, -EINVAL)38 are not detailed, but errors with specific meanings are.39 40The guest ioctl should be issued on a file descriptor of the /dev/sev-guest41device. The ioctl accepts struct snp_user_guest_request. The input and42output structure is specified through the req_data and resp_data field43respectively. If the ioctl fails to execute due to a firmware error, then44the fw_error code will be set, otherwise fw_error will be set to -1.45 46The firmware checks that the message sequence counter is one greater than47the guests message sequence counter. If guest driver fails to increment message48counter (e.g. counter overflow), then -EIO will be returned.49 50::51 52 struct snp_guest_request_ioctl {53 /* Message version number */54 __u32 msg_version;55 56 /* Request and response structure address */57 __u64 req_data;58 __u64 resp_data;59 60 /* bits[63:32]: VMM error code, bits[31:0] firmware error code (see psp-sev.h) */61 union {62 __u64 exitinfo2;63 struct {64 __u32 fw_error;65 __u32 vmm_error;66 };67 };68 };69 70The host ioctls are issued to a file descriptor of the /dev/sev device.71The ioctl accepts the command ID/input structure documented below.72 73::74 75 struct sev_issue_cmd {76 /* Command ID */77 __u32 cmd;78 79 /* Command request structure */80 __u64 data;81 82 /* Firmware error code on failure (see psp-sev.h) */83 __u32 error;84 };85 86 872.1 SNP_GET_REPORT88------------------89 90:Technology: sev-snp91:Type: guest ioctl92:Parameters (in): struct snp_report_req93:Returns (out): struct snp_report_resp on success, -negative on error94 95The SNP_GET_REPORT ioctl can be used to query the attestation report from the96SEV-SNP firmware. The ioctl uses the SNP_GUEST_REQUEST (MSG_REPORT_REQ) command97provided by the SEV-SNP firmware to query the attestation report.98 99On success, the snp_report_resp.data will contains the report. The report100contain the format described in the SEV-SNP specification. See the SEV-SNP101specification for further details.102 1032.2 SNP_GET_DERIVED_KEY104-----------------------105:Technology: sev-snp106:Type: guest ioctl107:Parameters (in): struct snp_derived_key_req108:Returns (out): struct snp_derived_key_resp on success, -negative on error109 110The SNP_GET_DERIVED_KEY ioctl can be used to get a key derive from a root key.111The derived key can be used by the guest for any purpose, such as sealing keys112or communicating with external entities.113 114The ioctl uses the SNP_GUEST_REQUEST (MSG_KEY_REQ) command provided by the115SEV-SNP firmware to derive the key. See SEV-SNP specification for further details116on the various fields passed in the key derivation request.117 118On success, the snp_derived_key_resp.data contains the derived key value. See119the SEV-SNP specification for further details.120 121 1222.3 SNP_GET_EXT_REPORT123----------------------124:Technology: sev-snp125:Type: guest ioctl126:Parameters (in/out): struct snp_ext_report_req127:Returns (out): struct snp_report_resp on success, -negative on error128 129The SNP_GET_EXT_REPORT ioctl is similar to the SNP_GET_REPORT. The difference is130related to the additional certificate data that is returned with the report.131The certificate data returned is being provided by the hypervisor through the132SNP_SET_EXT_CONFIG.133 134The ioctl uses the SNP_GUEST_REQUEST (MSG_REPORT_REQ) command provided by the SEV-SNP135firmware to get the attestation report.136 137On success, the snp_ext_report_resp.data will contain the attestation report138and snp_ext_report_req.certs_address will contain the certificate blob. If the139length of the blob is smaller than expected then snp_ext_report_req.certs_len will140be updated with the expected value.141 142See GHCB specification for further detail on how to parse the certificate blob.143 1442.4 SNP_PLATFORM_STATUS145-----------------------146:Technology: sev-snp147:Type: hypervisor ioctl cmd148:Parameters (out): struct sev_user_data_snp_status149:Returns (out): 0 on success, -negative on error150 151The SNP_PLATFORM_STATUS command is used to query the SNP platform status. The152status includes API major, minor version and more. See the SEV-SNP153specification for further details.154 1552.5 SNP_COMMIT156--------------157:Technology: sev-snp158:Type: hypervisor ioctl cmd159:Returns (out): 0 on success, -negative on error160 161SNP_COMMIT is used to commit the currently installed firmware using the162SEV-SNP firmware SNP_COMMIT command. This prevents roll-back to a previously163committed firmware version. This will also update the reported TCB to match164that of the currently installed firmware.165 1662.6 SNP_SET_CONFIG167------------------168:Technology: sev-snp169:Type: hypervisor ioctl cmd170:Parameters (in): struct sev_user_data_snp_config171:Returns (out): 0 on success, -negative on error172 173SNP_SET_CONFIG is used to set the system-wide configuration such as174reported TCB version in the attestation report. The command is similar175to SNP_CONFIG command defined in the SEV-SNP spec. The current values of176the firmware parameters affected by this command can be queried via177SNP_PLATFORM_STATUS.178 1792.7 SNP_VLEK_LOAD180-----------------181:Technology: sev-snp182:Type: hypervisor ioctl cmd183:Parameters (in): struct sev_user_data_snp_vlek_load184:Returns (out): 0 on success, -negative on error185 186When requesting an attestation report a guest is able to specify whether187it wants SNP firmware to sign the report using either a Versioned Chip188Endorsement Key (VCEK), which is derived from chip-unique secrets, or a189Versioned Loaded Endorsement Key (VLEK) which is obtained from an AMD190Key Derivation Service (KDS) and derived from seeds allocated to191enrolled cloud service providers.192 193In the case of VLEK keys, the SNP_VLEK_LOAD SNP command is used to load194them into the system after obtaining them from the KDS, and corresponds195closely to the SNP_VLEK_LOAD firmware command specified in the SEV-SNP196spec.197 1983. SEV-SNP CPUID Enforcement199============================200 201SEV-SNP guests can access a special page that contains a table of CPUID values202that have been validated by the PSP as part of the SNP_LAUNCH_UPDATE firmware203command. It provides the following assurances regarding the validity of CPUID204values:205 206 - Its address is obtained via bootloader/firmware (via CC blob), and those207 binaries will be measured as part of the SEV-SNP attestation report.208 - Its initial state will be encrypted/pvalidated, so attempts to modify209 it during run-time will result in garbage being written, or #VC exceptions210 being generated due to changes in validation state if the hypervisor tries211 to swap the backing page.212 - Attempts to bypass PSP checks by the hypervisor by using a normal page, or213 a non-CPUID encrypted page will change the measurement provided by the214 SEV-SNP attestation report.215 - The CPUID page contents are *not* measured, but attempts to modify the216 expected contents of a CPUID page as part of guest initialization will be217 gated by the PSP CPUID enforcement policy checks performed on the page218 during SNP_LAUNCH_UPDATE, and noticeable later if the guest owner219 implements their own checks of the CPUID values.220 221It is important to note that this last assurance is only useful if the kernel222has taken care to make use of the SEV-SNP CPUID throughout all stages of boot.223Otherwise, guest owner attestation provides no assurance that the kernel wasn't224fed incorrect values at some point during boot.225 2264. SEV Guest Driver Communication Key227=====================================228 229Communication between an SEV guest and the SEV firmware in the AMD Secure230Processor (ASP, aka PSP) is protected by a VM Platform Communication Key231(VMPCK). By default, the sev-guest driver uses the VMPCK associated with the232VM Privilege Level (VMPL) at which the guest is running. Should this key be233wiped by the sev-guest driver (see the driver for reasons why a VMPCK can be234wiped), a different key can be used by reloading the sev-guest driver and235specifying the desired key using the vmpck_id module parameter.236 237 238Reference239---------240 241SEV-SNP and GHCB specification: developer.amd.com/sev242 243The driver is based on SEV-SNP firmware spec 0.9 and GHCB spec version 2.0.244