Skip to content

Commit

Permalink
Merge branch 'rust_hal_impl' into layout_randomization
Browse files Browse the repository at this point in the history
  • Loading branch information
pawnlord committed Mar 4, 2024
2 parents ea3cd1c + 6722c48 commit 80ef547
Show file tree
Hide file tree
Showing 23 changed files with 281 additions and 273 deletions.
2 changes: 2 additions & 0 deletions application_processor/Cargo.lock

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

15 changes: 11 additions & 4 deletions application_processor/src/ap_driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,8 @@ impl ApDriver {
} = Peripherals::take().expect("could not initialize peripherals");

let i2c = i2c.init_master(I2C_FREQUENCY);
let seed = (trng.next_u32() as u64) | ((trng.next_u32() as u64) << 32);
let chacha = ChaCha20Rng::seed_from_u64(seed);

let chacha = ChaCha20Rng::from_seed(trng.gen_nonce());

ApDriver {
flash,
i2c,
Expand Down Expand Up @@ -67,6 +66,7 @@ impl ApDriver {
flash_data.components_len = COMPONENTS.len();
flash_data.components[..COMPONENTS.len()].copy_from_slice(COMPONENTS.as_slice());

// FIXME
//self.save_flash_data(flash_data);
}

Expand All @@ -89,6 +89,10 @@ impl ApDriver {
self.flash_data = Some(flash_data);
}

pub fn get_chacha(&mut self) -> &mut ChaCha20Rng {
&mut self.chacha
}

fn send_packet(&mut self, address: I2cAddr, packet: &[u8]) -> Result<(), ApError> {
let mut send_packet = [0; MAX_I2C_MESSAGE_LEN];
send_packet[0] = packet.len().try_into().expect("i2c send message to big");
Expand Down Expand Up @@ -132,7 +136,10 @@ impl ApDriver {
Ok(response?)
}

pub fn send_and_receive_struct<'de, M: Serialize, R: Deserialize<'de>>(&'de mut self, address: I2cAddr, message: M) -> Result<R, ApError> {
pub fn send_and_receive_struct<'de, M: Serialize, R: Deserialize<'de>>(
&'de mut self,
address: I2cAddr, message: M
) -> Result<R, ApError> {
self.send_struct(address, message)?;
self.receive_struct(address)
}
Expand Down
79 changes: 29 additions & 50 deletions application_processor/src/attest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,65 +3,19 @@ use core::time::Duration;

use max78000_hal::prelude::*;
use max78000_hal::i2c::MAX_I2C_MESSAGE_LEN;
use design_utils::{component_id_to_i2c_addr, ComponentId};
use design_utils::crypto::{hash, decrypt, hmac, EncryptedData};
use design_utils::component_id_to_i2c_addr;
use design_utils::crypto::{decrypt, hash, hmac, EncryptedData};
use design_utils::messages::{StartProtocolMessage, AttestationReqMessage};
use design_utils::str::concat;

use design_utils::double_down_if;

use design_utils::const_time_equal_or_error;

use crate::{recv_input_with_message, try_get_component_id, ApError};
use crate::ectf_params::{PIN_HASH, PIN_SALT, HMAC_KEY, ATTESTATION_DATA_ENC_KEY};
use crate::ap_driver::ApDriver;

const PIN_LEN: usize = 6;

/// Prompts the user for a pin, and returns true if it is correct
fn validate_attest_pin() -> bool {
let mut buf = [0u8; PIN_LEN];

recv_input_with_message("Enter pin: ", &mut buf).is_some_and(|input| {
let hash = hash(input.as_bytes(), &PIN_SALT);
//hash == PIN_HASH
let mut b: bool = true;

for i in 0..24 {
double_down_if!(
hash[i] ^ PIN_HASH[i] == 0,
b = b,
b = false
)
/*
if hash[i] ^ PIN_HASH[i] == 0 {
b = b;
} else {
b = false;
}*/
}
return b;
})
}

fn get_and_verify_attest_inputs(driver: &mut ApDriver) -> Result<ComponentId, ApError> {
if !validate_attest_pin() {
return Err(ApError::InvalidInput);
}

let Some(component_id) = try_get_component_id("Component ID: ") else {
return Err(ApError::InvalidInput);
};

if driver.get_flash_data().get_provisioned_component(component_id).is_none() {
return Err(ApError::InvalidComponentError);
}

Ok(component_id)
}

fn attempt_attest(driver: &mut ApDriver) -> Result<(), ApError> {
let component_id = get_and_verify_attest_inputs(driver)?;

fn perform_attest(driver: &mut ApDriver, component_id: u32) -> Result<(), ApError> {
let nonce = driver.gen_nonce();
let message = concat(component_id.to_le_bytes(), nonce.to_le_bytes());
let hmac = hmac(&message, &HMAC_KEY);
Expand All @@ -87,6 +41,31 @@ fn attempt_attest(driver: &mut ApDriver) -> Result<(), ApError> {
Ok(())
}

fn attempt_attest(driver: &mut ApDriver) -> Result<(), ApError> {
// get inputs
let mut buf = [0; PIN_LEN];
let pin= recv_input_with_message("Enter pin: ", &mut buf)
.ok_or(ApError::InvalidInput)?;

let hash = hash(pin.as_bytes(), &PIN_SALT);

const_time_equal_or_error!(
hash.as_slice(),
PIN_HASH.as_slice(),
ApError::InvalidInput,
driver.get_chacha(),
);

let component_id = try_get_component_id("Component ID: ")
.ok_or(ApError::InvalidInput)?;

if driver.get_flash_data().get_provisioned_component(component_id).is_none() {
return Err(ApError::InvalidComponentError);
}

perform_attest(driver, component_id)
}

pub fn attest(driver: &mut ApDriver) -> Result<(), ApError> {
if let Err(err) = attempt_attest(driver) {
driver.sleep(Duration::from_secs(5));
Expand Down
118 changes: 49 additions & 69 deletions application_processor/src/boot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,28 @@ use core::time::Duration;

use design_utils::component_id_to_i2c_addr;
use design_utils::crypto::{decrypt, EncryptedData};
use design_utils::messages::{BootMessage, BootMessageOneNonce, BootMessageWithBuildId, EncryptedMessage, MessageStage, Nonce, SignedMessage, StartProtocolMessage};
use design_utils::messages::{
BootMessageStart,
BootMessageComponentReply,
BootMessageFinalize,
EncryptedMessage,
MessageStage,
Nonce,
SignedMessage,
StartProtocolMessage
};
use max78000_hal::prelude::*;
use max78000_hal::i2c::{I2cAddr, MAX_I2C_MESSAGE_LEN};

use crate::ApError;
use crate::ectf_params::{build_id_to_key_index, AP_BOOT_MSG, AP_PRIVKEY, BOOT_CR_KEY, BOOT_DATA_ENC_KEY, COMPONENT_KEYS};
use crate::ectf_params::{
build_id_to_key_index,
AP_BOOT_MSG,
AP_PRIVKEY,
BOOT_CR_KEY,
BOOT_DATA_ENC_KEY,
COMPONENT_KEYS
};
use crate::ap_driver::ApDriver;

const COMPONENT_COUNT: usize = 2;
Expand All @@ -30,20 +46,17 @@ impl ComponentBootState {
fn boot_send_m1(driver: &mut ApDriver, state: &mut [ComponentBootState; COMPONENT_COUNT]) -> Result<(), ApError> {
for component in state {
// send enc(m1 || cid || ra)
//uprintln_debug!("m1 gen");
let ap_nonce = driver.gen_nonce();
let message = BootMessageOneNonce {
let message = BootMessageStart {
m: MessageStage::M1,
component_id: component.component_id,
nonce: ap_nonce,
};

//uprintln_debug!("m1 encrypt");
let req = StartProtocolMessage::Boot(
EncryptedMessage::new_encrypted(message, &BOOT_CR_KEY, driver.gen_bytes())?,
);

//uprintln_debug!("m1 send");
driver.send_struct(component.i2c_addr(), req)?;

// TODO: determine when this should be true, this might not be true if component answers with error
Expand All @@ -55,91 +68,54 @@ fn boot_send_m1(driver: &mut ApDriver, state: &mut [ComponentBootState; COMPONEN
Ok(())
}

fn boot_recv_m2_send_m3(driver: &mut ApDriver, state: &mut [ComponentBootState; COMPONENT_COUNT]) -> Result<(), ApError> {
for component in state {
let mut enc_response: EncryptedMessage<BootMessage> = driver.receive_struct(component.i2c_addr())?;
//uprintln_debug!("m2 recv");
fn boot_recv_m2_send_m3(
driver: &mut ApDriver,
state: &mut [ComponentBootState; COMPONENT_COUNT]
) -> Result<(), ApError> {
for component in state.iter_mut() {
let mut enc_response: EncryptedMessage<SignedMessage<BootMessageComponentReply>> = driver.receive_struct(component.i2c_addr())?;

// recieved enc(m2 || cid || ra + 1 || rb)
let response = enc_response.get_decrypted_data(&BOOT_CR_KEY)?;
//uprintln_debug!("m2 decrypted, verify");
// received enc(m2 || cid || bid || ra + 1 || rb || signature)
let signed_response = enc_response.get_decrypted_data(&BOOT_CR_KEY)?;

let response: BootMessageComponentReply = postcard::from_bytes(&signed_response.message_data)?;

if response.m != MessageStage::M2
|| response.component_id != component.component_id
||response.send_nonce != component.expected_reply_nonce {
return Err(ApError::SuspiciousActivity);
}

// send enc(m3 || cid || rb + 1 || rc)
//uprintln_debug!("m3 gen");
let mut component_nonce = response.reply_nonce + 1;
let ap_nonce = driver.gen_nonce();

let message = BootMessage {
m: MessageStage::M3,
component_id: component.component_id,
send_nonce: component_nonce,
reply_nonce: ap_nonce,
};

//uprintln_debug!("m3 encrypt");
let encrypted_message = EncryptedMessage::new_encrypted(message, &BOOT_CR_KEY, driver.gen_bytes())?;
//uprintln_debug!("m3 send");
driver.send_struct(component.i2c_addr(), encrypted_message)?;

component.expected_reply_nonce = ap_nonce;
}

Ok(())
}

fn boot_recv_m4_send_m5(driver: &mut ApDriver, state: &mut [ComponentBootState; COMPONENT_COUNT]) -> Result<(), ApError> {
for component in state.iter_mut() {
let signed_response: SignedMessage<BootMessageWithBuildId> = driver.receive_struct(component.i2c_addr())?;
//uprintln_debug!("m4 recv");

// recieved signed(m4 || cid || rc || rd || bid)
let response: BootMessageWithBuildId = postcard::from_bytes(signed_response.message_data.as_slice())?;

if response.boot_message.m != MessageStage::M4
|| response.boot_message.component_id != component.component_id
|| response.boot_message.send_nonce != component.expected_reply_nonce {
|| response.start_nonce_plus_one != component.expected_reply_nonce {
return Err(ApError::SuspiciousActivity);
}

let key_index = build_id_to_key_index(response.build_id)
.ok_or(ApError::InvalidBuildId)?;
//uprintln_debug!("m4 verify properties");
let pubkey = &COMPONENT_KEYS[key_index].pubkey;

if !signed_response.verify(&COMPONENT_KEYS[key_index].pubkey) {
if !signed_response.verify(pubkey, driver.get_chacha()) {
return Err(ApError::SuspiciousActivity);
}
//uprintln_debug!("m4 verify signature");

component.key_index = Some(key_index);
// this nonce is the one component expects us to reply with in m5
component.expected_reply_nonce = response.boot_message.reply_nonce;
component.expected_reply_nonce = response.reply_nonce + 1;
}

// verify components are using different build ids
// TODO: glitch protect this
if state[0].key_index == state[1].key_index {
return Err(ApError::SuspiciousActivity);
}

// only m5 after recieving and verifying both m4 from each component
for component in state {
// send signed(m5 || cid || rd)
//uprintln_debug!("m5 gen and sign");
let message = BootMessageOneNonce {
m: MessageStage::M5,
// send enc(m3 || cid || rb + 1 || signature)
let message = BootMessageFinalize {
m: MessageStage::M3,
component_id: component.component_id,
nonce: component.expected_reply_nonce,
reply_nonce_plus_one: component.expected_reply_nonce,
};

let signed_message = SignedMessage::new_signed(message, &AP_PRIVKEY)?;
//uprintln_debug!("m5 send");
let enc_message = EncryptedMessage::new_encrypted(signed_message, &BOOT_CR_KEY, driver.gen_bytes())?;

driver.send_struct(component.i2c_addr(), signed_message)?;
driver.send_struct(component.i2c_addr(), enc_message)?;
component.protocol_in_progress = false;
}

Expand All @@ -149,7 +125,6 @@ fn boot_recv_m4_send_m5(driver: &mut ApDriver, state: &mut [ComponentBootState;
fn boot_recv_messages(driver: &mut ApDriver, state: &mut [ComponentBootState; COMPONENT_COUNT]) -> Result<(), ApError> {
for component in state {
let mut encrypted_boot_message: EncryptedData<MAX_I2C_MESSAGE_LEN> = driver.receive_struct(component.i2c_addr())?;
//uprintln_debug!("boot message recieved");

let boot_message = decrypt(&mut encrypted_boot_message, &BOOT_DATA_ENC_KEY)?;
let boot_message = str::from_utf8(boot_message.as_slice())?;
Expand All @@ -165,20 +140,18 @@ fn boot_recv_messages(driver: &mut ApDriver, state: &mut [ComponentBootState; CO
fn boot_components(driver: &mut ApDriver, state: &mut [ComponentBootState; COMPONENT_COUNT]) -> Result<(), ApError> {
boot_send_m1(driver, state)?;
boot_recv_m2_send_m3(driver, state)?;
boot_recv_m4_send_m5(driver, state)?;
boot_recv_messages(driver, state)?;

// Print boot message
// This always needs to be printed when booting
uprintln_info!("AP>{}", AP_BOOT_MSG);
uprintln_success!("Boot");

Ok(())
}

// Boot the components and board if the components validate
pub fn attempt_boot(driver: &mut ApDriver) -> Result<(), ApError> {
let flash_data = driver.get_flash_data();
let mut flash_data = driver.get_flash_data();
if flash_data.components_len != COMPONENT_COUNT {
// not enough components to boot
return Err(ApError::InvalidBootConditions);
Expand All @@ -200,6 +173,13 @@ pub fn attempt_boot(driver: &mut ApDriver) -> Result<(), ApError> {
driver.sleep(Duration::from_secs(5));
Err(err)
} else {
// set key indexes for post boot code to use
for (i, component) in boot_state.iter().enumerate() {
flash_data.components[i].key_index = component.key_index.unwrap();
}
driver.save_flash_data(flash_data);

uprintln_success!("Boot");
Ok(())
}
}
}
2 changes: 1 addition & 1 deletion application_processor/src/list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,4 @@ pub fn scan_components(driver: &mut ApDriver) -> Result<(), ApError> {
uprintln_success!("List");

Ok(())
}
}
Loading

0 comments on commit 80ef547

Please sign in to comment.