Skip to content

Commit

Permalink
Unify separate FMC and RT SVNs into a single firmware SVN.
Browse files Browse the repository at this point in the history
Apologies for the size of this PR.

With this change, there is now a singular SVN representing the security state of both FMC and Runtime. This is done as part of enabling Stable Identity in ROM, which can only easily be implemented in terms of a single SVN.

As part of this deprecation, the duties of tracking min-SVN have been moved from FMC to ROM. This is a prelude to having ROM compute the Stable Identity chain based on the firmware's singular SVN.

This does not alter the external API for Caliptra, with the sole exception that what was previously reported as the FMC's SVN is now the value of the (FMC+RT) FW SVN as it was during cold-boot.

- The FMC and Runtime images still each carry an SVN, but this is done only for backwards compatibility in the build tooling, and ROM ensures the two SVNs are equal.
- The FMC and Runtime alias certificates still each carry an SVN.
- The FMC alias certificate's SVN is the value that the firmware's SVN was at cold-boot.
- The Runtime alias certificate's SVN is the value that the firmware's SVN was at the last update-reset.

See additional commentary in chipsalliance#1703.
  • Loading branch information
bluegate010 committed Nov 11, 2024
1 parent ba38c77 commit e757b77
Show file tree
Hide file tree
Showing 62 changed files with 452 additions and 760 deletions.
6 changes: 3 additions & 3 deletions api/src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,9 +769,9 @@ impl Response for FipsVersionResp {}
pub struct FwInfoResp {
pub hdr: MailboxRespHeader,
pub pl0_pauser: u32,
pub runtime_svn: u32,
pub min_runtime_svn: u32,
pub fmc_manifest_svn: u32,
pub fw_svn: u32,
pub min_fw_svn: u32,
pub deprecated_fmc_svn: u32,
pub attestation_disabled: u32,
pub rom_revision: [u8; 20],
pub fmc_revision: [u8; 20],
Expand Down
6 changes: 2 additions & 4 deletions api/types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,7 @@ pub struct Fuses {
pub key_manifest_pk_hash: [u32; 12],
pub key_manifest_pk_hash_mask: U4,
pub owner_pk_hash: [u32; 12],
pub fmc_key_manifest_svn: u32,
pub runtime_svn: [u32; 4],
pub fw_svn: [u32; 4],
pub anti_rollback_disable: bool,
pub idevid_cert_attr: [u32; 24],
pub idevid_manuf_hsm_id: [u32; 4],
Expand All @@ -177,8 +176,7 @@ impl Default for Fuses {
key_manifest_pk_hash: Default::default(),
key_manifest_pk_hash_mask: Default::default(),
owner_pk_hash: Default::default(),
fmc_key_manifest_svn: Default::default(),
runtime_svn: Default::default(),
fw_svn: Default::default(),
anti_rollback_disable: Default::default(),
idevid_cert_attr: Default::default(),
idevid_manuf_hsm_id: Default::default(),
Expand Down
13 changes: 2 additions & 11 deletions builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,9 +439,7 @@ pub fn elf_size(elf_bytes: &[u8]) -> io::Result<u64> {
#[derive(Clone)]
pub struct ImageOptions {
pub fmc_version: u16,
pub fmc_svn: u32,
pub app_version: u32,
pub app_svn: u32,
pub vendor_config: ImageGeneratorVendorConfig,
pub owner_config: Option<ImageGeneratorOwnerConfig>,
pub fw_image_type: FwImageType,
Expand All @@ -450,9 +448,7 @@ impl Default for ImageOptions {
fn default() -> Self {
Self {
fmc_version: Default::default(),
fmc_svn: Default::default(),
app_version: Default::default(),
app_svn: Default::default(),
vendor_config: caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0,
owner_config: Some(caliptra_image_fake_keys::OWNER_CONFIG),
fw_image_type: FwImageType::EccLms,
Expand All @@ -469,13 +465,8 @@ pub fn build_and_sign_image(
let app_elf = build_firmware_elf(app)?;
let gen = ImageGenerator::new(Crypto::default());
let image = gen.generate(&ImageGeneratorConfig {
fmc: ElfExecutable::new(
&fmc_elf,
opts.fmc_version as u32,
opts.fmc_svn,
image_revision()?,
)?,
runtime: ElfExecutable::new(&app_elf, opts.app_version, opts.app_svn, image_revision()?)?,
fmc: ElfExecutable::new(&fmc_elf, opts.fmc_version as u32, image_revision()?)?,
runtime: ElfExecutable::new(&app_elf, opts.app_version, image_revision()?)?,
vendor_config: opts.vendor_config,
owner_config: opts.owner_config,
fw_image_type: opts.fw_image_type,
Expand Down
11 changes: 3 additions & 8 deletions common/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,14 +128,9 @@ impl<'a, 'b> ImageVerificationEnv for &mut FirmwareImageVerificationEnv<'a, 'b>
self.data_vault.fmc_tci().into()
}

// Get Fuse FMC Key Manifest SVN
fn fmc_fuse_svn(&self) -> u32 {
self.soc_ifc.fuse_bank().fmc_fuse_svn()
}

// Get Runtime fuse SVN
fn runtime_fuse_svn(&self) -> u32 {
self.soc_ifc.fuse_bank().runtime_fuse_svn()
// Get firmware fuse SVN
fn fw_fuse_svn(&self) -> u32 {
self.soc_ifc.fuse_bank().fw_fuse_svn()
}

fn iccm_range(&self) -> Range<u32> {
Expand Down
37 changes: 14 additions & 23 deletions drivers/src/data_vault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl From<ColdResetEntry48> for usize {

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ColdResetEntry4 {
FmcSvn = 0,
DeprecatedFmcSvn = 0,
RomColdBootStatus = 1,
FmcEntryPoint = 2,
EccVendorPubKeyIndex = 3,
Expand All @@ -80,7 +80,7 @@ impl TryFrom<u8> for ColdResetEntry4 {
type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> {
match value {
0 => Ok(Self::FmcSvn),
0 => Ok(Self::DeprecatedFmcSvn),
2 => Ok(Self::FmcEntryPoint),
3 => Ok(Self::EccVendorPubKeyIndex),
4 => Ok(Self::LmsVendorPubKeyIndex),
Expand Down Expand Up @@ -132,10 +132,10 @@ impl From<WarmResetEntry48> for usize {

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum WarmResetEntry4 {
RtSvn = 0,
FwSvn = 0,
RtEntryPoint = 1,
ManifestAddr = 2,
RtMinSvn = 3,
FwMinSvn = 3,
RomUpdateResetStatus = 4,
}

Expand All @@ -161,10 +161,10 @@ impl TryFrom<u8> for WarmResetEntry4 {
type Error = ();
fn try_from(original: u8) -> Result<Self, Self::Error> {
match original {
0 => Ok(Self::RtSvn),
0 => Ok(Self::FwSvn),
1 => Ok(Self::RtEntryPoint),
2 => Ok(Self::ManifestAddr),
3 => Ok(Self::RtMinSvn),
3 => Ok(Self::FwMinSvn),
_ => Err(()),
}
}
Expand Down Expand Up @@ -298,15 +298,6 @@ impl DataVault {
self.read_cold_reset_entry48(ColdResetEntry48::OwnerPubKeyHash)
}

/// Get the fmc security version number.
///
/// # Returns
/// * fmc security version number
///
pub fn fmc_svn(&self) -> u32 {
self.read_cold_reset_entry4(ColdResetEntry4::FmcSvn)
}

/// Get the fmc entry.
///
/// # Returns
Expand Down Expand Up @@ -361,22 +352,22 @@ impl DataVault {
self.read_warm_reset_entry48(WarmResetEntry48::RtTci)
}

/// Get the rt security version number.
/// Get the fw security version number.
///
/// # Returns
/// * rt security version number
/// * fw security version number
///
pub fn rt_svn(&self) -> u32 {
self.read_warm_reset_entry4(WarmResetEntry4::RtSvn)
pub fn fw_svn(&self) -> u32 {
self.read_warm_reset_entry4(WarmResetEntry4::FwSvn)
}

/// Get the rt minimum security version number.
/// Get the fw minimum security version number.
///
/// # Returns
/// * rt minimum security version number
/// * fw minimum security version number
///
pub fn rt_min_svn(&self) -> u32 {
self.read_warm_reset_entry4(WarmResetEntry4::RtMinSvn)
pub fn fw_min_svn(&self) -> u32 {
self.read_warm_reset_entry4(WarmResetEntry4::FwMinSvn)
}

/// Get the rt entry.
Expand Down
23 changes: 4 additions & 19 deletions drivers/src/fuse_bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,32 +257,17 @@ impl FuseBank<'_> {
soc_ifc_regs.fuse_anti_rollback_disable().read().dis()
}

/// Get the fmc fuse security version number.
/// Get the firmware fuse security version number.
///
/// # Arguments
/// * None
///
/// # Returns
/// fmc security version number
/// firmware security version number
///
pub fn fmc_fuse_svn(&self) -> u32 {
let soc_ifc_regs = self.soc_ifc.regs();
32 - soc_ifc_regs
.fuse_fmc_key_manifest_svn()
.read()
.leading_zeros()
}

/// Get the runtime fuse security version number.
///
/// # Arguments
/// * None
///
/// # Returns
/// runtime security version number
///
pub fn runtime_fuse_svn(&self) -> u32 {
pub fn fw_fuse_svn(&self) -> u32 {
let soc_ifc_regs = self.soc_ifc.regs();
// The legacy name of this register is `fuse_runtime_svn`
first_set_msbit(&soc_ifc_regs.fuse_runtime_svn().read())
}

Expand Down
16 changes: 8 additions & 8 deletions drivers/src/fuse_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ pub enum FuseLogEntryId {
Invalid = 0,
VendorEccPubKeyIndex = 1, // 4 bytes (From Manifest)
VendorEccPubKeyRevocation = 2, // 4 bytes (From Fuse)
ManifestFmcSvn = 3, // 4 bytes
DeprecatedManifestFmcSvn = 3, // 4 bytes
ManifestReserved0 = 4, // 4 bytes
FuseFmcSvn = 5, // 4 bytes
ManifestRtSvn = 6, // 4 bytes
DeprecatedFuseFmcSvn = 5, // 4 bytes
ManifestFwSvn = 6, // 4 bytes
ManifestReserved1 = 7, // 4 bytes
FuseRtSvn = 8, // 4 bytes
FuseFwSvn = 8, // 4 bytes
VendorLmsPubKeyIndex = 9, // 4 bytes (From Manifest)
VendorLmsPubKeyRevocation = 10, // 4 bytes (From Fuse)
}
Expand All @@ -36,12 +36,12 @@ impl From<u32> for FuseLogEntryId {
match id {
1 => FuseLogEntryId::VendorEccPubKeyIndex,
2 => FuseLogEntryId::VendorEccPubKeyRevocation,
3 => FuseLogEntryId::ManifestFmcSvn,
3 => FuseLogEntryId::DeprecatedManifestFmcSvn,
4 => FuseLogEntryId::ManifestReserved0,
5 => FuseLogEntryId::FuseFmcSvn,
6 => FuseLogEntryId::ManifestRtSvn,
5 => FuseLogEntryId::DeprecatedFuseFmcSvn,
6 => FuseLogEntryId::ManifestFwSvn,
7 => FuseLogEntryId::ManifestReserved1,
8 => FuseLogEntryId::FuseRtSvn,
8 => FuseLogEntryId::FuseFwSvn,
9 => FuseLogEntryId::VendorLmsPubKeyIndex,
10 => FuseLogEntryId::VendorLmsPubKeyRevocation,
_ => FuseLogEntryId::Invalid,
Expand Down
42 changes: 14 additions & 28 deletions drivers/src/hand_off.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ pub struct FirmwareHandoffTable {
/// Index of FMC Certificate Signature S Component in the Data Vault.
pub fmc_cert_sig_s_dv_hdl: HandOffDataHandle,

/// Index of FMC SVN value in the Data Vault
pub fmc_svn_dv_hdl: HandOffDataHandle,
/// Index of FMC SVN value in the Data Vault. Deprecated.
pub deprecated_fmc_svn_dv_hdl: HandOffDataHandle,

/// Index of RT TCI value in the Data Vault.
pub rt_tci_dv_hdl: HandOffDataHandle,
Expand All @@ -235,11 +235,11 @@ pub struct FirmwareHandoffTable {
/// Index of RT Private Alias Key in the Key Vault.
pub rt_priv_key_kv_hdl: HandOffDataHandle,

/// Index of RT SVN value in the Data Vault
pub rt_svn_dv_hdl: HandOffDataHandle,
/// Index of FW SVN value in the Data Vault
pub fw_svn_dv_hdl: HandOffDataHandle,

/// Index of RT Min SVN value in the Data Vault
pub rt_min_svn_dv_hdl: HandOffDataHandle,
/// Index of FW Min SVN value in the Data Vault
pub fw_min_svn_dv_hdl: HandOffDataHandle,

/// LdevId TBS Address
pub ldevid_tbs_addr: u32,
Expand Down Expand Up @@ -292,20 +292,14 @@ pub struct FirmwareHandoffTable {
/// RtAlias TBS Size.
pub rtalias_tbs_size: u16,

/// Maximum value RT FW SVN can take.
#[cfg(any(feature = "fmc", feature = "runtime"))]
pub rt_hash_chain_max_svn: u16,
/// Maximum value FW SVN can take.
pub fw_hash_chain_max_svn: u16,

/// Index of RT hash chain value in the Key Vault.
#[cfg(any(feature = "fmc", feature = "runtime"))]
pub rt_hash_chain_kv_hdl: HandOffDataHandle,

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

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

impl Default for FirmwareHandoffTable {
Expand All @@ -324,12 +318,12 @@ impl Default for FirmwareHandoffTable {
fmc_pub_key_y_dv_hdl: FHT_INVALID_HANDLE,
fmc_cert_sig_r_dv_hdl: FHT_INVALID_HANDLE,
fmc_cert_sig_s_dv_hdl: FHT_INVALID_HANDLE,
fmc_svn_dv_hdl: FHT_INVALID_HANDLE,
deprecated_fmc_svn_dv_hdl: FHT_INVALID_HANDLE,
rt_tci_dv_hdl: FHT_INVALID_HANDLE,
rt_cdi_kv_hdl: FHT_INVALID_HANDLE,
rt_priv_key_kv_hdl: FHT_INVALID_HANDLE,
rt_svn_dv_hdl: FHT_INVALID_HANDLE,
rt_min_svn_dv_hdl: FHT_INVALID_HANDLE,
fw_svn_dv_hdl: FHT_INVALID_HANDLE,
fw_min_svn_dv_hdl: FHT_INVALID_HANDLE,
ldevid_tbs_addr: 0,
fmcalias_tbs_addr: 0,
ldevid_tbs_size: 0,
Expand All @@ -347,16 +341,9 @@ impl Default for FirmwareHandoffTable {
idev_dice_mldsa_pub_key_load_addr: 0,
rom_info_addr: RomAddr::new(FHT_INVALID_ADDRESS),
rtalias_tbs_size: 0,

#[cfg(any(feature = "fmc", feature = "runtime"))]
rt_hash_chain_max_svn: 0,
#[cfg(any(feature = "fmc", feature = "runtime"))]
fw_hash_chain_max_svn: 0,
rt_hash_chain_kv_hdl: HandOffDataHandle(0),
#[cfg(any(feature = "fmc", feature = "runtime"))]
reserved: [0u8; 1632],

#[cfg(not(any(feature = "fmc", feature = "runtime")))]
reserved: [0u8; 1638],
}
}
}
Expand Down Expand Up @@ -399,15 +386,14 @@ pub fn print_fht(fht: &FirmwareHandoffTable) {
"FMC Certificate Signature S DV Handle: 0x{:08x}",
fht.fmc_cert_sig_s_dv_hdl.0
);
crate::cprintln!("FMC SVN DV Handle: 0x{:08x}", fht.fmc_svn_dv_hdl.0);
crate::cprintln!("RT TCI DV Handle: 0x{:08x}", fht.rt_tci_dv_hdl.0);
crate::cprintln!("RT CDI KV Handle: 0x{:08x}", fht.rt_cdi_kv_hdl.0);
crate::cprintln!(
"RT Private Key KV Handle: 0x{:08x}",
fht.rt_priv_key_kv_hdl.0
);
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!("FW SVN DV Handle: 0x{:08x}", fht.fw_svn_dv_hdl.0);
crate::cprintln!("FW Min SVN DV Handle: 0x{:08x}", fht.fw_min_svn_dv_hdl.0);

crate::cprintln!(
"IdevId MLDSA Public Key Address: 0x{:08x}",
Expand Down
12 changes: 6 additions & 6 deletions error/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,16 @@
| Image Verifier | Verifier | FmcLoadAddrUnaligned |0x000B0022 |
| Image Verifier | Verifier | FmcEntryPointInvalid |0x000B0023 |
| Image Verifier | Verifier | FmcEntryPointUnaligned |0x000B0024 |
| Image Verifier | Verifier | FmcSvnGreaterThanMaxSupported |0x000B0025 |
| Image Verifier | Verifier | FmcSvnLessThanMinSupported |0x000B0026 |
| Image Verifier | Verifier | FmcSvnLessThanFuse |0x000B0027 |
| Image Verifier | Verifier | (Deprecated) FmcSvnGreaterThanMaxSupported |0x000B0025 |
| Image Verifier | Verifier | (Deprecated) FmcSvnLessThanMinSupported |0x000B0026 |
| Image Verifier | Verifier | (Deprecated) FmcSvnLessThanFuse |0x000B0027 |
| Image Verifier | Verifier | RuntimeLoadAddrInvalid |0x000B0028 |
| Image Verifier | Verifier | RuntimeLoadAddrUnaligned |0x000B0029 |
| Image Verifier | Verifier | RuntimeEntryPointInvalid |0x000B002A |
| Image Verifier | Verifier | RuntimeEntryPointUnaligned |0x000B002B |
| Image Verifier | Verifier | RuntimeSvnGreaterThanMaxSupported |0x000B002C |
| Image Verifier | Verifier | RuntimeSvnLessThanMinSupported |0x000B002D |
| Image Verifier | Verifier | RuntimeSvnLessThanFuse |0x000B002E |
| Image Verifier | Verifier | FirmwareSvnGreaterThanMaxSupported |0x000B002C |
| Image Verifier | Verifier | (Deprecated) FirmwareSvnLessThanMinSupported |0x000B002D |
| Image Verifier | Verifier | FirmwareSvnLessThanFuse |0x000B002E |
| Driver | LMS | InvalidLmsAlgorithmType |0x000C0001 |
| Driver | LMS | InvalidLmotsAlgorithmType |0x000C0002 |
| Driver | LMS | InvalidWinternitzParameter |0x000C0003 |
Expand Down
Loading

0 comments on commit e757b77

Please sign in to comment.