Change the implementation of various traites to ensure test_single is low overhead
This commit is contained in:
parent
2d179897bf
commit
19b07d1b1f
@ -88,7 +88,7 @@ pub unsafe fn attack_t_tables_poc<T: ChannelHandle>(
|
||||
|
||||
addresses.shuffle(&mut thread_rng());
|
||||
|
||||
let mut victims_handle = unsafe { side_channel.calibrate(addresses.clone()).unwrap() };
|
||||
let mut victims_handle = unsafe { side_channel.tcalibrate(addresses.clone()).unwrap() };
|
||||
|
||||
for addr in addresses.iter() {
|
||||
let mut timing = HashMap::new();
|
||||
|
@ -10,6 +10,10 @@
|
||||
// Should be used by F+F and non Naive F+R
|
||||
|
||||
//use crate::naive::NaiveTimingChannelHandle;
|
||||
use cache_side_channel::table_side_channel::{
|
||||
MultipleTableCacheSideChannel, SingleTableCacheSideChannel, TableAttackResult,
|
||||
TableCacheSideChannel,
|
||||
};
|
||||
use cache_side_channel::SideChannelError::AddressNotReady;
|
||||
use cache_side_channel::{
|
||||
CacheStatus, ChannelFatalError, ChannelHandle, CoreSpec, MultipleAddrCacheSideChannel,
|
||||
@ -550,6 +554,33 @@ impl<T: TimingChannelPrimitives> MultipleAddrCacheSideChannel for TopologyAwareT
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TimingChannelPrimitives> SingleAddrCacheSideChannel for TopologyAwareTimingChannel<T> {
|
||||
type Handle = TopologyAwareTimingChannelHandle;
|
||||
|
||||
unsafe fn test_single(
|
||||
&mut self,
|
||||
handle: &mut Self::Handle,
|
||||
reset: bool,
|
||||
) -> Result<CacheStatus, SideChannelError> {
|
||||
unsafe { self.test_one_impl(handle, reset) }
|
||||
}
|
||||
|
||||
unsafe fn prepare_single(&mut self, handle: &mut Self::Handle) -> Result<(), SideChannelError> {
|
||||
unsafe { self.prepare_one_impl(handle) }
|
||||
}
|
||||
|
||||
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) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TimingChannelPrimitives> CovertChannel for TopologyAwareTimingChannel<T> {
|
||||
type CovertChannelHandle = CovertChannelHandle<TopologyAwareTimingChannel<T>>;
|
||||
const BIT_PER_PAGE: usize = 1;
|
||||
@ -656,19 +687,42 @@ impl<T: TimingChannelPrimitives> CovertChannel for TopologyAwareTimingChannel<T>
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TimingChannelPrimitives> TableCacheSideChannel<TopologyAwareTimingChannelHandle>
|
||||
for TopologyAwareTimingChannel<T>
|
||||
{
|
||||
unsafe fn tcalibrate(
|
||||
&mut self,
|
||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||
) -> Result<Vec<TopologyAwareTimingChannelHandle>, ChannelFatalError> {
|
||||
unsafe { self.tcalibrate_multi(addresses) }
|
||||
}
|
||||
|
||||
unsafe fn attack<'a, 'b, 'c, 'd>(
|
||||
&'a mut self,
|
||||
addresses: &'b mut Vec<&'c mut TopologyAwareTimingChannelHandle>,
|
||||
victim: &'d dyn Fn(),
|
||||
num_iteration: u32,
|
||||
) -> Result<Vec<TableAttackResult>, ChannelFatalError>
|
||||
where
|
||||
TopologyAwareTimingChannelHandle: 'c,
|
||||
{
|
||||
unsafe { self.attack_multi(addresses, victim, num_iteration) }
|
||||
}
|
||||
}
|
||||
|
||||
// Extra helper for single address per page variants.
|
||||
#[derive(Debug)]
|
||||
pub struct SingleChannel<T: MultipleAddrCacheSideChannel> {
|
||||
pub struct SingleChannel<T: SingleAddrCacheSideChannel> {
|
||||
inner: T,
|
||||
}
|
||||
|
||||
impl<T: MultipleAddrCacheSideChannel> SingleChannel<T> {
|
||||
impl<T: SingleAddrCacheSideChannel> SingleChannel<T> {
|
||||
pub fn new(inner: T) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MultipleAddrCacheSideChannel> CoreSpec for SingleChannel<T> {
|
||||
impl<T: SingleAddrCacheSideChannel> CoreSpec for SingleChannel<T> {
|
||||
fn main_core(&self) -> CpuSet {
|
||||
self.inner.main_core()
|
||||
}
|
||||
@ -678,7 +732,7 @@ impl<T: MultipleAddrCacheSideChannel> CoreSpec for SingleChannel<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: MultipleAddrCacheSideChannel> SingleAddrCacheSideChannel for SingleChannel<T> {
|
||||
impl<T: SingleAddrCacheSideChannel> SingleAddrCacheSideChannel for SingleChannel<T> {
|
||||
type Handle = T::Handle;
|
||||
|
||||
unsafe fn test_single(
|
||||
@ -705,6 +759,31 @@ impl<T: MultipleAddrCacheSideChannel> SingleAddrCacheSideChannel for SingleChann
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SingleAddrCacheSideChannel>
|
||||
TableCacheSideChannel<<SingleChannel<T> as SingleAddrCacheSideChannel>::Handle>
|
||||
for SingleChannel<T>
|
||||
{
|
||||
unsafe fn tcalibrate(
|
||||
&mut self,
|
||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||
) -> Result<Vec<<SingleChannel<T> as SingleAddrCacheSideChannel>::Handle>, ChannelFatalError>
|
||||
{
|
||||
unsafe { self.inner.tcalibrate_single(addresses) }
|
||||
}
|
||||
|
||||
unsafe fn attack<'a, 'b, 'c, 'd>(
|
||||
&'a mut self,
|
||||
addresses: &'b mut Vec<&'c mut <SingleChannel<T> as SingleAddrCacheSideChannel>::Handle>,
|
||||
victim: &'d dyn Fn(),
|
||||
num_iteration: u32,
|
||||
) -> Result<Vec<TableAttackResult>, ChannelFatalError>
|
||||
where
|
||||
<SingleChannel<T> as SingleAddrCacheSideChannel>::Handle: 'c,
|
||||
{
|
||||
unsafe { self.inner.attack_single(addresses, victim, num_iteration) }
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
impl<T: MultipleAddrCacheSideChannel + Sync + Send> CovertChannel for SingleChannel<T> {
|
||||
type Handle = CovertChannelHandle<T>;
|
||||
|
@ -1,4 +1,7 @@
|
||||
use crate::TimingChannelPrimitives;
|
||||
use cache_side_channel::table_side_channel::{
|
||||
SingleTableCacheSideChannel, TableAttackResult, TableCacheSideChannel,
|
||||
};
|
||||
use cache_side_channel::{
|
||||
CacheStatus, ChannelFatalError, ChannelHandle, CoreSpec, MultipleAddrCacheSideChannel,
|
||||
SideChannelError, SingleAddrCacheSideChannel,
|
||||
@ -65,7 +68,7 @@ impl<T: TimingChannelPrimitives> NaiveTimingChannel<T> {
|
||||
//}
|
||||
}
|
||||
|
||||
unsafe fn test_impl(
|
||||
unsafe fn test_one_impl(
|
||||
&self,
|
||||
handle: &mut NaiveTimingChannelHandle,
|
||||
//limit: u32,
|
||||
@ -83,6 +86,39 @@ impl<T: TimingChannelPrimitives> NaiveTimingChannel<T> {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn test_impl(
|
||||
&self,
|
||||
handles: &mut Vec<&mut NaiveTimingChannelHandle>,
|
||||
limit: u32,
|
||||
reset: bool,
|
||||
) -> Result<Vec<(*const u8, CacheStatus)>, SideChannelError> {
|
||||
let mut result = Vec::new();
|
||||
let mut tmp = Vec::new();
|
||||
let mut i = 0;
|
||||
for addr in handles {
|
||||
let r = unsafe { self.test_one_impl(addr, false) };
|
||||
tmp.push((addr.to_const_u8_pointer(), r));
|
||||
i += 1;
|
||||
if i == limit {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (addr, r) in tmp {
|
||||
match r {
|
||||
Ok(status) => {
|
||||
result.push((addr, status));
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
if T::NEED_RESET && reset {
|
||||
unsafe { flush(addr) };
|
||||
}
|
||||
}
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
// The former invariant of one handle per page has been removed
|
||||
// Now tolerates as many handles per cache line as wanted
|
||||
// should the invariant be fixed into one handle per cache line ?
|
||||
@ -99,6 +135,36 @@ impl<T: TimingChannelPrimitives> NaiveTimingChannel<T> {
|
||||
Ok(NaiveTimingChannelHandle { vpn, addr })
|
||||
//}
|
||||
}
|
||||
|
||||
unsafe fn prepare_one_impl(
|
||||
&mut self,
|
||||
handle: &mut NaiveTimingChannelHandle,
|
||||
) -> Result<(), SideChannelError> {
|
||||
unsafe { flush(handle.addr) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
unsafe fn prepare_impl(
|
||||
&mut self,
|
||||
addresses: &mut Vec<&mut NaiveTimingChannelHandle>,
|
||||
limit: u32,
|
||||
) -> Result<(), SideChannelError> {
|
||||
// Iterate on addresse prparig them, error early exit
|
||||
let mut i = 0;
|
||||
for handle in addresses {
|
||||
match unsafe { self.prepare_one_impl(handle) } {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
i += 1;
|
||||
if i == limit {
|
||||
break;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: TimingChannelPrimitives> CoreSpec for NaiveTimingChannel<T> {
|
||||
@ -130,7 +196,7 @@ impl<T: TimingChannelPrimitives + Send + Sync> CovertChannel for NaiveTimingChan
|
||||
}
|
||||
|
||||
unsafe fn receive(&self, handle: &mut Self::CovertChannelHandle) -> Vec<bool> {
|
||||
let r = unsafe { self.test_impl(handle, false) };
|
||||
let r = unsafe { self.test_one_impl(handle, false) };
|
||||
match r {
|
||||
Err(e) => panic!(),
|
||||
Ok(status) => match status {
|
||||
@ -153,12 +219,11 @@ impl<T: TimingChannelPrimitives> SingleAddrCacheSideChannel for NaiveTimingChann
|
||||
handle: &mut Self::Handle,
|
||||
reset: bool,
|
||||
) -> Result<CacheStatus, SideChannelError> {
|
||||
unsafe { self.test_impl(handle, reset) }
|
||||
unsafe { self.test_one_impl(handle, reset) }
|
||||
}
|
||||
|
||||
unsafe fn prepare_single(&mut self, handle: &mut Self::Handle) -> Result<(), SideChannelError> {
|
||||
unsafe { flush(handle.addr) };
|
||||
Ok(())
|
||||
unsafe { self.prepare_one_impl(handle) }
|
||||
}
|
||||
|
||||
fn victim_single(&mut self, operation: &dyn Fn()) {
|
||||
@ -184,10 +249,10 @@ impl<T: TimingChannelPrimitives> SingleAddrCacheSideChannel for NaiveTimingChann
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
||||
impl<T: TimingChannelPrimitives> MultipleAddrCacheSideChannel for NaiveTimingChannel<T> {
|
||||
type Handle = NaiveTimingChannelHandle;
|
||||
const MAX_ADDR: u32 = 0;
|
||||
const MAX_ADDR: u32 = 1;
|
||||
|
||||
unsafe fn test<'a>(
|
||||
&mut self,
|
||||
@ -229,7 +294,29 @@ impl<T: TimingChannelPrimitives> MultipleAddrCacheSideChannel for NaiveTimingCha
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl<T: TimingChannelPrimitives> TableCacheSideChannel<NaiveTimingChannelHandle>
|
||||
for NaiveTimingChannel<T>
|
||||
{
|
||||
unsafe fn tcalibrate(
|
||||
&mut self,
|
||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||
) -> Result<Vec<NaiveTimingChannelHandle>, ChannelFatalError> {
|
||||
unsafe { self.tcalibrate_single(addresses) }
|
||||
}
|
||||
|
||||
unsafe fn attack<'a, 'b, 'c, 'd>(
|
||||
&'a mut self,
|
||||
addresses: &'b mut Vec<&'c mut NaiveTimingChannelHandle>,
|
||||
victim: &'d dyn Fn(),
|
||||
num_iteration: u32,
|
||||
) -> Result<Vec<TableAttackResult>, ChannelFatalError>
|
||||
where
|
||||
NaiveTimingChannelHandle: 'c,
|
||||
{
|
||||
unsafe { self.attack_single(addresses, victim, num_iteration) }
|
||||
}
|
||||
}
|
||||
// Include a helper code to get global threshold model ?
|
||||
|
||||
// TODO
|
||||
|
@ -106,6 +106,7 @@ pub trait MultipleAddrCacheSideChannel: CoreSpec + Debug {
|
||||
) -> Result<Vec<Self::Handle>, ChannelFatalError>;
|
||||
}
|
||||
|
||||
/*
|
||||
impl<T: MultipleAddrCacheSideChannel> SingleAddrCacheSideChannel for T {
|
||||
type Handle = <Self as MultipleAddrCacheSideChannel>::Handle;
|
||||
|
||||
@ -134,6 +135,7 @@ impl<T: MultipleAddrCacheSideChannel> SingleAddrCacheSideChannel for T {
|
||||
unsafe { self.calibrate(addresses) }
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
@ -26,7 +26,7 @@ pub trait TableCacheSideChannel<Handle: ChannelHandle>: CoreSpec + Debug {
|
||||
/// # Safety
|
||||
///
|
||||
/// addresses must contain only valid pointers to read.
|
||||
unsafe fn calibrate(
|
||||
unsafe fn tcalibrate(
|
||||
&mut self,
|
||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||
) -> Result<Vec<Handle>, ChannelFatalError>;
|
||||
@ -43,8 +43,51 @@ pub trait TableCacheSideChannel<Handle: ChannelHandle>: CoreSpec + Debug {
|
||||
Handle: 'c;
|
||||
}
|
||||
|
||||
impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel<T::Handle> for T {
|
||||
default unsafe fn calibrate(
|
||||
pub trait SingleTableCacheSideChannel<Handle: ChannelHandle>: CoreSpec + Debug {
|
||||
//type ChannelFatalError: Debug;
|
||||
/// # Safety
|
||||
///
|
||||
/// addresses must contain only valid pointers to read.
|
||||
unsafe fn tcalibrate_single(
|
||||
&mut self,
|
||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||
) -> Result<Vec<Handle>, ChannelFatalError>;
|
||||
/// # Safety
|
||||
///
|
||||
/// addresses must contain only valid pointers to read.
|
||||
unsafe fn attack_single<'a, 'b, 'c, 'd>(
|
||||
&'a mut self,
|
||||
addresses: &'b mut Vec<&'c mut Handle>,
|
||||
victim: &'d dyn Fn(),
|
||||
num_iteration: u32,
|
||||
) -> Result<Vec<TableAttackResult>, ChannelFatalError>
|
||||
where
|
||||
Handle: 'c;
|
||||
}
|
||||
pub trait MultipleTableCacheSideChannel<Handle: ChannelHandle>: CoreSpec + Debug {
|
||||
//type ChannelFatalError: Debug;
|
||||
/// # Safety
|
||||
///
|
||||
/// addresses must contain only valid pointers to read.
|
||||
unsafe fn tcalibrate_multi(
|
||||
&mut self,
|
||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||
) -> Result<Vec<Handle>, ChannelFatalError>;
|
||||
/// # Safety
|
||||
///
|
||||
/// addresses must contain only valid pointers to read.
|
||||
unsafe fn attack_multi<'a, 'b, 'c, 'd>(
|
||||
&'a mut self,
|
||||
addresses: &'b mut Vec<&'c mut Handle>,
|
||||
victim: &'d dyn Fn(),
|
||||
num_iteration: u32,
|
||||
) -> Result<Vec<TableAttackResult>, ChannelFatalError>
|
||||
where
|
||||
Handle: 'c;
|
||||
}
|
||||
|
||||
impl<T: SingleAddrCacheSideChannel> SingleTableCacheSideChannel<T::Handle> for T {
|
||||
default unsafe fn tcalibrate_single(
|
||||
&mut self,
|
||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||
) -> Result<Vec<T::Handle>, ChannelFatalError> {
|
||||
@ -52,7 +95,7 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel<T::Handle> for T {
|
||||
}
|
||||
//type ChannelFatalError = T::SingleChannelFatalError;
|
||||
|
||||
default unsafe fn attack<'a, 'b, 'c, 'd>(
|
||||
default unsafe fn attack_single<'a, 'b, 'c, 'd>(
|
||||
&'a mut self,
|
||||
addresses: &'b mut Vec<&'c mut T::Handle>,
|
||||
victim: &'d dyn Fn(),
|
||||
@ -122,8 +165,8 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel<T::Handle> for T {
|
||||
|
||||
// TODO limit number of simultaneous tested address + randomise order ?
|
||||
|
||||
impl<T: MultipleAddrCacheSideChannel> TableCacheSideChannel<T::Handle> for T {
|
||||
unsafe fn calibrate(
|
||||
impl<T: MultipleAddrCacheSideChannel> MultipleTableCacheSideChannel<T::Handle> for T {
|
||||
unsafe fn tcalibrate_multi(
|
||||
&mut self,
|
||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||
) -> Result<Vec<T::Handle>, ChannelFatalError> {
|
||||
@ -134,7 +177,7 @@ impl<T: MultipleAddrCacheSideChannel> TableCacheSideChannel<T::Handle> for T {
|
||||
/// # Safety
|
||||
///
|
||||
/// addresses must contain only valid pointers to read.
|
||||
unsafe fn attack<'a, 'b, 'c, 'd>(
|
||||
unsafe fn attack_multi<'a, 'b, 'c, 'd>(
|
||||
&'a mut self,
|
||||
mut addresses: &'b mut Vec<&'c mut T::Handle>,
|
||||
victim: &'d dyn Fn(),
|
||||
|
Loading…
Reference in New Issue
Block a user