From e757b772871cabc66dcfc73fa1503295f5cc0b1e Mon Sep 17 00:00:00 2001 From: Jeff Andersen Date: Sat, 2 Nov 2024 00:07:32 -0400 Subject: [PATCH] Unify separate FMC and RT SVNs into a single firmware SVN. 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 https://github.com/chipsalliance/caliptra-sw/issues/1703. --- api/src/mailbox.rs | 6 +- api/types/src/lib.rs | 6 +- builder/src/lib.rs | 13 +-- common/src/verifier.rs | 11 +- drivers/src/data_vault.rs | 37 +++---- drivers/src/fuse_bank.rs | 23 +--- drivers/src/fuse_log.rs | 16 +-- drivers/src/hand_off.rs | 42 +++----- error/README.md | 12 +-- error/src/lib.rs | 25 +++-- fmc/Makefile | 3 +- fmc/README.md | 28 +++-- fmc/src/flow/rt_alias.rs | 28 +---- fmc/src/hand_off.rs | 64 +---------- .../c-binding/examples/api/caliptra_api.c | 4 +- .../c-binding/examples/api/caliptra_api.h | 3 +- hw-model/src/lib.rs | 6 +- hw-model/types/src/lib.rs | 4 +- image/app/src/create/mod.rs | 17 ++- image/app/src/main.rs | 7 +- image/elf/src/lib.rs | 23 +--- image/fake-keys/src/lib.rs | 1 + image/gen/src/generator.rs | 11 +- image/gen/src/lib.rs | 5 +- image/verify/fuzz/src/fuzz_target_common.rs | 8 -- image/verify/src/lib.rs | 30 +++--- image/verify/src/verifier.rs | 101 +++++++----------- libcaliptra/inc/caliptra_types.h | 9 +- libcaliptra/src/caliptra_api.c | 3 +- rom/dev/Makefile | 3 +- rom/dev/README.md | 24 ++--- rom/dev/doc/error-attribution.md | 19 ++-- rom/dev/doc/test-coverage/test-coverage.md | 8 +- rom/dev/src/fht.rs | 24 ++--- rom/dev/src/flow/cold_reset/fmc_alias.rs | 8 +- rom/dev/src/flow/cold_reset/fw_processor.rs | 37 +++---- rom/dev/src/flow/fake.rs | 11 +- rom/dev/src/flow/update_reset.rs | 6 +- rom/dev/src/lock.rs | 12 ++- rom/dev/src/pcr.rs | 4 +- .../test_fmcalias_derivation.rs | 79 ++++++++------ .../test_image_validation.rs | 93 +++------------- .../rom_integration_tests/test_warm_reset.rs | 8 +- rom/dev/tools/test-fmc/src/main.rs | 12 +-- runtime/README.md | 6 +- runtime/src/handoff.rs | 24 ++--- runtime/src/info.rs | 12 +-- .../runtime_integration_tests/test_info.rs | 28 ++--- .../test_pauser_privilege_levels.rs | 10 +- .../test_warm_reset.rs | 15 +-- test/src/derive.rs | 12 +-- .../fake_collateral_boot_test.rs | 11 +- .../caliptra_integration_tests/jtag_test.rs | 7 +- .../caliptra_integration_tests/smoke_test.rs | 23 ++-- .../caliptra_integration_tests/warm_reset.rs | 15 +-- test/tests/fips_test_suite/README.md | 2 +- test/tests/fips_test_suite/fw_load.rs | 81 +++----------- x509/build/cert.rs | 6 +- x509/build/fmc_alias_cert_tbs.rs | 24 ++--- x509/build/rt_alias_cert_tbs.rs | 12 +-- x509/src/fmc_alias_cert.rs | 22 ++-- x509/src/rt_alias_cert.rs | 8 +- 62 files changed, 452 insertions(+), 760 deletions(-) diff --git a/api/src/mailbox.rs b/api/src/mailbox.rs index 46508b0d83..de8a165d27 100644 --- a/api/src/mailbox.rs +++ b/api/src/mailbox.rs @@ -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], diff --git a/api/types/src/lib.rs b/api/types/src/lib.rs index 10940e7bd9..fe1b77e88f 100644 --- a/api/types/src/lib.rs +++ b/api/types/src/lib.rs @@ -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], @@ -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(), diff --git a/builder/src/lib.rs b/builder/src/lib.rs index e9edb0a0b7..2fd19da442 100644 --- a/builder/src/lib.rs +++ b/builder/src/lib.rs @@ -439,9 +439,7 @@ pub fn elf_size(elf_bytes: &[u8]) -> io::Result { #[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, pub fw_image_type: FwImageType, @@ -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, @@ -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, diff --git a/common/src/verifier.rs b/common/src/verifier.rs index 35b7b2ef7a..721ea01799 100644 --- a/common/src/verifier.rs +++ b/common/src/verifier.rs @@ -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 { diff --git a/drivers/src/data_vault.rs b/drivers/src/data_vault.rs index 53fde23469..a78bd06d89 100644 --- a/drivers/src/data_vault.rs +++ b/drivers/src/data_vault.rs @@ -69,7 +69,7 @@ impl From for usize { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ColdResetEntry4 { - FmcSvn = 0, + DeprecatedFmcSvn = 0, RomColdBootStatus = 1, FmcEntryPoint = 2, EccVendorPubKeyIndex = 3, @@ -80,7 +80,7 @@ impl TryFrom for ColdResetEntry4 { type Error = (); fn try_from(value: u8) -> Result { match value { - 0 => Ok(Self::FmcSvn), + 0 => Ok(Self::DeprecatedFmcSvn), 2 => Ok(Self::FmcEntryPoint), 3 => Ok(Self::EccVendorPubKeyIndex), 4 => Ok(Self::LmsVendorPubKeyIndex), @@ -132,10 +132,10 @@ impl From 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, } @@ -161,10 +161,10 @@ impl TryFrom for WarmResetEntry4 { type Error = (); fn try_from(original: u8) -> Result { 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(()), } } @@ -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 @@ -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. diff --git a/drivers/src/fuse_bank.rs b/drivers/src/fuse_bank.rs index 9b060ed41c..196edf8b8c 100644 --- a/drivers/src/fuse_bank.rs +++ b/drivers/src/fuse_bank.rs @@ -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()) } diff --git a/drivers/src/fuse_log.rs b/drivers/src/fuse_log.rs index 1e09f6f321..4fda163ad8 100644 --- a/drivers/src/fuse_log.rs +++ b/drivers/src/fuse_log.rs @@ -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) } @@ -36,12 +36,12 @@ impl From 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, diff --git a/drivers/src/hand_off.rs b/drivers/src/hand_off.rs index 96e813fc47..2693b8341f 100644 --- a/drivers/src/hand_off.rs +++ b/drivers/src/hand_off.rs @@ -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, @@ -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, @@ -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 { @@ -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, @@ -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], } } } @@ -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}", diff --git a/error/README.md b/error/README.md index 2d91e4a1fa..6c594d6dcc 100644 --- a/error/README.md +++ b/error/README.md @@ -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 | diff --git a/error/src/lib.rs b/error/src/lib.rs index c0dae71998..2a5c62eaf0 100644 --- a/error/src/lib.rs +++ b/error/src/lib.rs @@ -215,12 +215,9 @@ impl CaliptraError { CaliptraError::new_const(0x000b0023); pub const IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_UNALIGNED: CaliptraError = CaliptraError::new_const(0x000b0024); - pub const IMAGE_VERIFIER_ERR_FMC_SVN_GREATER_THAN_MAX_SUPPORTED: CaliptraError = - CaliptraError::new_const(0x000b0025); - pub const IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_MIN_SUPPORTED: CaliptraError = - CaliptraError::new_const(0x000b0026); - pub const IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE: CaliptraError = - CaliptraError::new_const(0x000b0027); + // 0x000b0025 was IMAGE_VERIFIER_ERR_FMC_SVN_GREATER_THAN_MAX_SUPPORTED + // 0x000b0026 was IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_MIN_SUPPORTED + // 0x000b0027 was IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE pub const IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID: CaliptraError = CaliptraError::new_const(0x000b0028); pub const IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_UNALIGNED: CaliptraError = @@ -229,11 +226,10 @@ impl CaliptraError { CaliptraError::new_const(0x000b002a); pub const IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_UNALIGNED: CaliptraError = CaliptraError::new_const(0x000b002b); - pub const IMAGE_VERIFIER_ERR_RUNTIME_SVN_GREATER_THAN_MAX_SUPPORTED: CaliptraError = + pub const IMAGE_VERIFIER_ERR_FIRMWARE_SVN_GREATER_THAN_MAX_SUPPORTED: CaliptraError = CaliptraError::new_const(0x000b002c); - pub const IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_MIN_SUPPORTED: CaliptraError = - CaliptraError::new_const(0x000b002d); - pub const IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE: CaliptraError = + // 0x000b002d was IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_MIN_SUPPORTED + pub const IMAGE_VERIFIER_ERR_FIRMWARE_SVN_LESS_THAN_FUSE: CaliptraError = CaliptraError::new_const(0x000b002e); pub const IMAGE_VERIFIER_ERR_IMAGE_LEN_MORE_THAN_BUNDLE_SIZE: CaliptraError = CaliptraError::new_const(0x000b002f); @@ -289,6 +285,8 @@ impl CaliptraError { CaliptraError::new_const(0x000b004c); pub const IMAGE_VERIFIER_ERR_LMS_KEY_DESCRIPTOR_INVALID_HASH_COUNT: CaliptraError = CaliptraError::new_const(0x000b004d); + pub const IMAGE_VERIFIER_ERR_RUNTIME_FMC_SVNS_UNEQUAL: CaliptraError = + CaliptraError::new_const(0x000b004e); /// Driver Error: LMS pub const DRIVER_LMS_INVALID_LMS_ALGO_TYPE: CaliptraError = @@ -411,10 +409,11 @@ impl CaliptraError { CaliptraError::new_const(0x000E002A); pub const RUNTIME_CMD_BUSY_DURING_WARM_RESET: CaliptraError = CaliptraError::new_const(0x000E002B); - pub const RUNTIME_RT_SVN_HANDOFF_FAILED: CaliptraError = CaliptraError::new_const(0x000E002C); - pub const RUNTIME_RT_MIN_SVN_HANDOFF_FAILED: CaliptraError = + pub const RUNTIME_FW_SVN_HANDOFF_FAILED: CaliptraError = CaliptraError::new_const(0x000E002C); + pub const RUNTIME_FW_MIN_SVN_HANDOFF_FAILED: CaliptraError = CaliptraError::new_const(0x000E002D); - pub const RUNTIME_FMC_SVN_HANDOFF_FAILED: CaliptraError = CaliptraError::new_const(0x000E002E); + pub const RUNTIME_DEPRECATED_FMC_SVN_HANDOFF_FAILED: CaliptraError = + CaliptraError::new_const(0x000E002E); pub const RUNTIME_CONTEXT_HAS_TAG_VALIDATION_FAILED: CaliptraError = CaliptraError::new_const(0x000E002F); pub const RUNTIME_LDEV_ID_CERT_TOO_BIG: CaliptraError = CaliptraError::new_const(0x000E0030); diff --git a/fmc/Makefile b/fmc/Makefile index 4672911301..ba55ab8d68 100644 --- a/fmc/Makefile +++ b/fmc/Makefile @@ -73,12 +73,11 @@ build-fw-image: gen-certs build-emu build-test-rt --lms-pk-idx 3 \ --fmc $(TARGET_DIR)/caliptra-fmc \ --fmc-version 0 \ - --fmc-svn 0 \ --fmc-rev $(GIT_REV) \ --rt $(TARGET_DIR)/caliptra-runtime \ --rt-version 0 \ - --rt-svn 0 \ --rt-rev $(GIT_REV) \ + --fw-svn 0 \ --out $(TARGET_DIR)/caliptra-rom-test-fw \ bloat: build diff --git a/fmc/README.md b/fmc/README.md index ece00369f9..5567830da4 100644 --- a/fmc/README.md +++ b/fmc/README.md @@ -114,13 +114,13 @@ fields may not be changed or removed). Table revisions with different Major Vers | fmc_cert_sig_ecdsa_r_dv_hdl | 4 | ROM | Handle of FMC Certificate ECDSA Signature R Component in the DCCM datavault. | | fmc_cert_sig_ecdsa_s_dv_hdl | 4 | ROM | Handle of FMC Certificate ECDSA Signature S Component in the DCCM datavault. | | fmc_cert_sig_mldsa_dv_hdl | 4 | ROM | Handle of FMC Certificate MLDSA Signature in the DCCM datavault. | -| fmc_svn_dv_hdl | 4 | ROM | Handle of FMC SVN value in the DCCM datavault. | +| deprecated_fmc_svn_dv_hdl | 4 | ROM | Handle of FMC SVN value in the DCCM datavault. Deprecated. | | rt_tci_dv_hdl | 4 | ROM | Handle of RT TCI value in the DCCM datavault. | | rt_cdi_kv_hdl | 4 | FMC | Handle of RT CDI value in the Key Vault. | | rt_priv_key_ecdsa_kv_hdl | 4 | FMC | Handle of RT Alias ECDSA Private Key in the Key Vault. | | rt_keygen_seed_mldsa_kv_hdl | 4 | FMC | Handle of RT Alias MLDSA Key Generation Seed in the Key Vault. | -| rt_svn_dv_hdl | 4 | FMC | Handle of RT SVN value in the DCCM datavault. | -| rt_min_svn_dv_hdl | 4 | FMC | Handle of Min RT SVN value in the DCCM datavault. | +| fw_svn_dv_hdl | 4 | FMC | Handle of FW SVN value in the DCCM datavault. | +| fw_min_svn_dv_hdl | 4 | FMC | Handle of Min FW SVN value in the DCCM datavault. | | ldevid_tbs_ecdsa_addr | 4 | ROM | Local Device ID ECDSA TBS Address. | | fmcalias_tbs_ecdsa_addr | 4 | ROM | FMC Alias TBS ECDSA Address. | | ldevid_tbs_mldsa_addr | 4 | ROM | Local Device ID MLDSA TBS Address. | @@ -212,10 +212,6 @@ These fields provide the Handle into the DCCM datavault where the ECDSA Signatur This field provides the Handle into the DCCM datavault where the MLDSA SignatureFMC is stored. -### fmc_svn_dv_hdl - -This field provides the Handle into the DCCM datavault where the SVNFMC is stored. - ### rt_tci_dv_hdl This field provides the Handle into the DCCM datavault where the TCIRT is stored. TCIRT is a SHA-384 Hash of the RT FW Module. @@ -232,13 +228,13 @@ This field provides the Handle into the Key Vault where the ECDSA PrivateKeyRT is stored. -### rt_svn_dv_hdl +### fw_dv_hdl -This field provides the Handle into the DCCM datavault where the SVNRT is stored. +This field provides the Handle into the DCCM datavault where the firmware SVN is stored. -### rt_min_svn_dv_hdl +### fw_min_svn_dv_hdl -This field provides the Handle into the DCCM datavault where the Min-SVNRT is stored. Upon cold-boot this is set to SVNRT. On subsequent boots this is set to MIN(SVNRT, Min-SVNRT). +This field provides the Handle into the DCCM datavault where the firmware Min-SVN is stored. Upon cold-boot this is set to the firmware SVN. On subsequent boots this is set to MIN(firmware SVN, firmware Min-SVN). ### ldevid_tbs_ecdsa_addr @@ -336,10 +332,10 @@ This field provides the size of the *To Be Signed* portion of the Runtime Alias This field provides the size of the *To Be Signed* portion of the Runtime Alias MLDSA certificate. -### rt_hash_chain_max_svn +### fw_hash_chain_max_svn -This field informs firmware of the maximum RT SVN, which value was used -to determine the length of RT FW's hash chain. +This field informs firmware of the maximum FW SVN, which value was used +to determine the length of FW's hash chain. ### rt_hash_chain_kv_hdl @@ -410,7 +406,7 @@ The following list of steps are to be performed by FMC on each boot when ROM jum | 🔒Alias FMC Cert Signature S | | 🔒Alias FMC Cert MLDSA Signature | | 🔒FMC Digest | -| 🔒FMC SVN | +| 🔒FW SVN | | 🔒Owner PK Hash | | 🔒Manufacturer Public Key Index | @@ -512,7 +508,7 @@ sequenceDiagram | 🔒Alias FMC Cert ECDSA Signature S | | 🔒Alias FMC Cert MLDSA Signature | | 🔒FMC Digest | -| 🔒FMC SVN | +| 🔒FW SVN | | 🔒Owner PK Hash | | 🔒Manufacturer Public Key Index | diff --git a/fmc/src/flow/rt_alias.rs b/fmc/src/flow/rt_alias.rs index 404925dde4..8da8335e0e 100644 --- a/fmc/src/flow/rt_alias.rs +++ b/fmc/src/flow/rt_alias.rs @@ -112,9 +112,6 @@ impl RtAliasLayer { .set_pcr_lock(caliptra_common::RT_FW_JOURNEY_PCR); cprintln!("[alias rt] Lock RT PCRs Done"); - cprintln!("[alias rt] Populate DV"); - Self::populate_dv(env)?; - cprintln!("[alias rt] Populate DV Done"); report_boot_status(crate::FmcBootStatus::RtMeasurementComplete as u32); // Retrieve Dice Input Layer from Hand Off and Derive Key @@ -184,27 +181,6 @@ impl RtAliasLayer { } } - /// Populate Data Vault - /// - /// # Arguments - /// - /// * `env` - FMC Environment - /// * `hand_off` - HandOff - #[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)] - pub fn populate_dv(env: &mut FmcEnv) -> CaliptraResult<()> { - let rt_svn = HandOff::rt_svn(env); - let reset_reason = env.soc_ifc.reset_reason(); - - let rt_min_svn = if reset_reason == ResetReason::ColdReset { - cfi_assert_eq(reset_reason, ResetReason::ColdReset); - rt_svn - } else { - core::cmp::min(rt_svn, HandOff::rt_min_svn(env)) - }; - - HandOff::set_and_lock_rt_min_svn(env, rt_min_svn) - } - fn get_cert_validity_info( manifest: &caliptra_image_types::ImageManifest, ) -> (NotBefore, NotAfter) { @@ -306,7 +282,7 @@ impl RtAliasLayer { let serial_number = &X509::cert_sn(env, pub_key)?; let rt_tci: [u8; 48] = HandOff::rt_tci(env).into(); - let rt_svn = HandOff::rt_svn(env) as u8; + let fw_svn = HandOff::fw_svn(env) as u8; // Certificate `To Be Signed` Parameters let params = RtAliasCertTbsParams { @@ -320,7 +296,7 @@ impl RtAliasLayer { public_key: &pub_key.to_der(), not_before, not_after, - tcb_info_rt_svn: &rt_svn.to_be_bytes(), + tcb_info_fw_svn: &fw_svn.to_be_bytes(), tcb_info_rt_tci: &rt_tci, // Are there any fields missing? }; diff --git a/fmc/src/hand_off.rs b/fmc/src/hand_off.rs index 6033fcdc1a..de74a7746c 100644 --- a/fmc/src/hand_off.rs +++ b/fmc/src/hand_off.rs @@ -175,14 +175,14 @@ impl HandOff { } } - /// Retrieve runtime SVN. - pub fn rt_svn(env: &FmcEnv) -> u32 { + /// Retrieve firmware SVN. + pub fn fw_svn(env: &FmcEnv) -> u32 { let ds: DataStore = Self::fht(env) - .rt_svn_dv_hdl + .fw_svn_dv_hdl .try_into() .unwrap_or_else(|e: CaliptraError| { - cprintln!("[fht] Invalid RT SVN handle"); + cprintln!("[fht] Invalid FW SVN handle"); handle_fatal_error(e.into()) }); @@ -196,50 +196,6 @@ impl HandOff { } } - /// Retrieve runtime minimum SVN. - pub fn rt_min_svn(env: &FmcEnv) -> u32 { - let ds: DataStore = - Self::fht(env) - .rt_min_svn_dv_hdl - .try_into() - .unwrap_or_else(|e: CaliptraError| { - cprintln!("[fht] Invalid RT Min SVN handle"); - handle_fatal_error(e.into()) - }); - - // The data store must be a warm reset entry. - match ds { - DataVaultNonSticky4(dv_entry) => env.data_vault.read_warm_reset_entry4(dv_entry), - _ => { - handle_fatal_error(CaliptraError::FMC_HANDOFF_INVALID_PARAM.into()); - } - } - } - - #[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)] - pub fn set_and_lock_rt_min_svn(env: &mut FmcEnv, min_svn: u32) -> CaliptraResult<()> { - let ds: DataStore = - Self::fht(env) - .rt_min_svn_dv_hdl - .try_into() - .unwrap_or_else(|e: CaliptraError| { - cprintln!("[fht] Invalid RT Min SVN handle"); - handle_fatal_error(e.into()) - }); - - // The data store must be a warm reset entry. - match ds { - DataVaultNonSticky4(dv_entry) => { - env.data_vault.write_warm_reset_entry4(dv_entry, min_svn); - env.data_vault.lock_warm_reset_entry4(dv_entry); - Ok(()) - } - _ => { - handle_fatal_error(CaliptraError::FMC_HANDOFF_INVALID_PARAM.into()); - } - } - } - /// Store runtime Dice Signature #[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)] pub fn set_rt_dice_signature(env: &mut FmcEnv, sig: &Ecc384Signature) { @@ -270,18 +226,6 @@ impl HandOff { } } - #[allow(dead_code)] - #[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)] - pub fn set_rt_hash_chain_max_svn(env: &mut FmcEnv, max_svn: u16) { - Self::fht_mut(env).rt_hash_chain_max_svn = max_svn; - } - - #[allow(dead_code)] - #[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)] - pub fn set_rt_hash_chain_kv_hdl(env: &mut FmcEnv, kv_slot: KeyId) { - Self::fht_mut(env).rt_hash_chain_kv_hdl = Self::key_id_to_handle(kv_slot) - } - /// The FMC CDI is stored in a 32-bit DataVault sticky register. fn key_id_to_handle(key_id: KeyId) -> HandOffDataHandle { HandOffDataHandle(((Vault::KeyVault as u32) << 12) | key_id as u32) diff --git a/hw-model/c-binding/examples/api/caliptra_api.c b/hw-model/c-binding/examples/api/caliptra_api.c index 45d9c02189..055f8fc93e 100644 --- a/hw-model/c-binding/examples/api/caliptra_api.c +++ b/hw-model/c-binding/examples/api/caliptra_api.c @@ -24,8 +24,8 @@ int caliptra_init_fuses(struct caliptra_model *model, struct caliptra_fuses *fus caliptra_fuse_array_write(model, GENERIC_AND_FUSE_REG_FUSE_KEY_MANIFEST_PK_HASH_0, fuses->key_manifest_pk_hash, CALIPTRA_ARRAY_SIZE(fuses->key_manifest_pk_hash)); caliptra_fuse_write(model, GENERIC_AND_FUSE_REG_FUSE_KEY_MANIFEST_PK_HASH_MASK, fuses->key_manifest_pk_hash_mask); caliptra_fuse_array_write(model, GENERIC_AND_FUSE_REG_FUSE_OWNER_PK_HASH_0, fuses->owner_pk_hash, CALIPTRA_ARRAY_SIZE(fuses->owner_pk_hash)); - caliptra_fuse_write(model, GENERIC_AND_FUSE_REG_FUSE_FMC_KEY_MANIFEST_SVN, fuses->fmc_key_manifest_svn); - caliptra_fuse_array_write(model, GENERIC_AND_FUSE_REG_FUSE_FMC_KEY_MANIFEST_SVN, fuses->runtime_svn, CALIPTRA_ARRAY_SIZE(fuses->runtime_svn)); + caliptra_fuse_write(model, GENERIC_AND_FUSE_REG_FUSE_FMC_KEY_MANIFEST_SVN, 0); // FMC SVN deprecated + caliptra_fuse_array_write(model, GENERIC_AND_FUSE_REG_FUSE_RUNTIME_SVN_0, fuses->firmware_svn, CALIPTRA_ARRAY_SIZE(fuses->firmware_svn)); caliptra_fuse_write(model, GENERIC_AND_FUSE_REG_FUSE_ANTI_ROLLBACK_DISABLE, (uint32_t)fuses->anti_rollback_disable); caliptra_fuse_array_write(model, GENERIC_AND_FUSE_REG_FUSE_IDEVID_CERT_ATTR_0, fuses->idevid_cert_attr, CALIPTRA_ARRAY_SIZE(fuses->idevid_cert_attr)); caliptra_fuse_array_write(model, GENERIC_AND_FUSE_REG_FUSE_IDEVID_MANUF_HSM_ID_0, fuses->idevid_manuf_hsm_id, CALIPTRA_ARRAY_SIZE(fuses->idevid_manuf_hsm_id)); diff --git a/hw-model/c-binding/examples/api/caliptra_api.h b/hw-model/c-binding/examples/api/caliptra_api.h index 1ba241183f..51d22b184e 100644 --- a/hw-model/c-binding/examples/api/caliptra_api.h +++ b/hw-model/c-binding/examples/api/caliptra_api.h @@ -19,8 +19,7 @@ struct caliptra_fuses { uint32_t key_manifest_pk_hash_mask : 4; uint32_t rsvd : 28; uint32_t owner_pk_hash[12]; - uint32_t fmc_key_manifest_svn; - uint32_t runtime_svn[4]; + uint32_t firmware_svn[4]; bool anti_rollback_disable; uint32_t idevid_cert_attr[24]; uint32_t idevid_manuf_hsm_id[4]; diff --git a/hw-model/src/lib.rs b/hw-model/src/lib.rs index 137df6f207..9162de9085 100644 --- a/hw-model/src/lib.rs +++ b/hw-model/src/lib.rs @@ -633,10 +633,8 @@ pub trait HwModel: SocManager { self.soc_ifc() .fuse_owner_pk_hash() .write(&fuses.owner_pk_hash); - self.soc_ifc() - .fuse_fmc_key_manifest_svn() - .write(|_| fuses.fmc_key_manifest_svn); - self.soc_ifc().fuse_runtime_svn().write(&fuses.runtime_svn); + self.soc_ifc().fuse_fmc_key_manifest_svn().write(|_| 0); // FMC SVN deprecated + self.soc_ifc().fuse_runtime_svn().write(&fuses.fw_svn); self.soc_ifc() .fuse_anti_rollback_disable() .write(|w| w.dis(fuses.anti_rollback_disable)); diff --git a/hw-model/types/src/lib.rs b/hw-model/types/src/lib.rs index 244aff9be3..0fc7b9a344 100644 --- a/hw-model/types/src/lib.rs +++ b/hw-model/types/src/lib.rs @@ -121,8 +121,8 @@ impl std::fmt::Debug for FusesWrapper { &self.0.key_manifest_pk_hash_mask, ) .field("owner_pk_hash", &HexSlice(&self.0.owner_pk_hash)) - .field("fmc_key_manifest_svn", &self.0.fmc_key_manifest_svn) - .field("runtime_svn", &HexSlice(&self.0.runtime_svn)) + .field("deprecated_fmc_svn", &self.0.fw_svn) + .field("firmware_svn", &HexSlice(&self.0.fw_svn)) .field("anti_rollback_disable", &self.0.anti_rollback_disable) .field("idevid_cert_attr", &HexSlice(&self.0.idevid_cert_attr)) .field( diff --git a/image/app/src/create/mod.rs b/image/app/src/create/mod.rs index 6c660a4505..76b57d217f 100644 --- a/image/app/src/create/mod.rs +++ b/image/app/src/create/mod.rs @@ -90,10 +90,6 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { .get_one::("fmc-version") .with_context(|| "fmc-version arg not specified")?; - let fmc_svn: &u32 = args - .get_one::("fmc-svn") - .with_context(|| "fmc-svn arg not specified")?; - let fmc_rev: &String = args .get_one::("fmc-rev") .with_context(|| "fmc-rev arg not specified")?; @@ -106,14 +102,14 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { .get_one::("rt-version") .with_context(|| "rt-version arg not specified")?; - let runtime_svn: &u32 = args - .get_one::("rt-svn") - .with_context(|| "rt-svn arg not specified")?; - let runtime_rev: &String = args .get_one::("rt-rev") .with_context(|| "rt-rev arg not specified")?; + let firmware_svn: &u32 = args + .get_one::("fw-svn") + .with_context(|| "fw-svn arg not specified")?; + let ecc_key_idx: &u32 = args .get_one::("ecc-pk-idx") .with_context(|| "ecc-pk-idx arg not specified")?; @@ -158,7 +154,6 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { let fmc = ElfExecutable::open( fmc_path, *fmc_version, - *fmc_svn, fmc_rev[..IMAGE_REVISION_BYTE_SIZE].try_into()?, )?; @@ -166,7 +161,6 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { let runtime = ElfExecutable::open( runtime_path, *runtime_version, - *runtime_svn, runtime_rev[..IMAGE_REVISION_BYTE_SIZE].try_into()?, )?; @@ -182,6 +176,7 @@ pub(crate) fn run_cmd(args: &ArgMatches) -> anyhow::Result<()> { *lms_key_idx, mfg_from_date, mfg_to_date, + *firmware_svn, )?, owner_config: owner_config(config_dir, &config.owner, own_from_date, own_to_date)?, fmc, @@ -217,6 +212,7 @@ fn vendor_config( lms_key_idx: u32, from_date: [u8; 15], to_date: [u8; 15], + fw_svn: u32, ) -> anyhow::Result { let mut gen_config = ImageGeneratorVendorConfig::default(); @@ -279,6 +275,7 @@ fn vendor_config( gen_config.not_after = to_date; gen_config.ecc_key_count = ecc_key_count; gen_config.lms_key_count = lms_key_count; + gen_config.fw_svn = fw_svn; Ok(gen_config) } diff --git a/image/app/src/main.rs b/image/app/src/main.rs index 189d4b06b5..39de7158e8 100644 --- a/image/app/src/main.rs +++ b/image/app/src/main.rs @@ -56,11 +56,6 @@ fn main() { .required(true) .value_parser(value_parser!(u32)), ) - .arg( - arg!(--"fmc-svn" "FMC Security Version Number") - .required(true) - .value_parser(value_parser!(u32)), - ) .arg( arg!(--"rt" "Runtime ELF binary") .required(true) @@ -77,7 +72,7 @@ fn main() { .value_parser(value_parser!(u32)), ) .arg( - arg!(--"rt-svn" "Runtime Security Version Number") + arg!(--"fw-svn" "Firmware Security Version Number") .required(true) .value_parser(value_parser!(u32)), ) diff --git a/image/elf/src/lib.rs b/image/elf/src/lib.rs index 0dfb64b83d..ef4db31c02 100644 --- a/image/elf/src/lib.rs +++ b/image/elf/src/lib.rs @@ -24,7 +24,6 @@ use std::path::PathBuf; #[derive(Default)] pub struct ElfExecutable { version: u32, - svn: u32, rev: ImageRevision, load_addr: u32, entry_point: u32, @@ -50,22 +49,12 @@ fn load_into_image( } impl ElfExecutable { - pub fn open( - path: &PathBuf, - version: u32, - svn: u32, - rev: ImageRevision, - ) -> anyhow::Result { + pub fn open(path: &PathBuf, version: u32, rev: ImageRevision) -> anyhow::Result { let file_data = std::fs::read(path).with_context(|| "Failed to read file")?; - ElfExecutable::new(&file_data, version, svn, rev) + ElfExecutable::new(&file_data, version, rev) } /// Create new instance of `ElfExecutable`. - pub fn new( - elf_bytes: &[u8], - version: u32, - svn: u32, - rev: ImageRevision, - ) -> anyhow::Result { + pub fn new(elf_bytes: &[u8], version: u32, rev: ImageRevision) -> anyhow::Result { let mut content = vec![]; let elf_file = ElfBytes::::minimal_parse(elf_bytes) @@ -99,7 +88,6 @@ impl ElfExecutable { Ok(Self { version, - svn, rev, load_addr, entry_point, @@ -114,11 +102,6 @@ impl ImageGeneratorExecutable for ElfExecutable { self.version } - /// Executable Security Version Number - fn svn(&self) -> u32 { - self.svn - } - /// Executable Revision fn rev(&self) -> &ImageRevision { &self.rev diff --git a/image/fake-keys/src/lib.rs b/image/fake-keys/src/lib.rs index 733a7eddc4..b386a4b60c 100644 --- a/image/fake-keys/src/lib.rs +++ b/image/fake-keys/src/lib.rs @@ -342,6 +342,7 @@ pub const VENDOR_CONFIG_KEY_0: ImageGeneratorVendorConfig = ImageGeneratorVendor not_before: [0u8; 15], not_after: [0u8; 15], pl0_pauser: Some(0x1), + fw_svn: 0, }; pub const VENDOR_CONFIG_KEY_1: ImageGeneratorVendorConfig = ImageGeneratorVendorConfig { diff --git a/image/gen/src/generator.rs b/image/gen/src/generator.rs index f854bc8748..432bc8d558 100644 --- a/image/gen/src/generator.rs +++ b/image/gen/src/generator.rs @@ -54,15 +54,19 @@ impl ImageGenerator { ); } + // The firmware SVN is placed in both the FMC and RT FW TOC entries for backwards compatibility with 1.x + // Create FMC TOC & Content let id = ImageTocEntryId::Fmc; let offset = IMAGE_MANIFEST_BYTE_SIZE as u32; - let (fmc_toc, fmc) = self.gen_image(&config.fmc, id, offset)?; + let (fmc_toc, fmc) = + self.gen_image(&config.fmc, id, offset, config.vendor_config.fw_svn)?; // Create Runtime TOC & Content let id = ImageTocEntryId::Runtime; let offset = offset + fmc_toc.size; - let (runtime_toc, runtime) = self.gen_image(&config.runtime, id, offset)?; + let (runtime_toc, runtime) = + self.gen_image(&config.runtime, id, offset, config.vendor_config.fw_svn)?; // Check if fmc and runtime image load address ranges don't overlap. if fmc_toc.overlaps(&runtime_toc) { @@ -303,6 +307,7 @@ impl ImageGenerator { image: &E, id: ImageTocEntryId, offset: u32, + fw_svn: u32, ) -> anyhow::Result<(ImageTocEntry, Vec)> where E: ImageGeneratorExecutable, @@ -315,7 +320,7 @@ impl ImageGenerator { r#type: r#type.into(), revision: *image.rev(), version: image.version(), - svn: image.svn(), + svn: fw_svn, reserved: 0, load_addr: image.load_addr(), entry_point: image.entry_point(), diff --git a/image/gen/src/lib.rs b/image/gen/src/lib.rs index d20a443abc..254854fb0f 100644 --- a/image/gen/src/lib.rs +++ b/image/gen/src/lib.rs @@ -24,9 +24,6 @@ pub trait ImageGeneratorExecutable { /// Executable Version Number fn version(&self) -> u32; - /// Executable Security Version Number - fn svn(&self) -> u32; - /// Executable Revision fn rev(&self) -> &ImageRevision; @@ -109,6 +106,8 @@ pub struct ImageGeneratorVendorConfig { pub not_after: [u8; 15], pub pl0_pauser: Option, + + pub fw_svn: u32, } /// Image Generator Owner Configuration diff --git a/image/verify/fuzz/src/fuzz_target_common.rs b/image/verify/fuzz/src/fuzz_target_common.rs index 900fdbb3a6..5a39d1b07c 100644 --- a/image/verify/fuzz/src/fuzz_target_common.rs +++ b/image/verify/fuzz/src/fuzz_target_common.rs @@ -121,14 +121,6 @@ impl ImageVerificationEnv for TestEnv { self.fmc_digest } - fn fmc_fuse_svn(&self) -> u32 { - 0 - } - - fn runtime_fuse_svn(&self) -> u32 { - 0 - } - fn iccm_range(&self) -> Range { Range { start: ICCM_ORG, diff --git a/image/verify/src/lib.rs b/image/verify/src/lib.rs index f132b81f49..37f523486b 100644 --- a/image/verify/src/lib.rs +++ b/image/verify/src/lib.rs @@ -21,11 +21,11 @@ use core::ops::Range; pub use verifier::ImageVerifier; -pub const MAX_RUNTIME_SVN: u32 = 128; +pub const MAX_FIRMWARE_SVN: u32 = 128; /// Image Verifification Executable Info #[derive(Default, Debug)] -pub struct ImageSvnLogInfo { +pub struct BundleSvnLogInfo { pub manifest_svn: u32, pub reserved: u32, pub fuse_svn: u32, @@ -43,12 +43,6 @@ pub struct ImageVerificationExeInfo { /// Entry Point pub entry_point: u32, - /// Security version number - pub svn: u32, - - /// The effective fuse SVN for this image - pub effective_fuse_svn: u32, - /// Digest of the image pub digest: ImageDigest, } @@ -68,11 +62,8 @@ pub struct ImageVerificationLogInfo { /// Vendor LMS Public Key Revocation Fuse pub fuse_vendor_lms_pub_key_revocation: u32, - /// First Mutable code's logging information - pub fmc_log_info: ImageSvnLogInfo, - - /// Runtime Mutable code's logging information - pub rt_log_info: ImageSvnLogInfo, + /// Firmware's SVN logging information + pub fw_log_info: BundleSvnLogInfo, } /// Verified image information @@ -93,6 +84,12 @@ pub struct ImageVerificationInfo { /// Whether `owner_pub_keys_digest` was in fuses pub owner_pub_keys_digest_in_fuses: bool, + /// The SVN for this firmware bundle + pub fw_svn: u32, + + /// The effective fuse SVN for this firmware bundle + pub effective_fuse_svn: u32, + /// First mutable code pub fmc: ImageVerificationExeInfo, @@ -154,11 +151,8 @@ pub trait ImageVerificationEnv { // Save the fmc digest in the data vault on cold boot fn get_fmc_digest_dv(&self) -> ImageDigest; - // Get Fuse FMC Key Manifest SVN - fn fmc_fuse_svn(&self) -> u32; - - // Get Runtime fuse SVN - fn runtime_fuse_svn(&self) -> u32; + // Get FW SVN fuse value + fn fw_fuse_svn(&self) -> u32; // ICCM Range fn iccm_range(&self) -> Range; diff --git a/image/verify/src/verifier.rs b/image/verify/src/verifier.rs index 16b90ec4f3..3c184967e1 100644 --- a/image/verify/src/verifier.rs +++ b/image/verify/src/verifier.rs @@ -110,10 +110,30 @@ impl ImageVerifier { let image_info = okref(&image_info)?; // Verify FMC - let (fmc_info, fmc_log_info) = self.verify_fmc(image_info.fmc, reason)?; + let fmc_info = self.verify_fmc(image_info.fmc, reason)?; // Verify Runtime - let (runtime_info, rt_log_info) = self.verify_runtime(image_info.runtime)?; + let runtime_info = self.verify_runtime(image_info.runtime)?; + + // Verify SVN + if self.svn_check_required() { + if image_info.fmc.svn != image_info.runtime.svn { + Err(CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_FMC_SVNS_UNEQUAL)?; + } + + if image_info.runtime.svn > MAX_FIRMWARE_SVN { + Err(CaliptraError::IMAGE_VERIFIER_ERR_FIRMWARE_SVN_GREATER_THAN_MAX_SUPPORTED)?; + } + + if cfi_launder(image_info.runtime.svn) < self.env.fw_fuse_svn() { + Err(CaliptraError::IMAGE_VERIFIER_ERR_FIRMWARE_SVN_LESS_THAN_FUSE)?; + } else { + cfi_assert_ge(image_info.runtime.svn, self.env.fw_fuse_svn()); + } + } + + let effective_fuse_svn = + Self::effective_fuse_svn(self.env.fw_fuse_svn(), self.env.anti_rollback_disable()); let info = ImageVerificationInfo { vendor_ecc_pub_key_idx: header_info.vendor_ecc_pub_key_idx, @@ -122,13 +142,18 @@ impl ImageVerifier { owner_pub_keys_digest_in_fuses: header_info.owner_pub_keys_digest_in_fuses, fmc: fmc_info, runtime: runtime_info, + fw_svn: image_info.runtime.svn, + effective_fuse_svn, log_info: ImageVerificationLogInfo { vendor_ecc_pub_key_idx: header_info.vendor_ecc_pub_key_idx, fuse_vendor_ecc_pub_key_revocation: header_info.vendor_ecc_pub_key_revocation, - fmc_log_info, - rt_log_info, fuse_vendor_lms_pub_key_revocation: header_info.vendor_lms_pub_key_revocation, vendor_lms_pub_key_idx: header_info.vendor_lms_pub_key_idx, + fw_log_info: BundleSvnLogInfo { + manifest_svn: image_info.runtime.svn, + reserved: 0, + fuse_svn: effective_fuse_svn, + }, }, pqc_verify_config: manifest.fw_image_type.into(), }; @@ -746,7 +771,7 @@ impl ImageVerifier { &mut self, verify_info: &ImageTocEntry, reason: ResetReason, - ) -> CaliptraResult<(ImageVerificationExeInfo, ImageSvnLogInfo)> { + ) -> CaliptraResult { let range = verify_info.image_range()?; #[cfg(feature = "fips-test-hooks")] @@ -791,21 +816,6 @@ impl ImageVerifier { Err(CaliptraError::IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_UNALIGNED)?; } - if self.svn_check_required() { - if verify_info.svn > 32 { - Err(CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_GREATER_THAN_MAX_SUPPORTED)?; - } - - if cfi_launder(verify_info.svn) < self.env.fmc_fuse_svn() { - Err(CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE)?; - } else { - cfi_assert_ge(verify_info.svn, self.env.fmc_fuse_svn()); - } - } - - let effective_fuse_svn = - Self::effective_fuse_svn(self.env.fmc_fuse_svn(), self.env.anti_rollback_disable()); - if cfi_launder(reason) == ResetReason::UpdateReset { if cfi_launder(actual) != self.env.get_fmc_digest_dv() { Err(CaliptraError::IMAGE_VERIFIER_ERR_UPDATE_RESET_FMC_DIGEST_MISMATCH)?; @@ -819,19 +829,11 @@ impl ImageVerifier { let info = ImageVerificationExeInfo { load_addr: verify_info.load_addr, entry_point: verify_info.entry_point, - svn: verify_info.svn, - effective_fuse_svn, digest: verify_info.digest, size: verify_info.size, }; - let log_info: ImageSvnLogInfo = ImageSvnLogInfo { - manifest_svn: verify_info.svn, - reserved: verify_info.reserved, - fuse_svn: self.env.fmc_fuse_svn(), - }; - - Ok((info, log_info)) + Ok(info) } /// Verify Runtime @@ -839,7 +841,7 @@ impl ImageVerifier { fn verify_runtime( &mut self, verify_info: &ImageTocEntry, - ) -> CaliptraResult<(ImageVerificationExeInfo, ImageSvnLogInfo)> { + ) -> CaliptraResult { let range = verify_info.image_range()?; #[cfg(feature = "fips-test-hooks")] @@ -883,39 +885,14 @@ impl ImageVerifier { Err(CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_UNALIGNED)?; } - if self.svn_check_required() { - if verify_info.svn > MAX_RUNTIME_SVN { - Err(CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_GREATER_THAN_MAX_SUPPORTED)?; - } - - if cfi_launder(verify_info.svn) < self.env.runtime_fuse_svn() { - Err(CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE)?; - } else { - cfi_assert_ge(verify_info.svn, self.env.runtime_fuse_svn()); - } - } - - let effective_fuse_svn = Self::effective_fuse_svn( - self.env.runtime_fuse_svn(), - self.env.anti_rollback_disable(), - ); - let info = ImageVerificationExeInfo { load_addr: verify_info.load_addr, entry_point: verify_info.entry_point, - svn: verify_info.svn, - effective_fuse_svn, digest: verify_info.digest, size: verify_info.size, }; - let log_info: ImageSvnLogInfo = ImageSvnLogInfo { - manifest_svn: verify_info.svn, - reserved: verify_info.reserved, - fuse_svn: self.env.runtime_fuse_svn(), - }; - - Ok((info, log_info)) + Ok(info) } /// Calculates the effective fuse SVN. @@ -1938,10 +1915,9 @@ mod tests { let result = verifier.verify_fmc(&verify_info, ResetReason::ColdReset); assert!(result.is_ok()); - let (info, _log_info) = result.unwrap(); + let info = result.unwrap(); assert_eq!(info.load_addr, ICCM_ORG); assert_eq!(info.entry_point, ICCM_ORG); - assert_eq!(info.svn, 1); assert_eq!(info.size, 100); } @@ -2001,10 +1977,9 @@ mod tests { }; let result = verifier.verify_runtime(&verify_info); assert!(result.is_ok()); - let (info, _log_info) = result.unwrap(); + let info = result.unwrap(); assert_eq!(info.load_addr, ICCM_ORG); assert_eq!(info.entry_point, ICCM_ORG); - assert_eq!(info.svn, 1); assert_eq!(info.size, 100); } @@ -2107,11 +2082,7 @@ mod tests { self.fmc_digest } - fn fmc_fuse_svn(&self) -> u32 { - 0 - } - - fn runtime_fuse_svn(&self) -> u32 { + fn fw_fuse_svn(&self) -> u32 { 0 } diff --git a/libcaliptra/inc/caliptra_types.h b/libcaliptra/inc/caliptra_types.h index 165b27348a..25d2ac055c 100644 --- a/libcaliptra/inc/caliptra_types.h +++ b/libcaliptra/inc/caliptra_types.h @@ -32,8 +32,7 @@ struct caliptra_fuses { uint32_t key_manifest_pk_hash_mask : 4; uint32_t rsvd : 28; uint32_t owner_pk_hash[12]; - uint32_t fmc_key_manifest_svn; - uint32_t runtime_svn[4]; + uint32_t fw_svn[4]; bool anti_rollback_disable; uint32_t idevid_cert_attr[24]; uint32_t idevid_manuf_hsm_id[4]; @@ -134,9 +133,9 @@ struct caliptra_stash_measurement_resp { struct caliptra_fw_info_resp { struct caliptra_resp_header hdr; uint32_t pl0_pauser; - uint32_t runtime_svn; - uint32_t min_runtime_svn; - uint32_t fmc_manifest_svn; + uint32_t firmware_svn; + uint32_t min_firmware_svn; + uint32_t _deprecated_fmc_svn; uint32_t attestation_disabled; uint8_t rom_revision[20]; uint8_t fmc_revision[20]; diff --git a/libcaliptra/src/caliptra_api.c b/libcaliptra/src/caliptra_api.c index de470484b2..5da955a9af 100644 --- a/libcaliptra/src/caliptra_api.c +++ b/libcaliptra/src/caliptra_api.c @@ -280,8 +280,7 @@ int caliptra_init_fuses(const struct caliptra_fuses *fuses) caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_KEY_MANIFEST_PK_HASH_0, fuses->key_manifest_pk_hash, CALIPTRA_ARRAY_SIZE(fuses->key_manifest_pk_hash)); caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_FUSE_KEY_MANIFEST_PK_HASH_MASK, fuses->key_manifest_pk_hash_mask); caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_OWNER_PK_HASH_0, fuses->owner_pk_hash, CALIPTRA_ARRAY_SIZE(fuses->owner_pk_hash)); - caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_FUSE_FMC_KEY_MANIFEST_SVN, fuses->fmc_key_manifest_svn); - caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_RUNTIME_SVN_0, fuses->runtime_svn, CALIPTRA_ARRAY_SIZE(fuses->runtime_svn)); + caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_RUNTIME_SVN_0, fuses->fw_svn, CALIPTRA_ARRAY_SIZE(fuses->fw_svn)); caliptra_generic_and_fuse_write(GENERIC_AND_FUSE_REG_FUSE_ANTI_ROLLBACK_DISABLE, (uint32_t)fuses->anti_rollback_disable); caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_IDEVID_CERT_ATTR_0, fuses->idevid_cert_attr, CALIPTRA_ARRAY_SIZE(fuses->idevid_cert_attr)); caliptra_fuse_array_write(GENERIC_AND_FUSE_REG_FUSE_IDEVID_MANUF_HSM_ID_0, fuses->idevid_manuf_hsm_id, CALIPTRA_ARRAY_SIZE(fuses->idevid_manuf_hsm_id)); diff --git a/rom/dev/Makefile b/rom/dev/Makefile index c46f568124..e9455238af 100644 --- a/rom/dev/Makefile +++ b/rom/dev/Makefile @@ -74,12 +74,11 @@ build-fw-image: gen-certs build-test-fmc build-test-rt --lms-pk-idx 3 \ --fmc $(TARGET_DIR)/caliptra-rom-test-fmc \ --fmc-version 0 \ - --fmc-svn 0 \ --fmc-rev $(GIT_REV) \ --rt $(TARGET_DIR)/caliptra-rom-test-rt \ --rt-version 0 \ - --rt-svn 0 \ --rt-rev $(GIT_REV) \ + --fw-svn 0 \ --out $(TARGET_DIR)/caliptra-rom-test-fw \ bloat: build diff --git a/rom/dev/README.md b/rom/dev/README.md index 224e534127..3a49bdc038 100644 --- a/rom/dev/README.md +++ b/rom/dev/README.md @@ -62,8 +62,8 @@ Following are the main FUSE & Architectural Registers used by the Caliptra ROM f | FUSE_LMS_REVOCATION | 32 | Manufacturer LMS Public Key Revocation Mask | | FUSE_MLDSA_REVOCATION | 32 | Manufacturer MLDSA Public Key Revocation Mask | | FUSE_OWNER_PK_HASH | 384 | Owner ECC and LMS or MLDSA Public Key Hash | -| FUSE_FMC_KEY_MANIFEST_SVN | 32 | FMC Security Version Number | -| FUSE_RUNTIME_SVN | 128 | Runtime Security Version Number | +| FUSE_FMC_KEY_MANIFEST_SVN | 32 | FMC Security Version Number (Deprecated) | +| FUSE_FIRMWARE_SVN | 128 | Firmware Security Version Number | | FUSE_ANTI_ROLLBACK_DISABLE | 1 | Disable SVN checking for FMC & Runtime when bit is set | | FUSE_IDEVID_CERT_ATTR | 768 | FUSE containing information for generating IDEVID CSR
**Word 0:bits[0-2]**: ECDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse
**Word 0:bits[3-5]**: MLDSA X509 Key Id Algorithm (3 bits) 0: SHA1, 1: SHA256, 2: SHA384, 3: SHA512, 4: Fuse
**Word 1,2,3,4,5**: ECDSA Subject Key Id
**Word 6,7,8,9,10**: MLDSA Subject Key Id
**Words 11,12**: Unique Endpoint ID
**Words 13,14,15,16**: Manufacturer Serial Number | | MANUF_DEBUG_UNLOCK_TOKEN | 128 | Secret value for manufacturing debug unlock authorization | @@ -159,7 +159,7 @@ It contains the image information and SHA-384 hash of individual firmware images | Image Type | 4 | Image Type that defines format of the image section
**0x0000_0001:** Executable | | Image Revision | 20 | Git Commit hash of the build | | Image Version | 4 | Firmware release number | -| Image SVN | 4 | Security Version Number for the Image. This field is compared against the fuses (FMC SVN or RUNTIME SVN) | +| Image SVN | 4 | Security Version Number for the image. This field is present for backwards compatibility and must be equal between FMC and RT FW images. It is compared to FW SVN fuses. | | Reserved | 4 | Reserved field | | Image Load Address | 4 | Load address | | Image Entry Point | 4 | Entry point to start the execution from | @@ -682,7 +682,7 @@ Alias FMC Layer includes the measurement of the FMC and other security states. T - Firmware Image Bundle is successfully loaded and verified from the Mailbox - ROM has following information from Firmware Image Bundle - FMC_DIGEST - Digest of the FMC -- FMC_SVN - SVN for FMC +- FW_SVN - SVN for the firmware - MANUFACTURER_PK - Manufacturer Public Key(s) used to verify the firmware image bundle - MANUFACTURER_PK_INDEX - Index of the MANUFACTURER_PK in the firmware image bundle @@ -697,8 +697,8 @@ Alias FMC Layer includes the measurement of the FMC and other security states. T CPTRA_SECURITY_STATE.DEBUG_ENABLED, FUSE_ANTI_ROLLBACK_DISABLE, ECC_VENDOR_PK_INDEX, - FMC_SVN, - FMC_FUSE_SVN (or 0 if `FUSE_ANTI_ROLLBACK_DISABLE`), + FW_SVN, + FW_FUSE_SVN (or 0 if `FUSE_ANTI_ROLLBACK_DISABLE`), PQC_VENDOR_PK_INDEX, ROM_VERIFY_CONFIG, OWNER_PK_HASH_FROM_FUSES (0 or 1), @@ -773,7 +773,7 @@ Alias FMC Layer includes the measurement of the FMC and other security states. T `dccm_dv_store(FMC_DIGEST, lock_for_wr)` - `dccm_dv_store(FMC_SVN, lock_for_wr)` + `dccm_dv_store(FW_SVN, lock_for_wr)` `dccm_dv_store(FUSE_OWNER_PK_HASH, lock_for_wr)` @@ -810,7 +810,7 @@ Alias FMC Layer includes the measurement of the FMC and other security states. T | 🔒Alias FMC Cert ECDSA Signature R | | 🔒Alias FMC Cert ECDSA Signature S | | 🔒Alias FMC Cert MLDSA Signature | - | 🔒FMC SVN | + | 🔒FW SVN | | 🔒ROM Cold Boot Status | | 🔒FMC Entry Point | | 🔒Manufacturer ECDSA Public Key Index | @@ -827,7 +827,6 @@ Alias FMC Layer includes the measurement of the FMC and other security states. T - **Cold Reset Unlockable values:** These values are unlocked on a Cold Reset: - FMC TCI - - FMC SVN - FMC Entry Point - Owner Pub Key Hash - Ecc Vendor Pub Key Index @@ -837,8 +836,8 @@ Alias FMC Layer includes the measurement of the FMC and other security states. T - **Warm Reset unlockable values:** These values are unlocked on a Warm or Cold Reset: - RT TCI - - RT SVN - RT Entry Point + - FW SVN - Manifest Addr - ROM Update Reset Status @@ -942,8 +941,7 @@ The following are the pre-conditions that should be satisfied: - fuse_lms_revocation : This is the bitmask of the LMS keys which are revoked. - fuse_mldsa_revocation : This is the bitmask of the MLDSA keys which are revoked. - fuse_owner_pk_hash : The hash of the owner public keys in preamble. - - fuse_key_manifest_svn : Used in FMC validation to make sure that the version number is good. - - fuse_runtime_svn : Used in RT validation to make sure that the runtime image's version number is good. + - fuse_firmware_svn : Used in FW validation to make sure that the firmware image's SVN is good. - The SOC has written the data to the mailbox. - The SOC has written the data length in the DLEN mailbox register. - The SOC has put the FW_DOWNLOAD command in the command register. @@ -1052,7 +1050,7 @@ Compare the computed hash with the hash specified in the RT TOC. - Alias FMC Public MLDSA Key. - Digest of the FMC part of the image. - Digest of the ECC and LMS or MLDSA owner public keys portion of preamble. - - FMC SVN. + - FW SVN. - ROM Cold Boot Status. - FMC Entry Point. - ECC Vendor public key index. diff --git a/rom/dev/doc/error-attribution.md b/rom/dev/doc/error-attribution.md index 2ab9b22050..919455dda7 100644 --- a/rom/dev/doc/error-attribution.md +++ b/rom/dev/doc/error-attribution.md @@ -91,16 +91,12 @@ Verifier Library | IMAGE_VERIFIER_ERR_FMC_LOAD_ADDR_INVALID Verifier Library | IMAGE_VERIFIER_ERR_FMC_LOAD_ADDR_UNALIGNED | 0x000b0022 Verifier Library | IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_INVALID | 0x000b0023 Verifier Library | IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_UNALIGNED | 0x000b0024 -Verifier Library | IMAGE_VERIFIER_ERR_FMC_SVN_GREATER_THAN_MAX_SUPPORTED | 0x000b0025 -Verifier Library | IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_MIN_SUPPORTED | 0x000b0026 -Verifier Library | IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE | 0x000b0027 Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID | 0x000b0028 Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_UNALIGNED | 0x000b0029 Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_INVALID | 0x000b002a Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_UNALIGNED | 0x000b002b -Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_SVN_GREATER_THAN_MAX_SUPPORTED | 0x000b002c -Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_MIN_SUPPORTED | 0x000b002d -Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE | 0x000b002e +Verifier Library | IMAGE_VERIFIER_ERR_FIRMWARE_SVN_GREATER_THAN_MAX_SUPPORTED | 0x000b002c +Verifier Library | IMAGE_VERIFIER_ERR_FIRMWARE_SVN_LESS_THAN_FUSE | 0x000b002e Verifier Library | IMAGE_VERIFIER_ERR_IMAGE_LEN_MORE_THAN_BUNDLE_SIZE | 0x000b002f Verifier Library | IMAGE_VERIFIER_ERR_VENDOR_LMS_PUB_KEY_INDEX_MISMATCH | 0x000b0030 Verifier Library | IMAGE_VERIFIER_ERR_VENDOR_LMS_VERIFY_FAILURE | 0x000b0031 @@ -108,6 +104,8 @@ Verifier Library | IMAGE_VERIFIER_ERR_VENDOR_LMS_PUBKEY_INDEX_OUT_OF_BOUNDS Verifier Library | IMAGE_VERIFIER_ERR_VENDOR_LMS_SIGNATURE_INVALID | 0x000b0033 Verifier Library | IMAGE_VERIFIER_ERR_VEN_LMS_PUB_KEY_INDEX_OUT_OF_BOUNDS | 0x000b0034 Verifier Library | IMAGE_VERIFIER_ERR_FMC_RUNTIME_LOAD_ADDR_OVERLAP | 0x000b0035 +Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_FMC_SVNS_UNEQUAL | 0x000b0042 +
LMS Driver | DRIVER_LMS_INVALID_LMS_ALGO_TYPE | 0x000c0001 LMS Driver | DRIVER_LMS_INVALID_LMOTS_ALGO_TYPE | 0x000c0002 @@ -211,16 +209,12 @@ Verifier Library | IMAGE_VERIFIER_ERR_FMC_LOAD_ADDR_INVALID Verifier Library | IMAGE_VERIFIER_ERR_FMC_LOAD_ADDR_UNALIGNED | 0x000b0022 Verifier Library | IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_INVALID | 0x000b0023 Verifier Library | IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_UNALIGNED | 0x000b0024 -Verifier Library | IMAGE_VERIFIER_ERR_FMC_SVN_GREATER_THAN_MAX_SUPPORTED | 0x000b0025 -Verifier Library | IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_MIN_SUPPORTED | 0x000b0026 -Verifier Library | IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE | 0x000b0027 Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID | 0x000b0028 Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_UNALIGNED | 0x000b0029 Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_INVALID | 0x000b002a Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_UNALIGNED | 0x000b002b -Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_SVN_GREATER_THAN_MAX_SUPPORTED | 0x000b002c -Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_MIN_SUPPORTED | 0x000b002d -Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE | 0x000b002e +Verifier Library | IMAGE_VERIFIER_ERR_FIRMWARE_SVN_GREATER_THAN_MAX_SUPPORTED | 0x000b002c +Verifier Library | IMAGE_VERIFIER_ERR_FIRMWARE_SVN_LESS_THAN_FUSE | 0x000b002e Verifier Library | IMAGE_VERIFIER_ERR_IMAGE_LEN_MORE_THAN_BUNDLE_SIZE | 0x000b002f Verifier Library | IMAGE_VERIFIER_ERR_VENDOR_LMS_PUB_KEY_INDEX_MISMATCH | 0x000b0030 Verifier Library | IMAGE_VERIFIER_ERR_VENDOR_LMS_VERIFY_FAILURE | 0x000b0031 @@ -228,5 +222,6 @@ Verifier Library | IMAGE_VERIFIER_ERR_VENDOR_LMS_PUBKEY_INDEX_OUT_OF_BOUNDS Verifier Library | IMAGE_VERIFIER_ERR_VENDOR_LMS_SIGNATURE_INVALID | 0x000b0033 Verifier Library | IMAGE_VERIFIER_ERR_VEN_LMS_PUB_KEY_INDEX_OUT_OF_BOUNDS | 0x000b0034 Verifier Library | IMAGE_VERIFIER_ERR_FMC_RUNTIME_LOAD_ADDR_OVERLAP | 0x000b0035 +Verifier Library | IMAGE_VERIFIER_ERR_RUNTIME_FMC_SVNS_UNEQUAL | 0x000b0042
Mailbox Driver | DRIVER_MAILBOX_INVALID_STATE | 0x00080001 \ No newline at end of file diff --git a/rom/dev/doc/test-coverage/test-coverage.md b/rom/dev/doc/test-coverage/test-coverage.md index 85b1801763..caf0c34d93 100644 --- a/rom/dev/doc/test-coverage/test-coverage.md +++ b/rom/dev/doc/test-coverage/test-coverage.md @@ -37,8 +37,6 @@ Test Scenario| Test Name | ROM Error Code Check if FMC entry point is within ICCM range | **test_fmc_invalid_entry_point_before_iccm** | IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_INVALID Check if FMC entry point is within ICCM range | **test_fmc_invalid_entry_point_after_iccm** | IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_INVALID Check if FMC entry point is DWORD aligned | **test_fmc_entry_point_unaligned** | IMAGE_VERIFIER_ERR_FMC_ENTRY_POINT_UNALIGNED - Check if FMC SVN is greater than max (32) | **test_fmc_svn_greater_than_32** | IMAGE_VERIFIER_ERR_FMC_SVN_GREATER_THAN_MAX_SUPPORTED - Check if FMC SVN is less than fuse svn | **test_fmc_svn_less_than_fuse_svn** | IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE Check if RT size if 0 | **test_toc_rt_size_zero** | IMAGE_VERIFIER_ERR_RUNTIME_SIZE_ZERO Check if manifest.rt_toc.digest matches Runtime image digest | **test_runtime_digest_mismatch** | IMAGE_VERIFIER_ERR_RUNTIME_DIGEST_MISMATCH Check if RT load address is within ICCM range | **test_runtime_invalid_load_addr_before_iccm** | IMAGE_VERIFIER_ERR_RUNTIME_LOAD_ADDR_INVALID @@ -48,8 +46,8 @@ Test Scenario| Test Name | ROM Error Code Check if RT entry point is within ICCM range | **test_runtime_invalid_entry_point_before_iccm** | IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_INVALID Check if RT entry point is within ICCM range | **test_runtime_invalid_entry_point_after_iccm** | IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_INVALID Check if RT entry point is DWORD aligned | **test_runtime_entry_point_unaligned** | IMAGE_VERIFIER_ERR_RUNTIME_ENTRY_POINT_UNALIGNED - Check if RT SVN is greater than max (128) | **test_runtime_svn_greater_than_max** | IMAGE_VERIFIER_ERR_RUNTIME_SVN_GREATER_THAN_MAX_SUPPORTED - Check if RT SVN is less than fuse svn | **test_runtime_svn_less_than_fuse_svn** | IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE + Check if FW SVN is greater than max (128) | **test_firmware_svn_greater_than_max** | IMAGE_VERIFIER_ERR_FIRMWARE_SVN_GREATER_THAN_MAX_SUPPORTED + Check if FW SVN is less than fuse svn | **test_firmware_svn_less_than_fuse_svn** | IMAGE_VERIFIER_ERR_FIRMWARE_SVN_LESS_THAN_FUSE Generates the LDEVID and FMC Alias certificates |**cert_test** | N/A Check if the owner and vendor cert validty dates are present in FMC Alias cert | **cert_test_with_custom_dates** | N/A @@ -72,7 +70,7 @@ Check if firmware is zero-sized | **test_zero_firmware_size** | FW_PROC_INVALID_ Check if firmware is not more than max. size (128K) | **test_firmware_gt_max_size** | FW_PROC_INVALID_IMAGE_SIZE Check if PCR log entries are correctly logged to DCCM | **test_pcr_log** | N/A Check PCR log entries - No Onwer Public Key Hash in fuse_owner_pk_hash | **test_pcr_log_no_owner_key_digest_fuse** | N/A -Check PCR log entries - FMC Fuse SVN set in fuse_fmc_key_manifest_svn | **test_pcr_log_fmc_fuse_svn** | N/A +Check PCR log entries - FW Fuse SVN set in fuse_fw_manifest_svn | **test_pcr_log_fw_fuse_svn** | N/A Check PCR log entries across Update Reset | **test_pcr_log_across_update_reset** | N/A Check if Fuse log entries are correctly logged to DCCM | **test_fuse_log** | N/A diff --git a/rom/dev/src/fht.rs b/rom/dev/src/fht.rs index aa9cfa5378..e279b93351 100644 --- a/rom/dev/src/fht.rs +++ b/rom/dev/src/fht.rs @@ -39,12 +39,12 @@ impl FhtDataStore { pub const fn fmc_priv_key_store() -> HandOffDataHandle { HandOffDataHandle(((Vault::KeyVault as u32) << 12) | KEY_ID_FMC_ECDSA_PRIV_KEY as u32) } - /// The FMC SVN is stored in a 32-bit DataVault sticky register. - pub const fn fmc_svn_store() -> HandOffDataHandle { + /// The FW SVN is stored in a 32-bit DataVault sticky register. + pub const fn deprecated_fmc_svn_store() -> HandOffDataHandle { HandOffDataHandle( ((Vault::DataVault as u32) << 12) | (DataVaultRegister::Sticky32BitReg as u32) << 8 - | ColdResetEntry4::FmcSvn as u32, + | ColdResetEntry4::DeprecatedFmcSvn as u32, ) } /// The FMC TCI is stored in a 384-bit DataVault sticky register. @@ -93,20 +93,20 @@ impl FhtDataStore { | ColdResetEntry48::FmcPubKeyY as u32, ) } - /// The RT SVN is stored in a 32-bit DataVault non-sticky register. - pub const fn rt_svn_data_store() -> HandOffDataHandle { + /// The FW SVN is stored in a 32-bit DataVault non-sticky register. + pub const fn fw_svn_data_store() -> HandOffDataHandle { HandOffDataHandle( ((Vault::DataVault as u32) << 12) | (DataVaultRegister::NonSticky32BitReg as u32) << 8 - | WarmResetEntry4::RtSvn as u32, + | WarmResetEntry4::FwSvn as u32, ) } - /// The RT Min SVN is stored in a 32-bit DataVault non-sticky register. - pub const fn rt_min_svn_data_store() -> HandOffDataHandle { + /// The FW Min SVN is stored in a 32-bit DataVault non-sticky register. + pub const fn fw_min_svn_data_store() -> HandOffDataHandle { HandOffDataHandle( ((Vault::DataVault as u32) << 12) | (DataVaultRegister::NonSticky32BitReg as u32) << 8 - | WarmResetEntry4::RtMinSvn as u32, + | WarmResetEntry4::FwMinSvn as u32, ) } /// The RT TCI is stored in a 384-bit DataVault non-sticky register. @@ -170,12 +170,12 @@ pub fn initialize_fht(env: &mut RomEnv) { fmc_cert_sig_r_dv_hdl: FhtDataStore::fmc_cert_sig_r_store(), fmc_cert_sig_s_dv_hdl: FhtDataStore::fmc_cert_sig_s_store(), fmc_tci_dv_hdl: FhtDataStore::fmc_tci_store(), - fmc_svn_dv_hdl: FhtDataStore::fmc_svn_store(), + deprecated_fmc_svn_dv_hdl: FhtDataStore::deprecated_fmc_svn_store(), rt_cdi_kv_hdl: FHT_INVALID_HANDLE, rt_priv_key_kv_hdl: FHT_INVALID_HANDLE, rt_tci_dv_hdl: FhtDataStore::rt_tci_data_store(), - rt_svn_dv_hdl: FhtDataStore::rt_svn_data_store(), - rt_min_svn_dv_hdl: FhtDataStore::rt_min_svn_data_store(), + fw_svn_dv_hdl: FhtDataStore::fw_svn_data_store(), + fw_min_svn_dv_hdl: FhtDataStore::fw_min_svn_data_store(), ldevid_cert_sig_r_dv_hdl: FhtDataStore::ldevid_cert_sig_r_store(), ldevid_cert_sig_s_dv_hdl: FhtDataStore::ldevid_cert_sig_s_store(), rom_info_addr: RomAddr::from(unsafe { &CALIPTRA_ROM_INFO }), diff --git a/rom/dev/src/flow/cold_reset/fmc_alias.rs b/rom/dev/src/flow/cold_reset/fmc_alias.rs index c880a93c15..fa787b54f5 100644 --- a/rom/dev/src/flow/cold_reset/fmc_alias.rs +++ b/rom/dev/src/flow/cold_reset/fmc_alias.rs @@ -164,8 +164,8 @@ impl FmcAliasLayer { let flags = Self::make_flags(env.soc_ifc.lifecycle(), env.soc_ifc.debug_locked()); - let svn = env.data_vault.fmc_svn() as u8; - let fuse_svn = fw_proc_info.fmc_effective_fuse_svn as u8; + let svn = env.data_vault.fw_svn() as u8; + let fuse_svn = fw_proc_info.effective_fuse_svn as u8; let mut fuse_info_digest = Array4x12::default(); let mut hasher = env.sha384.digest_init()?; @@ -196,8 +196,8 @@ impl FmcAliasLayer { tcb_info_fmc_tci: &(&env.data_vault.fmc_tci()).into(), tcb_info_device_info_hash: &fuse_info_digest.into(), tcb_info_flags: &flags, - tcb_info_fmc_svn: &svn.to_be_bytes(), - tcb_info_fmc_svn_fuses: &fuse_svn.to_be_bytes(), + tcb_info_fw_svn: &svn.to_be_bytes(), + tcb_info_fw_svn_fuses: &fuse_svn.to_be_bytes(), not_before: &fw_proc_info.fmc_cert_valid_not_before.value, not_after: &fw_proc_info.fmc_cert_valid_not_after.value, }; diff --git a/rom/dev/src/flow/cold_reset/fw_processor.rs b/rom/dev/src/flow/cold_reset/fw_processor.rs index a69c3859dc..6793042e83 100644 --- a/rom/dev/src/flow/cold_reset/fw_processor.rs +++ b/rom/dev/src/flow/cold_reset/fw_processor.rs @@ -47,7 +47,7 @@ pub struct FwProcInfo { pub fmc_cert_valid_not_after: NotAfter, - pub fmc_effective_fuse_svn: u32, + pub effective_fuse_svn: u32, pub owner_pub_keys_digest_in_fuses: bool, @@ -148,7 +148,7 @@ impl FirmwareProcessor { Ok(FwProcInfo { fmc_cert_valid_not_before: nb, fmc_cert_valid_not_after: nf, - fmc_effective_fuse_svn: info.fmc.effective_fuse_svn, + effective_fuse_svn: info.effective_fuse_svn, owner_pub_keys_digest_in_fuses: info.owner_pub_keys_digest_in_fuses, pqc_verify_config: info.pqc_verify_config as u8, }) @@ -367,8 +367,8 @@ impl FirmwareProcessor { let info = verifier.verify(manifest, img_bundle_sz, ResetReason::ColdReset)?; cprintln!( - "[fwproc] Image verified using Vendor ECC Key Index {}", - info.vendor_ecc_pub_key_idx, + "[fwproc] Image verified using Vendor ECC Key Index {}, with SVN {} and effective fuse SVN {}", + info.vendor_ecc_pub_key_idx, info.fw_svn, info.effective_fuse_svn, ); report_boot_status(FwProcessorImageVerificationComplete.into()); Ok(info) @@ -406,43 +406,43 @@ impl FirmwareProcessor { // Log ManifestFmcSvn log_fuse_data( log, - FuseLogEntryId::ManifestFmcSvn, - log_info.fmc_log_info.manifest_svn.as_bytes(), + FuseLogEntryId::DeprecatedManifestFmcSvn, + log_info.fw_log_info.manifest_svn.as_bytes(), )?; // Log ManifestReserved0 log_fuse_data( log, FuseLogEntryId::ManifestReserved0, - log_info.fmc_log_info.reserved.as_bytes(), + log_info.fw_log_info.reserved.as_bytes(), )?; // Log FuseFmcSvn log_fuse_data( log, - FuseLogEntryId::FuseFmcSvn, - log_info.fmc_log_info.fuse_svn.as_bytes(), + FuseLogEntryId::DeprecatedFuseFmcSvn, + log_info.fw_log_info.fuse_svn.as_bytes(), )?; - // Log ManifestRtSvn + // Log ManifestFwSvn log_fuse_data( log, - FuseLogEntryId::ManifestRtSvn, - log_info.rt_log_info.manifest_svn.as_bytes(), + FuseLogEntryId::ManifestFwSvn, + log_info.fw_log_info.manifest_svn.as_bytes(), )?; // Log ManifestReserved1 log_fuse_data( log, FuseLogEntryId::ManifestReserved1, - log_info.rt_log_info.reserved.as_bytes(), + log_info.fw_log_info.reserved.as_bytes(), )?; - // Log FuseRtSvn + // Log FuseFwSvn log_fuse_data( log, - FuseLogEntryId::FuseRtSvn, - log_info.rt_log_info.fuse_svn.as_bytes(), + FuseLogEntryId::FuseFwSvn, + log_info.fw_log_info.fuse_svn.as_bytes(), )?; // Log VendorLmsPubKeyIndex @@ -517,7 +517,7 @@ impl FirmwareProcessor { ) { data_vault.write_cold_reset_entry48(ColdResetEntry48::FmcTci, &info.fmc.digest.into()); - data_vault.write_cold_reset_entry4(ColdResetEntry4::FmcSvn, info.fmc.svn); + data_vault.write_cold_reset_entry4(ColdResetEntry4::DeprecatedFmcSvn, info.fw_svn); data_vault.write_cold_reset_entry4(ColdResetEntry4::FmcEntryPoint, info.fmc.entry_point); @@ -540,7 +540,8 @@ impl FirmwareProcessor { data_vault.write_warm_reset_entry48(WarmResetEntry48::RtTci, &info.runtime.digest.into()); - data_vault.write_warm_reset_entry4(WarmResetEntry4::RtSvn, info.runtime.svn); + data_vault.write_warm_reset_entry4(WarmResetEntry4::FwSvn, info.fw_svn); + data_vault.write_warm_reset_entry4(WarmResetEntry4::FwMinSvn, info.fw_svn); // At cold-boot, min_svn == curr_svn data_vault.write_warm_reset_entry4(WarmResetEntry4::RtEntryPoint, info.runtime.entry_point); diff --git a/rom/dev/src/flow/fake.rs b/rom/dev/src/flow/fake.rs index e79fe95d93..9bc96a4a60 100644 --- a/rom/dev/src/flow/fake.rs +++ b/rom/dev/src/flow/fake.rs @@ -340,14 +340,9 @@ impl<'a, 'b> ImageVerificationEnv for &mut FakeRomImageVerificationEnv<'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 Fuse FW Manifest SVN + fn fw_fuse_svn(&self) -> u32 { + self.soc_ifc.fuse_bank().fw_fuse_svn() } fn iccm_range(&self) -> Range { diff --git a/rom/dev/src/flow/update_reset.rs b/rom/dev/src/flow/update_reset.rs index a952f177f2..c08ed6aae7 100644 --- a/rom/dev/src/flow/update_reset.rs +++ b/rom/dev/src/flow/update_reset.rs @@ -211,7 +211,11 @@ impl UpdateResetFlow { fn populate_data_vault(data_vault: &mut DataVault, info: &ImageVerificationInfo) { data_vault.write_warm_reset_entry48(WarmResetEntry48::RtTci, &info.runtime.digest.into()); - data_vault.write_warm_reset_entry4(WarmResetEntry4::RtSvn, info.runtime.svn); + let cur_min_svn = data_vault.read_warm_reset_entry4(WarmResetEntry4::FwMinSvn); + let new_min_svn = core::cmp::min(cur_min_svn, info.fw_svn); + + data_vault.write_warm_reset_entry4(WarmResetEntry4::FwSvn, info.fw_svn); + data_vault.write_warm_reset_entry4(WarmResetEntry4::FwMinSvn, new_min_svn); data_vault.write_warm_reset_entry4(WarmResetEntry4::RtEntryPoint, info.runtime.entry_point); diff --git a/rom/dev/src/lock.rs b/rom/dev/src/lock.rs index c39f039b71..d7f7138e82 100644 --- a/rom/dev/src/lock.rs +++ b/rom/dev/src/lock.rs @@ -59,9 +59,9 @@ fn lock_cold_reset_reg(env: &mut RomEnv) { env.data_vault .lock_cold_reset_entry48(ColdResetEntry48::FmcTci); - // Lock the FMC SVN in data vault until next cold reset + // Lock the deprecated FMC SVN in data vault until next cold reset env.data_vault - .lock_cold_reset_entry4(ColdResetEntry4::FmcSvn); + .lock_cold_reset_entry4(ColdResetEntry4::DeprecatedFmcSvn); // Lock the FMC entry point in data vault until next cold reset env.data_vault @@ -95,11 +95,13 @@ fn lock_common_reg_set(env: &mut RomEnv) { env.data_vault .lock_warm_reset_entry48(WarmResetEntry48::RtTci); - // Lock the Runtime SVN in data vault until next reset + // Lock the Firmware SVN in data vault until next reset env.data_vault - .lock_warm_reset_entry4(WarmResetEntry4::RtSvn); + .lock_warm_reset_entry4(WarmResetEntry4::FwSvn); - // Do not lock Runtime minimum SVN; FMC will manage this. + // Lock the Firmware Min-SVN in data vault until next reset + env.data_vault + .lock_warm_reset_entry4(WarmResetEntry4::FwMinSvn); // Lock the Runtime entry point in data vault until next reset env.data_vault diff --git a/rom/dev/src/pcr.rs b/rom/dev/src/pcr.rs index 41cbb2b77e..2373f9aa93 100644 --- a/rom/dev/src/pcr.rs +++ b/rom/dev/src/pcr.rs @@ -83,8 +83,8 @@ pub(crate) fn extend_pcrs( env.soc_ifc.debug_locked() as u8, env.soc_ifc.fuse_bank().anti_rollback_disable() as u8, env.data_vault.ecc_vendor_pk_index() as u8, - env.data_vault.fmc_svn() as u8, - info.fmc.effective_fuse_svn as u8, + env.data_vault.fw_svn() as u8, + info.effective_fuse_svn as u8, env.data_vault.lms_vendor_pk_index() as u8, info.pqc_verify_config as u8, info.owner_pub_keys_digest_in_fuses as u8, diff --git a/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs b/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs index 014a455121..4f60182a17 100644 --- a/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs +++ b/rom/dev/tests/rom_integration_tests/test_fmcalias_derivation.rs @@ -21,7 +21,7 @@ use caliptra_error::CaliptraError; use caliptra_hw_model::{BootParams, Fuses, HwModel, InitParams, ModelError, SecurityState}; use caliptra_image_crypto::OsslCrypto as Crypto; use caliptra_image_fake_keys::{OWNER_CONFIG, VENDOR_CONFIG_KEY_1}; -use caliptra_image_gen::ImageGenerator; +use caliptra_image_gen::{ImageGenerator, ImageGeneratorVendorConfig}; use caliptra_image_types::{FwImageType, IMAGE_BYTE_SIZE}; use caliptra_test::swap_word_bytes; use openssl::hash::{Hasher, MessageDigest}; @@ -159,10 +159,12 @@ fn test_pcr_log() { ) .unwrap(); - const FMC_SVN: u32 = 1; + const FW_SVN: u32 = 1; let image_options = ImageOptions { - vendor_config: VENDOR_CONFIG_KEY_1, - fmc_svn: FMC_SVN, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: FW_SVN, + ..VENDOR_CONFIG_KEY_1 + }, ..Default::default() }; let image_bundle = caliptra_builder::build_and_sign_image( @@ -199,7 +201,7 @@ fn test_pcr_log() { debug_locked as u8, anti_rollback_disable as u8, VENDOR_CONFIG_KEY_1.ecc_key_idx as u8, - FMC_SVN as u8, + FW_SVN as u8, 0_u8, VENDOR_CONFIG_KEY_1.lms_key_idx as u8, RomPqcVerifyConfig::EcdsaAndLms as u8, @@ -319,7 +321,7 @@ fn test_pcr_log_no_owner_key_digest_fuse() { } #[test] -fn test_pcr_log_fmc_fuse_svn() { +fn test_pcr_log_fw_fuse_svn() { let gen = ImageGenerator::new(Crypto::default()); let image_bundle = helpers::build_image_bundle(ImageOptions::default()); @@ -331,14 +333,14 @@ fn test_pcr_log_fmc_fuse_svn() { .owner_pubkey_digest(&image_bundle.manifest.preamble) .unwrap(); - const FMC_SVN: u32 = 3; - const FMC_FUSE_SVN: u32 = 2; + const FW_SVN: u32 = 3; + const FW_FUSE_SVN: u32 = 2; let fuses = Fuses { anti_rollback_disable: false, key_manifest_pk_hash: vendor_pubkey_digest, owner_pk_hash: owner_pubkey_digest, - fmc_key_manifest_svn: FMC_FUSE_SVN, + fw_svn: [2, 0, 0, 0], // Value of FW_FUSE_SVN ..Default::default() }; let rom = caliptra_builder::build_firmware_rom(firmware::rom_from_env()).unwrap(); @@ -356,8 +358,10 @@ fn test_pcr_log_fmc_fuse_svn() { .unwrap(); let image_options = ImageOptions { - vendor_config: VENDOR_CONFIG_KEY_1, - fmc_svn: FMC_SVN, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: FW_SVN, + ..VENDOR_CONFIG_KEY_1 + }, ..Default::default() }; let image_bundle = caliptra_builder::build_and_sign_image( @@ -394,8 +398,8 @@ fn test_pcr_log_fmc_fuse_svn() { debug_locked as u8, anti_rollback_disable as u8, VENDOR_CONFIG_KEY_1.ecc_key_idx as u8, - FMC_SVN as u8, - FMC_FUSE_SVN as u8, + FW_SVN as u8, + FW_FUSE_SVN as u8, VENDOR_CONFIG_KEY_1.lms_key_idx as u8, RomPqcVerifyConfig::EcdsaAndLms as u8, true as u8, @@ -472,12 +476,11 @@ fn test_pcr_log_across_update_reset() { .owner_pubkey_digest(&image_bundle.manifest.preamble) .unwrap(); - const FMC_SVN: u32 = 2; - const FMC_FUSE_SVN: u32 = 1; + const FW_SVN: u32 = 2; let fuses = Fuses { anti_rollback_disable: false, - fmc_key_manifest_svn: FMC_FUSE_SVN, + fw_svn: [1, 0, 0, 0], key_manifest_pk_hash: vendor_pubkey_digest, owner_pk_hash: owner_pubkey_digest, ..Default::default() @@ -497,8 +500,10 @@ fn test_pcr_log_across_update_reset() { .unwrap(); let image_options = ImageOptions { - vendor_config: VENDOR_CONFIG_KEY_1, - fmc_svn: FMC_SVN, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: FW_SVN, + ..VENDOR_CONFIG_KEY_1 + }, ..Default::default() }; let image_bundle = caliptra_builder::build_and_sign_image( @@ -573,12 +578,11 @@ fn test_pcr_log_across_update_reset() { #[test] fn test_fuse_log() { - const FMC_SVN: u32 = 4; + const FW_SVN: u32 = 4; + const FW_SVN_FUSE: u32 = 3; let fuses = Fuses { - anti_rollback_disable: true, - fmc_key_manifest_svn: 0x0F, // Value of FMC_SVN - runtime_svn: [0xF, 0, 0, 0], // Value of RT_SVN + fw_svn: [0x7, 0, 0, 0], // Value of FW_SVN_FUSE lms_verify: true, ..Default::default() }; @@ -598,14 +602,16 @@ fn test_fuse_log() { .unwrap(); let image_options = ImageOptions { - vendor_config: VENDOR_CONFIG_KEY_1, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: FW_SVN, + ..VENDOR_CONFIG_KEY_1 + }, owner_config: Some(OWNER_CONFIG), - fmc_svn: FMC_SVN, fmc_version: 0, - app_svn: FMC_SVN, app_version: 0, fw_image_type: FwImageType::EccLms, }; + let image_bundle = caliptra_builder::build_and_sign_image(&TEST_FMC_WITH_UART, &APP_WITH_UART, image_options) .unwrap(); @@ -646,9 +652,9 @@ fn test_fuse_log() { FuseLogEntry::read_from_prefix(fuse_entry_arr[fuse_log_entry_offset..].as_bytes()).unwrap(); assert_eq!( fuse_log_entry.entry_id, - FuseLogEntryId::ManifestFmcSvn as u32 + FuseLogEntryId::DeprecatedManifestFmcSvn as u32 ); - assert_eq!(fuse_log_entry.log_data[0], FMC_SVN); + assert_eq!(fuse_log_entry.log_data[0], FW_SVN); // Validate the ManifestReserved0 fuse_log_entry_offset += core::mem::size_of::(); @@ -664,18 +670,21 @@ fn test_fuse_log() { fuse_log_entry_offset += core::mem::size_of::(); let fuse_log_entry = FuseLogEntry::read_from_prefix(fuse_entry_arr[fuse_log_entry_offset..].as_bytes()).unwrap(); - assert_eq!(fuse_log_entry.entry_id, FuseLogEntryId::FuseFmcSvn as u32); - assert_eq!(fuse_log_entry.log_data[0], FMC_SVN); + assert_eq!( + fuse_log_entry.entry_id, + FuseLogEntryId::DeprecatedFuseFmcSvn as u32 + ); + assert_eq!(fuse_log_entry.log_data[0], FW_SVN_FUSE); - // Validate the ManifestRtSvn + // Validate the ManifestFwSvn fuse_log_entry_offset += core::mem::size_of::(); let fuse_log_entry = FuseLogEntry::read_from_prefix(fuse_entry_arr[fuse_log_entry_offset..].as_bytes()).unwrap(); assert_eq!( fuse_log_entry.entry_id, - FuseLogEntryId::ManifestRtSvn as u32 + FuseLogEntryId::ManifestFwSvn as u32 ); - assert_eq!(fuse_log_entry.log_data[0], FMC_SVN); + assert_eq!(fuse_log_entry.log_data[0], FW_SVN); // Validate the ManifestReserved1 fuse_log_entry_offset += core::mem::size_of::(); @@ -687,12 +696,12 @@ fn test_fuse_log() { ); assert_eq!(fuse_log_entry.log_data[0], 0); - // Validate the FuseRtSvn + // Validate the FuseFwSvn fuse_log_entry_offset += core::mem::size_of::(); let fuse_log_entry = FuseLogEntry::read_from_prefix(fuse_entry_arr[fuse_log_entry_offset..].as_bytes()).unwrap(); - assert_eq!(fuse_log_entry.entry_id, FuseLogEntryId::FuseRtSvn as u32); - assert_eq!(fuse_log_entry.log_data[0], FMC_SVN); + assert_eq!(fuse_log_entry.entry_id, FuseLogEntryId::FuseFwSvn as u32); + assert_eq!(fuse_log_entry.log_data[0], FW_SVN_FUSE); // Validate the VendorLmsPubKeyIndex fuse_log_entry_offset += core::mem::size_of::(); diff --git a/rom/dev/tests/rom_integration_tests/test_image_validation.rs b/rom/dev/tests/rom_integration_tests/test_image_validation.rs index db0f915aaf..725502915c 100644 --- a/rom/dev/tests/rom_integration_tests/test_image_validation.rs +++ b/rom/dev/tests/rom_integration_tests/test_image_validation.rs @@ -1348,77 +1348,6 @@ fn test_fmc_entry_point_unaligned() { ); } -#[test] -fn test_fmc_svn_greater_than_32() { - let gen = ImageGenerator::new(Crypto::default()); - let image_bundle = helpers::build_image_bundle(ImageOptions::default()); - let vendor_pubkey_digest = gen - .vendor_pubkey_digest(&image_bundle.manifest.preamble) - .unwrap(); - - let fuses = caliptra_hw_model::Fuses { - life_cycle: DeviceLifecycle::Manufacturing, - anti_rollback_disable: false, - key_manifest_pk_hash: vendor_pubkey_digest, - ..Default::default() - }; - - let image_options = ImageOptions { - fmc_svn: 33, - ..Default::default() - }; - - let (mut hw, image_bundle) = helpers::build_hw_model_and_image_bundle(fuses, image_options); - assert_eq!( - ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_GREATER_THAN_MAX_SUPPORTED.into() - ), - hw.upload_firmware(&image_bundle.to_bytes().unwrap()) - .unwrap_err() - ); - - assert_eq!( - hw.soc_ifc().cptra_boot_status().read(), - u32::from(FwProcessorManifestLoadComplete) - ); -} - -#[test] -fn test_fmc_svn_less_than_fuse_svn() { - let gen = ImageGenerator::new(Crypto::default()); - let image_bundle = helpers::build_image_bundle(ImageOptions::default()); - let vendor_pubkey_digest = gen - .vendor_pubkey_digest(&image_bundle.manifest.preamble) - .unwrap(); - - let fuses = caliptra_hw_model::Fuses { - life_cycle: DeviceLifecycle::Manufacturing, - anti_rollback_disable: false, - key_manifest_pk_hash: vendor_pubkey_digest, - fmc_key_manifest_svn: 0b11, // fuse svn = 2 - ..Default::default() - }; - - let image_options = ImageOptions { - fmc_svn: 1, - ..Default::default() - }; - - let (mut hw, image_bundle) = helpers::build_hw_model_and_image_bundle(fuses, image_options); - assert_eq!( - ModelError::MailboxCmdFailed(u32::from( - CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE - )), - hw.upload_firmware(&image_bundle.to_bytes().unwrap()) - .unwrap_err() - ); - - assert_eq!( - hw.soc_ifc().cptra_boot_status().read(), - u32::from(FwProcessorManifestLoadComplete) - ); -} - #[test] fn test_toc_rt_size_zero() { let (mut hw, mut image_bundle) = @@ -1598,7 +1527,7 @@ fn test_runtime_entry_point_unaligned() { } #[test] -fn test_runtime_svn_greater_than_max() { +fn test_firmware_svn_greater_than_max() { let gen = ImageGenerator::new(Crypto::default()); let image_bundle = helpers::build_image_bundle(ImageOptions::default()); let vendor_pubkey_digest = gen @@ -1612,14 +1541,17 @@ fn test_runtime_svn_greater_than_max() { ..Default::default() }; let image_options = ImageOptions { - app_svn: caliptra_image_verify::MAX_RUNTIME_SVN + 1, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: caliptra_image_verify::MAX_FIRMWARE_SVN + 1, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }; let (mut hw, image_bundle) = helpers::build_hw_model_and_image_bundle(fuses, image_options); assert_eq!( ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_GREATER_THAN_MAX_SUPPORTED.into() + CaliptraError::IMAGE_VERIFIER_ERR_FIRMWARE_SVN_GREATER_THAN_MAX_SUPPORTED.into() ), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() @@ -1632,7 +1564,7 @@ fn test_runtime_svn_greater_than_max() { } #[test] -fn test_runtime_svn_less_than_fuse_svn() { +fn test_firmware_svn_less_than_fuse_svn() { let gen = ImageGenerator::new(Crypto::default()); let image_bundle = helpers::build_image_bundle(ImageOptions::default()); let vendor_pubkey_digest = gen @@ -1644,25 +1576,28 @@ fn test_runtime_svn_less_than_fuse_svn() { life_cycle: DeviceLifecycle::Manufacturing, anti_rollback_disable: false, key_manifest_pk_hash: vendor_pubkey_digest, - runtime_svn: fuse_svn, + fw_svn: fuse_svn, ..Default::default() }; let image_options = ImageOptions { - app_svn: 62, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 62, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }; let (mut hw, image_bundle) = helpers::build_hw_model_and_image_bundle(fuses, image_options); assert_eq!( ModelError::MailboxCmdFailed( - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE.into() + CaliptraError::IMAGE_VERIFIER_ERR_FIRMWARE_SVN_LESS_THAN_FUSE.into() ), hw.upload_firmware(&image_bundle.to_bytes().unwrap()) .unwrap_err() ); assert_eq!( hw.soc_ifc().cptra_fw_error_fatal().read(), - u32::from(CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE) + u32::from(CaliptraError::IMAGE_VERIFIER_ERR_FIRMWARE_SVN_LESS_THAN_FUSE) ); assert_eq!( diff --git a/rom/dev/tests/rom_integration_tests/test_warm_reset.rs b/rom/dev/tests/rom_integration_tests/test_warm_reset.rs index 19d45dfb03..1a40f03b75 100644 --- a/rom/dev/tests/rom_integration_tests/test_warm_reset.rs +++ b/rom/dev/tests/rom_integration_tests/test_warm_reset.rs @@ -9,6 +9,7 @@ use caliptra_common::RomBootStatus::*; use caliptra_drivers::CaliptraError; use caliptra_hw_model::DeviceLifecycle; use caliptra_hw_model::{BootParams, Fuses, HwModel, InitParams, SecurityState}; +use caliptra_image_gen::ImageGeneratorVendorConfig; use caliptra_test::swap_word_bytes_inplace; use openssl::sha::sha384; use zerocopy::AsBytes; @@ -32,7 +33,10 @@ fn test_warm_reset_success() { &FMC_WITH_UART, &APP_WITH_UART, ImageOptions { - fmc_svn: 9, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 9, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }, ) @@ -55,7 +59,6 @@ fn test_warm_reset_success() { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }, fw_image: Some(&image.to_bytes().unwrap()), @@ -73,7 +76,6 @@ fn test_warm_reset_success() { hw.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }); diff --git a/rom/dev/tools/test-fmc/src/main.rs b/rom/dev/tools/test-fmc/src/main.rs index da6a6ca3cf..99fd7d738b 100644 --- a/rom/dev/tools/test-fmc/src/main.rs +++ b/rom/dev/tools/test-fmc/src/main.rs @@ -310,8 +310,8 @@ fn read_pcr31(mbox: &caliptra_registers::mbox::RegisterBlock) { fn read_datavault_coldresetentry4(mbox: &caliptra_registers::mbox::RegisterBlock) { let data_vault = unsafe { DataVault::new(DvReg::new()) }; - send_to_mailbox(mbox, (FmcSvn as u32).as_bytes(), false); - send_to_mailbox(mbox, data_vault.fmc_svn().as_bytes(), false); + send_to_mailbox(mbox, (DeprecatedFmcSvn as u32).as_bytes(), false); + send_to_mailbox(mbox, data_vault.fw_svn().as_bytes(), false); send_to_mailbox(mbox, (RomColdBootStatus as u32).as_bytes(), false); send_to_mailbox(mbox, data_vault.rom_cold_boot_status().as_bytes(), false); @@ -332,8 +332,8 @@ fn read_datavault_coldresetentry4(mbox: &caliptra_registers::mbox::RegisterBlock fn read_datavault_warmresetentry4(mbox: &caliptra_registers::mbox::RegisterBlock) { let data_vault = unsafe { DataVault::new(DvReg::new()) }; - send_to_mailbox(mbox, (RtSvn as u32).as_bytes(), false); - send_to_mailbox(mbox, data_vault.rt_svn().as_bytes(), false); + send_to_mailbox(mbox, (FwSvn as u32).as_bytes(), false); + send_to_mailbox(mbox, data_vault.fw_svn().as_bytes(), false); send_to_mailbox(mbox, (RtEntryPoint as u32).as_bytes(), false); send_to_mailbox(mbox, data_vault.rt_entry_point().as_bytes(), false); @@ -341,8 +341,8 @@ fn read_datavault_warmresetentry4(mbox: &caliptra_registers::mbox::RegisterBlock send_to_mailbox(mbox, (ManifestAddr as u32).as_bytes(), false); send_to_mailbox(mbox, data_vault.manifest_addr().as_bytes(), false); - send_to_mailbox(mbox, (RtMinSvn as u32).as_bytes(), false); - send_to_mailbox(mbox, data_vault.rt_min_svn().as_bytes(), false); + send_to_mailbox(mbox, (FwMinSvn as u32).as_bytes(), false); + send_to_mailbox(mbox, data_vault.fw_min_svn().as_bytes(), false); send_to_mailbox(mbox, (RomUpdateResetStatus as u32).as_bytes(), false); send_to_mailbox(mbox, data_vault.rom_update_reset_status().as_bytes(), false); diff --git a/runtime/README.md b/runtime/README.md index 51a65a4a98..47e8b2693a 100644 --- a/runtime/README.md +++ b/runtime/README.md @@ -768,9 +768,9 @@ Command Code: `0x494E_464F` ("INFO") | chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian. | fips\_status | u32 | Indicates if the command is FIPS approved or an error. | pl0_pauser | u32 | PAUSER with PL0 privileges (from image header). -| runtime_svn | u32 | Runtime SVN. -| min_runtime_svn | u32 | Min Runtime SVN. -| fmc_manifest_svn | u32 | FMC SVN. +| firmware_svn | u32 | Firmware SVN. +| min_firmware_svn | u32 | Min Firmware SVN. +| _deprecated_fmc_svn | u32 | FMC SVN (deprecated). | attestation_disabled | u32 | State of attestation disable. | rom_revision | u8[20] | Revision (Git commit ID) of ROM build. | fmc_revision | u8[20] | Revision (Git commit ID) of FMC build. diff --git a/runtime/src/handoff.rs b/runtime/src/handoff.rs index 7e763f2f9b..2d0965ec89 100644 --- a/runtime/src/handoff.rs +++ b/runtime/src/handoff.rs @@ -46,22 +46,22 @@ impl RtHandoff<'_> { } } - /// Retrieve runtime SVN. - pub fn rt_svn(&self) -> CaliptraResult { - self.read_from_ds(self.fht.rt_svn_dv_hdl.try_into()?) - .map_err(|_| CaliptraError::RUNTIME_RT_SVN_HANDOFF_FAILED) + /// Retrieve firmware SVN. + pub fn fw_svn(&self) -> CaliptraResult { + self.read_from_ds(self.fht.fw_svn_dv_hdl.try_into()?) + .map_err(|_| CaliptraError::RUNTIME_FW_SVN_HANDOFF_FAILED) } - /// Retrieve runtime minimum SVN. - pub fn rt_min_svn(&self) -> CaliptraResult { - self.read_from_ds(self.fht.rt_min_svn_dv_hdl.try_into()?) - .map_err(|_| CaliptraError::RUNTIME_RT_MIN_SVN_HANDOFF_FAILED) + /// Retrieve firmware minimum SVN. + pub fn fw_min_svn(&self) -> CaliptraResult { + self.read_from_ds(self.fht.fw_min_svn_dv_hdl.try_into()?) + .map_err(|_| CaliptraError::RUNTIME_FW_MIN_SVN_HANDOFF_FAILED) } - /// Retrieve FMC SVN. - pub fn fmc_svn(&self) -> CaliptraResult { - self.read_from_ds(self.fht.fmc_svn_dv_hdl.try_into()?) - .map_err(|_| CaliptraError::RUNTIME_FMC_SVN_HANDOFF_FAILED) + /// Retrieve cold-boot deprecated FMC SVN. + pub fn deprecated_fmc_svn(&self) -> CaliptraResult { + self.read_from_ds(self.fht.deprecated_fmc_svn_dv_hdl.try_into()?) + .map_err(|_| CaliptraError::RUNTIME_DEPRECATED_FMC_SVN_HANDOFF_FAILED) } /// Retrieve the RT FW hash chain. diff --git a/runtime/src/info.rs b/runtime/src/info.rs index e5d5c51f93..d26eaeaed8 100644 --- a/runtime/src/info.rs +++ b/runtime/src/info.rs @@ -27,17 +27,17 @@ impl FwInfoCmd { fht: &pdata.fht, }; - let runtime_svn = handoff.rt_svn()?; - let min_runtime_svn = handoff.rt_min_svn()?; - let fmc_manifest_svn = handoff.fmc_svn()?; + let fw_svn = handoff.fw_svn()?; + let min_fw_svn = handoff.fw_min_svn()?; + let deprecated_fmc_svn = handoff.deprecated_fmc_svn()?; let rom_info = handoff.fht.rom_info_addr.get()?; Ok(MailboxResp::FwInfo(FwInfoResp { hdr: MailboxRespHeader::default(), pl0_pauser: pdata.manifest1.header.pl0_pauser, - runtime_svn, - min_runtime_svn, - fmc_manifest_svn, + fw_svn, + min_fw_svn, + deprecated_fmc_svn, attestation_disabled: pdata.attestation_disabled.get().into(), rom_revision: rom_info.revision, fmc_revision: pdata.manifest1.fmc.revision, diff --git a/runtime/tests/runtime_integration_tests/test_info.rs b/runtime/tests/runtime_integration_tests/test_info.rs index 4b13cc6097..e6ba110e61 100644 --- a/runtime/tests/runtime_integration_tests/test_info.rs +++ b/runtime/tests/runtime_integration_tests/test_info.rs @@ -43,10 +43,9 @@ fn test_fw_info() { image_opts.vendor_config.pl0_pauser = Some(0x1); image_opts.fmc_version = 0xaaaa; image_opts.app_version = 0xbbbbbbbb; - image_opts.fmc_svn = 5; let mut image_opts10 = image_opts.clone(); - image_opts10.app_svn = 10; + image_opts10.vendor_config.fw_svn = 10; // Cannot use run_rt_test since we need the rom and image to verify info let rom = caliptra_builder::rom_for_fw_integration_tests().unwrap(); @@ -107,9 +106,9 @@ fn test_fw_info() { let info = get_fwinfo(&mut model); // Verify FW info assert_eq!(info.pl0_pauser, 0x1); - assert_eq!(info.fmc_manifest_svn, 5); - assert_eq!(info.runtime_svn, 10); - assert_eq!(info.min_runtime_svn, 10); + assert_eq!(info.deprecated_fmc_svn, 10); + assert_eq!(info.fw_svn, 10); + assert_eq!(info.min_fw_svn, 10); // Verify revision (Commit ID) and digest of each component assert_eq!(info.rom_revision, rom_info.revision); assert_eq!(info.fmc_revision, image.manifest.fmc.revision); @@ -120,7 +119,7 @@ fn test_fw_info() { // Make image with newer SVN. let mut image_opts20 = image_opts.clone(); - image_opts20.app_svn = 20; + image_opts20.vendor_config.fw_svn = 20; let image20 = caliptra_builder::build_and_sign_image(&FMC_WITH_UART, &APP_WITH_UART, image_opts20) @@ -132,12 +131,13 @@ fn test_fw_info() { update_to(&mut model, &image20); let info = get_fwinfo(&mut model); - assert_eq!(info.runtime_svn, 20); - assert_eq!(info.min_runtime_svn, 10); + assert_eq!(info.fw_svn, 20); + assert_eq!(info.min_fw_svn, 10); + assert_eq!(info.deprecated_fmc_svn, 10); // Make image with older SVN. let mut image_opts5 = image_opts; - image_opts5.app_svn = 5; + image_opts5.vendor_config.fw_svn = 5; let image5 = caliptra_builder::build_and_sign_image(&FMC_WITH_UART, &APP_WITH_UART, image_opts5) @@ -147,14 +147,16 @@ fn test_fw_info() { update_to(&mut model, &image5); let info = get_fwinfo(&mut model); - assert_eq!(info.runtime_svn, 5); - assert_eq!(info.min_runtime_svn, 5); + assert_eq!(info.fw_svn, 5); + assert_eq!(info.min_fw_svn, 5); + assert_eq!(info.deprecated_fmc_svn, 10); // Go back to SVN 20 update_to(&mut model, &image20); let info = get_fwinfo(&mut model); - assert_eq!(info.runtime_svn, 20); - assert_eq!(info.min_runtime_svn, 5); + assert_eq!(info.fw_svn, 20); + assert_eq!(info.min_fw_svn, 5); + assert_eq!(info.deprecated_fmc_svn, 10); } #[test] diff --git a/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs b/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs index 15865b98a3..39b6142d17 100644 --- a/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs +++ b/runtime/tests/runtime_integration_tests/test_pauser_privilege_levels.rs @@ -522,17 +522,11 @@ fn test_pl0_unset_in_header() { fmc: ElfExecutable::new( &fmc_elf, opts.fmc_version as u32, - opts.fmc_svn, - *b"~~~~~NO_GIT_REVISION", - ) - .unwrap(), - runtime: ElfExecutable::new( - &app_elf, - opts.app_version, - opts.app_svn, *b"~~~~~NO_GIT_REVISION", ) .unwrap(), + runtime: ElfExecutable::new(&app_elf, opts.app_version, *b"~~~~~NO_GIT_REVISION") + .unwrap(), vendor_config: opts.vendor_config, owner_config: opts.owner_config, fw_image_type: FwImageType::EccLms, diff --git a/runtime/tests/runtime_integration_tests/test_warm_reset.rs b/runtime/tests/runtime_integration_tests/test_warm_reset.rs index ad8a998086..b513a42115 100644 --- a/runtime/tests/runtime_integration_tests/test_warm_reset.rs +++ b/runtime/tests/runtime_integration_tests/test_warm_reset.rs @@ -7,6 +7,7 @@ use caliptra_builder::{ }; use caliptra_error::CaliptraError; use caliptra_hw_model::{BootParams, DeviceLifecycle, Fuses, HwModel, InitParams, SecurityState}; +use caliptra_image_gen::ImageGeneratorVendorConfig; use caliptra_registers::mbox::enums::MboxStatusE; use dpe::DPE_PROFILE; use openssl::sha::sha384; @@ -35,7 +36,10 @@ fn test_rt_journey_pcr_validation() { &FMC_WITH_UART, &firmware::runtime_tests::MBOX, ImageOptions { - fmc_svn: 9, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 9, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }, ) @@ -57,7 +61,6 @@ fn test_rt_journey_pcr_validation() { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }, fw_image: Some(&image.to_bytes().unwrap()), @@ -78,7 +81,6 @@ fn test_rt_journey_pcr_validation() { model.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }); @@ -102,7 +104,10 @@ fn test_mbox_busy_during_warm_reset() { &FMC_WITH_UART, &APP_WITH_UART, ImageOptions { - fmc_svn: 9, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 9, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }, ) @@ -124,7 +129,6 @@ fn test_mbox_busy_during_warm_reset() { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }, fw_image: Some(&image.to_bytes().unwrap()), @@ -145,7 +149,6 @@ fn test_mbox_busy_during_warm_reset() { model.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }); diff --git a/test/src/derive.rs b/test/src/derive.rs index b7b28bccc0..6b6c394f92 100644 --- a/test/src/derive.rs +++ b/test/src/derive.rs @@ -301,8 +301,8 @@ pub struct Pcr0Input { pub owner_pub_key_hash_from_fuses: bool, pub ecc_vendor_pub_key_index: u32, pub fmc_digest: [u32; 12], - pub fmc_svn: u32, - pub fmc_fuse_svn: u32, + pub fw_svn: u32, + pub fw_fuse_svn: u32, pub lms_vendor_pub_key_index: u32, pub rom_verify_config: u32, } @@ -324,8 +324,8 @@ impl Pcr0 { input.security_state.debug_locked() as u8, input.fuse_anti_rollback_disable as u8, input.ecc_vendor_pub_key_index as u8, - input.fmc_svn as u8, - input.fmc_fuse_svn as u8, + input.fw_svn as u8, + input.fw_fuse_svn as u8, input.lms_vendor_pub_key_index as u8, input.rom_verify_config as u8, input.owner_pub_key_hash_from_fuses as u8, @@ -368,8 +368,8 @@ fn test_derive_pcr0() { 0xe44ea855, 0x9fcf4063, 0xd3110a9a, 0xd60579db, 0xe03e6dd7, 0x4556cd98, 0xb2b941f5, 0x1bb5034b, 0x587eea1f, 0xfcdd0e0f, 0x8e88d406, 0x3327a3fe, ], - fmc_svn: 5, - fmc_fuse_svn: 2, + fw_svn: 5, + fw_fuse_svn: 2, lms_vendor_pub_key_index: u32::MAX, rom_verify_config: 1, // RomVerifyConfig::EcdsaAndLms }); diff --git a/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs b/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs index b837701cef..6eb6412fc0 100755 --- a/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs +++ b/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs @@ -11,6 +11,7 @@ use caliptra_common::mailbox_api::{ CommandId, GetFmcAliasCertResp, GetLdevCertResp, MailboxReqHeader, MailboxRespHeader, }; use caliptra_hw_model::{BootParams, HwModel, InitParams}; +use caliptra_image_gen::ImageGeneratorVendorConfig; use caliptra_test::{ derive::{DoeInput, DoeOutput, LDevId}, swap_word_bytes, swap_word_bytes_inplace, @@ -58,7 +59,10 @@ fn fake_boot_test() { &FMC_FAKE_WITH_UART, &APP_WITH_UART, ImageOptions { - fmc_svn: 9, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 9, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }, ) @@ -80,7 +84,6 @@ fn fake_boot_test() { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }, fw_image: Some(&image.to_bytes().unwrap()), @@ -259,9 +262,9 @@ fn fake_boot_test() { owner_pub_key_from_fuses: true, ecc_vendor_pub_key_index: image.manifest.preamble.vendor_ecc_pub_key_idx, fmc_digest: FMC_CANNED_DIGEST, - fmc_svn: image.manifest.fmc.svn, + fw_svn: image.manifest.fmc.svn, // This is from the SVN in the fuses (7 bits set) - fmc_fuse_svn: 7, + fw_fuse_svn: 7, lms_vendor_pub_key_index: u32::MAX, rom_verify_config: 0, // RomVerifyConfig::EcdsaOnly }), diff --git a/test/tests/caliptra_integration_tests/jtag_test.rs b/test/tests/caliptra_integration_tests/jtag_test.rs index 00535c1819..2a997e64bb 100644 --- a/test/tests/caliptra_integration_tests/jtag_test.rs +++ b/test/tests/caliptra_integration_tests/jtag_test.rs @@ -4,6 +4,7 @@ use caliptra_builder::{firmware, get_elf_path, ImageOptions}; use caliptra_api_types::DeviceLifecycle; use caliptra_hw_model::{BootParams, Fuses, HwModel, InitParams, SecurityState}; +use caliptra_image_gen::ImageGeneratorVendorConfig; use caliptra_test::swap_word_bytes_inplace; use openssl::sha::sha384; use std::io::{BufRead, BufReader, Write}; @@ -89,7 +90,10 @@ fn gdb_test() { &firmware::FMC_WITH_UART, &firmware::APP_WITH_UART, ImageOptions { - fmc_svn: 9, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 9, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }, ) @@ -102,7 +106,6 @@ fn gdb_test() { let fuses = Fuses { key_manifest_pk_hash: vendor_pk_desc_hash_words, owner_pk_hash: owner_pk_desc_hash_words, - fmc_key_manifest_svn: 0b1111111, lms_verify: true, ..Default::default() }; diff --git a/test/tests/caliptra_integration_tests/smoke_test.rs b/test/tests/caliptra_integration_tests/smoke_test.rs index 0e4900bd04..ad28191c4b 100644 --- a/test/tests/caliptra_integration_tests/smoke_test.rs +++ b/test/tests/caliptra_integration_tests/smoke_test.rs @@ -10,6 +10,7 @@ use caliptra_common::RomBootStatus; use caliptra_drivers::CaliptraError; use caliptra_hw_model::{BootParams, HwModel, InitParams, SecurityState}; use caliptra_hw_model_types::{RandomEtrngResponses, RandomNibbles}; +use caliptra_image_gen::ImageGeneratorVendorConfig; use caliptra_test::derive::{PcrRtCurrentInput, RtAliasKey}; use caliptra_test::{derive, redact_cert, run_test, RedactOpts, UnwrapSingle}; use caliptra_test::{ @@ -150,7 +151,10 @@ fn smoke_test() { &firmware::FMC_WITH_UART, &firmware::APP_WITH_UART, ImageOptions { - fmc_svn: 9, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 9, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }, ) @@ -163,8 +167,8 @@ fn smoke_test() { let fuses = Fuses { key_manifest_pk_hash: vendor_pk_desc_hash_words, owner_pk_hash: owner_pk_desc_hash_words, - fmc_key_manifest_svn: 0b1111111, lms_verify: true, + fw_svn: [0x7F, 0, 0, 0], // Equals 7 ..Default::default() }; let mut hw = caliptra_hw_model::new( @@ -318,9 +322,9 @@ fn smoke_test() { owner_pub_key_hash_from_fuses: true, ecc_vendor_pub_key_index: image.manifest.preamble.vendor_ecc_pub_key_idx, fmc_digest: image.manifest.fmc.digest, - fmc_svn: image.manifest.fmc.svn, + fw_svn: image.manifest.fmc.svn, // This is from the SVN in the fuses (7 bits set) - fmc_fuse_svn: 7, + fw_fuse_svn: 7, lms_vendor_pub_key_index: image.manifest.header.vendor_lms_pub_key_idx, rom_verify_config: 1, // RomVerifyConfig::EcdsaAndLms }), @@ -461,7 +465,8 @@ fn smoke_test() { Some(DiceTcbInfo { vendor: Some("Caliptra".into()), model: Some("RT".into()), - svn: Some(0x100), + // This is from the SVN in the image (9) + svn: Some(0x109), fwids: vec![DiceFwid { // RT hash_alg: asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 2), @@ -557,8 +562,11 @@ fn smoke_test() { &firmware::FMC_WITH_UART, &firmware::APP, ImageOptions { + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 10, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, fmc_version: 1, - fmc_svn: 10, app_version: 2, ..Default::default() }, @@ -611,7 +619,8 @@ fn smoke_test() { Some(DiceTcbInfo { vendor: Some("Caliptra".into()), model: Some("RT".into()), - svn: Some(0x100), + // This is from the SVN in the image (10) + svn: Some(0x10A), fwids: vec![DiceFwid { // FMC hash_alg: asn1::oid!(2, 16, 840, 1, 101, 3, 4, 2, 2), diff --git a/test/tests/caliptra_integration_tests/warm_reset.rs b/test/tests/caliptra_integration_tests/warm_reset.rs index c793369829..839b74438c 100644 --- a/test/tests/caliptra_integration_tests/warm_reset.rs +++ b/test/tests/caliptra_integration_tests/warm_reset.rs @@ -8,6 +8,7 @@ use caliptra_builder::{ }; use caliptra_common::mailbox_api::CommandId; use caliptra_hw_model::{mbox_write_fifo, BootParams, HwModel, InitParams, SecurityState}; +use caliptra_image_gen::ImageGeneratorVendorConfig; use caliptra_test::swap_word_bytes_inplace; use openssl::sha::sha384; use zerocopy::AsBytes; @@ -29,7 +30,10 @@ fn warm_reset_basic() { &FMC_WITH_UART, &APP_WITH_UART, ImageOptions { - fmc_svn: 9, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 9, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }, ) @@ -51,7 +55,6 @@ fn warm_reset_basic() { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }, fw_image: Some(&image.to_bytes().unwrap()), @@ -69,7 +72,6 @@ fn warm_reset_basic() { hw.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }); @@ -90,7 +92,10 @@ fn warm_reset_during_fw_load() { &FMC_WITH_UART, &APP_WITH_UART, ImageOptions { - fmc_svn: 9, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 9, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }, ) @@ -112,7 +117,6 @@ fn warm_reset_during_fw_load() { fuses: Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }, fw_image: None, @@ -141,7 +145,6 @@ fn warm_reset_during_fw_load() { hw.warm_reset_flow(&Fuses { key_manifest_pk_hash: vendor_pk_desc_hash, owner_pk_hash: owner_pk_desc_hash, - fmc_key_manifest_svn: 0b1111111, ..Default::default() }); diff --git a/test/tests/fips_test_suite/README.md b/test/tests/fips_test_suite/README.md index 38085b0624..dd101f7540 100755 --- a/test/tests/fips_test_suite/README.md +++ b/test/tests/fips_test_suite/README.md @@ -72,7 +72,7 @@ Test hooks are needed to meet the following FIPS 140-3 test requirements: | kat_sha1_digest_failure_rom
kat_sha1_digest_mismatch_rom
kat_sha256_digest_failure_rom
kat_sha256_digest_mismatch_rom
kat_sha384_digest_failure_rom
kat_sha384_digest_mismatch_rom
kat_sha2_512_384acc_digest_start_op_failure_rom
kat_sha2_512_384acc_digest_failure_rom
kat_sha2_512_384acc_digest_mismatch_rom
kat_ecc384_signature_generate_failure_rom
kat_ecc384_signature_verify_failure_rom
kat_hmac384_failure_rom
kat_hmac384_tag_mismatch_rom
kat_lms_digest_mismatch_rom | TE10.07.03
TE10.08.03
TE10.09.03
TE10.10.01
TE10.10.02 | Enable the hook for triggering an error with the SHA1 KAT
Verify the correct error is returned
Verify we cannot utilize the associated functionality by proving we can't issues commands
Verify an undocumented attempt to clear the error fails
Clear the error with an approved method - restart Caliptra
Verify crypto operations using the engine can be performed | | kat_sha1_digest_failure_rt
kat_sha1_digest_mismatch_rt
kat_sha256_digest_failure_rt
kat_sha256_digest_mismatch_rt
kat_sha384_digest_failure_rt
kat_sha384_digest_mismatch_rt
kat_sha2_512_384acc_digest_start_op_failure_rt
kat_sha2_512_384acc_digest_failure_rt
kat_sha2_512_384acc_digest_mismatch_rt
kat_ecc384_signature_generate_failure_rt
kat_ecc384_signature_verify_failure_rt
kat_hmac384_failure_rt
kat_hmac384_tag_mismatch_rt
kat_lms_digest_mismatch_rt | TE10.07.03
TE10.08.03
TE10.09.03
TE10.10.01
TE10.10.02 | Boot to runtime
Enable the hook for triggering an error with the KAT
Issue self test command
Verify the correct error is returned
Verify we cannot utilize the associated functionality by proving we can't issues commands
Verify an undocumented attempt to clear the error fails
Clear the error with an approved method - restart Caliptra
Verify crypto operations using the engine can be performed | | integrity_check_failure_rom | TE10.07.03
TE10.08.03
TE10.09.03
TE10.10.01
TE10.10.02 | Corrupt ROM integrity check hash
Verify the correct error is returned
Verify we cannot issue commands
Verify an undocumented attempt to clear the error fails
(Cannot clear this error without changing ROM which would invlove recreating the whole platform with a new ROM and therefore isn't really a continuation of this test) | -| fw_load_error_manifest_marker_mismatch
fw_load_error_manifest_size_mismatch
fw_load_error_vendor_pub_key_digest_invalid
fw_load_error_vendor_pub_key_digest_failure
fw_load_error_vendor_pub_key_digest_mismatch
fw_load_error_owner_pub_key_digest_failure
fw_load_error_owner_pub_key_digest_mismatch
fw_load_error_vendor_ecc_pub_key_index_out_of_bounds
fw_load_error_vendor_ecc_pub_key_revoked
fw_load_error_header_digest_failure
fw_load_error_vendor_ecc_verify_failure
fw_load_error_vendor_ecc_signature_invalid
fw_load_error_vendor_ecc_pub_key_index_mismatch
fw_load_error_owner_ecc_verify_failure
fw_load_error_owner_ecc_signature_invalid
fw_load_error_toc_entry_count_invalid
fw_load_error_toc_digest_failure
fw_load_error_toc_digest_mismatch
fw_load_error_fmc_digest_failure
fw_load_error_fmc_digest_mismatch
fw_load_error_runtime_digest_failure
fw_load_error_runtime_digest_mismatch
fw_load_error_fmc_runtime_overlap
fw_load_error_fmc_runtime_incorrect_order
fw_load_error_owner_ecc_pub_key_invalid_arg
fw_load_error_owner_ecc_signature_invalid_arg
fw_load_error_vendor_pub_key_digest_invalid_arg
fw_load_error_vendor_ecc_signature_invalid_arg
fw_load_error_update_reset_owner_digest_failure
fw_load_error_update_reset_vendor_ecc_pub_key_idx_mismatch
fw_load_error_update_reset_fmc_digest_mismatch
fw_load_error_fmc_load_addr_invalid
fw_load_error_fmc_load_addr_unaligned
fw_load_error_fmc_entry_point_invalid
fw_load_error_fmc_entry_point_unaligned
fw_load_error_fmc_svn_greater_than_max_supported
fw_load_error_fmc_svn_less_than_fuse
fw_load_error_runtime_load_addr_invalid
fw_load_error_runtime_load_addr_unaligned
fw_load_error_runtime_entry_point_invalid
fw_load_error_runtime_entry_point_unaligned
fw_load_error_runtime_svn_greater_than_max_supported
fw_load_error_runtime_svn_less_than_fuse
fw_load_error_image_len_more_than_bundle_size
fw_load_error_vendor_lms_pub_key_index_mismatch
fw_load_error_vendor_lms_verify_failure
fw_load_error_vendor_lms_pub_key_index_out_of_bounds
fw_load_error_vendor_lms_signature_invalid
fw_load_error_fmc_runtime_load_addr_overlap
fw_load_error_owner_lms_verify_failure
fw_load_error_owner_lms_signature_invalid
fw_load_error_vendor_lms_pub_key_revoked
fw_load_error_fmc_size_zero
fw_load_error_runtime_size_zero
fw_load_error_update_reset_vendor_lms_pub_key_idx_mismatch
fw_load_error_fmc_load_address_image_size_arithmetic_overflow
fw_load_error_runtime_load_address_image_size_arithmetic_overflow
fw_load_error_toc_entry_range_arithmetic_overflow | TE10.07.03
TE10.08.03
TE10.09.03
TE10.10.01
TE10.10.02 | Make change related to error in fw bundle or fuses
Attempt to load the FW
Verify the correct error is returned
Verify we cannot utilize RT FW by sending a message
Verify an undocumented attempt to clear the error fails
Clear the error with an approved method - restart Caliptra
Verify we can utilize RT FW by sending a message
NOTE: This isn't a specific crypto engine but this still counts as a self test, some of the requirements are tailored toward crypto engines. | +| fw_load_error_manifest_marker_mismatch
fw_load_error_manifest_size_mismatch
fw_load_error_vendor_pub_key_digest_invalid
fw_load_error_vendor_pub_key_digest_failure
fw_load_error_vendor_pub_key_digest_mismatch
fw_load_error_owner_pub_key_digest_failure
fw_load_error_owner_pub_key_digest_mismatch
fw_load_error_vendor_ecc_pub_key_index_out_of_bounds
fw_load_error_vendor_ecc_pub_key_revoked
fw_load_error_header_digest_failure
fw_load_error_vendor_ecc_verify_failure
fw_load_error_vendor_ecc_signature_invalid
fw_load_error_vendor_ecc_pub_key_index_mismatch
fw_load_error_owner_ecc_verify_failure
fw_load_error_owner_ecc_signature_invalid
fw_load_error_toc_entry_count_invalid
fw_load_error_toc_digest_failure
fw_load_error_toc_digest_mismatch
fw_load_error_fmc_digest_failure
fw_load_error_fmc_digest_mismatch
fw_load_error_runtime_digest_failure
fw_load_error_runtime_digest_mismatch
fw_load_error_fmc_runtime_overlap
fw_load_error_fmc_runtime_incorrect_order
fw_load_error_owner_ecc_pub_key_invalid_arg
fw_load_error_owner_ecc_signature_invalid_arg
fw_load_error_vendor_pub_key_digest_invalid_arg
fw_load_error_vendor_ecc_signature_invalid_arg
fw_load_error_update_reset_owner_digest_failure
fw_load_error_update_reset_vendor_ecc_pub_key_idx_mismatch
fw_load_error_update_reset_fmc_digest_mismatch
fw_load_error_fmc_load_addr_invalid
fw_load_error_fmc_load_addr_unaligned
fw_load_error_fmc_entry_point_invalid
fw_load_error_fmc_entry_point_unaligned
fw_load_error_runtime_load_addr_invalid
fw_load_error_runtime_load_addr_unaligned
fw_load_error_runtime_entry_point_invalid
fw_load_error_runtime_entry_point_unaligned
fw_load_error_firmware_svn_greater_than_max_supported
fw_load_error_firmware_svn_less_than_fuse
fw_load_error_image_len_more_than_bundle_size
fw_load_error_vendor_lms_pub_key_index_mismatch
fw_load_error_vendor_lms_verify_failure
fw_load_error_vendor_lms_pub_key_index_out_of_bounds
fw_load_error_vendor_lms_signature_invalid
fw_load_error_fmc_runtime_load_addr_overlap
fw_load_error_owner_lms_verify_failure
fw_load_error_owner_lms_signature_invalid
fw_load_error_vendor_lms_pub_key_revoked
fw_load_error_fmc_size_zero
fw_load_error_runtime_size_zero
fw_load_error_update_reset_vendor_lms_pub_key_idx_mismatch
fw_load_error_fmc_load_address_image_size_arithmetic_overflow
fw_load_error_runtime_load_address_image_size_arithmetic_overflow
fw_load_error_toc_entry_range_arithmetic_overflow | TE10.07.03
TE10.08.03
TE10.09.03
TE10.10.01
TE10.10.02 | Make change related to error in fw bundle or fuses
Attempt to load the FW
Verify the correct error is returned
Verify we cannot utilize RT FW by sending a message
Verify an undocumented attempt to clear the error fails
Clear the error with an approved method - restart Caliptra
Verify we can utilize RT FW by sending a message
NOTE: This isn't a specific crypto engine but this still counts as a self test, some of the requirements are tailored toward crypto engines. | | key_pair_consistency_error | TE10.35.04 | Enable hook to corrupt key pair during generation
Trigger the keypair generation (Just boot and allow DICE flow to start?)
Verify the correct error for key pair inconsistency is generated | | fw_load_blank_pub_keys
fw_load_blank_pub_key_hashes | TE10.37.09 | Clear the public keys/hashes from the FW image
Start the FW load
Verify the correct error is returned | | fips_self_test_rom
fips_self_test_rt | TE10.53.02 | Execute FIPS self test command
Verify the output is correct and the self tests pass | diff --git a/test/tests/fips_test_suite/fw_load.rs b/test/tests/fips_test_suite/fw_load.rs index 0d7192bb5b..eed65324bd 100755 --- a/test/tests/fips_test_suite/fw_load.rs +++ b/test/tests/fips_test_suite/fw_load.rs @@ -792,65 +792,6 @@ fn fw_load_error_fmc_entry_point_unaligned() { ); } -#[test] -fn fw_load_error_fmc_svn_greater_than_max_supported() { - // Generate image - let image_options = ImageOptions { - fmc_svn: 33, - ..Default::default() - }; - let fw_image = build_fw_image(image_options); - - // Set fuses - let gen = ImageGenerator::new(Crypto::default()); - let vendor_pubkey_digest = gen - .vendor_pubkey_digest(&fw_image.manifest.preamble) - .unwrap(); - let fuses = caliptra_hw_model::Fuses { - life_cycle: DeviceLifecycle::Manufacturing, - anti_rollback_disable: false, - key_manifest_pk_hash: vendor_pubkey_digest, - ..Default::default() - }; - - fw_load_error_flow( - Some(fw_image), - Some(fuses), - CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_GREATER_THAN_MAX_SUPPORTED.into(), - ); -} - -// IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_MIN_SUPPORTED is defined but never used in the code (svn is a u32) - -#[test] -fn fw_load_error_fmc_svn_less_than_fuse() { - // Generate image - let image_options = ImageOptions { - fmc_svn: 1, - ..Default::default() - }; - let fw_image = build_fw_image(image_options); - - // Set fuses - let gen = ImageGenerator::new(Crypto::default()); - let vendor_pubkey_digest = gen - .vendor_pubkey_digest(&fw_image.manifest.preamble) - .unwrap(); - let fuses = caliptra_hw_model::Fuses { - life_cycle: DeviceLifecycle::Manufacturing, - anti_rollback_disable: false, - key_manifest_pk_hash: vendor_pubkey_digest, - fmc_key_manifest_svn: 0b11, // fuse svn = 2 - ..Default::default() - }; - - fw_load_error_flow( - Some(fw_image), - Some(fuses), - CaliptraError::IMAGE_VERIFIER_ERR_FMC_SVN_LESS_THAN_FUSE.into(), - ); -} - #[test] fn fw_load_error_runtime_load_addr_invalid() { // Generate image @@ -912,10 +853,13 @@ fn fw_load_error_runtime_entry_point_unaligned() { } #[test] -fn fw_load_error_runtime_svn_greater_than_max_supported() { +fn fw_load_error_firmware_svn_greater_than_max_supported() { // Generate image let image_options = ImageOptions { - app_svn: caliptra_image_verify::MAX_RUNTIME_SVN + 1, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: caliptra_image_verify::MAX_FIRMWARE_SVN + 1, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }; let fw_image = build_fw_image(image_options); @@ -935,17 +879,18 @@ fn fw_load_error_runtime_svn_greater_than_max_supported() { fw_load_error_flow( Some(fw_image), Some(fuses), - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_GREATER_THAN_MAX_SUPPORTED.into(), + CaliptraError::IMAGE_VERIFIER_ERR_FIRMWARE_SVN_GREATER_THAN_MAX_SUPPORTED.into(), ); } -// IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_MIN_SUPPORTED is defined but never used in the code (svn is a u32) - #[test] -fn fw_load_error_runtime_svn_less_than_fuse() { +fn fw_load_error_firmware_svn_less_than_fuse() { // Generate image let image_options = ImageOptions { - app_svn: 62, + vendor_config: ImageGeneratorVendorConfig { + fw_svn: 62, + ..caliptra_image_fake_keys::VENDOR_CONFIG_KEY_0 + }, ..Default::default() }; let fw_image = build_fw_image(image_options); @@ -959,14 +904,14 @@ fn fw_load_error_runtime_svn_less_than_fuse() { life_cycle: DeviceLifecycle::Manufacturing, anti_rollback_disable: false, key_manifest_pk_hash: vendor_pubkey_digest, - runtime_svn: [0xffff_ffff, 0x7fff_ffff, 0, 0], // fuse svn = 63 + fw_svn: [0xffff_ffff, 0x7fff_ffff, 0, 0], // fuse svn = 63 ..Default::default() }; fw_load_error_flow( Some(fw_image), Some(fuses), - CaliptraError::IMAGE_VERIFIER_ERR_RUNTIME_SVN_LESS_THAN_FUSE.into(), + CaliptraError::IMAGE_VERIFIER_ERR_FIRMWARE_SVN_LESS_THAN_FUSE.into(), ); } diff --git a/x509/build/cert.rs b/x509/build/cert.rs index 966a6412bd..a13d7cce44 100644 --- a/x509/build/cert.rs +++ b/x509/build/cert.rs @@ -110,13 +110,13 @@ impl CertTemplateBuilder { }); self.params.push(CertTemplateParam { - tbs_param: TbsParam::new("tcb_info_fmc_svn", 0, std::mem::size_of_val(&svn)), + tbs_param: TbsParam::new("tcb_info_fw_svn", 0, std::mem::size_of_val(&svn)), needle: svn.to_be_bytes().to_vec(), }); self.params.push(CertTemplateParam { tbs_param: TbsParam::new( - "tcb_info_fmc_svn_fuses", + "tcb_info_fw_svn_fuses", 0, std::mem::size_of_val(&svn_fuses), ), @@ -141,7 +141,7 @@ impl CertTemplateBuilder { .unwrap(); self.params.push(CertTemplateParam { - tbs_param: TbsParam::new("tcb_info_rt_svn", 0, std::mem::size_of_val(&svn)), + tbs_param: TbsParam::new("tcb_info_fw_svn", 0, std::mem::size_of_val(&svn)), needle: svn.to_be_bytes().to_vec(), }); diff --git a/x509/build/fmc_alias_cert_tbs.rs b/x509/build/fmc_alias_cert_tbs.rs index dfda357ba1..c23b9fb12c 100644 --- a/x509/build/fmc_alias_cert_tbs.rs +++ b/x509/build/fmc_alias_cert_tbs.rs @@ -20,8 +20,8 @@ pub struct FmcAliasCertTbsParams<'a> { pub not_before: &'a [u8; 15usize], pub not_after: &'a [u8; 15usize], pub tcb_info_flags: &'a [u8; 4usize], - pub tcb_info_fmc_svn: &'a [u8; 1usize], - pub tcb_info_fmc_svn_fuses: &'a [u8; 1usize], + pub tcb_info_fw_svn: &'a [u8; 1usize], + pub tcb_info_fw_svn_fuses: &'a [u8; 1usize], } impl<'a> FmcAliasCertTbsParams<'a> { pub const PUBLIC_KEY_LEN: usize = 97usize; @@ -36,8 +36,8 @@ impl<'a> FmcAliasCertTbsParams<'a> { pub const NOT_BEFORE_LEN: usize = 15usize; pub const NOT_AFTER_LEN: usize = 15usize; pub const TCB_INFO_FLAGS_LEN: usize = 4usize; - pub const TCB_INFO_FMC_SVN_LEN: usize = 1usize; - pub const TCB_INFO_FMC_SVN_FUSES_LEN: usize = 1usize; + pub const TCB_INFO_FW_SVN_LEN: usize = 1usize; + pub const TCB_INFO_FW_SVN_FUSES_LEN: usize = 1usize; } pub struct FmcAliasCertTbs { tbs: [u8; Self::TBS_TEMPLATE_LEN], @@ -55,8 +55,8 @@ impl FmcAliasCertTbs { const NOT_BEFORE_OFFSET: usize = 154usize; const NOT_AFTER_OFFSET: usize = 171usize; const TCB_INFO_FLAGS_OFFSET: usize = 602usize; - const TCB_INFO_FMC_SVN_OFFSET: usize = 646usize; - const TCB_INFO_FMC_SVN_FUSES_OFFSET: usize = 533usize; + const TCB_INFO_FW_SVN_OFFSET: usize = 646usize; + const TCB_INFO_FW_SVN_FUSES_OFFSET: usize = 533usize; const PUBLIC_KEY_LEN: usize = 97usize; const SUBJECT_SN_LEN: usize = 64usize; const ISSUER_SN_LEN: usize = 64usize; @@ -69,8 +69,8 @@ impl FmcAliasCertTbs { const NOT_BEFORE_LEN: usize = 15usize; const NOT_AFTER_LEN: usize = 15usize; const TCB_INFO_FLAGS_LEN: usize = 4usize; - const TCB_INFO_FMC_SVN_LEN: usize = 1usize; - const TCB_INFO_FMC_SVN_FUSES_LEN: usize = 1usize; + const TCB_INFO_FW_SVN_LEN: usize = 1usize; + const TCB_INFO_FW_SVN_FUSES_LEN: usize = 1usize; pub const TBS_TEMPLATE_LEN: usize = 786usize; const TBS_TEMPLATE: [u8; Self::TBS_TEMPLATE_LEN] = [ 48u8, 130u8, 3u8, 14u8, 160u8, 3u8, 2u8, 1u8, 2u8, 2u8, 20u8, 95u8, 95u8, 95u8, 95u8, 95u8, @@ -196,13 +196,13 @@ impl FmcAliasCertTbs { &mut self.tbs, params.tcb_info_flags, ); - apply_slice::<{ Self::TCB_INFO_FMC_SVN_OFFSET }, { Self::TCB_INFO_FMC_SVN_LEN }>( + apply_slice::<{ Self::TCB_INFO_FW_SVN_OFFSET }, { Self::TCB_INFO_FW_SVN_LEN }>( &mut self.tbs, - params.tcb_info_fmc_svn, + params.tcb_info_fw_svn, ); - apply_slice::<{ Self::TCB_INFO_FMC_SVN_FUSES_OFFSET }, { Self::TCB_INFO_FMC_SVN_FUSES_LEN }>( + apply_slice::<{ Self::TCB_INFO_FW_SVN_FUSES_OFFSET }, { Self::TCB_INFO_FW_SVN_FUSES_LEN }>( &mut self.tbs, - params.tcb_info_fmc_svn_fuses, + params.tcb_info_fw_svn_fuses, ); } } diff --git a/x509/build/rt_alias_cert_tbs.rs b/x509/build/rt_alias_cert_tbs.rs index 6d07b86bbc..31073ee6e7 100644 --- a/x509/build/rt_alias_cert_tbs.rs +++ b/x509/build/rt_alias_cert_tbs.rs @@ -18,7 +18,7 @@ pub struct RtAliasCertTbsParams<'a> { pub ueid: &'a [u8; 17usize], pub not_before: &'a [u8; 15usize], pub not_after: &'a [u8; 15usize], - pub tcb_info_rt_svn: &'a [u8; 1usize], + pub tcb_info_fw_svn: &'a [u8; 1usize], } impl<'a> RtAliasCertTbsParams<'a> { pub const PUBLIC_KEY_LEN: usize = 97usize; @@ -31,7 +31,7 @@ impl<'a> RtAliasCertTbsParams<'a> { pub const UEID_LEN: usize = 17usize; pub const NOT_BEFORE_LEN: usize = 15usize; pub const NOT_AFTER_LEN: usize = 15usize; - pub const TCB_INFO_RT_SVN_LEN: usize = 1usize; + pub const TCB_INFO_FW_SVN_LEN: usize = 1usize; } pub struct RtAliasCertTbs { tbs: [u8; Self::TBS_TEMPLATE_LEN], @@ -47,7 +47,7 @@ impl RtAliasCertTbs { const UEID_OFFSET: usize = 476usize; const NOT_BEFORE_OFFSET: usize = 157usize; const NOT_AFTER_OFFSET: usize = 174usize; - const TCB_INFO_RT_SVN_OFFSET: usize = 524usize; + const TCB_INFO_FW_SVN_OFFSET: usize = 524usize; const PUBLIC_KEY_LEN: usize = 97usize; const SUBJECT_SN_LEN: usize = 64usize; const ISSUER_SN_LEN: usize = 64usize; @@ -58,7 +58,7 @@ impl RtAliasCertTbs { const UEID_LEN: usize = 17usize; const NOT_BEFORE_LEN: usize = 15usize; const NOT_AFTER_LEN: usize = 15usize; - const TCB_INFO_RT_SVN_LEN: usize = 1usize; + const TCB_INFO_FW_SVN_LEN: usize = 1usize; pub const TBS_TEMPLATE_LEN: usize = 663usize; const TBS_TEMPLATE: [u8; Self::TBS_TEMPLATE_LEN] = [ 48u8, 130u8, 2u8, 147u8, 160u8, 3u8, 2u8, 1u8, 2u8, 2u8, 20u8, 95u8, 95u8, 95u8, 95u8, @@ -168,9 +168,9 @@ impl RtAliasCertTbs { &mut self.tbs, params.not_after, ); - apply_slice::<{ Self::TCB_INFO_RT_SVN_OFFSET }, { Self::TCB_INFO_RT_SVN_LEN }>( + apply_slice::<{ Self::TCB_INFO_FW_SVN_OFFSET }, { Self::TCB_INFO_FW_SVN_LEN }>( &mut self.tbs, - params.tcb_info_rt_svn, + params.tcb_info_fw_svn, ); } } diff --git a/x509/src/fmc_alias_cert.rs b/x509/src/fmc_alias_cert.rs index 417f33cba5..89b3032dca 100644 --- a/x509/src/fmc_alias_cert.rs +++ b/x509/src/fmc_alias_cert.rs @@ -39,8 +39,8 @@ mod tests { const TEST_FMC_HASH: &[u8] = &[0xEFu8; FmcAliasCertTbsParams::TCB_INFO_FMC_TCI_LEN]; const TEST_UEID: &[u8] = &[0xABu8; FmcAliasCertTbsParams::UEID_LEN]; const TEST_TCB_INFO_FLAGS: &[u8] = &[0xB0, 0xB1, 0xB2, 0xB3]; - const TEST_TCB_INFO_FMC_SVN: &[u8] = &[0xB7]; - const TEST_TCB_INFO_FMC_SVN_FUSES: &[u8] = &[0xB8]; + const TEST_TCB_INFO_FW_SVN: &[u8] = &[0xB7]; + const TEST_TCB_INFO_FW_SVN_FUSES: &[u8] = &[0xB8]; fn make_test_cert(subject_key: &Ecc384AsymKey, issuer_key: &Ecc384AsymKey) -> FmcAliasCertTbs { let params = FmcAliasCertTbsParams { @@ -64,8 +64,8 @@ mod tests { tcb_info_flags: TEST_TCB_INFO_FLAGS.try_into().unwrap(), tcb_info_device_info_hash: &TEST_DEVICE_INFO_HASH.try_into().unwrap(), tcb_info_fmc_tci: &TEST_FMC_HASH.try_into().unwrap(), - tcb_info_fmc_svn: &TEST_TCB_INFO_FMC_SVN.try_into().unwrap(), - tcb_info_fmc_svn_fuses: &TEST_TCB_INFO_FMC_SVN_FUSES.try_into().unwrap(), + tcb_info_fw_svn: &TEST_TCB_INFO_FW_SVN.try_into().unwrap(), + tcb_info_fw_svn_fuses: &TEST_TCB_INFO_FW_SVN_FUSES.try_into().unwrap(), not_before: &NotBefore::default().value, not_after: &NotAfter::default().value, }; @@ -136,15 +136,15 @@ mod tests { TEST_FMC_HASH, ); assert_eq!( - &cert.tbs()[FmcAliasCertTbs::TCB_INFO_FMC_SVN_OFFSET - ..FmcAliasCertTbs::TCB_INFO_FMC_SVN_OFFSET + FmcAliasCertTbs::TCB_INFO_FMC_SVN_LEN], - TEST_TCB_INFO_FMC_SVN, + &cert.tbs()[FmcAliasCertTbs::TCB_INFO_FW_SVN_OFFSET + ..FmcAliasCertTbs::TCB_INFO_FW_SVN_OFFSET + FmcAliasCertTbs::TCB_INFO_FW_SVN_LEN], + TEST_TCB_INFO_FW_SVN, ); assert_eq!( - &cert.tbs()[FmcAliasCertTbs::TCB_INFO_FMC_SVN_FUSES_OFFSET - ..FmcAliasCertTbs::TCB_INFO_FMC_SVN_FUSES_OFFSET - + FmcAliasCertTbs::TCB_INFO_FMC_SVN_FUSES_LEN], - TEST_TCB_INFO_FMC_SVN_FUSES, + &cert.tbs()[FmcAliasCertTbs::TCB_INFO_FW_SVN_FUSES_OFFSET + ..FmcAliasCertTbs::TCB_INFO_FW_SVN_FUSES_OFFSET + + FmcAliasCertTbs::TCB_INFO_FW_SVN_FUSES_LEN], + TEST_TCB_INFO_FW_SVN_FUSES, ); let ecdsa_sig = crate::Ecdsa384Signature { diff --git a/x509/src/rt_alias_cert.rs b/x509/src/rt_alias_cert.rs index 675a76bf7a..f4c54923ed 100644 --- a/x509/src/rt_alias_cert.rs +++ b/x509/src/rt_alias_cert.rs @@ -57,7 +57,7 @@ mod tests { issuer_key.sha1(), ) .unwrap(), - tcb_info_rt_svn: &[0xE3], + tcb_info_fw_svn: &[0xE3], tcb_info_rt_tci: &[0xEFu8; RtAliasCertTbsParams::TCB_INFO_RT_TCI_LEN], not_before: &NotBefore::default().value, not_after: &NotAfter::default().value, @@ -105,9 +105,9 @@ mod tests { params.authority_key_id, ); assert_eq!( - &cert.tbs()[RtAliasCertTbs::TCB_INFO_RT_SVN_OFFSET - ..RtAliasCertTbs::TCB_INFO_RT_SVN_OFFSET + RtAliasCertTbs::TCB_INFO_RT_SVN_LEN], - params.tcb_info_rt_svn, + &cert.tbs()[RtAliasCertTbs::TCB_INFO_FW_SVN_OFFSET + ..RtAliasCertTbs::TCB_INFO_FW_SVN_OFFSET + RtAliasCertTbs::TCB_INFO_FW_SVN_LEN], + params.tcb_info_fw_svn, ); assert_eq!( &cert.tbs()[RtAliasCertTbs::TCB_INFO_RT_TCI_OFFSET