linux/arch/x86/include/asm/sgx.h

/* SPDX-License-Identifier: GPL-2.0 */
/**
 * Copyright(c) 2016-20 Intel Corporation.
 *
 * Intel Software Guard Extensions (SGX) support.
 */
#ifndef _ASM_X86_SGX_H
#define _ASM_X86_SGX_H

#include <linux/bits.h>
#include <linux/types.h>

/*
 * This file contains both data structures defined by SGX architecture and Linux
 * defined software data structures and functions.  The two should not be mixed
 * together for better readability.  The architectural definitions come first.
 */

/* The SGX specific CPUID function. */
#define SGX_CPUID
/* EPC enumeration. */
#define SGX_CPUID_EPC
/* An invalid EPC section, i.e. the end marker. */
#define SGX_CPUID_EPC_INVALID
/* A valid EPC section. */
#define SGX_CPUID_EPC_SECTION
/* The bitmask for the EPC section type. */
#define SGX_CPUID_EPC_MASK

enum sgx_encls_function {};

/**
 * SGX_ENCLS_FAULT_FLAG - flag signifying an ENCLS return code is a trapnr
 *
 * ENCLS has its own (positive value) error codes and also generates
 * ENCLS specific #GP and #PF faults.  And the ENCLS values get munged
 * with system error codes as everything percolates back up the stack.
 * Unfortunately (for us), we need to precisely identify each unique
 * error code, e.g. the action taken if EWB fails varies based on the
 * type of fault and on the exact SGX error code, i.e. we can't simply
 * convert all faults to -EFAULT.
 *
 * To make all three error types coexist, we set bit 30 to identify an
 * ENCLS fault.  Bit 31 (technically bits N:31) is used to differentiate
 * between positive (faults and SGX error codes) and negative (system
 * error codes) values.
 */
#define SGX_ENCLS_FAULT_FLAG

/**
 * enum sgx_return_code - The return code type for ENCLS, ENCLU and ENCLV
 * %SGX_EPC_PAGE_CONFLICT:	Page is being written by other ENCLS function.
 * %SGX_NOT_TRACKED:		Previous ETRACK's shootdown sequence has not
 *				been completed yet.
 * %SGX_CHILD_PRESENT		SECS has child pages present in the EPC.
 * %SGX_INVALID_EINITTOKEN:	EINITTOKEN is invalid and enclave signer's
 *				public key does not match IA32_SGXLEPUBKEYHASH.
 * %SGX_PAGE_NOT_MODIFIABLE:	The EPC page cannot be modified because it
 *				is in the PENDING or MODIFIED state.
 * %SGX_UNMASKED_EVENT:		An unmasked event, e.g. INTR, was received
 */
enum sgx_return_code {};

/* The modulus size for 3072-bit RSA keys. */
#define SGX_MODULUS_SIZE

/**
 * enum sgx_miscselect - additional information to an SSA frame
 * %SGX_MISC_EXINFO:	Report #PF or #GP to the SSA frame.
 *
 * Save State Area (SSA) is a stack inside the enclave used to store processor
 * state when an exception or interrupt occurs. This enum defines additional
 * information stored to an SSA frame.
 */
enum sgx_miscselect {};

#define SGX_MISC_RESERVED_MASK

#define SGX_SSA_GPRS_SIZE
#define SGX_SSA_MISC_EXINFO_SIZE

/**
 * enum sgx_attributes - the attributes field in &struct sgx_secs
 * %SGX_ATTR_INIT:		Enclave can be entered (is initialized).
 * %SGX_ATTR_DEBUG:		Allow ENCLS(EDBGRD) and ENCLS(EDBGWR).
 * %SGX_ATTR_MODE64BIT:		Tell that this a 64-bit enclave.
 * %SGX_ATTR_PROVISIONKEY:      Allow to use provisioning keys for remote
 *				attestation.
 * %SGX_ATTR_KSS:		Allow to use key separation and sharing (KSS).
 * %SGX_ATTR_EINITTOKENKEY:	Allow to use token signing key that is used to
 *				sign cryptographic tokens that can be passed to
 *				EINIT as an authorization to run an enclave.
 * %SGX_ATTR_ASYNC_EXIT_NOTIFY:	Allow enclaves to be notified after an
 *				asynchronous exit has occurred.
 */
enum sgx_attribute {};

#define SGX_ATTR_RESERVED_MASK

#define SGX_ATTR_UNPRIV_MASK

#define SGX_ATTR_PRIV_MASK

/**
 * struct sgx_secs - SGX Enclave Control Structure (SECS)
 * @size:		size of the address space
 * @base:		base address of the  address space
 * @ssa_frame_size:	size of an SSA frame
 * @miscselect:		additional information stored to an SSA frame
 * @attributes:		attributes for enclave
 * @xfrm:		XSave-Feature Request Mask (subset of XCR0)
 * @mrenclave:		SHA256-hash of the enclave contents
 * @mrsigner:		SHA256-hash of the public key used to sign the SIGSTRUCT
 * @config_id:		a user-defined value that is used in key derivation
 * @isv_prod_id:	a user-defined value that is used in key derivation
 * @isv_svn:		a user-defined value that is used in key derivation
 * @config_svn:		a user-defined value that is used in key derivation
 *
 * SGX Enclave Control Structure (SECS) is a special enclave page that is not
 * visible in the address space. In fact, this structure defines the address
 * range and other global attributes for the enclave and it is the first EPC
 * page created for any enclave. It is moved from a temporary buffer to an EPC
 * by the means of ENCLS[ECREATE] function.
 */
struct sgx_secs {} __packed;

/**
 * enum sgx_tcs_flags - execution flags for TCS
 * %SGX_TCS_DBGOPTIN:	If enabled allows single-stepping and breakpoints
 *			inside an enclave. It is cleared by EADD but can
 *			be set later with EDBGWR.
 */
enum sgx_tcs_flags {};

#define SGX_TCS_RESERVED_MASK
#define SGX_TCS_RESERVED_SIZE

/**
 * struct sgx_tcs - Thread Control Structure (TCS)
 * @state:		used to mark an entered TCS
 * @flags:		execution flags (cleared by EADD)
 * @ssa_offset:		SSA stack offset relative to the enclave base
 * @ssa_index:		the current SSA frame index (cleard by EADD)
 * @nr_ssa_frames:	the number of frame in the SSA stack
 * @entry_offset:	entry point offset relative to the enclave base
 * @exit_addr:		address outside the enclave to exit on an exception or
 *			interrupt
 * @fs_offset:		offset relative to the enclave base to become FS
 *			segment inside the enclave
 * @gs_offset:		offset relative to the enclave base to become GS
 *			segment inside the enclave
 * @fs_limit:		size to become a new FS-limit (only 32-bit enclaves)
 * @gs_limit:		size to become a new GS-limit (only 32-bit enclaves)
 *
 * Thread Control Structure (TCS) is an enclave page visible in its address
 * space that defines an entry point inside the enclave. A thread enters inside
 * an enclave by supplying address of TCS to ENCLU(EENTER). A TCS can be entered
 * by only one thread at a time.
 */
struct sgx_tcs {} __packed;

/**
 * struct sgx_pageinfo - an enclave page descriptor
 * @addr:	address of the enclave page
 * @contents:	pointer to the page contents
 * @metadata:	pointer either to a SECINFO or PCMD instance
 * @secs:	address of the SECS page
 */
struct sgx_pageinfo {} __packed __aligned();


/**
 * enum sgx_page_type - bits in the SECINFO flags defining the page type
 * %SGX_PAGE_TYPE_SECS:	a SECS page
 * %SGX_PAGE_TYPE_TCS:	a TCS page
 * %SGX_PAGE_TYPE_REG:	a regular page
 * %SGX_PAGE_TYPE_VA:	a VA page
 * %SGX_PAGE_TYPE_TRIM:	a page in trimmed state
 *
 * Make sure when making changes to this enum that its values can still fit
 * in the bitfield within &struct sgx_encl_page
 */
enum sgx_page_type {};

#define SGX_NR_PAGE_TYPES
#define SGX_PAGE_TYPE_MASK

/**
 * enum sgx_secinfo_flags - the flags field in &struct sgx_secinfo
 * %SGX_SECINFO_R:	allow read
 * %SGX_SECINFO_W:	allow write
 * %SGX_SECINFO_X:	allow execution
 * %SGX_SECINFO_SECS:	a SECS page
 * %SGX_SECINFO_TCS:	a TCS page
 * %SGX_SECINFO_REG:	a regular page
 * %SGX_SECINFO_VA:	a VA page
 * %SGX_SECINFO_TRIM:	a page in trimmed state
 */
enum sgx_secinfo_flags {};

#define SGX_SECINFO_PERMISSION_MASK
#define SGX_SECINFO_PAGE_TYPE_MASK
#define SGX_SECINFO_RESERVED_MASK

/**
 * struct sgx_secinfo - describes attributes of an EPC page
 * @flags:	permissions and type
 *
 * Used together with ENCLS leaves that add or modify an EPC page to an
 * enclave to define page permissions and type.
 */
struct sgx_secinfo {} __packed __aligned();

#define SGX_PCMD_RESERVED_SIZE

/**
 * struct sgx_pcmd - Paging Crypto Metadata (PCMD)
 * @enclave_id:	enclave identifier
 * @mac:	MAC over PCMD, page contents and isvsvn
 *
 * PCMD is stored for every swapped page to the regular memory. When ELDU loads
 * the page back it recalculates the MAC by using a isvsvn number stored in a
 * VA page. Together these two structures bring integrity and rollback
 * protection.
 */
struct sgx_pcmd {} __packed __aligned();

#define SGX_SIGSTRUCT_RESERVED1_SIZE
#define SGX_SIGSTRUCT_RESERVED2_SIZE
#define SGX_SIGSTRUCT_RESERVED3_SIZE
#define SGX_SIGSTRUCT_RESERVED4_SIZE

/**
 * struct sgx_sigstruct_header -  defines author of the enclave
 * @header1:		constant byte string
 * @vendor:		must be either 0x0000 or 0x8086
 * @date:		YYYYMMDD in BCD
 * @header2:		constant byte string
 * @swdefined:		software defined value
 */
struct sgx_sigstruct_header {} __packed;

/**
 * struct sgx_sigstruct_body - defines contents of the enclave
 * @miscselect:		additional information stored to an SSA frame
 * @misc_mask:		required miscselect in SECS
 * @attributes:		attributes for enclave
 * @xfrm:		XSave-Feature Request Mask (subset of XCR0)
 * @attributes_mask:	required attributes in SECS
 * @xfrm_mask:		required XFRM in SECS
 * @mrenclave:		SHA256-hash of the enclave contents
 * @isvprodid:		a user-defined value that is used in key derivation
 * @isvsvn:		a user-defined value that is used in key derivation
 */
struct sgx_sigstruct_body {} __packed;

/**
 * struct sgx_sigstruct - an enclave signature
 * @header:		defines author of the enclave
 * @modulus:		the modulus of the public key
 * @exponent:		the exponent of the public key
 * @signature:		the signature calculated over the fields except modulus,
 * @body:		defines contents of the enclave
 * @q1:			a value used in RSA signature verification
 * @q2:			a value used in RSA signature verification
 *
 * Header and body are the parts that are actual signed. The remaining fields
 * define the signature of the enclave.
 */
struct sgx_sigstruct {} __packed;

#define SGX_LAUNCH_TOKEN_SIZE

/*
 * Do not put any hardware-defined SGX structure representations below this
 * comment!
 */

#ifdef CONFIG_X86_SGX_KVM
int sgx_virt_ecreate(struct sgx_pageinfo *pageinfo, void __user *secs,
		     int *trapnr);
int sgx_virt_einit(void __user *sigstruct, void __user *token,
		   void __user *secs, u64 *lepubkeyhash, int *trapnr);
#endif

int sgx_set_attribute(unsigned long *allowed_attributes,
		      unsigned int attribute_fd);

#endif /* _ASM_X86_SGX_H */