diff --git a/aes-t-tables/src/lib.rs b/aes-t-tables/src/lib.rs index 1c211a1..2811e30 100644 --- a/aes-t-tables/src/lib.rs +++ b/aes-t-tables/src/lib.rs @@ -88,7 +88,7 @@ pub unsafe fn attack_t_tables_poc( 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(); diff --git a/basic_timing_cache_channel/src/lib.rs b/basic_timing_cache_channel/src/lib.rs index afb856b..ebd0b32 100644 --- a/basic_timing_cache_channel/src/lib.rs +++ b/basic_timing_cache_channel/src/lib.rs @@ -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 MultipleAddrCacheSideChannel for TopologyAwareT } } +impl SingleAddrCacheSideChannel for TopologyAwareTimingChannel { + type Handle = TopologyAwareTimingChannelHandle; + + unsafe fn test_single( + &mut self, + handle: &mut Self::Handle, + reset: bool, + ) -> Result { + 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 + Clone, + ) -> Result, ChannelFatalError> { + unsafe { self.calibrate(addresses) } + } +} + impl CovertChannel for TopologyAwareTimingChannel { type CovertChannelHandle = CovertChannelHandle>; const BIT_PER_PAGE: usize = 1; @@ -656,19 +687,42 @@ impl CovertChannel for TopologyAwareTimingChannel } } +impl TableCacheSideChannel + for TopologyAwareTimingChannel +{ + unsafe fn tcalibrate( + &mut self, + addresses: impl IntoIterator + Clone, + ) -> Result, 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, 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 { +pub struct SingleChannel { inner: T, } -impl SingleChannel { +impl SingleChannel { pub fn new(inner: T) -> Self { Self { inner } } } -impl CoreSpec for SingleChannel { +impl CoreSpec for SingleChannel { fn main_core(&self) -> CpuSet { self.inner.main_core() } @@ -678,7 +732,7 @@ impl CoreSpec for SingleChannel { } } -impl SingleAddrCacheSideChannel for SingleChannel { +impl SingleAddrCacheSideChannel for SingleChannel { type Handle = T::Handle; unsafe fn test_single( @@ -705,6 +759,31 @@ impl SingleAddrCacheSideChannel for SingleChann } } +impl + TableCacheSideChannel< as SingleAddrCacheSideChannel>::Handle> + for SingleChannel +{ + unsafe fn tcalibrate( + &mut self, + addresses: impl IntoIterator + Clone, + ) -> Result 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 as SingleAddrCacheSideChannel>::Handle>, + victim: &'d dyn Fn(), + num_iteration: u32, + ) -> Result, ChannelFatalError> + where + as SingleAddrCacheSideChannel>::Handle: 'c, + { + unsafe { self.inner.attack_single(addresses, victim, num_iteration) } + } +} + /* impl CovertChannel for SingleChannel { type Handle = CovertChannelHandle; diff --git a/basic_timing_cache_channel/src/naive.rs b/basic_timing_cache_channel/src/naive.rs index 3da8aaf..e805975 100644 --- a/basic_timing_cache_channel/src/naive.rs +++ b/basic_timing_cache_channel/src/naive.rs @@ -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 NaiveTimingChannel { //} } - unsafe fn test_impl( + unsafe fn test_one_impl( &self, handle: &mut NaiveTimingChannelHandle, //limit: u32, @@ -83,6 +86,39 @@ impl NaiveTimingChannel { } } + unsafe fn test_impl( + &self, + handles: &mut Vec<&mut NaiveTimingChannelHandle>, + limit: u32, + reset: bool, + ) -> Result, 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 NaiveTimingChannel { 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 CoreSpec for NaiveTimingChannel { @@ -130,7 +196,7 @@ impl CovertChannel for NaiveTimingChan } unsafe fn receive(&self, handle: &mut Self::CovertChannelHandle) -> Vec { - 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 SingleAddrCacheSideChannel for NaiveTimingChann handle: &mut Self::Handle, reset: bool, ) -> Result { - 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 SingleAddrCacheSideChannel for NaiveTimingChann Ok(result) } } -/* + impl MultipleAddrCacheSideChannel for NaiveTimingChannel { type Handle = NaiveTimingChannelHandle; - const MAX_ADDR: u32 = 0; + const MAX_ADDR: u32 = 1; unsafe fn test<'a>( &mut self, @@ -229,7 +294,29 @@ impl MultipleAddrCacheSideChannel for NaiveTimingCha Ok(result) } } -*/ + +impl TableCacheSideChannel + for NaiveTimingChannel +{ + unsafe fn tcalibrate( + &mut self, + addresses: impl IntoIterator + Clone, + ) -> Result, 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, ChannelFatalError> + where + NaiveTimingChannelHandle: 'c, + { + unsafe { self.attack_single(addresses, victim, num_iteration) } + } +} // Include a helper code to get global threshold model ? // TODO diff --git a/cache_side_channel/src/lib.rs b/cache_side_channel/src/lib.rs index fa98e2c..60689fd 100644 --- a/cache_side_channel/src/lib.rs +++ b/cache_side_channel/src/lib.rs @@ -106,6 +106,7 @@ pub trait MultipleAddrCacheSideChannel: CoreSpec + Debug { ) -> Result, ChannelFatalError>; } +/* impl SingleAddrCacheSideChannel for T { type Handle = ::Handle; @@ -134,6 +135,7 @@ impl SingleAddrCacheSideChannel for T { unsafe { self.calibrate(addresses) } } } +*/ #[cfg(test)] mod tests { diff --git a/cache_side_channel/src/table_side_channel.rs b/cache_side_channel/src/table_side_channel.rs index abbfdaf..8428395 100644 --- a/cache_side_channel/src/table_side_channel.rs +++ b/cache_side_channel/src/table_side_channel.rs @@ -26,7 +26,7 @@ pub trait TableCacheSideChannel: CoreSpec + Debug { /// # Safety /// /// addresses must contain only valid pointers to read. - unsafe fn calibrate( + unsafe fn tcalibrate( &mut self, addresses: impl IntoIterator + Clone, ) -> Result, ChannelFatalError>; @@ -43,8 +43,51 @@ pub trait TableCacheSideChannel: CoreSpec + Debug { Handle: 'c; } -impl TableCacheSideChannel for T { - default unsafe fn calibrate( +pub trait SingleTableCacheSideChannel: CoreSpec + Debug { + //type ChannelFatalError: Debug; + /// # Safety + /// + /// addresses must contain only valid pointers to read. + unsafe fn tcalibrate_single( + &mut self, + addresses: impl IntoIterator + Clone, + ) -> Result, 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, ChannelFatalError> + where + Handle: 'c; +} +pub trait MultipleTableCacheSideChannel: CoreSpec + Debug { + //type ChannelFatalError: Debug; + /// # Safety + /// + /// addresses must contain only valid pointers to read. + unsafe fn tcalibrate_multi( + &mut self, + addresses: impl IntoIterator + Clone, + ) -> Result, 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, ChannelFatalError> + where + Handle: 'c; +} + +impl SingleTableCacheSideChannel for T { + default unsafe fn tcalibrate_single( &mut self, addresses: impl IntoIterator + Clone, ) -> Result, ChannelFatalError> { @@ -52,7 +95,7 @@ impl TableCacheSideChannel 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 TableCacheSideChannel for T { // TODO limit number of simultaneous tested address + randomise order ? -impl TableCacheSideChannel for T { - unsafe fn calibrate( +impl MultipleTableCacheSideChannel for T { + unsafe fn tcalibrate_multi( &mut self, addresses: impl IntoIterator + Clone, ) -> Result, ChannelFatalError> { @@ -134,7 +177,7 @@ impl TableCacheSideChannel 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(),