Skip to content

Commit

Permalink
[feat] ROM IDEVID DICE changes for MLDSA support (#1733)
Browse files Browse the repository at this point in the history
This change adds MLDSA support to the IDEVID DICE derivation. Generation of MLDSA CSR is not included in this change and will come later.
  • Loading branch information
mhatrevi authored Nov 11, 2024
1 parent cb81f06 commit ba38c77
Show file tree
Hide file tree
Showing 28 changed files with 328 additions and 277 deletions.
12 changes: 9 additions & 3 deletions common/src/keyids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,19 @@ pub const KEY_ID_UDS: KeyId = KeyId::KeyId0;
#[cfg(feature = "rom")]
pub const KEY_ID_FE: KeyId = KeyId::KeyId1;
#[cfg(feature = "rom")]
pub const KEY_ID_IDEVID_PRIV_KEY: KeyId = KeyId::KeyId7;
pub const KEY_ID_IDEVID_ECDSA_PRIV_KEY: KeyId = KeyId::KeyId7;
#[cfg(feature = "rom")]
pub const KEY_ID_LDEVID_PRIV_KEY: KeyId = KeyId::KeyId5;
pub const KEY_ID_IDEVID_MLDSA_KEYPAIR_SEED: KeyId = KeyId::KeyId8;
#[cfg(feature = "rom")]
pub const KEY_ID_LDEVID_MLDSA_KEYPAIR_SEED: KeyId = KeyId::KeyId4;
#[cfg(feature = "rom")]
pub const KEY_ID_LDEVID_ECDSA_PRIV_KEY: KeyId = KeyId::KeyId5;
#[cfg(feature = "rom")]
pub const KEY_ID_ROM_FMC_CDI: KeyId = KeyId::KeyId6;
#[cfg(feature = "rom")]
pub const KEY_ID_FMC_PRIV_KEY: KeyId = KeyId::KeyId7;
pub const KEY_ID_FMC_ECDSA_PRIV_KEY: KeyId = KeyId::KeyId7;
#[cfg(feature = "rom")]
pub const KEY_ID_FMC_MLDSA_KEYPAIR_SEED: KeyId = KeyId::KeyId8;
#[cfg(feature = "fmc")]
pub const KEY_ID_RT_CDI: KeyId = KeyId::KeyId4;
#[cfg(feature = "fmc")]
Expand Down
47 changes: 0 additions & 47 deletions common/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,53 +83,6 @@ impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b>
self.soc_ifc.fuse_bank().vendor_pub_key_info_hash().into()
}

/// Retrieve Vendor Public Key Info Digest
fn vendor_pub_key_info_digest_from_image(
&mut self,
ecc_key_desc: (u32, u32),
ecc_pub_key_hashes: (u32, u32),
lms_key_desc: (u32, u32),
lms_pub_key_hashes: (u32, u32),
) -> CaliptraResult<ImageDigest> {
let err = CaliptraError::IMAGE_VERIFIER_ERR_DIGEST_OUT_OF_BOUNDS;
let ecc_key_desc = self
.image
.get(ecc_key_desc.0 as usize..)
.ok_or(err)?
.get(..ecc_key_desc.1 as usize)
.ok_or(err)?;

let ecc_pub_key_hashes = self
.image
.get(ecc_pub_key_hashes.0 as usize..)
.ok_or(err)?
.get(..ecc_pub_key_hashes.1 as usize)
.ok_or(err)?;

let lms_key_desc = self
.image
.get(lms_key_desc.0 as usize..)
.ok_or(err)?
.get(..lms_key_desc.1 as usize)
.ok_or(err)?;

let lms_pub_key_hashes = self
.image
.get(lms_pub_key_hashes.0 as usize..)
.ok_or(err)?
.get(..lms_pub_key_hashes.1 as usize)
.ok_or(err)?;

let mut digest = Array4x12::default();
let mut op = self.sha384.digest_init()?;
op.update(ecc_key_desc)?;
op.update(ecc_pub_key_hashes)?;
op.update(lms_key_desc)?;
op.update(lms_pub_key_hashes)?;
op.finalize(&mut digest)?;
Ok(digest.0)
}

/// Retrieve Vendor ECC Public Key Revocation Bitmask
fn vendor_ecc_pub_key_revocation(&self) -> VendorPubKeyRevocation {
self.soc_ifc.fuse_bank().vendor_ecc_pub_key_revocation()
Expand Down
30 changes: 19 additions & 11 deletions drivers/src/hand_off.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,8 +280,11 @@ pub struct FirmwareHandoffTable {
/// Index of LdevId Certificate Signature S Component in the Data Vault.
pub ldevid_cert_sig_s_dv_hdl: HandOffDataHandle,

/// IDevID public key
pub idev_dice_pub_key: Ecc384PubKey,
/// IDevID ECDSA public key
pub idev_dice_ecdsa_pub_key: Ecc384PubKey,

/// IDevID MLDSA public key address in DCCM
pub idev_dice_mldsa_pub_key_load_addr: u32,

/// Address of RomInfo struct
pub rom_info_addr: RomAddr<RomInfo>,
Expand All @@ -299,10 +302,10 @@ pub struct FirmwareHandoffTable {

/// Reserved for future use.
#[cfg(any(feature = "fmc", feature = "runtime"))]
pub reserved: [u8; 1636],
pub reserved: [u8; 1632],

#[cfg(not(any(feature = "fmc", feature = "runtime")))]
pub reserved: [u8; 1642],
pub reserved: [u8; 1638],
}

impl Default for FirmwareHandoffTable {
Expand Down Expand Up @@ -340,7 +343,8 @@ impl Default for FirmwareHandoffTable {
rt_dice_sign: Ecc384Signature::default(),
ldevid_cert_sig_r_dv_hdl: FHT_INVALID_HANDLE,
ldevid_cert_sig_s_dv_hdl: FHT_INVALID_HANDLE,
idev_dice_pub_key: Ecc384PubKey::default(),
idev_dice_ecdsa_pub_key: Ecc384PubKey::default(),
idev_dice_mldsa_pub_key_load_addr: 0,
rom_info_addr: RomAddr::new(FHT_INVALID_ADDRESS),
rtalias_tbs_size: 0,

Expand All @@ -349,10 +353,10 @@ impl Default for FirmwareHandoffTable {
#[cfg(any(feature = "fmc", feature = "runtime"))]
rt_hash_chain_kv_hdl: HandOffDataHandle(0),
#[cfg(any(feature = "fmc", feature = "runtime"))]
reserved: [0u8; 1636],
reserved: [0u8; 1632],

#[cfg(not(any(feature = "fmc", feature = "runtime")))]
reserved: [0u8; 1642],
reserved: [0u8; 1638],
}
}
}
Expand Down Expand Up @@ -405,6 +409,10 @@ pub fn print_fht(fht: &FirmwareHandoffTable) {
crate::cprintln!("RT SVN DV Handle: 0x{:08x}", fht.rt_svn_dv_hdl.0);
crate::cprintln!("RT Min SVN DV Handle: 0x{:08x}", fht.rt_min_svn_dv_hdl.0);

crate::cprintln!(
"IdevId MLDSA Public Key Address: 0x{:08x}",
fht.idev_dice_mldsa_pub_key_load_addr
);
crate::cprintln!("LdevId TBS Address: 0x{:08x}", fht.ldevid_tbs_addr);
crate::cprintln!("LdevId TBS Size: {} bytes", fht.ldevid_tbs_size);
crate::cprintln!(
Expand Down Expand Up @@ -470,14 +478,14 @@ mod tests {
use super::*;
use core::mem;
const FHT_SIZE: usize = 2048;
const KEY_ID_FMC_PRIV_KEY: KeyId = KeyId::KeyId5;
const KEY_ID_FMC_ECDSA_PRIV_KEY: KeyId = KeyId::KeyId7;

fn rt_tci_store() -> HandOffDataHandle {
HandOffDataHandle::from(DataStore::DataVaultNonSticky48(WarmResetEntry48::RtTci))
}

fn fmc_priv_key_store() -> HandOffDataHandle {
HandOffDataHandle(((Vault::KeyVault as u32) << 12) | KEY_ID_FMC_PRIV_KEY as u32)
HandOffDataHandle(((Vault::KeyVault as u32) << 12) | KEY_ID_FMC_ECDSA_PRIV_KEY as u32)
}

fn fmc_priv_key(fht: &FirmwareHandoffTable) -> KeyId {
Expand Down Expand Up @@ -541,9 +549,9 @@ mod tests {
// Check the key slot is correct
assert_eq!(
fht.fmc_priv_key_kv_hdl.reg_num(),
KEY_ID_FMC_PRIV_KEY.into()
KEY_ID_FMC_ECDSA_PRIV_KEY.into()
);

assert_eq!(fmc_priv_key(&fht), KEY_ID_FMC_PRIV_KEY);
assert_eq!(fmc_priv_key(&fht), KEY_ID_FMC_ECDSA_PRIV_KEY);
}
}
1 change: 1 addition & 0 deletions drivers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ pub use lms::{
Sha256Digest, D_INTR, D_LEAF, D_MESG, D_PBLC,
};
pub use mailbox::{Mailbox, MailboxRecvTxn, MailboxSendTxn};
pub use mldsa87::{MlDsa87, MlDsa87PubKey, MlDsa87Reg, MlDsa87Signature};
pub use okref::okmutref;
pub use okref::okref;
pub use pcr_bank::{PcrBank, PcrId};
Expand Down
61 changes: 38 additions & 23 deletions drivers/src/memory_layout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ use crate::FirmwareHandoffTable;
#[cfg(test)]
use caliptra_image_types::ImageManifest;

#[cfg(test)]
use crate::MlDsa87PubKey;

//
// Memory Addresses
//
Expand All @@ -29,27 +32,28 @@ pub const ROM_DATA_ORG: u32 = 0x50000000;
pub const CFI_STATE_ORG: u32 = 0x500003E4; // size = 6 words
pub const BOOT_STATUS_ORG: u32 = 0x500003FC;
pub const MAN1_ORG: u32 = 0x50000400;
pub const MAN2_ORG: u32 = 0x50002400;
pub const FHT_ORG: u32 = 0x50004400;
pub const LDEVID_TBS_ORG: u32 = 0x50004C00;
pub const FMCALIAS_TBS_ORG: u32 = 0x50005000;
pub const RTALIAS_TBS_ORG: u32 = 0x50005400;
pub const PCR_LOG_ORG: u32 = 0x50005800;
pub const MEASUREMENT_LOG_ORG: u32 = 0x50005C00;
pub const FUSE_LOG_ORG: u32 = 0x50006000;
pub const DPE_ORG: u32 = 0x50006400;
pub const PCR_RESET_COUNTER_ORG: u32 = 0x50007800;
pub const AUTH_MAN_IMAGE_METADATA_LIST_ORG: u32 = 0x50007C00;
pub const DATA_ORG: u32 = 0x50008000;

pub const STACK_ORG: u32 = 0x5001A000;
pub const ROM_STACK_ORG: u32 = 0x5001C000;

pub const ESTACK_ORG: u32 = 0x5001F800;
pub const ROM_ESTACK_ORG: u32 = 0x5001F800;

pub const NSTACK_ORG: u32 = 0x5001FC00;
pub const ROM_NSTACK_ORG: u32 = 0x5001FC00;
pub const MAN2_ORG: u32 = MAN1_ORG + MAN1_SIZE;
pub const FHT_ORG: u32 = MAN2_ORG + MAN2_SIZE;
pub const IDEVID_MLDSA_PUB_KEY_ORG: u32 = FHT_ORG + FHT_SIZE;
pub const LDEVID_TBS_ORG: u32 = IDEVID_MLDSA_PUB_KEY_ORG + IDEVID_MLDSA_PUB_KEY_MAX_SIZE;
pub const FMCALIAS_TBS_ORG: u32 = LDEVID_TBS_ORG + LDEVID_TBS_SIZE;
pub const RTALIAS_TBS_ORG: u32 = FMCALIAS_TBS_ORG + FMCALIAS_TBS_SIZE;
pub const PCR_LOG_ORG: u32 = RTALIAS_TBS_ORG + RTALIAS_TBS_SIZE;
pub const MEASUREMENT_LOG_ORG: u32 = PCR_LOG_ORG + PCR_LOG_SIZE;
pub const FUSE_LOG_ORG: u32 = MEASUREMENT_LOG_ORG + MEASUREMENT_LOG_SIZE;
pub const DPE_ORG: u32 = FUSE_LOG_ORG + FUSE_LOG_SIZE;
pub const PCR_RESET_COUNTER_ORG: u32 = DPE_ORG + DPE_SIZE;
pub const AUTH_MAN_IMAGE_METADATA_LIST_ORG: u32 = PCR_RESET_COUNTER_ORG + PCR_RESET_COUNTER_SIZE;
pub const DATA_ORG: u32 = AUTH_MAN_IMAGE_METADATA_LIST_ORG + AUTH_MAN_IMAGE_METADATA_LIST_MAX_SIZE;

pub const STACK_ORG: u32 = DATA_ORG + DATA_SIZE;
pub const ROM_STACK_ORG: u32 = STACK_ORG + (STACK_SIZE - ROM_STACK_SIZE);

pub const ESTACK_ORG: u32 = ROM_STACK_ORG + ROM_STACK_SIZE;
pub const ROM_ESTACK_ORG: u32 = ESTACK_ORG;

pub const NSTACK_ORG: u32 = ROM_ESTACK_ORG + ROM_ESTACK_SIZE;
pub const ROM_NSTACK_ORG: u32 = NSTACK_ORG;

//
// Memory Sizes In Bytes
Expand All @@ -63,6 +67,7 @@ pub const ROM_DATA_SIZE: u32 = 996;
pub const MAN1_SIZE: u32 = 8 * 1024;
pub const MAN2_SIZE: u32 = 8 * 1024;
pub const FHT_SIZE: u32 = 2 * 1024;
pub const IDEVID_MLDSA_PUB_KEY_MAX_SIZE: u32 = 3 * 1024;
pub const LDEVID_TBS_SIZE: u32 = 1024;
pub const FMCALIAS_TBS_SIZE: u32 = 1024;
pub const RTALIAS_TBS_SIZE: u32 = 1024;
Expand All @@ -72,7 +77,7 @@ pub const FUSE_LOG_SIZE: u32 = 1024;
pub const DPE_SIZE: u32 = 5 * 1024;
pub const PCR_RESET_COUNTER_SIZE: u32 = 1024;
pub const AUTH_MAN_IMAGE_METADATA_LIST_MAX_SIZE: u32 = 1024;
pub const DATA_SIZE: u32 = 72 * 1024;
pub const DATA_SIZE: u32 = 69 * 1024;
pub const STACK_SIZE: u32 = 22 * 1024;
pub const ROM_STACK_SIZE: u32 = 14 * 1024;
pub const ESTACK_SIZE: u32 = 1024;
Expand All @@ -99,7 +104,17 @@ fn mem_layout_test_manifest() {
#[allow(clippy::assertions_on_constants)]
fn mem_layout_test_fht() {
assert!(FHT_SIZE as usize >= core::mem::size_of::<FirmwareHandoffTable>());
assert_eq!((LDEVID_TBS_ORG - FHT_ORG), FHT_SIZE);
assert_eq!((IDEVID_MLDSA_PUB_KEY_ORG - FHT_ORG), FHT_SIZE);
}

#[test]
#[allow(clippy::assertions_on_constants)]
fn mem_layout_test_idevid_mldsa_pub_key() {
assert!(IDEVID_MLDSA_PUB_KEY_MAX_SIZE as usize >= core::mem::size_of::<MlDsa87PubKey>());
assert_eq!(
(LDEVID_TBS_ORG - IDEVID_MLDSA_PUB_KEY_ORG),
IDEVID_MLDSA_PUB_KEY_MAX_SIZE
);
}

#[test]
Expand Down
10 changes: 9 additions & 1 deletion drivers/src/persistent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{
fuse_log::FuseLogEntry,
memory_layout,
pcr_log::{MeasurementLogEntry, PcrLogEntry},
FirmwareHandoffTable,
FirmwareHandoffTable, MlDsa87PubKey,
};

#[cfg(feature = "runtime")]
Expand Down Expand Up @@ -56,6 +56,10 @@ pub struct PersistentData {
pub fht: FirmwareHandoffTable,
reserved2: [u8; memory_layout::FHT_SIZE as usize - size_of::<FirmwareHandoffTable>()],

pub idevid_mldsa_pub_key: MlDsa87PubKey,
reserved2_1:
[u8; memory_layout::IDEVID_MLDSA_PUB_KEY_MAX_SIZE as usize - size_of::<MlDsa87PubKey>()],

// TODO: Do we want to hide these fields from the FMC/runtime and force them
// to go through the FHT addresses?
pub ldevid_tbs: [u8; memory_layout::LDEVID_TBS_SIZE as usize],
Expand Down Expand Up @@ -110,6 +114,10 @@ impl PersistentData {
assert_eq!(addr_of!((*P).manifest1) as u32, layout::MAN1_ORG);
assert_eq!(addr_of!((*P).manifest2) as u32, layout::MAN2_ORG);
assert_eq!(addr_of!((*P).fht) as u32, layout::FHT_ORG);
assert_eq!(
addr_of!((*P).idevid_mldsa_pub_key) as u32,
layout::IDEVID_MLDSA_PUB_KEY_ORG
);
assert_eq!(addr_of!((*P).ldevid_tbs) as u32, layout::LDEVID_TBS_ORG);
assert_eq!(addr_of!((*P).fmcalias_tbs) as u32, layout::FMCALIAS_TBS_ORG);
assert_eq!(addr_of!((*P).rtalias_tbs) as u32, layout::RTALIAS_TBS_ORG);
Expand Down
17 changes: 11 additions & 6 deletions fmc/tests/fmc_integration_tests/test_rtalias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ use caliptra_builder::{
firmware::{self, runtime_tests::MOCK_RT_INTERACTIVE, FMC_WITH_UART},
ImageOptions,
};
use caliptra_common::RomBootStatus::*;
use caliptra_common::{
memory_layout::{
FMCALIAS_TBS_ORG, FUSE_LOG_ORG, LDEVID_TBS_ORG, MEASUREMENT_LOG_ORG, PCR_LOG_ORG,
},
RomBootStatus::*,
};

use caliptra_common::mailbox_api::CommandId;
use caliptra_drivers::{
Expand Down Expand Up @@ -92,11 +97,11 @@ fn test_fht_info() {
let fht = FirmwareHandoffTable::read_from_prefix(data.as_bytes()).unwrap();
assert_eq!(fht.ldevid_tbs_size, 552);
assert_eq!(fht.fmcalias_tbs_size, 786);
assert_eq!(fht.ldevid_tbs_addr, 0x50004C00);
assert_eq!(fht.fmcalias_tbs_addr, 0x50005000);
assert_eq!(fht.pcr_log_addr, 0x50005800);
assert_eq!(fht.meas_log_addr, 0x50005C00);
assert_eq!(fht.fuse_log_addr, 0x50006000);
assert_eq!(fht.ldevid_tbs_addr, LDEVID_TBS_ORG);
assert_eq!(fht.fmcalias_tbs_addr, FMCALIAS_TBS_ORG);
assert_eq!(fht.pcr_log_addr, PCR_LOG_ORG);
assert_eq!(fht.meas_log_addr, MEASUREMENT_LOG_ORG);
assert_eq!(fht.fuse_log_addr, FUSE_LOG_ORG);
}

#[test]
Expand Down
9 changes: 0 additions & 9 deletions image/verify/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,6 @@ pub trait ImageVerificationEnv {
/// Get Vendor Public Key Digest from fuses
fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest;

/// Compute theVendor Public Key Digest from Image
fn vendor_pub_key_info_digest_from_image(
&mut self,
ecc_key_desc: (u32, u32),
ecc_pub_key_hashes: (u32, u32),
lms_key_desc: (u32, u32),
lms_pub_key_hashes: (u32, u32),
) -> CaliptraResult<ImageDigest>;

/// Get Vendor ECC Public Key Revocation list
fn vendor_ecc_pub_key_revocation(&self) -> VendorPubKeyRevocation;

Expand Down
10 changes: 0 additions & 10 deletions image/verify/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2067,16 +2067,6 @@ mod tests {
}
}

fn vendor_pub_key_info_digest_from_image(
&mut self,
_ecc_key_desc: (u32, u32),
_ecc_pub_key_hashes: (u32, u32),
_lms_key_desc: (u32, u32),
_lms_pub_key_hashes: (u32, u32),
) -> CaliptraResult<ImageDigest> {
Ok(self.digest)
}

fn vendor_pub_key_info_digest_fuses(&self) -> ImageDigest {
self.vendor_pub_key_digest
}
Expand Down
Loading

0 comments on commit ba38c77

Please sign in to comment.