sigpwny / 2024-ectf-uiuc

UIUC's implementation of the Medical Infrastructure Supply Chain (MISC) for MITRE eCTF 2024
Apache License 2.0
6 stars 2 forks source link

Migrate MSDK functions to Rust #1

Closed WhiteHoodHacker closed 7 months ago

WhiteHoodHacker commented 8 months ago

MSDK Functionality to Rust

Current MSDK Migration Process

Reference documentation:

Helpful examples for Rust migration from last year:

Application Processor

Required:

Optional:

Optional:

yumenegi commented 8 months ago

Implementation for TRNG: wrapper.c

#include "trng.h"

/*
trng_var: trng_var is the memory address at which the TRNG will store data
num_bytes: number of bytes the TRNG will modify starting from trng_var
*/
void trng_gen(uint8_t trng_var, uint8_t num_bytes) {
    // Clearing memory for TRNG
    memset(trng_var, 0, sizeof(trng_var));

    // Initialize TRNG
    MXC_TRNG_Init();

    // Run TRNG
    MXC_TRNG_Random(trng_var, num_bytes);

    // Shutdown
    MXC_TRNG_Shutdown();
}

driverlib.rs


mod driverwrapper {
    #[link(name = "driverwrapper")]
    extern "C" {
        pub(super) fn trng_gen(data: u8, num_bytes: u8);
    }
}

/// Run TRNG
pub fn trng_gen(data: u8, num_bytes: u8) {
    unsafe {
        driverwrapper::trng_gen(data, num_bytes);
    }
}```
WhiteHoodHacker commented 8 months ago

void trng_gen(uint8_t trng_var, uint8_t num_bytes) - this signature is incorrect, since trng_var is supposed to be a pointer to bytes (as it is, this would just accept a single byte). The Rust function also has the same problem. Last year's eeprom_read() code (Rust, C) is a good example of what you need to do (except you should be reading in bytes, not words). Also, note the use of .as_mut_ptr() when sending the C function a pointer from Rust; read about Rust mutability and think about why we need to do this.

Something I didn't explain earlier is that we generally want to have a large init_system() function in C which initializes all of the peripherals on the board. So anything related to one-time initialization will go in this large function, which we call when the board turns on. Here is an example from last year. MXC_TRNG_Init() is one example that would go in this function.

You may also want to look into checking whether the TRNG peripheral is truly initialized. A simple function which checks the TRNG register can do this. This function would be called either on initialization (meaning the board hangs if a peripheral is not able to be initialized for some reason) and/or right before any function that utilizes the peripheral. There are a few ways we implemented this from last year, some depend on custom TI SDK functions, so we'd have to find the equivalent in MSDK (1, 2).

Finally, we should not shut down peripherals since we want to keep them running at all times.

WhiteHoodHacker commented 7 months ago

Closed in favor of #34