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