#[cfg(feature = "backend-kvm")]
pub mod kvm;
#[cfg(feature = "backend-sev")]
pub mod sev;
#[cfg(feature = "backend-sgx")]
pub mod sgx;
mod binary;
mod probe;
use binary::Binary;
use std::convert::TryFrom;
use std::sync::Arc;
use anyhow::{Error, Result};
use mmarinus::{perms, Map};
use sallyport::Block;
use spinning::Lazy;
trait Config: Sized {
type Flags;
fn flags(flags: u32) -> Self::Flags;
fn new(shim: &Binary, exec: &Binary) -> Result<Self>;
}
trait Mapper: Sized + TryFrom<Self::Config, Error = Error> {
type Config: Config;
type Output: TryFrom<Self, Error = Error>;
fn map(
&mut self,
pages: Map<perms::ReadWrite>,
to: usize,
with: <Self::Config as Config>::Flags,
) -> Result<()>;
}
trait Loader: Mapper {
fn load(shim: impl AsRef<[u8]>, exec: impl AsRef<[u8]>) -> Result<Self::Output>;
}
pub trait Backend: Sync + Send {
fn name(&self) -> &'static str;
fn shim(&self) -> &'static [u8];
fn data(&self) -> Vec<Datum>;
fn keep(&self, shim: &[u8], exec: &[u8]) -> Result<Arc<dyn Keep>>;
fn hash(&self, shim: &[u8], exec: &[u8]) -> Result<Vec<u8>>;
fn have(&self) -> bool {
!self.data().iter().fold(false, |e, d| e | !d.pass)
}
}
pub struct Datum {
pub name: String,
pub pass: bool,
pub info: Option<String>,
pub mesg: Option<String>,
}
pub trait Keep {
fn spawn(self: Arc<Self>) -> Result<Option<Box<dyn Thread>>>;
}
pub trait Thread {
fn enter(&mut self) -> Result<Command>;
}
pub enum Command<'a> {
#[allow(dead_code)]
SysCall(&'a mut Block),
#[allow(dead_code)]
CpuId(&'a mut Block),
#[allow(dead_code)]
Continue,
}
pub static BACKENDS: Lazy<Vec<Box<dyn Backend>>> = Lazy::new(|| {
vec![
#[cfg(feature = "backend-sgx")]
Box::new(sgx::Backend),
#[cfg(feature = "backend-sev")]
Box::new(sev::Backend),
#[cfg(feature = "backend-kvm")]
Box::new(kvm::Backend),
]
});