diff --git a/fmc/src/flow/rt_alias.rs b/fmc/src/flow/rt_alias.rs index 019c92e57c..4210b4e413 100644 --- a/fmc/src/flow/rt_alias.rs +++ b/fmc/src/flow/rt_alias.rs @@ -24,17 +24,13 @@ use caliptra_common::crypto::Ecc384KeyPair; use caliptra_common::keyids::{KEY_ID_RT_CDI, KEY_ID_RT_PRIV_KEY, KEY_ID_TMP}; use caliptra_common::HexBytes; use caliptra_drivers::{ - okref, report_boot_status, CaliptraError, CaliptraResult, Ecc384Result, KeyId, ResetReason, + okref, report_boot_status, CaliptraError, CaliptraResult, Ecc384Result, KeyId, PersistentData, + ResetReason, }; use caliptra_x509::{NotAfter, NotBefore, RtAliasCertTbs, RtAliasCertTbsParams}; const SHA384_HASH_SIZE: usize = 48; -const RT_ALIAS_TBS_SIZE: usize = 0x1000; -extern "C" { - static mut RTALIAS_TBS_ORG: [u8; RT_ALIAS_TBS_SIZE]; -} - #[derive(Default)] pub struct RtAliasLayer {} @@ -323,25 +319,18 @@ impl RtAliasLayer { hand_off.set_rt_dice_signature(sig); // Copy TBS to DCCM. - Self::copy_tbs(tbs.tbs())?; + Self::copy_tbs(tbs.tbs(), env.persistent_data.get_mut())?; report_boot_status(FmcBootStatus::RtAliasCertSigGenerationComplete as u32); Ok(()) } - fn copy_tbs(tbs: &[u8]) -> CaliptraResult<()> { - let dst = unsafe { - let ptr = &mut RTALIAS_TBS_ORG as *mut u8; - core::slice::from_raw_parts_mut(ptr, tbs.len()) - }; - - if tbs.len() <= RT_ALIAS_TBS_SIZE { - dst[..tbs.len()].copy_from_slice(tbs); - } else { + fn copy_tbs(tbs: &[u8], persistent_data: &mut PersistentData) -> CaliptraResult<()> { + let Some(dest) = persistent_data.rtalias_tbs.get_mut(..tbs.len()) else { return Err(CaliptraError::FMC_RT_ALIAS_TBS_SIZE_EXCEEDED); - } - + }; + dest.copy_from_slice(tbs); Ok(()) } } diff --git a/fmc/src/flow/tci.rs b/fmc/src/flow/tci.rs index c52a840d33..e7e429c298 100644 --- a/fmc/src/flow/tci.rs +++ b/fmc/src/flow/tci.rs @@ -36,6 +36,7 @@ impl Tci { env: &mut FmcEnv, hand_off: &HandOff, ) -> CaliptraResult { + // TODO: Should compare this address to env. let image_manifest_bytes = unsafe { core::slice::from_raw_parts_mut( hand_off.image_manifest_address(env) as *mut u8, diff --git a/fmc/src/fmc_env.rs b/fmc/src/fmc_env.rs index 6dfd670487..c499b2ea4e 100644 --- a/fmc/src/fmc_env.rs +++ b/fmc/src/fmc_env.rs @@ -16,8 +16,8 @@ Abstract: --*/ use caliptra_drivers::{ - CaliptraResult, DataVault, Ecc384, Hmac384, KeyVault, Mailbox, PcrBank, Sha1, Sha256, Sha384, - Sha384Acc, SocIfc, Trng, + CaliptraResult, DataVault, Ecc384, Hmac384, KeyVault, Mailbox, PcrBank, PersistentDataAccessor, + Sha1, Sha256, Sha384, Sha384Acc, SocIfc, Trng, }; use caliptra_registers::{ csrng::CsrngReg, dv::DvReg, ecc::EccReg, entropy_src::EntropySrcReg, hmac::HmacReg, kv::KvReg, @@ -62,6 +62,9 @@ pub struct FmcEnv { /// Cryptographically Secure Random Number Generator pub trng: Trng, + + /// Persistent Data + pub persistent_data: PersistentDataAccessor, } impl FmcEnv { @@ -93,6 +96,7 @@ impl FmcEnv { mbox: Mailbox::new(MboxCsr::new()), pcr_bank: PcrBank::new(PvReg::new()), trng, + persistent_data: PersistentDataAccessor::new(), }) } } diff --git a/fmc/src/hand_off.rs b/fmc/src/hand_off.rs index 5b74684592..029825fee7 100644 --- a/fmc/src/hand_off.rs +++ b/fmc/src/hand_off.rs @@ -15,7 +15,7 @@ use crate::flow::dice::DiceOutput; use crate::fmc_env::FmcEnv; use caliptra_common::DataStore::*; use caliptra_common::{DataStore, FirmwareHandoffTable, HandOffDataHandle, Vault}; -use caliptra_drivers::{Array4x12, Ecc384Signature, KeyId}; +use caliptra_drivers::{memory_layout, Array4x12, Ecc384Signature, KeyId, PersistentDataAccessor}; use caliptra_drivers::{Ecc384PubKey, Ecc384Scalar}; use caliptra_error::CaliptraResult; @@ -37,11 +37,9 @@ impl MemoryRegion { } impl IccmAddress { - const ICCM_ORG: u32 = 0x40000000; - const ICCM_SIZE: u32 = 128 << 10; const ICCM: MemoryRegion = MemoryRegion { - start: Self::ICCM_ORG, - size: Self::ICCM_SIZE, + start: memory_layout::ICCM_ORG, + size: memory_layout::ICCM_SIZE, }; /// Validate that the address is within the ICCM region. @@ -51,11 +49,9 @@ impl IccmAddress { } impl DccmAddress { - const DCCM_ORG: u32 = 0x50000000; - const DCCM_SIZE: u32 = 128 << 10; const DCCM: MemoryRegion = MemoryRegion { - start: Self::DCCM_ORG, - size: Self::DCCM_SIZE, + start: memory_layout::DCCM_ORG, + size: memory_layout::DCCM_SIZE, }; /// Validate that the address is within the ICCM region. @@ -70,14 +66,13 @@ pub struct HandOff { impl HandOff { /// Create a new `HandOff` from the FHT table. - pub fn from_previous() -> Option { - // try_load performs basic sanity check of the FHT (check FHT marker, valid indices, etc.) - if let Some(fht) = unsafe { FirmwareHandoffTable::try_load() } { - let me = Self { fht }; - - return Some(me); + pub fn from_previous(persistent_data: &PersistentDataAccessor) -> Option { + let fht = &persistent_data.get().fht; + // Perform basic sanity check of the FHT (check FHT marker, valid indices, etc.) + if !fht.is_valid() { + return None; } - None + Some(Self { fht: fht.clone() }) } /// Retrieve FMC CDI @@ -189,7 +184,8 @@ impl HandOff { fn transfer_control(entry: u32) -> !; } - unsafe { FirmwareHandoffTable::save(&self.fht) }; + env.persistent_data.get_mut().fht = self.fht.clone(); + // Retrieve runtime entry point let rt_entry = IccmAddress(self.rt_entry_point(env)); diff --git a/fmc/src/main.rs b/fmc/src/main.rs index 5200991501..006c8551d8 100644 --- a/fmc/src/main.rs +++ b/fmc/src/main.rs @@ -40,13 +40,12 @@ Running Caliptra FMC ... #[no_mangle] pub extern "C" fn entry_point() -> ! { cprintln!("{}", BANNER); + let mut env = match unsafe { fmc_env::FmcEnv::new_from_registers() } { + Ok(env) => env, + Err(e) => report_error(e.into()), + }; - if let Some(mut hand_off) = HandOff::from_previous() { - let mut env = match unsafe { fmc_env::FmcEnv::new_from_registers() } { - Ok(env) => env, - Err(e) => report_error(e.into()), - }; - + if let Some(mut hand_off) = HandOff::from_previous(&env.persistent_data) { match flow::run(&mut env, &mut hand_off) { Ok(_) => { if hand_off.is_valid() { diff --git a/fmc/test-fw/test-rt/src/main.rs b/fmc/test-fw/test-rt/src/main.rs index 9e57b88f91..7b426ac5fb 100644 --- a/fmc/test-fw/test-rt/src/main.rs +++ b/fmc/test-fw/test-rt/src/main.rs @@ -16,7 +16,7 @@ Abstract: use caliptra_common::cprintln; use caliptra_cpu::TrapRecord; -use caliptra_drivers::{report_fw_error_non_fatal, Mailbox, PcrBank}; +use caliptra_drivers::{report_fw_error_non_fatal, Mailbox, PcrBank, PersistentDataAccessor}; use caliptra_registers::pv::PvReg; use core::hint::black_box; @@ -35,22 +35,22 @@ const BANNER: &str = r#" #[no_mangle] pub extern "C" fn entry_point() -> ! { cprintln!("{}", BANNER); + let persistent_data = unsafe { PersistentDataAccessor::new() }; - if let Some(_fht) = unsafe { caliptra_common::FirmwareHandoffTable::try_load() } { - // Test PCR is locked. - let mut pcr_bank = unsafe { PcrBank::new(PvReg::new()) }; - // Test erasing pcr. This should fail. - assert!(pcr_bank - .erase_pcr(caliptra_common::RT_FW_CURRENT_PCR) - .is_err()); - assert!(pcr_bank - .erase_pcr(caliptra_common::RT_FW_JOURNEY_PCR) - .is_err()); - caliptra_drivers::ExitCtrl::exit(0) - } else { + if !persistent_data.get().fht.is_valid() { cprintln!("FHT not loaded"); caliptra_drivers::ExitCtrl::exit(0xff) } + // Test PCR is locked. + let mut pcr_bank = unsafe { PcrBank::new(PvReg::new()) }; + // Test erasing pcr. This should fail. + assert!(pcr_bank + .erase_pcr(caliptra_common::RT_FW_CURRENT_PCR) + .is_err()); + assert!(pcr_bank + .erase_pcr(caliptra_common::RT_FW_JOURNEY_PCR) + .is_err()); + caliptra_drivers::ExitCtrl::exit(0) } #[no_mangle]