Message ID | 20200716135303.276442-5-jarkko.sakkinen@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Intel SGX foundations | expand |
On Thursday, 2020-07-16 at 16:52:43 +03, Jarkko Sakkinen wrote: > Define the SGX microarchitectural data structures used by various SGX > opcodes. This is not an exhaustive representation of all SGX data > structures but only those needed by the kernel. > > The data structures are described in: > > Intel SDM: 37.6 INTELĀ® SGX DATA STRUCTURES OVERVIEW > > Acked-by: Jethro Beekman <jethro@fortanix.com> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Reviewed-by: Darren Kenny <darren.kenny@oracle.com> > --- > arch/x86/kernel/cpu/sgx/arch.h | 343 +++++++++++++++++++++++++++++++++ > 1 file changed, 343 insertions(+) > create mode 100644 arch/x86/kernel/cpu/sgx/arch.h > > diff --git a/arch/x86/kernel/cpu/sgx/arch.h b/arch/x86/kernel/cpu/sgx/arch.h > new file mode 100644 > index 000000000000..ddae55e9d4d8 > --- /dev/null > +++ b/arch/x86/kernel/cpu/sgx/arch.h > @@ -0,0 +1,343 @@ > +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ > +/** > + * Copyright(c) 2016-18 Intel Corporation. > + * > + * Contains data structures defined by the SGX architecture. Data structures > + * defined by the Linux software stack should not be placed here. > + */ > +#ifndef _ASM_X86_SGX_ARCH_H > +#define _ASM_X86_SGX_ARCH_H > + > +#include <linux/bits.h> > +#include <linux/types.h> > + > +#define SGX_CPUID 0x12 > +#define SGX_CPUID_FIRST_VARIABLE_SUB_LEAF 2 > + > +/** > + * enum sgx_return_code - The return code type for ENCLS, ENCLU and ENCLV > + * %SGX_NOT_TRACKED: Previous ETRACK's shootdown sequence has not > + * been completed yet. > + * %SGX_INVALID_EINITTOKEN: EINITTOKEN is invalid and enclave signer's > + * public key does not match IA32_SGXLEPUBKEYHASH. > + * %SGX_UNMASKED_EVENT: An unmasked event, e.g. INTR, was received > + */ > +enum sgx_return_code { > + SGX_NOT_TRACKED = 11, > + SGX_INVALID_EINITTOKEN = 16, > + SGX_UNMASKED_EVENT = 128, > +}; > + > +/** > + * enum sgx_sub_leaf_types - SGX CPUID variable sub-leaf types > + * %SGX_CPUID_SUB_LEAF_INVALID: Indicates this sub-leaf is invalid. > + * %SGX_CPUID_SUB_LEAF_EPC_SECTION: Sub-leaf enumerates an EPC section. > + */ > +enum sgx_sub_leaf_types { > + SGX_CPUID_SUB_LEAF_INVALID = 0x0, > + SGX_CPUID_SUB_LEAF_EPC_SECTION = 0x1, > +}; > + > +#define SGX_CPUID_SUB_LEAF_TYPE_MASK GENMASK(3, 0) > + > +#define SGX_MODULUS_SIZE 384 > + > +/** > + * 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 { > + SGX_MISC_EXINFO = BIT(0), > +}; > + > +#define SGX_MISC_RESERVED_MASK GENMASK_ULL(63, 1) > + > +#define SGX_SSA_GPRS_SIZE 184 > +#define SGX_SSA_MISC_EXINFO_SIZE 16 > + > +/** > + * 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. > + */ > +enum sgx_attribute { > + SGX_ATTR_INIT = BIT(0), > + SGX_ATTR_DEBUG = BIT(1), > + SGX_ATTR_MODE64BIT = BIT(2), > + SGX_ATTR_PROVISIONKEY = BIT(4), > + SGX_ATTR_EINITTOKENKEY = BIT(5), > + SGX_ATTR_KSS = BIT(7), > +}; > + > +#define SGX_ATTR_RESERVED_MASK (BIT_ULL(3) | BIT_ULL(6) | GENMASK_ULL(63, 8)) > +#define SGX_ATTR_ALLOWED_MASK (SGX_ATTR_DEBUG | SGX_ATTR_MODE64BIT | \ > + SGX_ATTR_KSS) > + > +/** > + * 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) leaf. > + */ > +struct sgx_secs { > + u64 size; > + u64 base; > + u32 ssa_frame_size; > + u32 miscselect; > + u8 reserved1[24]; > + u64 attributes; > + u64 xfrm; > + u32 mrenclave[8]; > + u8 reserved2[32]; > + u32 mrsigner[8]; > + u8 reserved3[32]; > + u32 config_id[16]; > + u16 isv_prod_id; > + u16 isv_svn; > + u16 config_svn; > + u8 reserved4[3834]; > +} __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 { > + SGX_TCS_DBGOPTIN = 0x01, > +}; > + > +#define SGX_TCS_RESERVED_MASK GENMASK_ULL(63, 1) > +#define SGX_TCS_RESERVED_SIZE 4024 > + > +/** > + * 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 { > + u64 state; > + u64 flags; > + u64 ssa_offset; > + u32 ssa_index; > + u32 nr_ssa_frames; > + u64 entry_offset; > + u64 exit_addr; > + u64 fs_offset; > + u64 gs_offset; > + u32 fs_limit; > + u32 gs_limit; > + u8 reserved[SGX_TCS_RESERVED_SIZE]; > +} __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 { > + u64 addr; > + u64 contents; > + u64 metadata; > + u64 secs; > +} __packed __aligned(32); > + > + > +/** > + * 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 > + */ > +enum sgx_page_type { > + SGX_PAGE_TYPE_SECS, > + SGX_PAGE_TYPE_TCS, > + SGX_PAGE_TYPE_REG, > + SGX_PAGE_TYPE_VA, > + SGX_PAGE_TYPE_TRIM, > +}; > + > +#define SGX_NR_PAGE_TYPES 5 > +#define SGX_PAGE_TYPE_MASK GENMASK(7, 0) > + > +/** > + * 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 { > + SGX_SECINFO_R = BIT(0), > + SGX_SECINFO_W = BIT(1), > + SGX_SECINFO_X = BIT(2), > + SGX_SECINFO_SECS = (SGX_PAGE_TYPE_SECS << 8), > + SGX_SECINFO_TCS = (SGX_PAGE_TYPE_TCS << 8), > + SGX_SECINFO_REG = (SGX_PAGE_TYPE_REG << 8), > + SGX_SECINFO_VA = (SGX_PAGE_TYPE_VA << 8), > + SGX_SECINFO_TRIM = (SGX_PAGE_TYPE_TRIM << 8), > +}; > + > +#define SGX_SECINFO_PERMISSION_MASK GENMASK_ULL(2, 0) > +#define SGX_SECINFO_PAGE_TYPE_MASK (SGX_PAGE_TYPE_MASK << 8) > +#define SGX_SECINFO_RESERVED_MASK ~(SGX_SECINFO_PERMISSION_MASK | \ > + SGX_SECINFO_PAGE_TYPE_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 { > + u64 flags; > + u8 reserved[56]; > +} __packed __aligned(64); > + > +#define SGX_PCMD_RESERVED_SIZE 40 > + > +/** > + * 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 { > + struct sgx_secinfo secinfo; > + u64 enclave_id; > + u8 reserved[SGX_PCMD_RESERVED_SIZE]; > + u8 mac[16]; > +} __packed __aligned(128); > + > +#define SGX_SIGSTRUCT_RESERVED1_SIZE 84 > +#define SGX_SIGSTRUCT_RESERVED2_SIZE 20 > +#define SGX_SIGSTRUCT_RESERVED3_SIZE 32 > +#define SGX_SIGSTRUCT_RESERVED4_SIZE 12 > + > +/** > + * 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: costant byte string > + * @swdefined: software defined value > + */ > +struct sgx_sigstruct_header { > + u64 header1[2]; > + u32 vendor; > + u32 date; > + u64 header2[2]; > + u32 swdefined; > + u8 reserved1[84]; > +} __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 { > + u32 miscselect; > + u32 misc_mask; > + u8 reserved2[20]; > + u64 attributes; > + u64 xfrm; > + u64 attributes_mask; > + u64 xfrm_mask; > + u8 mrenclave[32]; > + u8 reserved3[32]; > + u16 isvprodid; > + u16 isvsvn; > +} __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 { > + struct sgx_sigstruct_header header; > + u8 modulus[SGX_MODULUS_SIZE]; > + u32 exponent; > + u8 signature[SGX_MODULUS_SIZE]; > + struct sgx_sigstruct_body body; > + u8 reserved4[12]; > + u8 q1[SGX_MODULUS_SIZE]; > + u8 q2[SGX_MODULUS_SIZE]; > +} __packed; > + > +#define SGX_LAUNCH_TOKEN_SIZE 304 > + > +#endif /* _ASM_X86_SGX_ARCH_H */ > -- > 2.25.1
diff --git a/arch/x86/kernel/cpu/sgx/arch.h b/arch/x86/kernel/cpu/sgx/arch.h new file mode 100644 index 000000000000..ddae55e9d4d8 --- /dev/null +++ b/arch/x86/kernel/cpu/sgx/arch.h @@ -0,0 +1,343 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ +/** + * Copyright(c) 2016-18 Intel Corporation. + * + * Contains data structures defined by the SGX architecture. Data structures + * defined by the Linux software stack should not be placed here. + */ +#ifndef _ASM_X86_SGX_ARCH_H +#define _ASM_X86_SGX_ARCH_H + +#include <linux/bits.h> +#include <linux/types.h> + +#define SGX_CPUID 0x12 +#define SGX_CPUID_FIRST_VARIABLE_SUB_LEAF 2 + +/** + * enum sgx_return_code - The return code type for ENCLS, ENCLU and ENCLV + * %SGX_NOT_TRACKED: Previous ETRACK's shootdown sequence has not + * been completed yet. + * %SGX_INVALID_EINITTOKEN: EINITTOKEN is invalid and enclave signer's + * public key does not match IA32_SGXLEPUBKEYHASH. + * %SGX_UNMASKED_EVENT: An unmasked event, e.g. INTR, was received + */ +enum sgx_return_code { + SGX_NOT_TRACKED = 11, + SGX_INVALID_EINITTOKEN = 16, + SGX_UNMASKED_EVENT = 128, +}; + +/** + * enum sgx_sub_leaf_types - SGX CPUID variable sub-leaf types + * %SGX_CPUID_SUB_LEAF_INVALID: Indicates this sub-leaf is invalid. + * %SGX_CPUID_SUB_LEAF_EPC_SECTION: Sub-leaf enumerates an EPC section. + */ +enum sgx_sub_leaf_types { + SGX_CPUID_SUB_LEAF_INVALID = 0x0, + SGX_CPUID_SUB_LEAF_EPC_SECTION = 0x1, +}; + +#define SGX_CPUID_SUB_LEAF_TYPE_MASK GENMASK(3, 0) + +#define SGX_MODULUS_SIZE 384 + +/** + * 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 { + SGX_MISC_EXINFO = BIT(0), +}; + +#define SGX_MISC_RESERVED_MASK GENMASK_ULL(63, 1) + +#define SGX_SSA_GPRS_SIZE 184 +#define SGX_SSA_MISC_EXINFO_SIZE 16 + +/** + * 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. + */ +enum sgx_attribute { + SGX_ATTR_INIT = BIT(0), + SGX_ATTR_DEBUG = BIT(1), + SGX_ATTR_MODE64BIT = BIT(2), + SGX_ATTR_PROVISIONKEY = BIT(4), + SGX_ATTR_EINITTOKENKEY = BIT(5), + SGX_ATTR_KSS = BIT(7), +}; + +#define SGX_ATTR_RESERVED_MASK (BIT_ULL(3) | BIT_ULL(6) | GENMASK_ULL(63, 8)) +#define SGX_ATTR_ALLOWED_MASK (SGX_ATTR_DEBUG | SGX_ATTR_MODE64BIT | \ + SGX_ATTR_KSS) + +/** + * 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) leaf. + */ +struct sgx_secs { + u64 size; + u64 base; + u32 ssa_frame_size; + u32 miscselect; + u8 reserved1[24]; + u64 attributes; + u64 xfrm; + u32 mrenclave[8]; + u8 reserved2[32]; + u32 mrsigner[8]; + u8 reserved3[32]; + u32 config_id[16]; + u16 isv_prod_id; + u16 isv_svn; + u16 config_svn; + u8 reserved4[3834]; +} __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 { + SGX_TCS_DBGOPTIN = 0x01, +}; + +#define SGX_TCS_RESERVED_MASK GENMASK_ULL(63, 1) +#define SGX_TCS_RESERVED_SIZE 4024 + +/** + * 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 { + u64 state; + u64 flags; + u64 ssa_offset; + u32 ssa_index; + u32 nr_ssa_frames; + u64 entry_offset; + u64 exit_addr; + u64 fs_offset; + u64 gs_offset; + u32 fs_limit; + u32 gs_limit; + u8 reserved[SGX_TCS_RESERVED_SIZE]; +} __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 { + u64 addr; + u64 contents; + u64 metadata; + u64 secs; +} __packed __aligned(32); + + +/** + * 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 + */ +enum sgx_page_type { + SGX_PAGE_TYPE_SECS, + SGX_PAGE_TYPE_TCS, + SGX_PAGE_TYPE_REG, + SGX_PAGE_TYPE_VA, + SGX_PAGE_TYPE_TRIM, +}; + +#define SGX_NR_PAGE_TYPES 5 +#define SGX_PAGE_TYPE_MASK GENMASK(7, 0) + +/** + * 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 { + SGX_SECINFO_R = BIT(0), + SGX_SECINFO_W = BIT(1), + SGX_SECINFO_X = BIT(2), + SGX_SECINFO_SECS = (SGX_PAGE_TYPE_SECS << 8), + SGX_SECINFO_TCS = (SGX_PAGE_TYPE_TCS << 8), + SGX_SECINFO_REG = (SGX_PAGE_TYPE_REG << 8), + SGX_SECINFO_VA = (SGX_PAGE_TYPE_VA << 8), + SGX_SECINFO_TRIM = (SGX_PAGE_TYPE_TRIM << 8), +}; + +#define SGX_SECINFO_PERMISSION_MASK GENMASK_ULL(2, 0) +#define SGX_SECINFO_PAGE_TYPE_MASK (SGX_PAGE_TYPE_MASK << 8) +#define SGX_SECINFO_RESERVED_MASK ~(SGX_SECINFO_PERMISSION_MASK | \ + SGX_SECINFO_PAGE_TYPE_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 { + u64 flags; + u8 reserved[56]; +} __packed __aligned(64); + +#define SGX_PCMD_RESERVED_SIZE 40 + +/** + * 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 { + struct sgx_secinfo secinfo; + u64 enclave_id; + u8 reserved[SGX_PCMD_RESERVED_SIZE]; + u8 mac[16]; +} __packed __aligned(128); + +#define SGX_SIGSTRUCT_RESERVED1_SIZE 84 +#define SGX_SIGSTRUCT_RESERVED2_SIZE 20 +#define SGX_SIGSTRUCT_RESERVED3_SIZE 32 +#define SGX_SIGSTRUCT_RESERVED4_SIZE 12 + +/** + * 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: costant byte string + * @swdefined: software defined value + */ +struct sgx_sigstruct_header { + u64 header1[2]; + u32 vendor; + u32 date; + u64 header2[2]; + u32 swdefined; + u8 reserved1[84]; +} __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 { + u32 miscselect; + u32 misc_mask; + u8 reserved2[20]; + u64 attributes; + u64 xfrm; + u64 attributes_mask; + u64 xfrm_mask; + u8 mrenclave[32]; + u8 reserved3[32]; + u16 isvprodid; + u16 isvsvn; +} __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 { + struct sgx_sigstruct_header header; + u8 modulus[SGX_MODULUS_SIZE]; + u32 exponent; + u8 signature[SGX_MODULUS_SIZE]; + struct sgx_sigstruct_body body; + u8 reserved4[12]; + u8 q1[SGX_MODULUS_SIZE]; + u8 q2[SGX_MODULUS_SIZE]; +} __packed; + +#define SGX_LAUNCH_TOKEN_SIZE 304 + +#endif /* _ASM_X86_SGX_ARCH_H */