in binder/src/ipc/app.rs [60:129]
fn ecall_ipc_app_to_tee(
&mut self,
cmd: u32,
request_payload: Vec<u8>,
) -> std::result::Result<Vec<u8>, IpcError> {
debug! {"ecall_ipc_app_to_tee: {:x}, {:x} bytes", cmd, request_payload.len()};
let in_ptr: *const u8 = request_payload.as_ptr();
let in_len: usize = request_payload.len();
let mut retried = false;
let out_buf = loop {
let out_max: usize = self.curr_out_buf_size;
let mut out_buf: Vec<u8> = Vec::with_capacity(out_max);
let mut out_len: usize = out_max;
let out_ptr: *mut u8 = out_buf.as_mut_ptr();
let mut ecall_ret = ECallStatus::default();
let sgx_status = unsafe {
ecall_ipc_entry_point(
self.enclave_id,
&mut ecall_ret,
cmd,
in_ptr,
in_len,
out_ptr,
out_max,
&mut out_len,
)
};
// Check sgx return values
if sgx_status != SgxStatus::Success {
error!("ecall_ipc_entry_point, app sgx_error:{}", sgx_status);
return Err(IpcError::SgxError(sgx_status));
}
// Check rust logic return values
// If out_buf is not big enough, realloc based on the returned out_len
// We only retry once for once invocation.
if ecall_ret.is_err_ffi_outbuf() && !retried {
debug!(
"ecall_ipc_entry_point, expand app request buffer size: {:?}",
ecall_ret
);
assert!(out_len > out_max);
self.curr_out_buf_size = out_len;
retried = true;
continue;
}
// Check rust logic return values
// Transparent deliever the errors to outer logic.
if ecall_ret.is_err() {
error!("ecall_ipc_entry_point, app api_error: {:?}", ecall_ret);
return Err(IpcError::ECallError(ecall_ret));
}
unsafe {
out_buf.set_len(out_len);
}
debug!("ecall_ipc_entry_point OK. App Received Buf: {:?}", out_buf);
break out_buf;
};
Ok(out_buf)
}