Repository: chipsalliance/caliptra-sw
Pull request #569 (2023-07-31 22:28:24)

Introducing the  "no-kats"  feature and the FAST_ROM target 
Enable integrators to produce a test ROM that skips the FIPS KATS testing. Add asserts to the smoke test to ensure that KATs tests are not skipped in the production ROM target. Additionally , created a test to ensure the new "FAST ROM" target skips KAT tests.


Patch:
diff --git a/builder/src/lib.rs b/builder/src/lib.rs
index b8559363..0d307815 100644
--- a/builder/src/lib.rs
+++ b/builder/src/lib.rs
@@ -37,6 +37,13 @@ pub const ROM_WITH_UART: FwId = FwId {
     workspace_dir: None,
 };
 
+pub const ROM_FAST_WITH_UART: FwId = FwId {
+    crate_name: "caliptra-rom",
+    bin_name: "caliptra-rom",
+    features: &["emu", "no-kats"],
+    workspace_dir: None,
+};
+
 pub const FMC_WITH_UART: FwId = FwId {
     crate_name: "caliptra-fmc",
     bin_name: "caliptra-fmc",
diff --git a/common/src/boot_status.rs b/common/src/boot_status.rs
index 95469896..825862d6 100644
--- a/common/src/boot_status.rs
+++ b/common/src/boot_status.rs
@@ -18,6 +18,7 @@ const FWPROCESSOR_BOOT_STATUS_BASE: u32 = 129;
 const FMCALIAS_BOOT_STATUS_BASE: u32 = 193;
 const COLD_RESET_BOOT_STATUS_BASE: u32 = 257;
 const UPDATE_RESET_BOOT_STATUS_BASE: u32 = 321;
+const ROM_GLOBAL_BOOT_STATUS_BASE: u32 = 385;
 
 /// Statuses used by ROM to log dice derivation progress.
 #[repr(u32)]
@@ -72,6 +73,9 @@ pub enum RomBootStatus {
     UpdateResetLoadImageComplete = UPDATE_RESET_BOOT_STATUS_BASE + 3,
     UpdateResetOverwriteManifestComplete = UPDATE_RESET_BOOT_STATUS_BASE + 4,
     UpdateResetComplete = UPDATE_RESET_BOOT_STATUS_BASE + 5,
+
+    KatStarted = ROM_GLOBAL_BOOT_STATUS_BASE,
+    KatComplete = ROM_GLOBAL_BOOT_STATUS_BASE + 1,
 }
 
 impl From<RomBootStatus> for u32 {
diff --git a/rom/dev/Cargo.toml b/rom/dev/Cargo.toml
index 7b575615..5e365be5 100644
--- a/rom/dev/Cargo.toml
+++ b/rom/dev/Cargo.toml
@@ -48,6 +48,7 @@ std = [
 ]
 no-fmc = []
 fpga_realtime = ["caliptra-drivers/fpga_realtime"]
+no-kats = []
 
 [[bin]]
 name = "asm_tests"
diff --git a/rom/dev/src/kat.rs b/rom/dev/src/kat.rs
index a8cf2127..330ab156 100644
--- a/rom/dev/src/kat.rs
+++ b/rom/dev/src/kat.rs
@@ -12,7 +12,8 @@ Abstract:
 
 --*/
 
-use caliptra_drivers::CaliptraResult;
+use caliptra_common::RomBootStatus::*;
+use caliptra_drivers::{report_boot_status, CaliptraResult};
 use caliptra_kat::{Ecc384Kat, Hmac384Kat, LmsKat, Sha1Kat, Sha256Kat, Sha384AccKat, Sha384Kat};
 
 use crate::{cprintln, rom_env::RomEnv};
@@ -24,6 +25,7 @@ use crate::{cprintln, rom_env::RomEnv};
 /// * `env` - ROM Environment
 pub fn execute_kat(env: &mut RomEnv) -> CaliptraResult<()> {
     cprintln!("[kat] ++");
+    report_boot_status(KatStarted.into());
 
     cprintln!("[kat] sha1");
     Sha1Kat::default().execute(&mut env.sha1)?;
@@ -46,6 +48,7 @@ pub fn execute_kat(env: &mut RomEnv) -> CaliptraResult<()> {
     cprintln!("[kat] LMS");
     LmsKat::default().execute(&mut env.sha256, &env.lms)?;
 
+    report_boot_status(KatComplete.into());
     cprintln!("[kat] --");
 
     Ok(())
diff --git a/rom/dev/src/main.rs b/rom/dev/src/main.rs
index 59bfbaad..ece06e7f 100644
--- a/rom/dev/src/main.rs
+++ b/rom/dev/src/main.rs
@@ -13,6 +13,7 @@ Abstract:
 --*/
 #![cfg_attr(not(feature = "std"), no_std)]
 #![cfg_attr(not(feature = "std"), no_main)]
+#![cfg_attr(not(feature = "no-kats"), allow(unused_imports))]
 
 use crate::lock::lock_registers;
 use core::hint::black_box;
@@ -77,9 +78,11 @@ pub extern "C" fn rom_entry() -> ! {
     // Start the watchdog timer
     wdt::start_wdt(&mut env.soc_ifc);
 
-    let result = kat::execute_kat(&mut env);
-    if let Err(err) = result {
-        handle_fatal_error(err.into());
+    if !cfg!(feature = "no-kats") {
+        let result = kat::execute_kat(&mut env);
+        if let Err(err) = result {
+            handle_fatal_error(err.into());
+        }
     }
 
     let reset_reason = env.soc_ifc.reset_reason();


Test patch:
diff --git a/rom/dev/tests/test_dice_derivations.rs b/rom/dev/tests/test_dice_derivations.rs
index bb654a4c..a0d5a2e0 100644
--- a/rom/dev/tests/test_dice_derivations.rs
+++ b/rom/dev/tests/test_dice_derivations.rs
@@ -14,6 +14,8 @@ fn test_cold_reset_status_reporting() {
     let (mut hw, image_bundle) =
         helpers::build_hw_model_and_image_bundle(Fuses::default(), ImageOptions::default());
 
+    hw.step_until_boot_status(KatStarted.into(), false);
+    hw.step_until_boot_status(KatComplete.into(), false);
     hw.step_until_boot_status(ColdResetStarted.into(), false);
     hw.step_until_boot_status(IDevIdDecryptUdsComplete.into(), false);
     hw.step_until_boot_status(IDevIdDecryptFeComplete.into(), false);
diff --git a/rom/dev/tests/test_fast_rom.rs b/rom/dev/tests/test_fast_rom.rs
new file mode 100644
index 00000000..3b37fd6d
--- /dev/null
+++ b/rom/dev/tests/test_fast_rom.rs
@@ -0,0 +1,23 @@
+// Licensed under the Apache-2.0 license
+
+use caliptra_builder::ROM_FAST_WITH_UART;
+use caliptra_hw_model::{BootParams, HwModel, InitParams};
+
+#[test]
+fn test_skip_kats() {
+    let rom = caliptra_builder::build_firmware_rom(&ROM_FAST_WITH_UART).unwrap();
+    let mut hw = caliptra_hw_model::new(BootParams {
+        init_params: InitParams {
+            rom: &rom,
+            ..Default::default()
+        },
+        ..Default::default()
+    })
+    .unwrap();
+
+    // If KatStarted boot status is posted before ColResetStarted, the statement below will trigger panic.
+    hw.step_until_boot_status(
+        caliptra_common::RomBootStatus::ColdResetStarted.into(),
+        false,
+    );
+}
diff --git a/rom/dev/tests/test_update_reset.rs b/rom/dev/tests/test_update_reset.rs
index 9e500b9f..9c5bd4b9 100644
--- a/rom/dev/tests/test_update_reset.rs
+++ b/rom/dev/tests/test_update_reset.rs
@@ -39,6 +39,8 @@ fn test_update_reset_success() {
     )
     .unwrap();
 
+    hw.step_until_boot_status(KatStarted.into(), true);
+
     hw.upload_firmware(&image_bundle.to_bytes().unwrap())
         .unwrap();
 
@@ -47,6 +49,9 @@ fn test_update_reset_success() {
     hw.mailbox_execute(TEST_FMC_CMD_RESET_FOR_UPDATE, &[])
         .unwrap();
 
+    hw.step_until_boot_status(KatStarted.into(), true);
+    hw.step_until_boot_status(KatComplete.into(), true);
+
     hw.step_until_boot_status(UpdateResetStarted.into(), false);
 
     hw.upload_firmware(&image_bundle.to_bytes().unwrap())
@@ -92,6 +97,8 @@ fn test_update_reset_no_mailbox_cmd() {
     hw.mailbox_execute(TEST_FMC_CMD_RESET_FOR_UPDATE, &[])
         .unwrap();
 
+    hw.step_until_boot_status(KatStarted.into(), true);
+    hw.step_until_boot_status(KatComplete.into(), true);
     hw.step_until_boot_status(UpdateResetStarted.into(), false);
 
     // No command in the mailbox.
@@ -143,7 +150,8 @@ fn test_update_reset_non_fw_load_cmd() {
 
     hw.mailbox_execute(TEST_FMC_CMD_RESET_FOR_UPDATE, &[])
         .unwrap();
-
+    hw.step_until_boot_status(KatStarted.into(), true);
+    hw.step_until_boot_status(KatComplete.into(), true);
     hw.step_until_boot_status(UpdateResetStarted.into(), false);
 
     // Send a non-fw load command
@@ -192,6 +200,8 @@ fn test_update_reset_verify_image_failure() {
 
     hw.mailbox_execute(TEST_FMC_CMD_RESET_FOR_UPDATE, &[])
         .unwrap();
+    hw.step_until_boot_status(KatStarted.into(), true);
+    hw.step_until_boot_status(KatComplete.into(), true);
 
     hw.step_until_boot_status(UpdateResetStarted.into(), false);
 
@@ -242,6 +252,8 @@ fn test_update_reset_boot_status() {
 
     hw.mailbox_execute(TEST_FMC_CMD_RESET_FOR_UPDATE, &[])
         .unwrap();
+    hw.step_until_boot_status(KatStarted.into(), true);
+    hw.step_until_boot_status(KatComplete.into(), true);
 
     hw.step_until_boot_status(UpdateResetStarted.into(), false);
 
diff --git a/test/tests/smoke_test.rs b/test/tests/smoke_test.rs
index 79d015e4..8ea37cdf 100644
--- a/test/tests/smoke_test.rs
+++ b/test/tests/smoke_test.rs
@@ -164,6 +164,15 @@ fn smoke_test() {
     let output = String::from_utf8_lossy(&output);
     assert_output_contains(&output, "Running Caliptra ROM");
     assert_output_contains(&output, "[cold-reset]");
+    // Confirm KAT is running.
+    assert_output_contains(&output, "[kat] ++");
+    assert_output_contains(&output, "[kat] sha1");
+    assert_output_contains(&output, "[kat] SHA2-256");
+    assert_output_contains(&output, "[kat] SHA2-384");
+    assert_output_contains(&output, "[kat] SHA2-384-ACC");
+    assert_output_contains(&output, "[kat] HMAC-384");
+    assert_output_contains(&output, "[kat] LMS");
+    assert_output_contains(&output, "[kat] --");
     assert_output_contains(&output, "Running Caliptra FMC");
     assert_output_contains(
         &output,