Reference

psp(4)

AMD Platform Security Processor

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 ⟨[email protected]⟩.