Skip to content

Commit

Permalink
Remove endoscope Shared magic, start, and len fields.
Browse files Browse the repository at this point in the history
Also add safety command in endoscope.
  • Loading branch information
lzrd committed Feb 22, 2025
1 parent 2f49e0c commit f1fc10c
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 59 deletions.
3 changes: 0 additions & 3 deletions drv/lpc55-swd/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1407,10 +1407,7 @@ impl ServerImpl {
};

let mut shared = Shared {
magic: 0,
state: Shared::STATE_PREBOOT,
start: 0,
len: 0,
digest: [0u8; 32],
};

Expand Down
3 changes: 0 additions & 3 deletions lib/endoscope-abi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,7 @@ pub enum State {
#[derive(FromBytes, AsBytes, Copy, Clone)]
#[repr(C, packed)]
pub struct Shared {
pub magic: u32,
pub state: u32,
pub start: u32,
pub len: u32,
pub digest: [u8; 256 / 8],
}

Expand Down
37 changes: 18 additions & 19 deletions lib/endoscope/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,27 +45,30 @@ invalidate any previous measurements that have been recorded.

## Size and Performance

The smaller program is currently under 5KiB and takes less than 5.5 seconds to run.
The larger version took 6.4 seconds to run.
```bash
# The program is about 5KiB and takes less than 0.5 seconds to inject and run.
$ find target/thumbv8m.main-none-eabihf/release/build \
-name endoscope.bin -print -exec stat -c '%s' '{}' ';'
target/thumbv8m.main-none-eabihf/release/build/drv-lpc55-swd-da6462ef675419cb/out/endoscope.bin
5740
```

Building as a cargo `bindeps` artifact allows the source to be maintained
in the Hubris repo and removes any concern that it is out of date with
respect to the RoT firmware.

The program is built as a `bindeps` artifact. As such, the profile
that it is built with is not allowed to specify `lto` or `panic`.
Not being able to use the desired profile costs an extra 462 bytes at
the time of writing.
However, as a `bindeps` artifact, the profile that it is built with is not
allowed to specify `lto` or `panic`.

In addition to the normal Rust code golf opportunities for space and time
include fixing the above, there is the possibility of using an FFI SHA3
library, if a more compact or faster implementation is found in another language.
Not being able to use the desired profile costs something around an extra 462 bytes at
the time of writing.

```
# The current implementation size is 4968 bytes.
$ stat -c '%s' target/thumbv8m.main-none-eabihf/release/build/drv-lpc55-swd-2e300752b097b62f/out/endoscope.bin
4968
Rust "code golf" opportunities for space and time include:
- Fix the build profile `lto` and `panic` prohibition described above,
- Use an FFI SHA3 library, if a more compact or faster implementation can be found.
- On the RoT side, inject the code more efficiently.

```bash
# Building it as a stand-alone bin results in a smaller executable (4660 bytes)
$ arm-none-eabi-size target/thumbv7em-none-eabihf/release/endoscope
text data bss dec hex filename
Expand Down Expand Up @@ -145,6 +148,8 @@ the ITCM/DTCM memories.
### Read the Results

The results are in a `struct Shared`.
Given that `endoscope` and the `swd` task are compiled together, no structure magic
number or versioning is required and compile- and link-time constants are trustworthy.

```rust
#[repr(u32)]
Expand All @@ -157,10 +162,7 @@ pub enum State {

#[repr(C)]
pub struct Shared {
pub magic: u32,
pub state: State,
pub start: *const u8,
pub len: usize,
pub digest: [u8; 32],
}

Expand All @@ -187,10 +189,7 @@ Or, as the struct being used:

```rust
Shared {
magic: Shared::MAGIC,
state: State::Done,
start: 0x0800_0000,
len: 0x0010_0000,
digest: [
03, 6f, 35, cc, af, ba, 2a, 6e,
09, d7, 55, db, 33, a5, be, 73,
Expand Down
21 changes: 11 additions & 10 deletions lib/endoscope/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,6 @@
#![no_std]
#![no_main]

// We have to do this if we don't otherwise use it to ensure its vector table
// gets linked in.
// extern crate stm32h7;
//use stm32h7::stm32h753 as device;

// use cortex_m_rt::entry;
//

// use panic_halt as _;
use core::arch::{self};
use core::panic::PanicInfo;
Expand Down Expand Up @@ -69,16 +61,25 @@ const CLOCK_CONFIG: ClockConfig = ClockConfig {
mod shared;
use shared::{State, SHARED};

extern "C" {
static FLASH_BASE: [u8; 0];
static FLASH_SIZE: [u32; 0];
}

#[entry]
fn main() -> ! {
// Note: The RoT does not examine results until the SP is halted.
SHARED.set_state(State::Running);
let _p = system_init(CLOCK_CONFIG);
SHARED.set_flash_area();
let mut hash = Sha3_256::new();

// Safety: The bounds of the device's flash area are link-time constants.
let image = unsafe {
core::slice::from_raw_parts(SHARED.get_start(), SHARED.get_len())
core::slice::from_raw_parts(
FLASH_BASE.as_ptr() as u32 as *const u8,
FLASH_SIZE.as_ptr() as u32 as usize)
};

hash.update(image[..].as_ref());
let digest: [u8; 256 / 8] = hash.finalize().into();
SHARED.set_digest(&digest);
Expand Down
24 changes: 0 additions & 24 deletions lib/endoscope/src/shared.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,6 @@ use core::cell::UnsafeCell;
use core::marker::Sync;
pub use endoscope_abi::{Shared, State};

extern "C" {
static FLASH_BASE: [u8; 0];
static FLASH_SIZE: [u32; 0];
}

#[repr(C)]
pub struct SharedWrapper {
shared: UnsafeCell<Shared>,
Expand All @@ -22,10 +17,7 @@ impl SharedWrapper {
pub const fn new() -> Self {
SharedWrapper {
shared: UnsafeCell::new(Shared {
magic: Shared::MAGIC,
state: State::Preboot as u32,
start: 0,
len: 0,
digest: [0xff_u8; 32],
}),
}
Expand All @@ -37,27 +29,11 @@ impl SharedWrapper {
}
}

pub fn get_start(&self) -> *const u8 {
unsafe { (*self.shared.get()).start as *const u8 }
}

pub fn get_len(&self) -> usize {
unsafe { (*self.shared.get()).len as usize }
}

pub fn set_digest(&self, digest: &[u8; 32]) {
unsafe {
(*self.shared.get()).digest.copy_from_slice(digest);
}
}

// Get around complaints about static initializations from statics.
pub fn set_flash_area(&self) {
unsafe {
(*self.shared.get()).start = FLASH_BASE.as_ptr() as u32;
(*self.shared.get()).len = FLASH_SIZE.as_ptr() as u32;
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit f1fc10c

Please sign in to comment.