Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
mhatrevi committed Feb 27, 2025
1 parent 72e939f commit 68ef3a2
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 36 deletions.
15 changes: 12 additions & 3 deletions drivers/src/trng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use caliptra_registers::{
csrng::CsrngReg, entropy_src::EntropySrcReg, soc_ifc::SocIfcReg, soc_ifc_trng::SocIfcTrngReg,
};

use crate::{trng_ext::TrngExt, Array4x12, Csrng, MfgFlags};
use crate::{cprintln, trng_ext::TrngExt, Array4x12, Csrng, MfgFlags};

#[repr(u32)]
pub enum Trng {
Expand Down Expand Up @@ -65,10 +65,19 @@ impl Trng {
fn cfi_panic_handler(code: u32) -> !;
}

cprintln!("Generating entropy...");

match self {
Self::Internal(csrng) => Ok(csrng.generate12()?.into()),
Self::External(trng_ext) => trng_ext.generate(),
Self::Internal(csrng) => {
cprintln!("Internal");
Ok(csrng.generate12()?.into())
}
Self::External(trng_ext) => {
cprintln!("External");
trng_ext.generate()
}
Self::MfgMode() => {
cprintln!("MfgMode");
unsafe {
let soc_ifc = SocIfcReg::new();
if soc_ifc.regs().cptra_security_state().read().debug_locked() {
Expand Down
4 changes: 2 additions & 2 deletions rom/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,11 @@ The following flows are conducted when the ROM is operating in the manufacturing
3. ROM then retrieves the UDS granularity from the `CPTRA_HW_CONFIG` register Bit6 to learn if the fuse row is accessible with 32-bit or 64-bit granularity.

4. ROM then performs the following steps until all the 512 bits of the UDS seed are programmed:
1. The ROM verifies the idle state of the DAI by reading the `STATUS` register `DAI_IDLE` bit (Bit 14) of the Fuse Controller, located at offset 0x10 from the Fuse Controller's base address.
1. The ROM verifies the idle state of the DAI by reading the `STATUS` register `DAI_IDLE` bit (Bit-21) of the Fuse Controller, located at offset 0x10 from the Fuse Controller's base address.
2. If the granularity is 32-bit, the ROM writes the next word from the UDS seed to the `DIRECT_ACCESS_WDATA_0` register. If the granularity is 64-bit, the ROM writes the next two words to `the DIRECT_ACCESS_WDATA_0` and `DIRECT_ACCESS_WDATA_1` registers, located at offsets 0x44 and 0x48 respectively from the Fuse Controller's base address.
3. The ROM writes the lower 32 bits of the UDS Seed programming base address to the `DIRECT_ACCESS_ADDRESS` register at offset 0x40.
4. The ROM triggers the UDS seed write command by writing 0x2 to the `DIRECT_ACCESS_CMD` register at offset 0x3C.
5. [OPEN] Handle DAI error.
5. [OPEN] Handle DAI error. - Remove
6. The ROM increments the `DIRECT_ACCESS_ADDRESS` register by 4 for 32-bit granularity or 8 for 64-bit granularity and repeats the process for the remaining words of the UDS seed.

5. The ROM continuously polls the Fuse Controller's `STATUS` register until the DAI state returns to idle.
Expand Down
80 changes: 56 additions & 24 deletions rom/dev/src/flow/uds_programming.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ use caliptra_common::cprintln;
use caliptra_drivers::{AxiAddr, CaliptraError, CaliptraResult, Lifecycle};

const STATUS_REG_OFFSET: u64 = 0x10;
const DIRECT_ACCESS_WDATA_0_REG_OFFSET: u64 = 0x44;
const DIRECT_ACCESS_WDATA_1_REG_OFFSET: u64 = 0x48;
const DIRECT_ACCESS_ADDRESS_REG_OFFSET: u64 = 0x40;
const DIRECT_ACCESS_CMD_REG_OFFSET: u64 = 0x3C;
const DAI_IDLE_BIT: u32 = 1 << 14;
const DIRECT_ACCESS_WDATA_0_REG_OFFSET: u64 = 0x60;
const DIRECT_ACCESS_WDATA_1_REG_OFFSET: u64 = 0x64;
const DIRECT_ACCESS_ADDRESS_REG_OFFSET: u64 = 0x5C;
const DIRECT_ACCESS_CMD_REG_OFFSET: u64 = 0x58;
const DAI_IDLE_BIT: u32 = 1 << 21;
const DIRECT_ACCESS_CMD_WRITE: u32 = 0x2;
const DIRECT_ACCESS_CMD_DIGEST: u32 = 0x4;

Expand All @@ -33,8 +33,6 @@ impl UdsProgrammingFlow {
#[inline(never)]
#[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)]
pub fn program_uds(env: &mut RomEnv) -> CaliptraResult<()> {
cprintln!("[uds] ++");

// Check if UDS programming is requested.
if !env.soc_ifc.uds_program_req() {
return Ok(());
Expand All @@ -55,35 +53,48 @@ impl UdsProgrammingFlow {
}

// Update the UDS programming state.
cprintln!("[uds] Updating the UDS programming state");
env.soc_ifc
.set_uds_programming_flow_state(true /* in_progress */);

let result = (|| {
// Generate a 512-bit random value.
let mut seed = [0u32; 16];
let seed1 = env.trng.generate()?;
let seed2 = env.trng.generate()?;
seed[..12].copy_from_slice(&seed1.0);
seed[12..16].copy_from_slice(&seed2.0[0..4]);
for i in 0..16 {
seed[i] = (i * 4) as u32
| ((i * 4 + 1) as u32) << 8
| ((i * 4 + 2) as u32) << 16
| ((i * 4 + 3) as u32) << 24;
}
// let seed1 = env.trng.generate()?;
// let seed2 = env.trng.generate()?;
// seed[..12].copy_from_slice(&seed1.0);
// seed[12..16].copy_from_slice(&seed2.0[0..4]);

let uds_fuse_row_granularity_64: bool = env.soc_ifc.uds_fuse_row_granularity_64();
//let uds_fuse_row_granularity_64: bool = env.soc_ifc.uds_fuse_row_granularity_64();
let uds_fuse_row_granularity_64 = true;
let fuse_controller_base_addr = env.soc_ifc.fuse_controller_base_addr();
let status_reg_addr = fuse_controller_base_addr + STATUS_REG_OFFSET;
let direct_access_wdata_0_reg_addr =
fuse_controller_base_addr + DIRECT_ACCESS_WDATA_0_REG_OFFSET;
let direct_access_wdata_1_reg_addr =
fuse_controller_base_addr + DIRECT_ACCESS_WDATA_1_REG_OFFSET;
let mut uds_seed_dest_address = env.soc_ifc.uds_seed_dest_base_addr_low();
let uds_seed_dest_address = env.soc_ifc.uds_seed_dest_base_addr_low();
let direct_access_address_reg_addr =
fuse_controller_base_addr + DIRECT_ACCESS_ADDRESS_REG_OFFSET;
let direct_access_cmd_reg_addr =
fuse_controller_base_addr + DIRECT_ACCESS_CMD_REG_OFFSET;
let mut seed_index = 0;
let seed_index = 0;

while seed_index < seed.len() {
//while seed_index < seed.len() {
// Poll the STATUS register until the DAI state returns to idle.
cprintln!(
"[uds] Polling the STATUS register: {:x} until the DAI state returns to idle",
status_reg_addr
);
while {
let status_value = env.dma.read_dword(AxiAddr::from(status_reg_addr))?;
cprintln!("[uds] STATUS register value: {:#x}", status_value);
(status_value & DAI_IDLE_BIT) == 0
} {
// [TODO][CAP2] Handle errors.
Expand All @@ -92,6 +103,10 @@ impl UdsProgrammingFlow {
// Write the UDS seed to the DIRECT_ACCESS_WDATA_0 register
// and the DIRECT_ACCESS_WDATA_1 register (for 64-bit granularity).
let wdata_0 = seed[seed_index];
cprintln!(
"[uds] Writing the UDS seed to the DIRECT_ACCESS_WDATA_0: {:x} register, wdata_0: {:#x}",
direct_access_wdata_0_reg_addr, wdata_0
);
env.dma
.write_dword(AxiAddr::from(direct_access_wdata_0_reg_addr), wdata_0)?;
if uds_fuse_row_granularity_64 {
Expand All @@ -100,59 +115,74 @@ impl UdsProgrammingFlow {
}
// 64-bit granularity
let wdata_1 = seed[seed_index + 1];
cprintln!(
"[uds] Writing the UDS seed to the DIRECT_ACCESS_WDATA_1: {:x} register, wdata_1: {:#x}",
direct_access_wdata_1_reg_addr, wdata_1
);
env.dma
.write_dword(AxiAddr::from(direct_access_wdata_1_reg_addr), wdata_1)?;
seed_index += 2;
//seed_index += 2;
} else {
// 32-bit granularity
seed_index += 1;
//seed_index += 1;
}

// Write the lower 32 bits of the UDS Seed programming destination address to the DIRECT_ACCESS_ADDRESS register.
cprintln!("[uds] Writing the lower 32 bits of the UDS Seed programming destination address: {:x} to the DIRECT_ACCESS_ADDRESS register: {:x}",
uds_seed_dest_address, direct_access_address_reg_addr);
env.dma.write_dword(
AxiAddr::from(direct_access_address_reg_addr),
uds_seed_dest_address,
)?;

// Trigger the UDS seed write command
cprintln!("[uds] Triggering the UDS seed write command, direct_access_cmd_reg_addr: {:x}, command: {:#x}",
direct_access_cmd_reg_addr, DIRECT_ACCESS_CMD_WRITE);
env.dma.write_dword(
AxiAddr::from(direct_access_cmd_reg_addr),
DIRECT_ACCESS_CMD_WRITE,
)?;

// Increment the DIRECT_ACCESS_ADDRESS register
if uds_fuse_row_granularity_64 {
uds_seed_dest_address += 8;
} else {
uds_seed_dest_address += 4;
}
} // End of UDS seed write loop.
// if uds_fuse_row_granularity_64 {
// uds_seed_dest_address += 8;
// } else {
// uds_seed_dest_address += 4;
// }
//} // End of UDS seed write loop.

// Trigger the partition digest operation
// Poll the STATUS register until the DAI state returns to idle.
cprintln!("[uds] Polling the STATUS register: {:x} until the DAI state returns to idle", status_reg_addr);
while {
let status_value = env.dma.read_dword(AxiAddr::from(status_reg_addr))?;
cprintln!("[uds] STATUS register value: {:#x}", status_value);
(status_value & DAI_IDLE_BIT) == 0
} {
// [TODO][CAP2] Handle errors.
}

// Write the lower 32 bits of the UDS Seed programming base address to the DIRECT_ACCESS_ADDRESS register.
cprintln!("[uds] Triggering the partition digest operation");
cprintln!("[uds] Triggering the partition digest operation, direct_access_address_reg_addr: {:x}, uds_seed_dest_address: {:#x}",
direct_access_address_reg_addr, env.soc_ifc.uds_seed_dest_base_addr_low());
env.dma.write_dword(
AxiAddr::from(direct_access_address_reg_addr),
env.soc_ifc.uds_seed_dest_base_addr_low(),
)?;

// Trigger the digest calculation command
cprintln!("[uds] Triggering the digest calculation command, direct_access_cmd_reg_addr: {:x}, command: {:#x}",
direct_access_cmd_reg_addr, DIRECT_ACCESS_CMD_DIGEST);
env.dma.write_dword(
AxiAddr::from(direct_access_cmd_reg_addr),
DIRECT_ACCESS_CMD_DIGEST,
)?;

// Poll the STATUS register until the DAI state returns to idle
cprintln!("[uds] Polling the STATUS register until the DAI state returns to idle, status_reg_addr: {:x}", status_reg_addr);
while {
let status_value = env.dma.read_dword(AxiAddr::from(status_reg_addr))?;
cprintln!("[uds] STATUS register value: {:#x}", status_value);
(status_value & DAI_IDLE_BIT) == 0
} {
// [TODO][CAP2] Handle errors.
Expand All @@ -162,9 +192,11 @@ impl UdsProgrammingFlow {
})();

// Set the UDS programming result.
cprintln!("[uds] Setting the UDS programming result");
env.soc_ifc.set_uds_programming_flow_status(result.is_ok());

// Update the UDS programming state.
cprintln!("[uds] Updating the UDS programming state");
env.soc_ifc
.set_uds_programming_flow_state(false /* in_progress */);

Expand Down
3 changes: 2 additions & 1 deletion rom/dev/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ use caliptra_drivers::printer as print;
pub fn main() {}

const BANNER: &str = r#"
Running Caliptra ROM ...
Running Caliptra ROM ...2/27/2025 11:00:00 AM
"#;

extern "C" {
Expand All @@ -77,6 +77,7 @@ pub extern "C" fn rom_entry() -> ! {
if !cfg!(feature = "no-cfi") {
cprintln!("[state] CFI Enabled");
let mut entropy_gen = || env.trng.generate().map(|a| a.0);
cprintln!("Generating entropy done");
CfiCounter::reset(&mut entropy_gen);
CfiCounter::reset(&mut entropy_gen);
CfiCounter::reset(&mut entropy_gen);
Expand Down
12 changes: 6 additions & 6 deletions rom/dev/src/start.S
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,14 @@ _start:
//

// Zero ICCM
la a0, ICCM_ORG // dest
la a1, ICCM_SIZE // len
call _zero_mem256
// la a0, ICCM_ORG // dest
// la a1, ICCM_SIZE // len
// call _zero_mem256

// Zero DCCM
la a0, DCCM_ORG // dest
la a1, DCCM_SIZE // len
call _zero_mem256
// la a0, DCCM_ORG // dest
// la a1, DCCM_SIZE // len
// call _zero_mem256

post_ecc_init:

Expand Down

0 comments on commit 68ef3a2

Please sign in to comment.