use core::arch::asm;
macro_rules! encls {
($rax:expr, $rbx:expr) => {
$crate::bits64::sgx::encls2($rax as u64, $rbx as u64)
};
($rax:expr, $rbx:expr, $rcx:expr) => {
$crate::bits64::sgx::encls3($rax as u64, $rbx as u64, $rcx as u64)
};
($rax:expr, $rbx:expr, $rcx:expr, $rdx:expr) => {
$crate::bits64::sgx::encls4($rax as u64, $rbx as u64, $rcx as u64, $rdx as u64)
};
}
unsafe fn encls2(rax: u64, rbx: u64) -> (u32, u64) {
let eax: u32;
let out_rbx: u64;
asm!(
"pushq %rbx; movq %rsi, %rbx; encls; movq %rbx, %rsi; popq %rbx",
lateout("eax") eax, lateout("rsi") out_rbx,
in("rax") rax, in("rsi") rbx,
options(att_syntax),
);
(eax, out_rbx)
}
unsafe fn encls3(rax: u64, rbx: u64, rcx: u64) -> (u32, u64) {
let eax: u32;
let out_rbx: u64;
asm!(
"pushq %rbx; movq %rsi, %rbx; encls; movq %rbx, %r11; popq %rbx",
lateout("eax") eax, lateout("rsi") out_rbx,
in("rax") rax, in("rsi") rbx, in("rcx") rcx,
options(att_syntax),
);
(eax, out_rbx)
}
unsafe fn encls4(rax: u64, rbx: u64, rcx: u64, rdx: u64) -> (u32, u64) {
let eax: u32;
let out_rbx: u64;
asm!(
"pushq %rbx; movq %rsi, %rbx; encls; movq %rbx, %rsi; popq %rbx",
lateout("eax") eax, lateout("rsi") out_rbx,
in("rax") rax, in("rsi") rbx, in("rcx") rcx, in("rdx") rdx,
options(att_syntax),
);
(eax, out_rbx)
}
#[allow(clippy::upper_case_acronyms)]
enum EnclsCommand {
EADD = 0x01,
EAUG = 0x0D,
EBLOCK = 0x09,
ECREATE = 0x00,
EDBGRD = 0x04,
EDBGWR = 0x05,
EEXTEND = 0x06,
EINIT = 0x02,
ELDB = 0x07,
ELDU = 0x08,
EMODPR = 0x0E,
EMODT = 0x0F,
EPA = 0x0A,
EREMOVE = 0x03,
ETRACK = 0x0C,
EWB = 0x0B,
}
pub unsafe fn encls_eadd(pageinfo: u64, epc_page: u64) {
encls!(EnclsCommand::EADD as u64, pageinfo, epc_page);
}
pub unsafe fn encls_eaug(secinfo_address: u64, epc_page: u64) {
encls!(EnclsCommand::EAUG as u64, secinfo_address, epc_page);
}
pub unsafe fn encls_eblock(epc_page: u64) -> u32 {
encls!(EnclsCommand::EBLOCK as u64, epc_page).0
}
pub unsafe fn encls_create(pageinfo: u64, secs_page: u64) {
encls!(EnclsCommand::ECREATE as u64, pageinfo, secs_page);
}
pub unsafe fn encls_edbgrd(source_address: u64) -> u64 {
encls!(EnclsCommand::EDBGRD as u64, source_address).1
}
pub unsafe fn encls_edbgwr(data: u64, target_address: u64) {
encls!(EnclsCommand::EDBGWR as u64, data, target_address);
}
pub unsafe fn encls_eextend(secs_chunk: u64, epc_chunk: u64) {
encls!(EnclsCommand::EEXTEND as u64, secs_chunk, epc_chunk);
}
pub unsafe fn encls_einit(sigstruct: u64, secs: u64, einittoken: u64) -> u32 {
encls!(EnclsCommand::EINIT as u64, sigstruct, secs, einittoken).0
}
pub unsafe fn encls_eldb(pageinfo: u64, epc_page: u64, verion_array_slot: u64) -> u32 {
encls!(
EnclsCommand::ELDB as u64,
pageinfo,
epc_page,
verion_array_slot
)
.0
}
pub unsafe fn encls_eldu(pageinfo: u64, epc_page: u64, verion_array_slot: u64) -> u32 {
encls!(
EnclsCommand::ELDU as u64,
pageinfo,
epc_page,
verion_array_slot
)
.0
}
pub unsafe fn encls_emodpr(secinfo: u64, epc_page: u64) -> u32 {
encls!(EnclsCommand::EMODPR as u64, secinfo, epc_page).0
}
pub unsafe fn encls_emodt(secinfo: u64, epc_page: u64) -> u32 {
encls!(EnclsCommand::EMODT as u64, secinfo, epc_page).0
}
pub unsafe fn encls_epa(pt_va: u64, epc_page: u64) {
encls!(EnclsCommand::EPA as u64, pt_va, epc_page);
}
pub unsafe fn encls_eremove(epc_page: u64) {
encls!(EnclsCommand::EREMOVE as u64, epc_page);
}
pub unsafe fn encls_etrack(secs_pointer: u64) -> u32 {
encls!(EnclsCommand::ETRACK as u64, secs_pointer).0
}
pub unsafe fn encls_ewb(pageinfo: u64, epc_page: u64, va_slot: u64) -> u32 {
encls!(EnclsCommand::EWB as u64, pageinfo, epc_page, va_slot).0
}
macro_rules! enclu {
($rax:expr, $rbx:expr, $rcx:expr) => {
$crate::bits64::sgx::enclu3($rax as u64, $rbx as u64, $rcx as u64)
};
($rax:expr, $rbx:expr, $rcx:expr, $rdx:expr) => {
$crate::bits64::sgx::enclu4($rax as u64, $rbx as u64, $rcx as u64, $rdx as u64)
};
}
unsafe fn enclu3(rax: u64, rbx: u64, rcx: u64) -> (u32, u64) {
let eax: u32;
let out_rcx: u64;
asm!(
"pushq %rbx; movq %rsi, %rbx; enclu; popq %rbx",
lateout("eax") eax, lateout("rcx") out_rcx,
in("rax") rax, in("rsi") rbx, in("rcx") rcx,
options(att_syntax),
);
(eax, out_rcx)
}
unsafe fn enclu4(rax: u64, rbx: u64, rcx: u64, rdx: u64) -> (u32, u64) {
let eax: u32;
let out_rcx: u64;
asm!(
"pushq %rbx; movq %rsi, %rbx; enclu; popq %rbx",
lateout("eax") eax, lateout("rcx") out_rcx,
in("rax") rax, in("rsi") rbx, in("rcx") rcx, in("rdx") rdx,
options(att_syntax),
);
(eax, out_rcx)
}
enum EncluCommand {
EAccept = 0x05,
EAcceptCopy = 0x07,
EEnter = 0x02,
EExit = 0x04,
EGetKey = 0x01,
EModePE = 0x06,
EReport = 0x00,
EResume = 0x03,
}
pub unsafe fn enclu_eaccept(secinfo: u64, epc_page: u64) -> u32 {
enclu!(EncluCommand::EAccept as u64, secinfo, epc_page).0
}
pub unsafe fn enclu_eacceptcopy(
secinfo: u64,
destination_epc_page: u64,
source_epc_page: u64,
) -> u32 {
enclu!(
EncluCommand::EAcceptCopy as u64,
secinfo,
destination_epc_page,
source_epc_page
)
.0
}
pub unsafe fn enclu_eenter(tcs: u64, aep: u64) -> (u32, u64) {
enclu!(EncluCommand::EEnter as u64, tcs, aep)
}
pub unsafe fn enclu_eexit(ip: u64, aep: u64) {
enclu!(EncluCommand::EExit as u64, ip, aep);
}
pub unsafe fn enclu_egetkey(keyrequest: u64, outputdata: u64) {
enclu!(EncluCommand::EGetKey as u64, keyrequest, outputdata);
}
pub unsafe fn enclu_emodepe(secinfo: u64, epc_page: u64) {
enclu!(EncluCommand::EModePE as u64, secinfo, epc_page);
}
pub unsafe fn enclu_ereport(targetinfo: u64, reportdata: u64, outputdata: u64) {
enclu!(
EncluCommand::EReport as u64,
targetinfo,
reportdata,
outputdata
);
}
pub unsafe fn enclu_eresume(tcs: u64, aep: u64) {
enclu!(EncluCommand::EResume as u64, tcs, aep);
}