|
| 1 | +/* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | +/** |
| 3 | + * Copyright(c) 2016-20 Intel Corporation. |
| 4 | + * |
| 5 | + * Contains data structures defined by the SGX architecture. Data structures |
| 6 | + * defined by the Linux software stack should not be placed here. |
| 7 | + */ |
| 8 | +#ifndef _ASM_X86_SGX_ARCH_H |
| 9 | +#define _ASM_X86_SGX_ARCH_H |
| 10 | + |
| 11 | +#include <linux/bits.h> |
| 12 | +#include <linux/types.h> |
| 13 | + |
| 14 | +/* The SGX specific CPUID function. */ |
| 15 | +#define SGX_CPUID 0x12 |
| 16 | +/* EPC enumeration. */ |
| 17 | +#define SGX_CPUID_EPC 2 |
| 18 | +/* An invalid EPC section, i.e. the end marker. */ |
| 19 | +#define SGX_CPUID_EPC_INVALID 0x0 |
| 20 | +/* A valid EPC section. */ |
| 21 | +#define SGX_CPUID_EPC_SECTION 0x1 |
| 22 | +/* The bitmask for the EPC section type. */ |
| 23 | +#define SGX_CPUID_EPC_MASK GENMASK(3, 0) |
| 24 | + |
| 25 | +/** |
| 26 | + * enum sgx_return_code - The return code type for ENCLS, ENCLU and ENCLV |
| 27 | + * %SGX_NOT_TRACKED: Previous ETRACK's shootdown sequence has not |
| 28 | + * been completed yet. |
| 29 | + * %SGX_INVALID_EINITTOKEN: EINITTOKEN is invalid and enclave signer's |
| 30 | + * public key does not match IA32_SGXLEPUBKEYHASH. |
| 31 | + * %SGX_UNMASKED_EVENT: An unmasked event, e.g. INTR, was received |
| 32 | + */ |
| 33 | +enum sgx_return_code { |
| 34 | + SGX_NOT_TRACKED = 11, |
| 35 | + SGX_INVALID_EINITTOKEN = 16, |
| 36 | + SGX_UNMASKED_EVENT = 128, |
| 37 | +}; |
| 38 | + |
| 39 | +/* The modulus size for 3072-bit RSA keys. */ |
| 40 | +#define SGX_MODULUS_SIZE 384 |
| 41 | + |
| 42 | +/** |
| 43 | + * enum sgx_miscselect - additional information to an SSA frame |
| 44 | + * %SGX_MISC_EXINFO: Report #PF or #GP to the SSA frame. |
| 45 | + * |
| 46 | + * Save State Area (SSA) is a stack inside the enclave used to store processor |
| 47 | + * state when an exception or interrupt occurs. This enum defines additional |
| 48 | + * information stored to an SSA frame. |
| 49 | + */ |
| 50 | +enum sgx_miscselect { |
| 51 | + SGX_MISC_EXINFO = BIT(0), |
| 52 | +}; |
| 53 | + |
| 54 | +#define SGX_MISC_RESERVED_MASK GENMASK_ULL(63, 1) |
| 55 | + |
| 56 | +#define SGX_SSA_GPRS_SIZE 184 |
| 57 | +#define SGX_SSA_MISC_EXINFO_SIZE 16 |
| 58 | + |
| 59 | +/** |
| 60 | + * enum sgx_attributes - the attributes field in &struct sgx_secs |
| 61 | + * %SGX_ATTR_INIT: Enclave can be entered (is initialized). |
| 62 | + * %SGX_ATTR_DEBUG: Allow ENCLS(EDBGRD) and ENCLS(EDBGWR). |
| 63 | + * %SGX_ATTR_MODE64BIT: Tell that this a 64-bit enclave. |
| 64 | + * %SGX_ATTR_PROVISIONKEY: Allow to use provisioning keys for remote |
| 65 | + * attestation. |
| 66 | + * %SGX_ATTR_KSS: Allow to use key separation and sharing (KSS). |
| 67 | + * %SGX_ATTR_EINITTOKENKEY: Allow to use token signing key that is used to |
| 68 | + * sign cryptographic tokens that can be passed to |
| 69 | + * EINIT as an authorization to run an enclave. |
| 70 | + */ |
| 71 | +enum sgx_attribute { |
| 72 | + SGX_ATTR_INIT = BIT(0), |
| 73 | + SGX_ATTR_DEBUG = BIT(1), |
| 74 | + SGX_ATTR_MODE64BIT = BIT(2), |
| 75 | + SGX_ATTR_PROVISIONKEY = BIT(4), |
| 76 | + SGX_ATTR_EINITTOKENKEY = BIT(5), |
| 77 | + SGX_ATTR_KSS = BIT(7), |
| 78 | +}; |
| 79 | + |
| 80 | +#define SGX_ATTR_RESERVED_MASK (BIT_ULL(3) | BIT_ULL(6) | GENMASK_ULL(63, 8)) |
| 81 | + |
| 82 | +/** |
| 83 | + * struct sgx_secs - SGX Enclave Control Structure (SECS) |
| 84 | + * @size: size of the address space |
| 85 | + * @base: base address of the address space |
| 86 | + * @ssa_frame_size: size of an SSA frame |
| 87 | + * @miscselect: additional information stored to an SSA frame |
| 88 | + * @attributes: attributes for enclave |
| 89 | + * @xfrm: XSave-Feature Request Mask (subset of XCR0) |
| 90 | + * @mrenclave: SHA256-hash of the enclave contents |
| 91 | + * @mrsigner: SHA256-hash of the public key used to sign the SIGSTRUCT |
| 92 | + * @config_id: a user-defined value that is used in key derivation |
| 93 | + * @isv_prod_id: a user-defined value that is used in key derivation |
| 94 | + * @isv_svn: a user-defined value that is used in key derivation |
| 95 | + * @config_svn: a user-defined value that is used in key derivation |
| 96 | + * |
| 97 | + * SGX Enclave Control Structure (SECS) is a special enclave page that is not |
| 98 | + * visible in the address space. In fact, this structure defines the address |
| 99 | + * range and other global attributes for the enclave and it is the first EPC |
| 100 | + * page created for any enclave. It is moved from a temporary buffer to an EPC |
| 101 | + * by the means of ENCLS[ECREATE] function. |
| 102 | + */ |
| 103 | +struct sgx_secs { |
| 104 | + u64 size; |
| 105 | + u64 base; |
| 106 | + u32 ssa_frame_size; |
| 107 | + u32 miscselect; |
| 108 | + u8 reserved1[24]; |
| 109 | + u64 attributes; |
| 110 | + u64 xfrm; |
| 111 | + u32 mrenclave[8]; |
| 112 | + u8 reserved2[32]; |
| 113 | + u32 mrsigner[8]; |
| 114 | + u8 reserved3[32]; |
| 115 | + u32 config_id[16]; |
| 116 | + u16 isv_prod_id; |
| 117 | + u16 isv_svn; |
| 118 | + u16 config_svn; |
| 119 | + u8 reserved4[3834]; |
| 120 | +} __packed; |
| 121 | + |
| 122 | +/** |
| 123 | + * enum sgx_tcs_flags - execution flags for TCS |
| 124 | + * %SGX_TCS_DBGOPTIN: If enabled allows single-stepping and breakpoints |
| 125 | + * inside an enclave. It is cleared by EADD but can |
| 126 | + * be set later with EDBGWR. |
| 127 | + */ |
| 128 | +enum sgx_tcs_flags { |
| 129 | + SGX_TCS_DBGOPTIN = 0x01, |
| 130 | +}; |
| 131 | + |
| 132 | +#define SGX_TCS_RESERVED_MASK GENMASK_ULL(63, 1) |
| 133 | +#define SGX_TCS_RESERVED_SIZE 4024 |
| 134 | + |
| 135 | +/** |
| 136 | + * struct sgx_tcs - Thread Control Structure (TCS) |
| 137 | + * @state: used to mark an entered TCS |
| 138 | + * @flags: execution flags (cleared by EADD) |
| 139 | + * @ssa_offset: SSA stack offset relative to the enclave base |
| 140 | + * @ssa_index: the current SSA frame index (cleard by EADD) |
| 141 | + * @nr_ssa_frames: the number of frame in the SSA stack |
| 142 | + * @entry_offset: entry point offset relative to the enclave base |
| 143 | + * @exit_addr: address outside the enclave to exit on an exception or |
| 144 | + * interrupt |
| 145 | + * @fs_offset: offset relative to the enclave base to become FS |
| 146 | + * segment inside the enclave |
| 147 | + * @gs_offset: offset relative to the enclave base to become GS |
| 148 | + * segment inside the enclave |
| 149 | + * @fs_limit: size to become a new FS-limit (only 32-bit enclaves) |
| 150 | + * @gs_limit: size to become a new GS-limit (only 32-bit enclaves) |
| 151 | + * |
| 152 | + * Thread Control Structure (TCS) is an enclave page visible in its address |
| 153 | + * space that defines an entry point inside the enclave. A thread enters inside |
| 154 | + * an enclave by supplying address of TCS to ENCLU(EENTER). A TCS can be entered |
| 155 | + * by only one thread at a time. |
| 156 | + */ |
| 157 | +struct sgx_tcs { |
| 158 | + u64 state; |
| 159 | + u64 flags; |
| 160 | + u64 ssa_offset; |
| 161 | + u32 ssa_index; |
| 162 | + u32 nr_ssa_frames; |
| 163 | + u64 entry_offset; |
| 164 | + u64 exit_addr; |
| 165 | + u64 fs_offset; |
| 166 | + u64 gs_offset; |
| 167 | + u32 fs_limit; |
| 168 | + u32 gs_limit; |
| 169 | + u8 reserved[SGX_TCS_RESERVED_SIZE]; |
| 170 | +} __packed; |
| 171 | + |
| 172 | +/** |
| 173 | + * struct sgx_pageinfo - an enclave page descriptor |
| 174 | + * @addr: address of the enclave page |
| 175 | + * @contents: pointer to the page contents |
| 176 | + * @metadata: pointer either to a SECINFO or PCMD instance |
| 177 | + * @secs: address of the SECS page |
| 178 | + */ |
| 179 | +struct sgx_pageinfo { |
| 180 | + u64 addr; |
| 181 | + u64 contents; |
| 182 | + u64 metadata; |
| 183 | + u64 secs; |
| 184 | +} __packed __aligned(32); |
| 185 | + |
| 186 | + |
| 187 | +/** |
| 188 | + * enum sgx_page_type - bits in the SECINFO flags defining the page type |
| 189 | + * %SGX_PAGE_TYPE_SECS: a SECS page |
| 190 | + * %SGX_PAGE_TYPE_TCS: a TCS page |
| 191 | + * %SGX_PAGE_TYPE_REG: a regular page |
| 192 | + * %SGX_PAGE_TYPE_VA: a VA page |
| 193 | + * %SGX_PAGE_TYPE_TRIM: a page in trimmed state |
| 194 | + */ |
| 195 | +enum sgx_page_type { |
| 196 | + SGX_PAGE_TYPE_SECS, |
| 197 | + SGX_PAGE_TYPE_TCS, |
| 198 | + SGX_PAGE_TYPE_REG, |
| 199 | + SGX_PAGE_TYPE_VA, |
| 200 | + SGX_PAGE_TYPE_TRIM, |
| 201 | +}; |
| 202 | + |
| 203 | +#define SGX_NR_PAGE_TYPES 5 |
| 204 | +#define SGX_PAGE_TYPE_MASK GENMASK(7, 0) |
| 205 | + |
| 206 | +/** |
| 207 | + * enum sgx_secinfo_flags - the flags field in &struct sgx_secinfo |
| 208 | + * %SGX_SECINFO_R: allow read |
| 209 | + * %SGX_SECINFO_W: allow write |
| 210 | + * %SGX_SECINFO_X: allow execution |
| 211 | + * %SGX_SECINFO_SECS: a SECS page |
| 212 | + * %SGX_SECINFO_TCS: a TCS page |
| 213 | + * %SGX_SECINFO_REG: a regular page |
| 214 | + * %SGX_SECINFO_VA: a VA page |
| 215 | + * %SGX_SECINFO_TRIM: a page in trimmed state |
| 216 | + */ |
| 217 | +enum sgx_secinfo_flags { |
| 218 | + SGX_SECINFO_R = BIT(0), |
| 219 | + SGX_SECINFO_W = BIT(1), |
| 220 | + SGX_SECINFO_X = BIT(2), |
| 221 | + SGX_SECINFO_SECS = (SGX_PAGE_TYPE_SECS << 8), |
| 222 | + SGX_SECINFO_TCS = (SGX_PAGE_TYPE_TCS << 8), |
| 223 | + SGX_SECINFO_REG = (SGX_PAGE_TYPE_REG << 8), |
| 224 | + SGX_SECINFO_VA = (SGX_PAGE_TYPE_VA << 8), |
| 225 | + SGX_SECINFO_TRIM = (SGX_PAGE_TYPE_TRIM << 8), |
| 226 | +}; |
| 227 | + |
| 228 | +#define SGX_SECINFO_PERMISSION_MASK GENMASK_ULL(2, 0) |
| 229 | +#define SGX_SECINFO_PAGE_TYPE_MASK (SGX_PAGE_TYPE_MASK << 8) |
| 230 | +#define SGX_SECINFO_RESERVED_MASK ~(SGX_SECINFO_PERMISSION_MASK | \ |
| 231 | + SGX_SECINFO_PAGE_TYPE_MASK) |
| 232 | + |
| 233 | +/** |
| 234 | + * struct sgx_secinfo - describes attributes of an EPC page |
| 235 | + * @flags: permissions and type |
| 236 | + * |
| 237 | + * Used together with ENCLS leaves that add or modify an EPC page to an |
| 238 | + * enclave to define page permissions and type. |
| 239 | + */ |
| 240 | +struct sgx_secinfo { |
| 241 | + u64 flags; |
| 242 | + u8 reserved[56]; |
| 243 | +} __packed __aligned(64); |
| 244 | + |
| 245 | +#define SGX_PCMD_RESERVED_SIZE 40 |
| 246 | + |
| 247 | +/** |
| 248 | + * struct sgx_pcmd - Paging Crypto Metadata (PCMD) |
| 249 | + * @enclave_id: enclave identifier |
| 250 | + * @mac: MAC over PCMD, page contents and isvsvn |
| 251 | + * |
| 252 | + * PCMD is stored for every swapped page to the regular memory. When ELDU loads |
| 253 | + * the page back it recalculates the MAC by using a isvsvn number stored in a |
| 254 | + * VA page. Together these two structures bring integrity and rollback |
| 255 | + * protection. |
| 256 | + */ |
| 257 | +struct sgx_pcmd { |
| 258 | + struct sgx_secinfo secinfo; |
| 259 | + u64 enclave_id; |
| 260 | + u8 reserved[SGX_PCMD_RESERVED_SIZE]; |
| 261 | + u8 mac[16]; |
| 262 | +} __packed __aligned(128); |
| 263 | + |
| 264 | +#define SGX_SIGSTRUCT_RESERVED1_SIZE 84 |
| 265 | +#define SGX_SIGSTRUCT_RESERVED2_SIZE 20 |
| 266 | +#define SGX_SIGSTRUCT_RESERVED3_SIZE 32 |
| 267 | +#define SGX_SIGSTRUCT_RESERVED4_SIZE 12 |
| 268 | + |
| 269 | +/** |
| 270 | + * struct sgx_sigstruct_header - defines author of the enclave |
| 271 | + * @header1: constant byte string |
| 272 | + * @vendor: must be either 0x0000 or 0x8086 |
| 273 | + * @date: YYYYMMDD in BCD |
| 274 | + * @header2: costant byte string |
| 275 | + * @swdefined: software defined value |
| 276 | + */ |
| 277 | +struct sgx_sigstruct_header { |
| 278 | + u64 header1[2]; |
| 279 | + u32 vendor; |
| 280 | + u32 date; |
| 281 | + u64 header2[2]; |
| 282 | + u32 swdefined; |
| 283 | + u8 reserved1[84]; |
| 284 | +} __packed; |
| 285 | + |
| 286 | +/** |
| 287 | + * struct sgx_sigstruct_body - defines contents of the enclave |
| 288 | + * @miscselect: additional information stored to an SSA frame |
| 289 | + * @misc_mask: required miscselect in SECS |
| 290 | + * @attributes: attributes for enclave |
| 291 | + * @xfrm: XSave-Feature Request Mask (subset of XCR0) |
| 292 | + * @attributes_mask: required attributes in SECS |
| 293 | + * @xfrm_mask: required XFRM in SECS |
| 294 | + * @mrenclave: SHA256-hash of the enclave contents |
| 295 | + * @isvprodid: a user-defined value that is used in key derivation |
| 296 | + * @isvsvn: a user-defined value that is used in key derivation |
| 297 | + */ |
| 298 | +struct sgx_sigstruct_body { |
| 299 | + u32 miscselect; |
| 300 | + u32 misc_mask; |
| 301 | + u8 reserved2[20]; |
| 302 | + u64 attributes; |
| 303 | + u64 xfrm; |
| 304 | + u64 attributes_mask; |
| 305 | + u64 xfrm_mask; |
| 306 | + u8 mrenclave[32]; |
| 307 | + u8 reserved3[32]; |
| 308 | + u16 isvprodid; |
| 309 | + u16 isvsvn; |
| 310 | +} __packed; |
| 311 | + |
| 312 | +/** |
| 313 | + * struct sgx_sigstruct - an enclave signature |
| 314 | + * @header: defines author of the enclave |
| 315 | + * @modulus: the modulus of the public key |
| 316 | + * @exponent: the exponent of the public key |
| 317 | + * @signature: the signature calculated over the fields except modulus, |
| 318 | + * @body: defines contents of the enclave |
| 319 | + * @q1: a value used in RSA signature verification |
| 320 | + * @q2: a value used in RSA signature verification |
| 321 | + * |
| 322 | + * Header and body are the parts that are actual signed. The remaining fields |
| 323 | + * define the signature of the enclave. |
| 324 | + */ |
| 325 | +struct sgx_sigstruct { |
| 326 | + struct sgx_sigstruct_header header; |
| 327 | + u8 modulus[SGX_MODULUS_SIZE]; |
| 328 | + u32 exponent; |
| 329 | + u8 signature[SGX_MODULUS_SIZE]; |
| 330 | + struct sgx_sigstruct_body body; |
| 331 | + u8 reserved4[12]; |
| 332 | + u8 q1[SGX_MODULUS_SIZE]; |
| 333 | + u8 q2[SGX_MODULUS_SIZE]; |
| 334 | +} __packed; |
| 335 | + |
| 336 | +#define SGX_LAUNCH_TOKEN_SIZE 304 |
| 337 | + |
| 338 | +#endif /* _ASM_X86_SGX_ARCH_H */ |
0 commit comments