2020-10-22 14:38:41 +02:00
|
|
|
use cache_side_channel::{
|
2020-11-20 10:52:58 +01:00
|
|
|
CacheStatus, ChannelFatalError, CoreSpec, SideChannelError, SingleAddrCacheSideChannel,
|
2020-10-22 14:38:41 +02:00
|
|
|
};
|
2020-11-24 10:25:32 +01:00
|
|
|
use cache_utils::calibration::{get_vpn, only_flush, only_reload, VPN};
|
2020-09-22 14:36:07 +02:00
|
|
|
use cache_utils::flush;
|
2020-11-20 10:52:58 +01:00
|
|
|
use covert_channels_evaluation::{BitIterator, CovertChannel};
|
|
|
|
use nix::sched::{sched_getaffinity, CpuSet};
|
|
|
|
use nix::unistd::Pid;
|
2020-11-24 10:25:32 +01:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::thread::current;
|
2020-09-22 14:36:07 +02:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct NaiveFlushAndReload {
|
|
|
|
pub threshold: u64,
|
2020-11-24 10:25:32 +01:00
|
|
|
current: HashMap<VPN, *const u8>,
|
2020-12-02 16:43:26 +01:00
|
|
|
main_core: CpuSet,
|
|
|
|
helper_core: CpuSet,
|
2020-09-22 14:36:07 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl NaiveFlushAndReload {
|
|
|
|
pub fn from_threshold(threshold: u64) -> Self {
|
|
|
|
NaiveFlushAndReload {
|
|
|
|
threshold,
|
2020-11-24 10:25:32 +01:00
|
|
|
current: Default::default(),
|
2020-12-02 16:43:26 +01:00
|
|
|
main_core: sched_getaffinity(Pid::from_raw(0)).unwrap(),
|
|
|
|
helper_core: sched_getaffinity(Pid::from_raw(0)).unwrap(),
|
2020-09-22 14:36:07 +02:00
|
|
|
}
|
|
|
|
}
|
2020-11-24 10:25:32 +01:00
|
|
|
unsafe fn test_impl(&self, addr: *const u8) -> Result<CacheStatus, SideChannelError> {
|
|
|
|
let vpn = get_vpn(addr);
|
|
|
|
if self.current.get(&vpn) != Some(&addr) {
|
2020-09-22 16:49:22 +02:00
|
|
|
return Err(SideChannelError::AddressNotReady(addr));
|
2020-09-22 14:36:07 +02:00
|
|
|
}
|
|
|
|
let t = unsafe { only_reload(addr) };
|
2020-11-24 10:25:32 +01:00
|
|
|
unsafe { flush(addr) };
|
2020-09-22 14:36:07 +02:00
|
|
|
if t > self.threshold {
|
|
|
|
Ok(CacheStatus::Miss)
|
|
|
|
} else {
|
|
|
|
Ok(CacheStatus::Hit)
|
|
|
|
}
|
|
|
|
}
|
2020-12-02 16:43:26 +01:00
|
|
|
|
|
|
|
pub fn set_cores(&mut self, main_core: usize, helper_core: usize) {
|
|
|
|
self.main_core = CpuSet::new();
|
|
|
|
self.main_core.set(main_core).unwrap();
|
|
|
|
|
|
|
|
self.helper_core = CpuSet::new();
|
|
|
|
self.helper_core.set(helper_core).unwrap();
|
|
|
|
}
|
2020-11-24 10:25:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
impl SingleAddrCacheSideChannel for NaiveFlushAndReload {
|
|
|
|
/// # Safety
|
|
|
|
///
|
|
|
|
/// addr needs to be a valid pointer
|
|
|
|
unsafe fn test_single(&mut self, addr: *const u8) -> Result<CacheStatus, SideChannelError> {
|
|
|
|
unsafe { self.test_impl(addr) }
|
|
|
|
}
|
2020-09-22 14:36:07 +02:00
|
|
|
|
2020-09-22 17:09:46 +02:00
|
|
|
/// # Safety:
|
|
|
|
///
|
|
|
|
/// addr needs to be a valid pointer
|
2020-09-22 16:49:22 +02:00
|
|
|
unsafe fn prepare_single(&mut self, addr: *const u8) -> Result<(), SideChannelError> {
|
2020-09-22 14:36:07 +02:00
|
|
|
unsafe { flush(addr) };
|
2020-11-24 10:25:32 +01:00
|
|
|
let vpn = get_vpn(addr);
|
|
|
|
self.current.insert(vpn, addr);
|
2020-09-22 14:36:07 +02:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn victim_single(&mut self, operation: &dyn Fn()) {
|
|
|
|
operation()
|
|
|
|
}
|
|
|
|
|
2020-09-22 17:09:46 +02:00
|
|
|
/// # Safety
|
|
|
|
///
|
|
|
|
/// addr needs to be a valid pointer
|
2020-09-22 16:49:22 +02:00
|
|
|
unsafe fn calibrate_single(
|
2020-09-22 14:36:07 +02:00
|
|
|
&mut self,
|
|
|
|
_addresses: impl IntoIterator<Item = *const u8>,
|
|
|
|
) -> Result<(), ChannelFatalError> {
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
2020-11-20 10:52:58 +01:00
|
|
|
|
|
|
|
unsafe impl Send for NaiveFlushAndReload {}
|
|
|
|
unsafe impl Sync for NaiveFlushAndReload {}
|
|
|
|
|
|
|
|
impl CoreSpec for NaiveFlushAndReload {
|
|
|
|
fn main_core(&self) -> CpuSet {
|
2020-12-02 16:43:26 +01:00
|
|
|
self.main_core
|
2020-11-20 10:52:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fn helper_core(&self) -> CpuSet {
|
2020-12-02 16:43:26 +01:00
|
|
|
self.helper_core
|
2020-11-20 10:52:58 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl CovertChannel for NaiveFlushAndReload {
|
|
|
|
const BIT_PER_PAGE: usize = 1;
|
|
|
|
|
|
|
|
unsafe fn transmit<'a>(&self, page: *const u8, bits: &mut BitIterator<'a>) {
|
2020-11-24 10:25:32 +01:00
|
|
|
let vpn = get_vpn(page);
|
|
|
|
let addr = self.current.get(&vpn).unwrap();
|
|
|
|
if let Some(b) = bits.next() {
|
|
|
|
if b {
|
|
|
|
unsafe { only_reload(*addr) };
|
|
|
|
} else {
|
|
|
|
unsafe { only_flush(*addr) };
|
|
|
|
}
|
|
|
|
}
|
2020-11-20 10:52:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn receive(&self, page: *const u8) -> Vec<bool> {
|
2020-11-24 10:25:32 +01:00
|
|
|
let r = unsafe { self.test_impl(page) };
|
2020-11-20 10:52:58 +01:00
|
|
|
match r {
|
2020-11-24 10:25:32 +01:00
|
|
|
Err(e) => panic!(),
|
2020-11-20 10:52:58 +01:00
|
|
|
Ok(status) => match status {
|
|
|
|
CacheStatus::Hit => vec![true],
|
|
|
|
CacheStatus::Miss => vec![false],
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn ready_page(&mut self, page: *const u8) {
|
2020-11-24 10:25:32 +01:00
|
|
|
unsafe { self.prepare_single(page) };
|
2020-11-20 10:52:58 +01:00
|
|
|
}
|
|
|
|
}
|