#sgx #async #x86-64 #usercall

nightly async-usercalls

An interface for asynchronous usercalls in SGX enclaves. This is an SGX-only crate, you should compile it with the x86_64-fortanix-unknown-sgx target

1 unstable release

new 0.5.0 Apr 16, 2024

#402 in Asynchronous

Download history 163/week @ 2024-04-15

163 downloads per month

MPL-2.0 license

165KB
3K SLoC

This crate provides an interface for performing asynchronous usercalls in SGX enclaves. The motivation behind asynchronous usercalls and ABI documentation can be found here. The API provided here is fairly low level and is not meant for general use. These APIs can be used to implement mio abstractions which in turn allows us to use tokio in SGX enclaves!

The main interface is provided through AsyncUsercallProvider which works in tandem with CallbackHandler:

use async_usercalls::AsyncUsercallProvider;
use std::{io::Result, net::TcpStream, sync::mpsc, time::Duration};

let (provider, callback_handler) = AsyncUsercallProvider::new();
let (tx, rx) = mpsc::sync_channel(1);
// The closure is called when userspace sends back the result of the
// usercall.
let cancel_handle = provider.connect_stream("www.example.com:80", move |res| {
    tx.send(res).unwrap();
});
// We can cancel the connect usercall using `cancel_handle.cancel()`, but
// note that we may still get a successful result.
// We need to poll `callback_handler` to make progress.
loop {
    let n = callback_handler.poll(Some(Duration::from_millis(100)));
    if n > 0 {
        break; // at least 1 callback function was executed!
    }
}
let connect_result: Result<TcpStream> = rx.recv().unwrap();

Dependencies

~375KB