1use core::arch::asm;
4
5macro_rules! encls {
10 ($rax:expr, $rbx:expr) => {
11 $crate::bits64::sgx::encls2($rax as u64, $rbx as u64)
12 };
13
14 ($rax:expr, $rbx:expr, $rcx:expr) => {
15 $crate::bits64::sgx::encls3($rax as u64, $rbx as u64, $rcx as u64)
16 };
17
18 ($rax:expr, $rbx:expr, $rcx:expr, $rdx:expr) => {
19 $crate::bits64::sgx::encls4($rax as u64, $rbx as u64, $rcx as u64, $rdx as u64)
20 };
21}
22
23unsafe fn encls2(rax: u64, rbx: u64) -> (u32, u64) {
25 let eax: u32;
26 let out_rbx: u64;
27 asm!(
28 "pushq %rbx; movq %rsi, %rbx; encls; movq %rbx, %rsi; popq %rbx",
29 lateout("eax") eax, lateout("rsi") out_rbx,
30 in("rax") rax, in("rsi") rbx,
31 options(att_syntax),
32 );
33 (eax, out_rbx)
34}
35
36unsafe fn encls3(rax: u64, rbx: u64, rcx: u64) -> (u32, u64) {
38 let eax: u32;
39 let out_rbx: u64;
40 asm!(
41 "pushq %rbx; movq %rsi, %rbx; encls; movq %rbx, %r11; popq %rbx",
42 lateout("eax") eax, lateout("rsi") out_rbx,
43 in("rax") rax, in("rsi") rbx, in("rcx") rcx,
44 options(att_syntax),
45 );
46 (eax, out_rbx)
47}
48
49unsafe fn encls4(rax: u64, rbx: u64, rcx: u64, rdx: u64) -> (u32, u64) {
51 let eax: u32;
52 let out_rbx: u64;
53 asm!(
54 "pushq %rbx; movq %rsi, %rbx; encls; movq %rbx, %rsi; popq %rbx",
55 lateout("eax") eax, lateout("rsi") out_rbx,
56 in("rax") rax, in("rsi") rbx, in("rcx") rcx, in("rdx") rdx,
57 options(att_syntax),
58 );
59 (eax, out_rbx)
60}
61
62#[allow(clippy::upper_case_acronyms)]
63enum EnclsCommand {
64 EADD = 0x01,
65 EAUG = 0x0D,
66 EBLOCK = 0x09,
67 ECREATE = 0x00,
68 EDBGRD = 0x04,
69 EDBGWR = 0x05,
70 EEXTEND = 0x06,
71 EINIT = 0x02,
72 ELDB = 0x07,
73 ELDU = 0x08,
74 EMODPR = 0x0E,
75 EMODT = 0x0F,
76 EPA = 0x0A,
77 EREMOVE = 0x03,
78 ETRACK = 0x0C,
79 EWB = 0x0B,
80}
81
82pub unsafe fn encls_eadd(pageinfo: u64, epc_page: u64) {
91 encls!(EnclsCommand::EADD as u64, pageinfo, epc_page);
92}
93
94pub unsafe fn encls_eaug(secinfo_address: u64, epc_page: u64) {
103 encls!(EnclsCommand::EAUG as u64, secinfo_address, epc_page);
104}
105
106pub unsafe fn encls_eblock(epc_page: u64) -> u32 {
114 encls!(EnclsCommand::EBLOCK as u64, epc_page).0
115}
116
117pub unsafe fn encls_create(pageinfo: u64, secs_page: u64) {
126 encls!(EnclsCommand::ECREATE as u64, pageinfo, secs_page);
127}
128
129pub unsafe fn encls_edbgrd(source_address: u64) -> u64 {
140 encls!(EnclsCommand::EDBGRD as u64, source_address).1
141}
142
143pub unsafe fn encls_edbgwr(data: u64, target_address: u64) {
152 encls!(EnclsCommand::EDBGWR as u64, data, target_address);
153}
154
155pub unsafe fn encls_eextend(secs_chunk: u64, epc_chunk: u64) {
164 encls!(EnclsCommand::EEXTEND as u64, secs_chunk, epc_chunk);
165}
166
167pub unsafe fn encls_einit(sigstruct: u64, secs: u64, einittoken: u64) -> u32 {
177 encls!(EnclsCommand::EINIT as u64, sigstruct, secs, einittoken).0
178}
179
180pub unsafe fn encls_eldb(pageinfo: u64, epc_page: u64, verion_array_slot: u64) -> u32 {
190 encls!(
191 EnclsCommand::ELDB as u64,
192 pageinfo,
193 epc_page,
194 verion_array_slot
195 )
196 .0
197}
198
199pub unsafe fn encls_eldu(pageinfo: u64, epc_page: u64, verion_array_slot: u64) -> u32 {
209 encls!(
210 EnclsCommand::ELDU as u64,
211 pageinfo,
212 epc_page,
213 verion_array_slot
214 )
215 .0
216}
217
218pub unsafe fn encls_emodpr(secinfo: u64, epc_page: u64) -> u32 {
227 encls!(EnclsCommand::EMODPR as u64, secinfo, epc_page).0
228}
229
230pub unsafe fn encls_emodt(secinfo: u64, epc_page: u64) -> u32 {
239 encls!(EnclsCommand::EMODT as u64, secinfo, epc_page).0
240}
241
242pub unsafe fn encls_epa(pt_va: u64, epc_page: u64) {
251 encls!(EnclsCommand::EPA as u64, pt_va, epc_page);
252}
253
254pub unsafe fn encls_eremove(epc_page: u64) {
262 encls!(EnclsCommand::EREMOVE as u64, epc_page);
263}
264
265pub unsafe fn encls_etrack(secs_pointer: u64) -> u32 {
273 encls!(EnclsCommand::ETRACK as u64, secs_pointer).0
274}
275
276pub unsafe fn encls_ewb(pageinfo: u64, epc_page: u64, va_slot: u64) -> u32 {
285 encls!(EnclsCommand::EWB as u64, pageinfo, epc_page, va_slot).0
286}
287
288macro_rules! enclu {
293 ($rax:expr, $rbx:expr, $rcx:expr) => {
294 $crate::bits64::sgx::enclu3($rax as u64, $rbx as u64, $rcx as u64)
295 };
296
297 ($rax:expr, $rbx:expr, $rcx:expr, $rdx:expr) => {
298 $crate::bits64::sgx::enclu4($rax as u64, $rbx as u64, $rcx as u64, $rdx as u64)
299 };
300}
301
302unsafe fn enclu3(rax: u64, rbx: u64, rcx: u64) -> (u32, u64) {
304 let eax: u32;
305 let out_rcx: u64;
306 asm!(
307 "pushq %rbx; movq %rsi, %rbx; enclu; popq %rbx",
308 lateout("eax") eax, lateout("rcx") out_rcx,
309 in("rax") rax, in("rsi") rbx, in("rcx") rcx,
310 options(att_syntax),
311 );
312 (eax, out_rcx)
313}
314
315unsafe fn enclu4(rax: u64, rbx: u64, rcx: u64, rdx: u64) -> (u32, u64) {
317 let eax: u32;
318 let out_rcx: u64;
319 asm!(
320 "pushq %rbx; movq %rsi, %rbx; enclu; popq %rbx",
321 lateout("eax") eax, lateout("rcx") out_rcx,
322 in("rax") rax, in("rsi") rbx, in("rcx") rcx, in("rdx") rdx,
323 options(att_syntax),
324 );
325 (eax, out_rcx)
326}
327
328enum EncluCommand {
329 EAccept = 0x05,
330 EAcceptCopy = 0x07,
331 EEnter = 0x02,
332 EExit = 0x04,
333 EGetKey = 0x01,
334 EModePE = 0x06,
335 EReport = 0x00,
336 EResume = 0x03,
337}
338
339pub unsafe fn enclu_eaccept(secinfo: u64, epc_page: u64) -> u32 {
350 enclu!(EncluCommand::EAccept as u64, secinfo, epc_page).0
351}
352
353pub unsafe fn enclu_eacceptcopy(
365 secinfo: u64,
366 destination_epc_page: u64,
367 source_epc_page: u64,
368) -> u32 {
369 enclu!(
370 EncluCommand::EAcceptCopy as u64,
371 secinfo,
372 destination_epc_page,
373 source_epc_page
374 )
375 .0
376}
377
378pub unsafe fn enclu_eenter(tcs: u64, aep: u64) -> (u32, u64) {
390 enclu!(EncluCommand::EEnter as u64, tcs, aep)
391}
392
393pub unsafe fn enclu_eexit(ip: u64, aep: u64) {
402 enclu!(EncluCommand::EExit as u64, ip, aep);
403}
404
405pub unsafe fn enclu_egetkey(keyrequest: u64, outputdata: u64) {
414 enclu!(EncluCommand::EGetKey as u64, keyrequest, outputdata);
415}
416
417pub unsafe fn enclu_emodepe(secinfo: u64, epc_page: u64) {
426 enclu!(EncluCommand::EModePE as u64, secinfo, epc_page);
427}
428
429pub unsafe fn enclu_ereport(targetinfo: u64, reportdata: u64, outputdata: u64) {
439 enclu!(
440 EncluCommand::EReport as u64,
441 targetinfo,
442 reportdata,
443 outputdata
444 );
445}
446
447pub unsafe fn enclu_eresume(tcs: u64, aep: u64) {
456 enclu!(EncluCommand::EResume as u64, tcs, aep);
457}