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 readability. 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
30enum 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 EUPDATESVN = 0x18,
47};
48
49/**
50 * SGX_ENCLS_FAULT_FLAG - flag signifying an ENCLS return code is a trapnr
51 *
52 * ENCLS has its own (positive value) error codes and also generates
53 * ENCLS specific #GP and #PF faults. And the ENCLS values get munged
54 * with system error codes as everything percolates back up the stack.
55 * Unfortunately (for us), we need to precisely identify each unique
56 * error code, e.g. the action taken if EWB fails varies based on the
57 * type of fault and on the exact SGX error code, i.e. we can't simply
58 * convert all faults to -EFAULT.
59 *
60 * To make all three error types coexist, we set bit 30 to identify an
61 * ENCLS fault. Bit 31 (technically bits N:31) is used to differentiate
62 * between positive (faults and SGX error codes) and negative (system
63 * error codes) values.
64 */
65#define SGX_ENCLS_FAULT_FLAG 0x40000000
66
67/**
68 * enum sgx_return_code - The return code type for ENCLS, ENCLU and ENCLV
69 * @SGX_EPC_PAGE_CONFLICT: Page is being written by other ENCLS function.
70 * @SGX_NOT_TRACKED: Previous ETRACK's shootdown sequence has not
71 * been completed yet.
72 * @SGX_CHILD_PRESENT: SECS has child pages present in the EPC.
73 * @SGX_INVALID_EINITTOKEN: EINITTOKEN is invalid and enclave signer's
74 * public key does not match IA32_SGXLEPUBKEYHASH.
75 * @SGX_PAGE_NOT_MODIFIABLE: The EPC page cannot be modified because it
76 * is in the PENDING or MODIFIED state.
77 * @SGX_INSUFFICIENT_ENTROPY: Insufficient entropy in RNG.
78 * @SGX_NO_UPDATE: EUPDATESVN could not update the CPUSVN because the
79 * current SVN was not newer than CPUSVN. This is the most
80 * common error code returned by EUPDATESVN.
81 * @SGX_UNMASKED_EVENT: An unmasked event, e.g. INTR, was received
82 */
83enum sgx_return_code {
84 SGX_EPC_PAGE_CONFLICT = 7,
85 SGX_NOT_TRACKED = 11,
86 SGX_CHILD_PRESENT = 13,
87 SGX_INVALID_EINITTOKEN = 16,
88 SGX_PAGE_NOT_MODIFIABLE = 20,
89 SGX_INSUFFICIENT_ENTROPY = 29,
90 SGX_NO_UPDATE = 31,
91 SGX_UNMASKED_EVENT = 128,
92};
93
94/* The modulus size for 3072-bit RSA keys. */
95#define SGX_MODULUS_SIZE 384
96
97/**
98 * enum sgx_miscselect - additional information to an SSA frame
99 * @SGX_MISC_EXINFO: Report #PF or #GP to the SSA frame.
100 *
101 * Save State Area (SSA) is a stack inside the enclave used to store processor
102 * state when an exception or interrupt occurs. This enum defines additional
103 * information stored to an SSA frame.
104 */
105enum sgx_miscselect {
106 SGX_MISC_EXINFO = BIT(0),
107};
108
109#define SGX_MISC_RESERVED_MASK GENMASK_ULL(63, 1)
110
111#define SGX_SSA_GPRS_SIZE 184
112#define SGX_SSA_MISC_EXINFO_SIZE 16
113
114/**
115 * enum sgx_attribute - the attributes field in &struct sgx_secs
116 * @SGX_ATTR_INIT: Enclave can be entered (is initialized).
117 * @SGX_ATTR_DEBUG: Allow ENCLS(EDBGRD) and ENCLS(EDBGWR).
118 * @SGX_ATTR_MODE64BIT: Tell that this a 64-bit enclave.
119 * @SGX_ATTR_PROVISIONKEY: Allow to use provisioning keys for remote
120 * attestation.
121 * @SGX_ATTR_KSS: Allow to use key separation and sharing (KSS).
122 * @SGX_ATTR_EINITTOKENKEY: Allow to use token signing key that is used to
123 * sign cryptographic tokens that can be passed to
124 * EINIT as an authorization to run an enclave.
125 * @SGX_ATTR_ASYNC_EXIT_NOTIFY: Allow enclaves to be notified after an
126 * asynchronous exit has occurred.
127 */
128enum sgx_attribute {
129 SGX_ATTR_INIT = BIT(0),
130 SGX_ATTR_DEBUG = BIT(1),
131 SGX_ATTR_MODE64BIT = BIT(2),
132 /* BIT(3) is reserved */
133 SGX_ATTR_PROVISIONKEY = BIT(4),
134 SGX_ATTR_EINITTOKENKEY = BIT(5),
135 /* BIT(6) is for CET */
136 SGX_ATTR_KSS = BIT(7),
137 /* BIT(8) is reserved */
138 /* BIT(9) is reserved */
139 SGX_ATTR_ASYNC_EXIT_NOTIFY = BIT(10),
140};
141
142#define SGX_ATTR_RESERVED_MASK (BIT_ULL(3) | \
143 BIT_ULL(6) | \
144 BIT_ULL(8) | \
145 BIT_ULL(9) | \
146 GENMASK_ULL(63, 11))
147
148#define SGX_ATTR_UNPRIV_MASK (SGX_ATTR_DEBUG | \
149 SGX_ATTR_MODE64BIT | \
150 SGX_ATTR_KSS | \
151 SGX_ATTR_ASYNC_EXIT_NOTIFY)
152
153#define SGX_ATTR_PRIV_MASK (SGX_ATTR_PROVISIONKEY | \
154 SGX_ATTR_EINITTOKENKEY)
155
156/**
157 * struct sgx_secs - SGX Enclave Control Structure (SECS)
158 * @size: size of the address space
159 * @base: base address of the address space
160 * @ssa_frame_size: size of an SSA frame
161 * @miscselect: additional information stored to an SSA frame
162 * @attributes: attributes for enclave
163 * @xfrm: XSave-Feature Request Mask (subset of XCR0)
164 * @mrenclave: SHA256-hash of the enclave contents
165 * @mrsigner: SHA256-hash of the public key used to sign the SIGSTRUCT
166 * @config_id: a user-defined value that is used in key derivation
167 * @isv_prod_id: a user-defined value that is used in key derivation
168 * @isv_svn: a user-defined value that is used in key derivation
169 * @config_svn: a user-defined value that is used in key derivation
170 *
171 * SGX Enclave Control Structure (SECS) is a special enclave page that is not
172 * visible in the address space. In fact, this structure defines the address
173 * range and other global attributes for the enclave and it is the first EPC
174 * page created for any enclave. It is moved from a temporary buffer to an EPC
175 * by the means of ENCLS[ECREATE] function.
176 */
177struct sgx_secs {
178 u64 size;
179 u64 base;
180 u32 ssa_frame_size;
181 u32 miscselect;
182 u8 reserved1[24];
183 u64 attributes;
184 u64 xfrm;
185 u32 mrenclave[8];
186 u8 reserved2[32];
187 u32 mrsigner[8];
188 u8 reserved3[32];
189 u32 config_id[16];
190 u16 isv_prod_id;
191 u16 isv_svn;
192 u16 config_svn;
193 u8 reserved4[3834];
194} __packed;
195
196/**
197 * enum sgx_tcs_flags - execution flags for TCS
198 * @SGX_TCS_DBGOPTIN: If enabled allows single-stepping and breakpoints
199 * inside an enclave. It is cleared by EADD but can
200 * be set later with EDBGWR.
201 */
202enum sgx_tcs_flags {
203 SGX_TCS_DBGOPTIN = 0x01,
204};
205
206#define SGX_TCS_RESERVED_MASK GENMASK_ULL(63, 1)
207#define SGX_TCS_RESERVED_SIZE 4024
208
209/**
210 * struct sgx_tcs - Thread Control Structure (TCS)
211 * @state: used to mark an entered TCS
212 * @flags: execution flags (cleared by EADD)
213 * @ssa_offset: SSA stack offset relative to the enclave base
214 * @ssa_index: the current SSA frame index (cleard by EADD)
215 * @nr_ssa_frames: the number of frame in the SSA stack
216 * @entry_offset: entry point offset relative to the enclave base
217 * @exit_addr: address outside the enclave to exit on an exception or
218 * interrupt
219 * @fs_offset: offset relative to the enclave base to become FS
220 * segment inside the enclave
221 * @gs_offset: offset relative to the enclave base to become GS
222 * segment inside the enclave
223 * @fs_limit: size to become a new FS-limit (only 32-bit enclaves)
224 * @gs_limit: size to become a new GS-limit (only 32-bit enclaves)
225 *
226 * Thread Control Structure (TCS) is an enclave page visible in its address
227 * space that defines an entry point inside the enclave. A thread enters inside
228 * an enclave by supplying address of TCS to ENCLU(EENTER). A TCS can be entered
229 * by only one thread at a time.
230 */
231struct sgx_tcs {
232 u64 state;
233 u64 flags;
234 u64 ssa_offset;
235 u32 ssa_index;
236 u32 nr_ssa_frames;
237 u64 entry_offset;
238 u64 exit_addr;
239 u64 fs_offset;
240 u64 gs_offset;
241 u32 fs_limit;
242 u32 gs_limit;
243 u8 reserved[SGX_TCS_RESERVED_SIZE];
244} __packed;
245
246/**
247 * struct sgx_pageinfo - an enclave page descriptor
248 * @addr: address of the enclave page
249 * @contents: pointer to the page contents
250 * @metadata: pointer either to a SECINFO or PCMD instance
251 * @secs: address of the SECS page
252 */
253struct sgx_pageinfo {
254 u64 addr;
255 u64 contents;
256 u64 metadata;
257 u64 secs;
258} __packed __aligned(32);
259
260
261/**
262 * enum sgx_page_type - bits in the SECINFO flags defining the page type
263 * @SGX_PAGE_TYPE_SECS: a SECS page
264 * @SGX_PAGE_TYPE_TCS: a TCS page
265 * @SGX_PAGE_TYPE_REG: a regular page
266 * @SGX_PAGE_TYPE_VA: a VA page
267 * @SGX_PAGE_TYPE_TRIM: a page in trimmed state
268 *
269 * Make sure when making changes to this enum that its values can still fit
270 * in the bitfield within &struct sgx_encl_page
271 */
272enum sgx_page_type {
273 SGX_PAGE_TYPE_SECS,
274 SGX_PAGE_TYPE_TCS,
275 SGX_PAGE_TYPE_REG,
276 SGX_PAGE_TYPE_VA,
277 SGX_PAGE_TYPE_TRIM,
278};
279
280#define SGX_NR_PAGE_TYPES 5
281#define SGX_PAGE_TYPE_MASK GENMASK(7, 0)
282
283/**
284 * enum sgx_secinfo_flags - the flags field in &struct sgx_secinfo
285 * @SGX_SECINFO_R: allow read
286 * @SGX_SECINFO_W: allow write
287 * @SGX_SECINFO_X: allow execution
288 * @SGX_SECINFO_SECS: a SECS page
289 * @SGX_SECINFO_TCS: a TCS page
290 * @SGX_SECINFO_REG: a regular page
291 * @SGX_SECINFO_VA: a VA page
292 * @SGX_SECINFO_TRIM: a page in trimmed state
293 */
294enum sgx_secinfo_flags {
295 SGX_SECINFO_R = BIT(0),
296 SGX_SECINFO_W = BIT(1),
297 SGX_SECINFO_X = BIT(2),
298 SGX_SECINFO_SECS = (SGX_PAGE_TYPE_SECS << 8),
299 SGX_SECINFO_TCS = (SGX_PAGE_TYPE_TCS << 8),
300 SGX_SECINFO_REG = (SGX_PAGE_TYPE_REG << 8),
301 SGX_SECINFO_VA = (SGX_PAGE_TYPE_VA << 8),
302 SGX_SECINFO_TRIM = (SGX_PAGE_TYPE_TRIM << 8),
303};
304
305#define SGX_SECINFO_PERMISSION_MASK GENMASK_ULL(2, 0)
306#define SGX_SECINFO_PAGE_TYPE_MASK (SGX_PAGE_TYPE_MASK << 8)
307#define SGX_SECINFO_RESERVED_MASK ~(SGX_SECINFO_PERMISSION_MASK | \
308 SGX_SECINFO_PAGE_TYPE_MASK)
309
310/**
311 * struct sgx_secinfo - describes attributes of an EPC page
312 * @flags: permissions and type
313 *
314 * Used together with ENCLS leaves that add or modify an EPC page to an
315 * enclave to define page permissions and type.
316 */
317struct sgx_secinfo {
318 u64 flags;
319 u8 reserved[56];
320} __packed __aligned(64);
321
322#define SGX_PCMD_RESERVED_SIZE 40
323
324/**
325 * struct sgx_pcmd - Paging Crypto Metadata (PCMD)
326 * @enclave_id: enclave identifier
327 * @mac: MAC over PCMD, page contents and isvsvn
328 *
329 * PCMD is stored for every swapped page to the regular memory. When ELDU loads
330 * the page back it recalculates the MAC by using a isvsvn number stored in a
331 * VA page. Together these two structures bring integrity and rollback
332 * protection.
333 */
334struct sgx_pcmd {
335 struct sgx_secinfo secinfo;
336 u64 enclave_id;
337 u8 reserved[SGX_PCMD_RESERVED_SIZE];
338 u8 mac[16];
339} __packed __aligned(128);
340
341#define SGX_SIGSTRUCT_RESERVED1_SIZE 84
342#define SGX_SIGSTRUCT_RESERVED2_SIZE 20
343#define SGX_SIGSTRUCT_RESERVED3_SIZE 32
344#define SGX_SIGSTRUCT_RESERVED4_SIZE 12
345
346/**
347 * struct sgx_sigstruct_header - defines author of the enclave
348 * @header1: constant byte string
349 * @vendor: must be either 0x0000 or 0x8086
350 * @date: YYYYMMDD in BCD
351 * @header2: constant byte string
352 * @swdefined: software defined value
353 */
354struct sgx_sigstruct_header {
355 u64 header1[2];
356 u32 vendor;
357 u32 date;
358 u64 header2[2];
359 u32 swdefined;
360 u8 reserved1[84];
361} __packed;
362
363/**
364 * struct sgx_sigstruct_body - defines contents of the enclave
365 * @miscselect: additional information stored to an SSA frame
366 * @misc_mask: required miscselect in SECS
367 * @attributes: attributes for enclave
368 * @xfrm: XSave-Feature Request Mask (subset of XCR0)
369 * @attributes_mask: required attributes in SECS
370 * @xfrm_mask: required XFRM in SECS
371 * @mrenclave: SHA256-hash of the enclave contents
372 * @isvprodid: a user-defined value that is used in key derivation
373 * @isvsvn: a user-defined value that is used in key derivation
374 */
375struct sgx_sigstruct_body {
376 u32 miscselect;
377 u32 misc_mask;
378 u8 reserved2[20];
379 u64 attributes;
380 u64 xfrm;
381 u64 attributes_mask;
382 u64 xfrm_mask;
383 u8 mrenclave[32];
384 u8 reserved3[32];
385 u16 isvprodid;
386 u16 isvsvn;
387} __packed;
388
389/**
390 * struct sgx_sigstruct - an enclave signature
391 * @header: defines author of the enclave
392 * @modulus: the modulus of the public key
393 * @exponent: the exponent of the public key
394 * @signature: the signature calculated over the fields except modulus,
395 * @body: defines contents of the enclave
396 * @q1: a value used in RSA signature verification
397 * @q2: a value used in RSA signature verification
398 *
399 * Header and body are the parts that are actual signed. The remaining fields
400 * define the signature of the enclave.
401 */
402struct sgx_sigstruct {
403 struct sgx_sigstruct_header header;
404 u8 modulus[SGX_MODULUS_SIZE];
405 u32 exponent;
406 u8 signature[SGX_MODULUS_SIZE];
407 struct sgx_sigstruct_body body;
408 u8 reserved4[12];
409 u8 q1[SGX_MODULUS_SIZE];
410 u8 q2[SGX_MODULUS_SIZE];
411} __packed;
412
413#define SGX_LAUNCH_TOKEN_SIZE 304
414
415/*
416 * Do not put any hardware-defined SGX structure representations below this
417 * comment!
418 */
419
420#ifdef CONFIG_X86_SGX_KVM
421int sgx_virt_ecreate(struct sgx_pageinfo *pageinfo, void __user *secs,
422 int *trapnr);
423int sgx_virt_einit(void __user *sigstruct, void __user *token,
424 void __user *secs, u64 *lepubkeyhash, int *trapnr);
425#endif
426
427int sgx_set_attribute(unsigned long *allowed_attributes,
428 unsigned int attribute_fd);
429
430#endif /* _ASM_X86_SGX_H */
431

source code of linux/arch/x86/include/asm/sgx.h