From a272c79127ae3f7228c8d01865ed17722a99398b Mon Sep 17 00:00:00 2001 From: Guillume DIDIER Date: Mon, 27 Sep 2021 16:27:53 +0200 Subject: [PATCH] More work on unknown cache slicing handling --- basic_timing_cache_channel/src/lib.rs | 32 ++++++++++++--------------- cache_utils/src/bin/two_thread_cal.rs | 17 ++++++-------- cache_utils/src/calibrate_2t.rs | 14 +++++------- cache_utils/src/calibration.rs | 27 +++++++++++++++++++--- 4 files changed, 51 insertions(+), 39 deletions(-) diff --git a/basic_timing_cache_channel/src/lib.rs b/basic_timing_cache_channel/src/lib.rs index 9fb0425..5a7cc94 100644 --- a/basic_timing_cache_channel/src/lib.rs +++ b/basic_timing_cache_channel/src/lib.rs @@ -20,13 +20,13 @@ use cache_side_channel::{ SideChannelError, SingleAddrCacheSideChannel, }; use cache_utils::calibration::{ - accumulate, calibrate_fixed_freq_2_thread, calibration_result_to_ASVP, get_cache_slicing, - get_vpn, only_flush, only_reload, CalibrateOperation2T, CalibrationOptions, ErrorPrediction, - ErrorPredictions, HashMap, HistParams, HistogramCumSum, PotentialThresholds, Slice, Threshold, - ThresholdError, Verbosity, ASVP, AV, CFLUSH_BUCKET_NUMBER, CFLUSH_BUCKET_SIZE, CFLUSH_NUM_ITER, - PAGE_LEN, SP, VPN, + accumulate, calibrate_fixed_freq_2_thread, calibration_result_to_ASVP, + get_cache_attack_slicing, get_vpn, only_flush, only_reload, CalibrateOperation2T, + CalibrationOptions, ErrorPrediction, ErrorPredictions, HashMap, HistParams, HistogramCumSum, + PotentialThresholds, Slice, Threshold, ThresholdError, Verbosity, ASVP, AV, + CFLUSH_BUCKET_NUMBER, CFLUSH_BUCKET_SIZE, CFLUSH_NUM_ITER, PAGE_LEN, SP, VPN, }; -use cache_utils::complex_addressing::CacheSlicing; +use cache_utils::complex_addressing::{CacheAttackSlicing, CacheSlicing}; use cache_utils::mmap::MMappedMemory; use cache_utils::{find_core_per_socket, flush, maccess, noop}; use covert_channels_evaluation::{BitIterator, CovertChannel}; @@ -71,9 +71,9 @@ pub enum TopologyAwareError { pub struct TopologyAwareTimingChannel { // TODO - slicing: CacheSlicing, // TODO : include fallback option (with per address thresholds ?) - main_core: usize, // aka attacker - helper_core: usize, // aka victim + slicing: CacheAttackSlicing, // TODO : include fallback option (with per address thresholds ?) + main_core: usize, // aka attacker + helper_core: usize, // aka victim t: T, thresholds: HashMap, addresses: HashSet<*const u8>, @@ -86,11 +86,7 @@ unsafe impl Sync for TopologyAwareTimingChann impl TopologyAwareTimingChannel { pub fn new(main_core: usize, helper_core: usize) -> Result { - if let Some(slicing) = get_cache_slicing(find_core_per_socket()) { - if !slicing.can_hash() { - return Err(TopologyAwareError::NoSlicing); - } - + if let Some(slicing) = get_cache_attack_slicing(find_core_per_socket()) { let ret = Self { thresholds: Default::default(), addresses: Default::default(), @@ -139,13 +135,13 @@ impl TopologyAwareTimingChannel { let mut calibrate_results2t_vec = Vec::new(); - let slicing = match get_cache_slicing(core_per_socket) { + let slicing = match get_cache_attack_slicing(core_per_socket) { Some(s) => s, None => { return Err(TopologyAwareError::NoSlicing); } }; - let h = |addr: usize| slicing.hash(addr).unwrap(); + let h = |addr: usize| slicing.hash(addr); for page in pages { // FIXME Cache line size is magic @@ -288,7 +284,7 @@ impl TopologyAwareTimingChannel { fn get_slice(&self, addr: *const u8) -> Slice { // This will not work well if slicing is not known FIXME - self.slicing.hash(addr as usize).unwrap() + self.slicing.hash(addr as usize) } pub fn set_cores(&mut self, main: usize, helper: usize) -> Result<(), TopologyAwareError> { @@ -537,7 +533,7 @@ impl MultipleAddrCacheSideChannel for TopologyAwareT for addr in addresses { let vpn = get_vpn(addr); - let slice = self.slicing.hash(addr as usize).unwrap(); + let slice = self.slicing.hash(addr as usize); let handle = TopologyAwareTimingChannelHandle { threshold: self .thresholds diff --git a/cache_utils/src/bin/two_thread_cal.rs b/cache_utils/src/bin/two_thread_cal.rs index 52e5aa1..c33a34f 100644 --- a/cache_utils/src/bin/two_thread_cal.rs +++ b/cache_utils/src/bin/two_thread_cal.rs @@ -2,10 +2,11 @@ use cache_utils::calibration::{ accumulate, calibrate_fixed_freq_2_thread, calibration_result_to_ASVP, flush_and_reload, - get_cache_slicing, load_and_flush, map_values, only_flush, only_reload, reduce, - reload_and_flush, CalibrateOperation2T, CalibrateResult2T, CalibrationOptions, ErrorPrediction, - ErrorPredictions, HistParams, HistogramCumSum, PotentialThresholds, ThresholdError, Verbosity, - ASP, ASVP, AV, CFLUSH_BUCKET_NUMBER, CFLUSH_BUCKET_SIZE, CFLUSH_NUM_ITER, SP, SVP, + get_cache_attack_slicing, get_cache_slicing, load_and_flush, map_values, only_flush, + only_reload, reduce, reload_and_flush, CalibrateOperation2T, CalibrateResult2T, + CalibrationOptions, ErrorPrediction, ErrorPredictions, HistParams, HistogramCumSum, + PotentialThresholds, ThresholdError, Verbosity, ASP, ASVP, AV, CFLUSH_BUCKET_NUMBER, + CFLUSH_BUCKET_SIZE, CFLUSH_NUM_ITER, SP, SVP, }; use cache_utils::mmap::MMappedMemory; use cache_utils::{flush, maccess, noop}; @@ -244,14 +245,10 @@ fn main() { .position(|op| op.name == hit_name) .unwrap(); - let slicing = get_cache_slicing(core_per_socket); + let slicing = get_cache_attack_slicing(core_per_socket); let h = if let Some(s) = slicing { - if s.can_hash() { - |addr: usize| -> u8 { slicing.unwrap().hash(addr).unwrap() } - } else { - panic!("No slicing function known"); - } + |addr: usize| -> usize { slicing.unwrap().hash(addr) } } else { panic!("No slicing function known"); }; diff --git a/cache_utils/src/calibrate_2t.rs b/cache_utils/src/calibrate_2t.rs index 7d7974a..d5ebd9b 100644 --- a/cache_utils/src/calibrate_2t.rs +++ b/cache_utils/src/calibrate_2t.rs @@ -1,6 +1,6 @@ use crate::calibration::Verbosity::{RawResult, Thresholds}; use crate::calibration::{ - get_cache_slicing, get_vpn, CalibrateResult, CalibrationOptions, HashMap, ASVP, + get_cache_attack_slicing, get_vpn, CalibrateResult, CalibrationOptions, HashMap, ASVP, SPURIOUS_THRESHOLD, }; use crate::complex_addressing::CacheAttackSlicing; @@ -88,9 +88,7 @@ fn calibrate_fixed_freq_2_thread_impl, T>( let to_bucket = |time: u64| -> usize { time as usize / bucket_size }; let from_bucket = |bucket: usize| -> u64 { (bucket * bucket_size) as u64 }; - let slicing = get_cache_slicing(core_per_socket); - - let cache_attack_slicing = CacheAttackSlicing::from(slicing.unwrap(), cache_line_length); + let slicing = get_cache_attack_slicing(core_per_socket).unwrap(); let mut ret = Vec::new(); @@ -136,9 +134,9 @@ fn calibrate_fixed_freq_2_thread_impl, T>( ); } - let image_antecedent = cache_attack_slicing.image_antecedent(len as usize - 1); + let image_antecedent = slicing.image_antecedent(len as usize - 1); - match cache_attack_slicing { + match slicing { CacheAttackSlicing::ComplexAddressing(_) | CacheAttackSlicing::SimpleAddressing(_) => { options.hist_params.iterations *= OPTIMISED_ADDR_ITER_FACTOR; } @@ -214,7 +212,7 @@ fn calibrate_fixed_freq_2_thread_impl, T>( let pointer = unsafe { p.offset(i) }; params.address = pointer; - let hash = cache_attack_slicing.hash(pointer as usize); + let hash = slicing.hash(pointer as usize); if options.verbosity >= Thresholds { print!("Calibration for {:p}", pointer); @@ -411,7 +409,7 @@ fn calibrate_fixed_freq_2_thread_helper( pub fn calibration_result_to_ASVP T>( results: Vec, analysis: Analysis, - slicing: &impl Fn(usize) -> u8, + slicing: &impl Fn(usize) -> usize, ) -> Result, nix::Error> { let mut analysis_result: HashMap = HashMap::new(); for calibrate_2t_result in results { diff --git a/cache_utils/src/calibration.rs b/cache_utils/src/calibration.rs index 3331a72..926a762 100644 --- a/cache_utils/src/calibration.rs +++ b/cache_utils/src/calibration.rs @@ -1,6 +1,6 @@ #![allow(clippy::missing_safety_doc)] -use crate::complex_addressing::{cache_slicing, CacheSlicing}; +use crate::complex_addressing::{cache_slicing, CacheAttackSlicing, CacheSlicing}; use crate::{flush, maccess, rdtsc_fence}; use cpuid::MicroArchitecture; @@ -470,7 +470,7 @@ fn calibrate_impl_fixed_freq( ret } -pub fn get_cache_slicing(core_per_socket: u8) -> Option { +fn get_cache_slicing(core_per_socket: u8) -> Option { if let Some(uarch) = MicroArchitecture::get_micro_architecture() { if let Some(vendor_family_model_stepping) = MicroArchitecture::get_family_model_stepping() { Some(cache_slicing( @@ -488,6 +488,27 @@ pub fn get_cache_slicing(core_per_socket: u8) -> Option { } } +pub fn get_cache_attack_slicing(core_per_socket: u8) -> Option { + if let Some(uarch) = MicroArchitecture::get_micro_architecture() { + if let Some(vendor_family_model_stepping) = MicroArchitecture::get_family_model_stepping() { + Some(CacheAttackSlicing::from( + cache_slicing( + uarch, + core_per_socket, + vendor_family_model_stepping.0, + vendor_family_model_stepping.1, + vendor_family_model_stepping.2, + ), + 64, + )) // FIXME Cache length magic number + } else { + None + } + } else { + None + } +} + #[allow(non_snake_case)] pub fn calibrate_L3_miss_hit( array: &[u8], @@ -525,7 +546,7 @@ pub fn calibrate_L3_miss_hit( */ pub type VPN = usize; -pub type Slice = u8; +pub type Slice = usize; #[derive(PartialEq, Eq, Debug, Hash, Clone, Copy, Default)] pub struct ASVP {