mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
Add audit code for the keystore
the snippet `attack_keystore()` is left in place along with hints on how to attack the keystore. Nominally, the attack should fail, but there are some critical pre-assumptions that can be violated. I am interested in knowing how robust those assumptions are, so, documentation and sample code is provided to would-be attackers. Do me a solid and if you do find a vulnerability, open an issue ASAP and let me know. Full well aware that some vulns may well be unpatchable; it is what it is. Hardware is hard, but maybe we can work together to make it better.
This commit is contained in:
parent
1c435909a2
commit
ba91aa5b58
1 changed files with 72 additions and 0 deletions
|
|
@ -13,3 +13,75 @@ fn main() -> ! {
|
|||
|
||||
platform::keystore(keys_sid);
|
||||
}
|
||||
|
||||
/// This piece of code can be copy/pasted into any other process to test the integrity of the hardware
|
||||
/// protection mechanism. It does two things:
|
||||
///
|
||||
/// 1. Maps the key store into its memory space
|
||||
/// 2. Attempts to override the coreuser mappings to fake permissions to access the keys
|
||||
///
|
||||
/// For the test to even run, the keystore's mapping on the COREUSER peripheral *and* the `SlotManager`
|
||||
/// need to be disabled. This is because the virtual memory system causes the keystore to "own" these
|
||||
/// mappings which gives it exclusive access to these register banks.
|
||||
///
|
||||
/// Once those protections are bypassed, then, the coreuser mapping is a second line of protection.
|
||||
/// This mapping *should* be set and locked down by the boot1 stage bootloader.
|
||||
///
|
||||
/// Thus any viable attack against this has to start with a chain before the one-way door is sealed
|
||||
/// on this configuration. If the one-way door has been successfully defeated, you will be able to
|
||||
/// read the keys out with this code.
|
||||
///
|
||||
/// Alternatively, one can find a kernel exploit that gains arbitrary exec in supervisor mode, which
|
||||
/// will allow you to set the ASID arbitrarily. This would allow an attacker to spoof the PID of
|
||||
/// the keystore process and thus access the keys.
|
||||
///
|
||||
/// Of course, this code running inside this process will work to read out the keys, since this
|
||||
/// is the designated, trusted process for accessing the key store.
|
||||
#[allow(dead_code)]
|
||||
fn attack_keystore() {
|
||||
use utralib::*;
|
||||
let cu_range = xous::map_memory(
|
||||
xous::MemoryAddress::new(utra::coreuser::HW_COREUSER_BASE),
|
||||
None,
|
||||
4096,
|
||||
xous::MemoryFlags::R | xous::MemoryFlags::W,
|
||||
)
|
||||
.unwrap();
|
||||
let mut cu = CSR::new(cu_range.as_ptr() as *mut u32);
|
||||
log::info!("coreuser status: {:x}", cu.r(utra::coreuser::STATUS));
|
||||
|
||||
cu.rmwf(utra::coreuser::MAP_HI_LUT7, 0);
|
||||
cu.rmwf(utra::coreuser::USERVALUE_USER7, bao1x_hal::coreuser::TRUSTED_USER.as_dense());
|
||||
log::info!("--------- COREUSER SET: {:x} -------------", cu.r(utra::coreuser::STATUS));
|
||||
|
||||
let slot_mgr = bao1x_hal::acram::SlotManager::new();
|
||||
// let slot = bao1x_api::baosec::ROOT_SEED;
|
||||
let slot =
|
||||
bao1x_api::offsets::SlotIndex::Key(0, bao1x_api::PartitionAccess::Fw0, bao1x_api::RwPerms::ReadOnly);
|
||||
let data_index = slot.try_into_data_offset().unwrap();
|
||||
let acl_index = slot.try_into_acl_offset().unwrap();
|
||||
let user_states = [
|
||||
bao1x_hal::coreuser::CoreuserId::Boot0,
|
||||
bao1x_hal::coreuser::CoreuserId::Boot1,
|
||||
bao1x_hal::coreuser::CoreuserId::Fw0,
|
||||
bao1x_hal::coreuser::CoreuserId::Fw1,
|
||||
];
|
||||
for i in 0..2 {
|
||||
cu.rmwf(utra::coreuser::CONTROL_INVERT_PRIV, i % 2);
|
||||
for state in user_states {
|
||||
cu.rmwf(utra::coreuser::MAP_LO_LUT2, xous::process::id() as u32);
|
||||
cu.rmwf(utra::coreuser::USERVALUE_USER2, state.as_dense());
|
||||
log::info!(" COREUSER STATUS {:x}", cu.r(utra::coreuser::STATUS));
|
||||
unsafe {
|
||||
let bytes = slot_mgr.read_key_slot(data_index);
|
||||
let acl = slot_mgr.get_key_acl(acl_index);
|
||||
log::info!(
|
||||
" Key {} ({:x?}): {:x?}",
|
||||
data_index / bao1x_api::offsets::SLOT_ELEMENT_LEN_BYTES,
|
||||
acl,
|
||||
bytes
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue