diff --git a/tests/Cargo.toml b/tests/Cargo.toml index c4c7673..185d5e9 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -13,8 +13,12 @@ cortex-m-rt = { version = "0.7.3", features = ["set-sp", "set-vtor"] } cortex-m-semihosting = "0.5.0" libm = "0.2.8" max78000-hal = { version = "0.1.0", path = "../hal", features = ["rt"] } -panic-semihosting = "0.6.0" embedded-hal = { version = "1.0"} +# panic-semihosting = "0.6.0" +# cant use because duplicate lang item in crate `fault_injection_protection_arm` +# (which `max78000_hal_tests` depends on): `panic_impl`. +fault-injection-protection-arm = {git = "ssh://git@github.com/SlugSecurity/fault-injection-protection-arm.git", default-features = false} +subtle = { version = "2.5", default-features = false} [features] low_frequency_test = ["max78000-hal/low_frequency"] diff --git a/tests/src/bin/i2c_master_test.rs b/tests/src/bin/i2c_master_test.rs index 6c6eb90..0e8a5d9 100644 --- a/tests/src/bin/i2c_master_test.rs +++ b/tests/src/bin/i2c_master_test.rs @@ -18,7 +18,7 @@ use max78000_hal::peripherals::oscillator::{Ipo, IpoDivider, IpoFrequency}; use max78000_hal::peripherals::timer::{Oscillator, Prescaler, Time}; use max78000_hal::peripherals::{PeripheralManagerBuilder, SplittablePeripheral}; -extern crate panic_semihosting; +extern crate fault_injection_protection_arm; /// Entry point for tests. #[entry] diff --git a/tests/src/bin/i2c_slave_test.rs b/tests/src/bin/i2c_slave_test.rs index 806a3c5..ba28cf3 100644 --- a/tests/src/bin/i2c_slave_test.rs +++ b/tests/src/bin/i2c_slave_test.rs @@ -16,7 +16,7 @@ use max78000_hal::peripherals::oscillator::{Ipo, IpoDivider, IpoFrequency}; use max78000_hal::peripherals::timer::{Oscillator, Prescaler, Time}; use max78000_hal::peripherals::{PeripheralManagerBuilder, SplittablePeripheral}; -extern crate panic_semihosting; +extern crate fault_injection_protection_arm; /// Entry point for tests. #[entry] diff --git a/tests/src/main.rs b/tests/src/main.rs index 2e6b4b1..724d561 100644 --- a/tests/src/main.rs +++ b/tests/src/main.rs @@ -17,11 +17,11 @@ use max78000_hal::{ }, }; use tests::{ - bit_band_tests, csprng_tests, flc_tests, gpio_tests, oscillator_tests, timer_tests, trng_tests, - uart_tests, + bit_band_tests, csprng_tests, fip_tests, flc_tests, gpio_tests, oscillator_tests, timer_tests, + trng_tests, uart_tests, }; -extern crate panic_semihosting; +extern crate fault_injection_protection_arm; pub mod tests; @@ -84,6 +84,8 @@ fn main() -> ! { trng_tests::run_trng_tests(manager.trng().unwrap(), &mut stdout); csprng_tests::run_csprng_tests(manager.csprng().unwrap(), &mut stdout); + fip_tests::run_fip_tests(manager.csprng().unwrap(), &mut stdout); + gpio_tests::run_gpio_tests( manager.gpio0(), manager.gpio1(), diff --git a/tests/src/tests.rs b/tests/src/tests.rs index 5d6256c..527caa3 100644 --- a/tests/src/tests.rs +++ b/tests/src/tests.rs @@ -2,6 +2,7 @@ pub mod bit_band_tests; pub mod csprng_tests; +pub mod fip_tests; pub mod flc_tests; pub mod gpio_tests; pub mod oscillator_tests; diff --git a/tests/src/tests/fip_tests.rs b/tests/src/tests/fip_tests.rs new file mode 100644 index 0000000..621adf0 --- /dev/null +++ b/tests/src/tests/fip_tests.rs @@ -0,0 +1,104 @@ +//! Tests for the Fault Injection Prevention crate. + +use core::fmt::Write; +use core::{borrow::BorrowMut, ptr::write_volatile}; +use cortex_m_semihosting::hio; +use fault_injection_protection_arm as fip; +use fip::{FaultInjectionPrevention, SecureBool}; +use max78000_hal::communication::lower_layers::crypto::RandomSource; +use max78000_hal::peripherals::rand_chacha::rand_core::RngCore; +use max78000_hal::peripherals::{rand_chacha::ChaChaRng, PeripheralHandle}; +use subtle::ConstantTimeEq; + +/// Runs all FIP tests. +pub fn run_fip_tests(mut csprng: PeripheralHandle<'_, ChaChaRng>, stdout: &mut hio::HostStream) { + writeln!(stdout, "Starting fip peripheral tests...").unwrap(); + + let fip = fip::FaultInjectionPrevention::new(); + test_critical_if(&fip, csprng.borrow_mut(), stdout); + + // Run tests. + writeln!(stdout, "FIP tests complete!\n").unwrap(); +} + +/// Tests [`fault_injection_protection_arm::critical_if`], +/// [`fault_injection_protection_arm::critical_write`], +/// [`fault_injection_protection_arm::critical_read`] functions +fn test_critical_if( + fip: &FaultInjectionPrevention, + csprng: &mut ChaChaRng, + stdout: &mut hio::HostStream, +) { + #[allow(clippy::eq_op)] + fip.critical_if( + || (true == true).into(), + || writeln!(stdout, "Success: True path").unwrap(), + || panic!("Error: False path"), + csprng, + ); + + fip.critical_if( + || (true == false).into(), + || panic!("Error: True path"), + || writeln!(stdout, "Success: False path").unwrap(), + csprng, + ); + + writeln!(stdout, "Testing using rng in critical-if closure").unwrap(); + let mut secure_buffer = [0u8; 24]; + csprng.fill_rand_slice(&mut secure_buffer); + + let mut other_secure_buffer = [0u8; 24]; + + fip.critical_if( + || true.into(), + |rng: &mut ChaChaRng| { + fip.critical_write( + &mut other_secure_buffer, + secure_buffer, + |dst, src| unsafe { write_volatile(dst, src) }, + rng, + ) + }, + || (), + csprng, + ); + + fip.critical_if( + || { + SecureBool::from(>::into( + other_secure_buffer.ct_eq(&secure_buffer), + )) + }, + || { + writeln!( + stdout, + "Success: critical-write work inside of critical-if closure" + ) + .unwrap() + }, + || panic!("Error: critical-write fails"), + csprng, + ); + + if fip.critical_read(&other_secure_buffer, csprng) == secure_buffer { + writeln!(stdout, "Success: critical-read works").unwrap(); + } else { + writeln!(stdout, "Error: critical-read fails").unwrap(); + } + + writeln!(stdout, "Testing using rng in critical-if failure closure").unwrap(); + fip.critical_if( + || (true == false).into(), + || panic!("Error: True path"), + |rng: &mut ChaChaRng| writeln!(stdout, "Success: False path {}", rng.next_u64()).unwrap(), + csprng, + ); + + fip.critical_if( + |rng: &mut ChaChaRng| (rng.next_u64() == rng.next_u64()).into(), + |rng: &mut ChaChaRng| panic!("Error: True path {}", rng.next_u64()), + |rng: &mut ChaChaRng| writeln!(stdout, "Success: False path {}", rng.next_u64()).unwrap(), + csprng, + ); +}