147 lines
3.9 KiB
Rust
147 lines
3.9 KiB
Rust
#![feature(specialization)]
|
|
#![feature(unsafe_block_in_unsafe_fn)]
|
|
#![deny(unsafe_op_in_unsafe_fn)]
|
|
|
|
use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet};
|
|
use nix::unistd::Pid;
|
|
use std::fmt::Debug;
|
|
|
|
pub mod table_side_channel;
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
pub enum CacheStatus {
|
|
Hit,
|
|
Miss,
|
|
}
|
|
|
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
|
pub enum ChannelFatalError {
|
|
Oops,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum SideChannelError {
|
|
NeedRecalibration,
|
|
FatalError(ChannelFatalError),
|
|
AddressNotReady(*const u8),
|
|
AddressNotCalibrated(*const u8),
|
|
}
|
|
|
|
pub trait ChannelHandle {
|
|
fn to_const_u8_pointer(&self) -> *const u8;
|
|
}
|
|
|
|
pub trait CoreSpec {
|
|
fn main_core(&self) -> CpuSet;
|
|
fn helper_core(&self) -> CpuSet;
|
|
}
|
|
|
|
pub fn restore_affinity(cpu_set: &CpuSet) {
|
|
sched_setaffinity(Pid::from_raw(0), &cpu_set).unwrap();
|
|
}
|
|
|
|
#[must_use = "This result must be used to restore affinity"]
|
|
pub fn set_affinity(cpu_set: &CpuSet) -> Result<CpuSet, nix::Error> {
|
|
let old = sched_getaffinity(Pid::from_raw(0))?;
|
|
sched_setaffinity(Pid::from_raw(0), &cpu_set)?;
|
|
Ok(old)
|
|
}
|
|
|
|
pub trait SingleAddrCacheSideChannel: CoreSpec + Debug {
|
|
type Handle: ChannelHandle;
|
|
//type SingleChannelFatalError: Debug;
|
|
/// # Safety
|
|
///
|
|
/// addr must be a valid pointer to read.
|
|
unsafe fn test_single(
|
|
&mut self,
|
|
handle: &mut Self::Handle,
|
|
reset: bool,
|
|
) -> Result<CacheStatus, SideChannelError>;
|
|
/// # Safety
|
|
///
|
|
/// addr must be a valid pointer to read.
|
|
unsafe fn prepare_single(&mut self, handle: &mut Self::Handle) -> Result<(), SideChannelError>;
|
|
fn victim_single(&mut self, operation: &dyn Fn());
|
|
/// # Safety
|
|
///
|
|
/// addresses must contain only valid pointers to read.
|
|
unsafe fn calibrate_single(
|
|
&mut self,
|
|
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
|
) -> Result<Vec<Self::Handle>, ChannelFatalError>;
|
|
}
|
|
|
|
pub trait MultipleAddrCacheSideChannel: CoreSpec + Debug {
|
|
type Handle: ChannelHandle;
|
|
const MAX_ADDR: u32;
|
|
/// # Safety
|
|
///
|
|
/// addresses must contain only valid pointers to read.
|
|
unsafe fn test<'a, 'b, 'c>(
|
|
&'a mut self,
|
|
addresses: &'b mut Vec<&'c mut Self::Handle>,
|
|
reset: bool,
|
|
) -> Result<Vec<(*const u8, CacheStatus)>, SideChannelError>
|
|
where
|
|
Self::Handle: 'c;
|
|
|
|
/// # Safety
|
|
///
|
|
/// addresses must contain only valid pointers to read.
|
|
unsafe fn prepare<'a, 'b, 'c>(
|
|
&'a mut self,
|
|
addresses: &'b mut Vec<&'c mut Self::Handle>,
|
|
) -> Result<(), SideChannelError>
|
|
where
|
|
Self::Handle: 'c;
|
|
fn victim(&mut self, operation: &dyn Fn());
|
|
|
|
/// # Safety
|
|
///
|
|
/// addresses must contain only valid pointers to read.
|
|
unsafe fn calibrate(
|
|
&mut self,
|
|
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
|
) -> Result<Vec<Self::Handle>, ChannelFatalError>;
|
|
}
|
|
|
|
/*
|
|
impl<T: MultipleAddrCacheSideChannel> SingleAddrCacheSideChannel for T {
|
|
type Handle = <Self as MultipleAddrCacheSideChannel>::Handle;
|
|
|
|
unsafe fn test_single(
|
|
&mut self,
|
|
handle: &mut Self::Handle,
|
|
reset: bool,
|
|
) -> Result<CacheStatus, SideChannelError> {
|
|
let mut handles = vec![handle];
|
|
unsafe { self.test(&mut handles, reset) }.map(|v| v[0].1)
|
|
}
|
|
|
|
unsafe fn prepare_single(&mut self, handle: &mut Self::Handle) -> Result<(), SideChannelError> {
|
|
let mut handles = vec![handle];
|
|
unsafe { self.prepare(&mut handles) }
|
|
}
|
|
|
|
fn victim_single(&mut self, operation: &dyn Fn()) {
|
|
self.victim(operation);
|
|
}
|
|
|
|
unsafe fn calibrate_single(
|
|
&mut self,
|
|
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
|
) -> Result<Vec<Self::Handle>, ChannelFatalError> {
|
|
unsafe { self.calibrate(addresses) }
|
|
}
|
|
}
|
|
*/
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
#[test]
|
|
fn it_works() {
|
|
assert_eq!(2 + 2, 4);
|
|
}
|
|
}
|