Skip to content

Commit

Permalink
added timeouts
Browse files Browse the repository at this point in the history
  • Loading branch information
Athryx committed Mar 10, 2024
1 parent eb4a862 commit 092f0ee
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 52 deletions.
1 change: 1 addition & 0 deletions application_processor/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions application_processor/src/ap_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::time::Duration;
use bytemuck::{must_cast_slice, Pod, Zeroable};

use serde::{Serialize, Deserialize};
use max78000_hal::{flash::PAGE_MASK, i2c::{I2cAddr, MAX_I2C_MESSAGE_LEN}, Flash, MasterI2c, Peripherals, Timer, Trng};
use max78000_hal::{flash::PAGE_MASK, i2c::{I2cAddr, MAX_I2C_MESSAGE_LEN}, Flash, MasterI2c, Peripherals, Trng, timer};
use design_utils::{component_id_to_i2c_addr, messages::ProtocolError, I2C_FREQUENCY};

use rand_core::{RngCore, SeedableRng};
Expand All @@ -20,7 +20,6 @@ pub struct ApDriver {
i2c: MasterI2c,
trng: Trng,
chacha: ChaCha20Rng,
timer: Timer,
flash_data: Option<FlashData>,
i2c_recv_buffer: [u8; MAX_I2C_MESSAGE_LEN],
}
Expand All @@ -30,7 +29,6 @@ impl ApDriver {
let Peripherals {
flash,
i2c,
timer,
mut trng,
} = Peripherals::take().expect("could not initialize peripherals");

Expand All @@ -42,7 +40,6 @@ impl ApDriver {
i2c,
trng,
chacha,
timer,
flash_data: None,
i2c_recv_buffer: [0; MAX_I2C_MESSAGE_LEN],
}
Expand Down Expand Up @@ -162,7 +159,7 @@ impl ApDriver {
}

pub fn sleep(&mut self, duration: Duration) {
self.timer.sleep(duration);
timer::sleep(duration);
}
}

Expand Down
12 changes: 9 additions & 3 deletions application_processor/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use design_utils::messages::{
};
use max78000_hal::prelude::*;
use max78000_hal::i2c::{I2cAddr, MAX_I2C_MESSAGE_LEN};
use max78000_hal::timer::timeout;
use tinyvec::ArrayVec;

use crate::ApError;
Expand Down Expand Up @@ -66,7 +67,10 @@ fn send_m3_and_boot(
let signed_message = SignedMessage::new_signed(message, &AP_PRIVKEY)?;
let enc_message = EncryptedMessage::new_encrypted(signed_message, &BOOT_CR_KEY, driver.gen_bytes())?;

let mut encrypted_boot_message: EncryptedData<MAX_I2C_MESSAGE_LEN> = driver.send_and_receive_struct(component.i2c_addr(), enc_message)?;
let mut encrypted_boot_message: EncryptedData<MAX_I2C_MESSAGE_LEN> = timeout(
|| driver.send_and_receive_struct(component.i2c_addr(), enc_message),
Duration::from_secs(1),
)??;
// recieved encrypted boot message
component.protocol_in_progress = false;

Expand Down Expand Up @@ -118,8 +122,10 @@ fn boot_components(driver_option: &mut Option<ApDriver>, state: &mut [ComponentB
EncryptedMessage::new_encrypted(message, &BOOT_CR_KEY, driver.gen_bytes())?,
);

let mut enc_response: EncryptedMessage<SignedMessage<BootMessageComponentReply>> =
driver.send_and_receive_struct(component.i2c_addr(), req)?;
let mut enc_response: EncryptedMessage<SignedMessage<BootMessageComponentReply>> = timeout(
|| driver.send_and_receive_struct(component.i2c_addr(), req),
Duration::from_secs(1),
)??;
component.protocol_in_progress = true;

// received enc(m2 || cid || bid || ra + 1 || rb || signature)
Expand Down
8 changes: 7 additions & 1 deletion application_processor/src/post_boot/messaging.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use core::time::Duration;

use design_utils::crypto::{verify_signature, sign};
use design_utils::messages::{Nonce, PostBootMessage, SignedPostBootMessage, PostBootMessageStart};
use design_utils::{multi_if, MAX_POST_BOOT_MESSAGE_SIZE};
use max78000_hal::i2c::I2cAddr;
use max78000_hal::timer::timeout;
use tinyvec::ArrayVec;

use crate::ectf_params::{AP_PRIVKEY, COMPONENT_KEYS};
Expand Down Expand Up @@ -49,7 +52,10 @@ pub fn secure_receive(
let SignedPostBootMessage {
message,
signature,
} = driver.send_and_receive_struct(address, PostBootMessageStart::ApToComponentNonce(nonce))?;
} = timeout(
|| driver.send_and_receive_struct(address, PostBootMessageStart::ApToComponentNonce(nonce)),
Duration::from_secs(1),
)??;

multi_if!(
component.component_id == message.component_id && message.nonce == nonce,
Expand Down
1 change: 1 addition & 0 deletions component/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 2 additions & 5 deletions component/src/component_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use max78000_hal::i2c::MAX_I2C_MESSAGE_LEN;
use serde::{Serialize, Deserialize};
use design_utils::{I2C_FREQUENCY, component_id_to_i2c_addr};
use design_utils::messages::ProtocolError;
use max78000_hal::{ClientI2c, Peripherals, Timer, Trng};
use max78000_hal::{ClientI2c, Peripherals, Trng, timer};

use crate::ComponentError;
use crate::ectf_params::COMPONENT_ID;
Expand All @@ -13,7 +13,6 @@ use rand_core::{RngCore, SeedableRng};
use rand_chacha::ChaCha20Rng;

pub struct ComponentDriver {
timer: Timer,
trng: Trng,
i2c: ClientI2c,
chacha: ChaCha20Rng,
Expand All @@ -24,7 +23,6 @@ impl ComponentDriver {
pub fn new() -> Self {
let Peripherals {
i2c,
timer,
mut trng,
..
} = Peripherals::take().expect("could not initialize peripherals");
Expand All @@ -33,7 +31,6 @@ impl ComponentDriver {
let chacha = ChaCha20Rng::from_seed(trng.gen_nonce());

ComponentDriver {
timer,
trng,
i2c,
chacha,
Expand Down Expand Up @@ -97,6 +94,6 @@ impl ComponentDriver {
}

pub fn sleep(&mut self, duration: Duration) {
self.timer.sleep(duration);
timer::sleep(duration);
}
}
7 changes: 5 additions & 2 deletions component/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use design_utils::messages::{
use design_utils::str::concat;
use max78000_hal::prelude::*;
use max78000_hal::HalError;
use max78000_hal::timer::timeout;
use max78000_hal::led::{led_on, led_off, Led};

use ectf_params::{
Expand Down Expand Up @@ -117,7 +118,7 @@ fn process_attest(driver: &mut ComponentDriver) -> Result<(), ComponentError> {
let nonce = driver.gen_nonce();
driver.send_struct(nonce)?;

let request: AttestationReqMessage = driver.recv_struct()?;
let request: AttestationReqMessage = timeout(|| driver.recv_struct(), Duration::from_millis(100))??;

if request.component_id != COMPONENT_ID || request.nonce != nonce {
return Err(ComponentError::SuspiciousActivity);
Expand Down Expand Up @@ -170,7 +171,9 @@ fn process_boot(
driver.send_struct(encrypted_reply)?;

// received enc(m3 || cid || rb + 1 || signature)
let mut encrypted_message: EncryptedMessage<SignedMessage<BootMessageFinalize>> = driver.recv_struct()?;
let mut encrypted_message: EncryptedMessage<SignedMessage<BootMessageFinalize>> =
timeout(|| driver.recv_struct(), Duration::from_secs(3))??;

let signed_message = encrypted_message.get_decrypted_data(&BOOT_CR_KEY)?;
let message: BootMessageFinalize = postcard::from_bytes(&signed_message.message_data)?;

Expand Down
3 changes: 2 additions & 1 deletion component/src/post_boot/messaging.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use core::time::Duration;

use max78000_hal::timer::timeout;
use design_utils::crypto::{sign, verify_signature};
use tinyvec::ArrayVec;
use design_utils::{multi_if, MAX_POST_BOOT_MESSAGE_SIZE};
Expand Down Expand Up @@ -60,7 +61,7 @@ pub fn secure_receive(
let SignedPostBootMessage {
message,
signature,
} = driver.recv_struct()?;
} = timeout(|| driver.recv_struct(), Duration::from_secs(1))??;

multi_if!(
message.component_id == COMPONENT_ID && message.nonce == nonce,
Expand Down
1 change: 1 addition & 0 deletions max78000_hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ edition = "2021"
[dependencies]
max78000_device = { path = "../max78000_device", features = ["rt", "critical-section"] }
cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7.2"
thiserror-no-std = "2.0.2"
once_cell = { version = "1.19.0", default_features = false, features = ["critical-section"] }
6 changes: 3 additions & 3 deletions max78000_hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ pub use flash::Flash;
pub use gcr::Gcr;
pub use gpio::Gpio;
pub use i2c::{UninitializedI2c, MasterI2c, ClientI2c};
pub use timer::Timer;
pub use trng::Trng;
pub use uart::Uart;

Expand All @@ -37,14 +36,15 @@ pub enum HalError {
FlashError,
#[error("Error with i2c connection")]
I2cConnectionError,
#[error("Error: timeout occured")]
Timeout,
#[error("Error with committed array: {0}")]
CommittedArrayError(#[from] committed_array::CommittedArrayError),
}

pub struct Peripherals {
pub flash: Flash,
pub i2c: UninitializedI2c,
pub timer: Timer,
pub trng: Trng,
}

Expand All @@ -71,12 +71,12 @@ impl Peripherals {
Gpio::init(GPIO0, GPIO2);
Uart::init(UART);

timer::init(SYST);
led::init();

Some(Peripherals {
flash: Flash::new(FLC),
i2c: UninitializedI2c::new(I2C1),
timer: Timer::new(SYST),
trng: Trng::new(TRNG),
})
}
Expand Down
132 changes: 100 additions & 32 deletions max78000_hal/src/timer.rs
Original file line number Diff line number Diff line change
@@ -1,53 +1,121 @@
use core::sync::atomic::{AtomicU32, Ordering};
use core::time::Duration;
use core::cell::RefCell;
use core::ops::Add;

use cortex_m::interrupt::{self, Mutex};
use cortex_m::peripheral::{SYST, syst::SystClkSource};
use cortex_m_rt::exception;

use crate::Gcr;
use crate::{Gcr, HalError};

const SYSTICK_RELOAD_VAL: u32 = 0xffffff;

pub struct Timer {
systick: SYST,
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub struct Instant {
time_since_boot: Duration,
}

impl Timer {
pub(crate) fn new(mut systick: SYST) -> Self {
systick.set_reload(SYSTICK_RELOAD_VAL);
systick.clear_current();
systick.enable_counter();
systick.set_clock_source(SystClkSource::Core);
impl Instant {
pub fn now() -> Instant {
let (current_tick, wrap_count) = interrupt::free(|token| {
let mut systick_ref = SYSTICK.borrow(token).borrow_mut();

Timer {
systick,
}
}
let systick = systick_ref
.as_mut()
.expect("timer not initialized");

// first read current tick
let current_tick = SYST::get_current();

pub fn sleep(&mut self, duration: Duration) {
// NOTE: this systick thing counts down, not up
let start_tick = SYST::get_current();
if systick.has_wrapped() {
// a wrap has occured, use tick count of 0 and new value for wrap count
let wrap_count = WRAP_COUNT.fetch_add(1, Ordering::Relaxed) + 1;

(current_tick, wrap_count)
} else {
// no wrap occured, current tick count and wrap count are accurate
(current_tick, WRAP_COUNT.load(Ordering::Relaxed))
}
});

// current tick subtracted from reaload val because it counts down
let total_ticks = (wrap_count as u64 * SYSTICK_RELOAD_VAL as u64) + (SYSTICK_RELOAD_VAL - current_tick) as u64;

let usecs = duration.as_micros() as u64;
let sysclock_freq = Gcr::with(|gcr| gcr.get_sysclock_frequency()) as u64;

// total number of ticks we need to wait for
let delay_ticks = ((usecs * sysclock_freq) / 1000000) as u32;
// calculate seconds and microseconds seperately to avoid
// potential overflow when ticks are multiplied by 1_000_000
let seconds = total_ticks / sysclock_freq;
let remaining_ticks = total_ticks % sysclock_freq;

let remaining_microseconds = (remaining_ticks * 1_000_000) / sysclock_freq;
let total_microseconds = (seconds * 1_000_000) + remaining_microseconds;

let mut wrap_count = delay_ticks / SYSTICK_RELOAD_VAL;
let tick_count = delay_ticks % SYSTICK_RELOAD_VAL;
Instant {
time_since_boot: Duration::from_micros(total_microseconds),
}
}
}

let end_tick = if tick_count > start_tick {
wrap_count += 1;
(SYSTICK_RELOAD_VAL - tick_count) + start_tick
} else {
start_tick - tick_count
};
impl Add<Duration> for Instant {
type Output = Instant;

while wrap_count > 0 {
if self.systick.has_wrapped() {
wrap_count -= 1;
}
fn add(self, rhs: Duration) -> Instant {
Instant {
time_since_boot: self.time_since_boot + rhs,
}
}
}

while SYST::get_current() > end_tick && !self.systick.has_wrapped() {}
pub fn sleep(duration: Duration) {
let start = Instant::now();
let end = start + duration;

while Instant::now() < end {}
}

/// Runs the function, returns the result or none if it took too long
pub fn timeout<T>(f: impl FnOnce() -> T, timeout_len: Duration) -> Result<T, HalError> {
let start = Instant::now();
let result = f();
let end = Instant::now();

if start + timeout_len < end {
Err(HalError::Timeout)
} else {
Ok(result)
}
}

/// Initializes the timer
pub(crate) fn init(mut systick: SYST) {
interrupt::free(|token| {
systick.set_reload(SYSTICK_RELOAD_VAL);
systick.clear_current();
systick.enable_counter();
systick.set_clock_source(SystClkSource::Core);
systick.enable_interrupt();

let mut systick_ref = SYSTICK.borrow(token).borrow_mut();
*systick_ref = Some(systick);
})
}

static SYSTICK: Mutex<RefCell<Option<SYST>>> = Mutex::new(RefCell::new(None));
static WRAP_COUNT: AtomicU32 = AtomicU32::new(0);

#[exception]
fn SysTick() {
interrupt::free(|token| {
let mut systick_ref = SYSTICK.borrow(token).borrow_mut();

let systick = systick_ref
.as_mut()
.expect("timer not initialized");

if systick.has_wrapped() {
WRAP_COUNT.fetch_add(1, Ordering::Relaxed);
}
})
}

0 comments on commit 092f0ee

Please sign in to comment.