Skip to content

Commit

Permalink
Make DPE auto-init locality 0xFFFFFFF
Browse files Browse the repository at this point in the history
We do this since the auto init measurement is provided by
Caliptra itself, and not the pl0 pauser. We also add another
derive child call after auto-init to measure the mailbox
valid pausers and change locality from 0xFFFFFFFF to the
pl0_pauser locality.
  • Loading branch information
sree-revoori1 authored and jhand2 committed Nov 27, 2023
1 parent d6cacb4 commit c7d6458
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 12 deletions.
17 changes: 17 additions & 0 deletions drivers/src/soc_ifc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ impl SocIfc {
soc_ifc_regs.cptra_security_state().read().debug_locked()
}

pub fn mbox_valid_pauser(&self) -> [u32; 5] {
let soc_ifc_regs = self.soc_ifc.regs();
soc_ifc_regs.cptra_mbox_valid_pauser().read()
}

pub fn mbox_pauser_lock(&self) -> [bool; 5] {
let soc_ifc_regs = self.soc_ifc.regs();
let pauser_lock = soc_ifc_regs.cptra_mbox_pauser_lock();
[
pauser_lock.at(0).read().lock(),
pauser_lock.at(1).read().lock(),
pauser_lock.at(2).read().lock(),
pauser_lock.at(3).read().lock(),
pauser_lock.at(4).read().lock(),
]
}

/// Locks or unlocks the ICCM.
///
/// # Arguments
Expand Down
2 changes: 2 additions & 0 deletions error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ impl CaliptraError {
CaliptraError::new_const(0x000E0021);
pub const RUNTIME_ADD_ROM_MEASUREMENTS_TO_DPE_FAILED: CaliptraError =
CaliptraError::new_const(0x000E0022);
pub const RUNTIME_ADD_VALID_PAUSER_MEASUREMENT_TO_DPE_FAILED: CaliptraError =
CaliptraError::new_const(0x000E0023);

/// FMC Errors
pub const FMC_GLOBAL_NMI: CaliptraError = CaliptraError::new_const(0x000F0001);
Expand Down
58 changes: 52 additions & 6 deletions runtime/src/drivers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use dpe::{
};

use crypto::{AlgLen, Crypto, CryptoBuf};
use zerocopy::AsBytes;

pub struct Drivers {
pub mbox: Mailbox,
Expand Down Expand Up @@ -240,7 +241,8 @@ impl Drivers {
}

fn initialize_dpe(drivers: &mut Drivers) -> CaliptraResult<()> {
let locality = drivers.persistent_data.get().manifest1.header.pl0_pauser;
let caliptra_locality = 0xFFFFFFFF;
let pl0_pauser_locality = drivers.persistent_data.get().manifest1.header.pl0_pauser;
let hashed_rt_pub_key = drivers.compute_rt_alias_sn()?;
let mut crypto = DpeCrypto::new(
&mut drivers.sha384,
Expand All @@ -251,9 +253,36 @@ impl Drivers {
drivers.persistent_data.get().fht.rt_dice_pub_key,
);

// create a hash of all the mailbox valid pausers
const PAUSER_COUNT: usize = 5;
let mbox_valid_pauser: [u32; PAUSER_COUNT] = drivers.soc_ifc.mbox_valid_pauser();
let mbox_pauser_lock: [bool; PAUSER_COUNT] = drivers.soc_ifc.mbox_pauser_lock();
let mut valid_pausers = [0u32; PAUSER_COUNT];
let mut num_valid_pausers = 0;
for i in 0..PAUSER_COUNT {
if num_valid_pausers >= PAUSER_COUNT {
// Prevent panic; compiler doesn't realize this is impossible.
return Err(CaliptraError::RUNTIME_ADD_VALID_PAUSER_MEASUREMENT_TO_DPE_FAILED);
}
if mbox_pauser_lock[i] {
valid_pausers[num_valid_pausers] = mbox_valid_pauser[i];
num_valid_pausers += 1;
}
}
let valid_pauser_hash = crypto
.hash(
AlgLen::Bit384,
valid_pausers[..num_valid_pausers].as_bytes(),
)
.map_err(|_| CaliptraError::RUNTIME_ADD_VALID_PAUSER_MEASUREMENT_TO_DPE_FAILED)?;

let mut env = DpeEnv::<CptraDpeTypes> {
crypto,
platform: DpePlatform::new(locality, hashed_rt_pub_key, &mut drivers.cert_chain),
platform: DpePlatform::new(
caliptra_locality,
hashed_rt_pub_key,
&mut drivers.cert_chain,
),
};
let mut dpe = DpeInstance::new(&mut env, DPE_SUPPORT)
.map_err(|_| CaliptraError::RUNTIME_INITIALIZE_DPE_FAILED)?;
Expand All @@ -270,11 +299,28 @@ impl Drivers {
| DeriveChildFlags::INPUT_ALLOW_CA
| DeriveChildFlags::INPUT_ALLOW_X509,
tci_type: u32::from_be_bytes(*b"RTJM"),
target_locality: locality,
target_locality: caliptra_locality,
}
.execute(&mut dpe, &mut env, locality)
.execute(&mut dpe, &mut env, caliptra_locality)
.map_err(|_| CaliptraError::RUNTIME_INITIALIZE_DPE_FAILED)?;

// Call DeriveChild to create a measurement for the mailbox valid pausers and change locality to the pl0 pauser locality
DeriveChildCmd {
handle: ContextHandle::default(),
data: valid_pauser_hash
.bytes()
.try_into()
.map_err(|_| CaliptraError::RUNTIME_ADD_VALID_PAUSER_MEASUREMENT_TO_DPE_FAILED)?,
flags: DeriveChildFlags::MAKE_DEFAULT
| DeriveChildFlags::CHANGE_LOCALITY
| DeriveChildFlags::INPUT_ALLOW_CA
| DeriveChildFlags::INPUT_ALLOW_X509,
tci_type: u32::from_be_bytes(*b"MBVP"),
target_locality: pl0_pauser_locality,
}
.execute(&mut dpe, &mut env, caliptra_locality)
.map_err(|_| CaliptraError::RUNTIME_ADD_VALID_PAUSER_MEASUREMENT_TO_DPE_FAILED)?;

// Call DeriveChild to create TCIs for each measurement added in ROM
let num_measurements = drivers.persistent_data.get().fht.meas_log_index as usize;
let measurement_log = drivers.persistent_data.get().measurement_log;
Expand All @@ -291,9 +337,9 @@ impl Drivers {
| DeriveChildFlags::INPUT_ALLOW_CA
| DeriveChildFlags::INPUT_ALLOW_X509,
tci_type,
target_locality: locality,
target_locality: pl0_pauser_locality,
}
.execute(&mut dpe, &mut env, locality)
.execute(&mut dpe, &mut env, pl0_pauser_locality)
.map_err(|_| CaliptraError::RUNTIME_ADD_ROM_MEASUREMENTS_TO_DPE_FAILED)?;
}

Expand Down
10 changes: 4 additions & 6 deletions runtime/tests/runtime_integration_tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,12 +669,10 @@ fn test_pauser_privilege_level_dpe_context_thresholds() {
let mut handle = rotate_ctx_resp.handle;

// Call DeriveChild with PL0 enough times to breach the threshold on the last iteration.
// Note that this loop runs exactly PL0_DPE_ACTIVE_CONTEXT_THRESHOLD - 1 times. Due to
// auto initialization of DPE, context[0] has a default context. When we initialize drivers,
// we also call derive child once without setting RETAINS_PARENT, so context[1] will be
// active. Thus, we can call derive child from PL0 exactly 6 times, and the last iteration
// of this loop, is expected to throw a threshold breached error.
let num_iterations = InvokeDpeCmd::PL0_DPE_ACTIVE_CONTEXT_THRESHOLD - 1;
// Note that this loop runs exactly PL0_DPE_ACTIVE_CONTEXT_THRESHOLD times. When we initialize
// DPE, we measure mailbox valid pausers in pl0_pauser's locality. Thus, we can call derive child
// from PL0 exactly 7 times, and the last iteration of this loop, is expected to throw a threshold breached error.
let num_iterations = InvokeDpeCmd::PL0_DPE_ACTIVE_CONTEXT_THRESHOLD;
for i in 0..num_iterations {
let mut cmd_data: [u8; 512] = [0u8; InvokeDpeReq::DATA_MAX_SIZE];
let derive_child_cmd = DeriveChildCmd {
Expand Down

0 comments on commit c7d6458

Please sign in to comment.