PSP(4) | Device Drivers Manual | PSP(4)

# NAME

`psp` — AMD Platform Security Processor

# SYNOPSIS

`psp* at ccp?`

# DESCRIPTION

The `psp` driver provides an interface to the AMD Platform Security Processor. The interface can be accessed through the ioctl(2) interface exposed by /dev/psp.

vmd(8) uses `psp` to configure and launch SEV-enabled guests.

# IOCTL INTERFACE

The ioctl(2) command codes below are defined in `<dev/ic/pspvar.h>`.

`PSP_IOC_GET_PSTATUS` struct psp_platform_status *pspst
  Collect the current status of the platform.

      struct psp_platform_status {
      	/* Output parameters from PSP_CMD_PLATFORMSTATUS */
      	uint8_t			api_major;
      	uint8_t			api_minor;
      	uint8_t			state;
      	uint8_t			owner;
      	uint32_t		cfges_build;
      	uint32_t		guest_count;
      } __packed;

  api_major and api_minor indicate the PSP firmware version.

  The current platform state is indicated by state. The following values are defined:

  PSP_PSTATE_UNINIT
    The platform is uninitialized.
  PSP_PSTATE_INIT
    The platform is initialized but not managing any guests.
  PSP_PSTATE_WORKING
    The platform is initialized and currently managing guests.

  owner indicates whether the platform is self-owned or externally owned.

  Bit 0 of cfgs_build indicates whether SEV-ES is configured on the platform or not. Bits 31:24 indicate the firmware build ID.

  guest_count indicates the number of valid guests currently maintained by the firmware.

`PSP_IOC_DF_FLUSH`
  This command flushes all write buffers of the CPU's data fabric. It must be invoked after deactivating one or more guests with `PSP_IOC_DEACTIVATE`.
`PSP_IOC_DECOMMISSION` struct psp_decommission *pspdec
  Deletes all guest context of the guest identified by handle.

      struct psp_decommission {
      	/* Input parameter for PSP_CMD_DECOMMISSION */
      	uint32_t		handle;
      } __packed;

`PSP_IOC_GET_GSTATUS`
  Retrieves status information about an SEV-enabled guest identified by handle.

      struct psp_guest_status {
      	/* Input parameter for PSP_CMD_GUESTSTATUS */
      	uint32_t		handle;

      	/* Output parameters from PSP_CMD_GUESTSTATUS */
      	uint32_t		policy;
      	uint32_t		asid;
      	uint8_t			state;
      } __packed;

  policy indicates the policy used for this guest. asid indicates the guest's address space identifier (ASID).

  The state of the guest is indicated by state. The following values are defined:

  PSP_GSTATE_UNINIT
    The guest is uninitialized.
  PSP_GSTATE_LUPDATE
    The guest is currently being launched and plaintext data is imported.
  PSP_GSTATE_LSECRET
    The guest is currently being launched and ciphertext data is imported.
  PSP_GSTATE_RUNNING
    The guest is fully launched.
  PSP_GSTATE_SUPDATE
    The guest is migrated to another machine.
  PSP_GSTATE_RUPDATE
    The guest is migrated from another machine.
  PSP_GSTATE_SENT
    Thee guest has bin migrated to another machine.
`PSP_IOC_LAUNCH_START`
  This command encrypts a guest's memory.

      struct psp_launch_start {
      	/* Input/Output parameter for PSP_CMD_LAUNCH_START */
      	uint32_t		handle;

      	/* Input parameters for PSP_CMD_LAUNCH_START */
      	uint32_t		policy;

      	/* The following input parameters are not used yet */
      	uint64_t		dh_cert_paddr;
      	uint32_t		dh_cert_len;
      	uint32_t		reserved;
      	uint64_t		session_paddr;
      	uint32_t		session_len;
      } __packed;

  If handle is zero, a new key is created. A unique handle is assigned to the guest and returned in handle.

  policy specifies the policy used for that guest.

  dh_cert_paddr, dh_cert len, session_paddr and session_len are currently not used.

`PSP_IOC_LAUNCH_UPDATE_DATA`
  This command encrypts data of the guest identified by handle.

      struct psp_launch_update_data {
      	/* Input parameters for PSP_CMD_LAUNCH_UPDATE_DATA */
      	uint32_t		handle;
      	uint32_t		reserved;
      	uint64_t		paddr;
      	uint32_t		length;
      } __packed;

  paddr and length specify the address and length of the data to be encrypted. Both values must be a multiple of 16 bytes.

`PSP_IOC_LAUNCH_MEASURE`
  This commands generates a measurement of the guest's memory. The guest is identified by handle.

      struct psp_measure {
      	/* Output buffer for PSP_CMD_LAUNCH_MEASURE */
      	uint8_t			measure[32];
      	uint8_t			measure_nonce[16];
      } __packed;

      struct psp_launch_measure {
      	/* Input parameters for PSP_CMD_LAUNCH_MEASURE */
      	uint32_t		handle;
      	uint32_t		reserved;
      	uint64_t		measure_paddr;

      	/* Input/output parameter for PSP_CMD_LAUNCH_MEASURE */
      	uint32_t		measure_len;
      	uint32_t		padding;

      	/* Output buffer from PSP_CMD_LAUNCH_MEASURE */
      	struct psp_measure	psp_measure;	/* 64bit aligned */
      #define measure		psp_measure.measure
      #define measure_nonce	psp_measure.measure_nonce
      } __packed;

  measure_paddr is currently not used and measure_len must always be `sizeof(struct psp_measure)`.

  psp_measure contains the buffers measure and measure_nonce. These contain the measurement and nonce generated by the PSP.

`PSP_IOC_LAUNCH_FINISH`
  This command finalizes the launch of the guest identified by handle.

      struct psp_launch_finish {
      	/* Input parameter for PSP_CMD_LAUNCH_FINISH */
      	uint32_t		handle;
      } __packed;

`PSP_IOC_ATTESTATION`
  This command generates an attestation report signed by the PSP with a platform specific key.

      struct psp_report {
      	/* Output buffer for PSP_CMD_ATTESTATION */
      	uint8_t			report_nonce[16];
      	uint8_t			report_launch_digest[32];
      	uint32_t		report_policy;
      	uint32_t		report_sig_usage;
      	uint32_t		report_sig_algo;
      	uint32_t		reserved2;
      	uint8_t			report_sig1[144];
      } __packed;

      struct psp_attestation {
      	/* Input parameters for PSP_CMD_ATTESTATION */
      	uint32_t		handle;
      	uint32_t		reserved;
      	uint64_t		attest_paddr;
      	uint8_t			attest_nonce[16];

      	/* Input/output parameter from PSP_CMD_ATTESTATION */
      	uint32_t		attest_len;
      	uint32_t		padding;

      	/* Output parameter from PSP_CMD_ATTESTATION */
      	struct psp_report	psp_report;	/* 64bit aligned */
      #define report_nonce		psp_report.report_nonce
      #define report_launch_digest	psp_report.report_launch_digest
      #define report_policy		psp_report.report_policy
      #define report_sig_usage	psp_report.report_sig_usage;
      #define report_report_sig_alg	psp_report.report_sig_algo;
      #define report_report_sig1	psp_report.report_sig1;
      } __packed;

  handle identifies the guest. attest_paddr is currently not used. attest_nonce is the nonce returned by a previous `PSP_IOC_LAUNCH_MEASURE` command. attest_len must always be `sizeof(struct psp_report)`.

  The attestation report is returned in psp_report. The format of the report is defined by `struct psp_report`.

`PSP_IOC_ACTIVATE`
  This commands associates the context of the guest identified by handle with the address space identifier provided in asid.

      struct psp_activate {
      	/* Input parameters for PSP_CMD_ACTIVATE */
      	uint32_t		handle;
      	uint32_t		asid;
      } __packed;

`PSP_IOC_DEACTIVATE`
  This command dissociates the context of the guest identified by handle from its current the address space identifier.

      struct psp_deactivate {
      	/* Input parameter for PSP_CMD_DEACTIVATE */
      	uint32_t		handle;
      } __packed;

`PSP_IOC_SNP_GET_PSTATUS`
  This command returns the state of a SEV-SNP enabled platform.

      struct psp_snp_platform_status {
      	uint8_t			api_major;
      	uint8_t			api_minor;
      	uint8_t			state;
      	uint8_t			is_rmp_init;
      	uint32_t		build;
      	uint32_t		features;
      	uint32_t		guest_count;
      	uint64_t		current_tcb;
      	uint64_t		reported_tcb;
      } __packed;

`PSP_IOC_GUEST_SHUTDOWN`
  This command shuts down a guest identified by handle.

      struct psp_guest_shutdown {
      	/* Input parameter for PSP_CMD_GUEST_SHUTDOWN */
      	uint32_t		handle;
      } __packed;

  The command combines `PSP_IOC_DEACTIVATE` and `PSP_IOC_DECOMMISSION` in a single ioctl(2) call.

# FILES

/dev/psp

# SEE ALSO

ioctl(2), ccp(4), vmd(8)

Secure Encrypted Virtualization API, Publication #55766.

SEV Secure Nested Paging Firmware ABI Specification, Publication #56860.

# HISTORY

The `psp` device driver first appeared in OpenBSD 7.6.

# AUTHORS

The `psp` driver was written by Hans-Joerg Hoexer <hshoexer@genua.de>.

September 17, 2024 | Debian