Repository: chipsalliance/caliptra-sw
Pull request #467 (2023-07-11 22:01:41)

RT FIPS Infrastructure
This commit adds scaffold  for FIPs command handling in RT firmware.


Patch:
diff --git a/error/src/lib.rs b/error/src/lib.rs
index b23d3da0..65db9870 100644
--- a/error/src/lib.rs
+++ b/error/src/lib.rs
@@ -267,6 +267,7 @@ impl CaliptraError {
     pub const RUNTIME_INSUFFICIENT_MEMORY: CaliptraError = CaliptraError::new_const(0x000E0003);
     pub const RUNTIME_ECDSA_VERIF_FAILED: CaliptraError = CaliptraError::new_const(0x000E0004);
     pub const RUNTIME_INVALID_CHECKSUM: CaliptraError = CaliptraError::new_const(0x000E0005);
+    pub const RUNTIME_FIPS_UNIMPLEMENTED: CaliptraError = CaliptraError::new_const(0x000E0006);
 
     /// FMC Errors
     pub const FMC_GLOBAL_NMI: CaliptraError = CaliptraError::new_const(0x000F0001);
diff --git a/runtime/src/fips.rs b/runtime/src/fips.rs
new file mode 100644
index 00000000..bcbad212
--- /dev/null
+++ b/runtime/src/fips.rs
@@ -0,0 +1,27 @@
+// Licensed under the Apache-2.0 license
+use caliptra_common::cprintln;
+use caliptra_drivers::CaliptraError;
+use caliptra_drivers::CaliptraResult;
+use caliptra_registers::mbox::enums::MboxStatusE;
+
+use crate::Drivers;
+
+/// Fips command handler.
+pub struct FipsModule;
+
+impl FipsModule {
+    pub fn version(_env: &Drivers) -> CaliptraResult<MboxStatusE> {
+        cprintln!("[rt] FIPS Version");
+        Err(CaliptraError::RUNTIME_FIPS_UNIMPLEMENTED)
+    }
+
+    pub fn self_test(_env: &Drivers) -> CaliptraResult<MboxStatusE> {
+        cprintln!("[rt] FIPS self test");
+        Err(CaliptraError::RUNTIME_FIPS_UNIMPLEMENTED)
+    }
+
+    pub fn shutdown(_env: &Drivers) -> CaliptraResult<MboxStatusE> {
+        cprintln!("[rt] FIPS shutdown");
+        Err(CaliptraError::RUNTIME_FIPS_UNIMPLEMENTED)
+    }
+}
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index 99bd3919..655f033a 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -6,11 +6,13 @@ pub mod dice;
 mod verify;
 
 // Used by runtime tests
+pub(crate) mod fips;
 pub mod mailbox;
 
 use mailbox::Mailbox;
 
 pub mod packet;
+pub use fips::FipsModule;
 use packet::Packet;
 
 use caliptra_common::{cprintln, FirmwareHandoffTable};
@@ -36,6 +38,14 @@ impl CommandId {
 
     pub const TEST_ONLY_GET_LDEV_CERT: Self = Self(0x4345524c); // "CERL"
     pub const TEST_ONLY_GET_FMC_ALIAS_CERT: Self = Self(0x43455246); // "CERF"
+
+    /// FIPS module commands.
+    /// The status command.
+    pub const VERSION: Self = Self(0x4650_5652); // "FPVR"
+    /// The self-test command.
+    pub const SELF_TEST: Self = Self(0x4650_4C54); // "FPST"
+    /// The shutdown command.
+    pub const SHUTDOWN: Self = Self(0x4650_5344); // "FPSD"
 }
 impl From<u32> for CommandId {
     fn from(value: u32) -> Self {
@@ -143,6 +153,9 @@ fn handle_command(drivers: &mut Drivers) -> CaliptraResult<MboxStatusE> {
             )?;
             Ok(MboxStatusE::DataReady)
         }
+        CommandId::VERSION => FipsModule::version(drivers),
+        CommandId::SELF_TEST => FipsModule::self_test(drivers),
+        CommandId::SHUTDOWN => FipsModule::shutdown(drivers),
         _ => Err(CaliptraError::RUNTIME_UNIMPLEMENTED_COMMAND),
     }
 }


Test patch:
diff --git a/runtime/tests/integration_tests.rs b/runtime/tests/integration_tests.rs
index d5699391..afb549a8 100644
--- a/runtime/tests/integration_tests.rs
+++ b/runtime/tests/integration_tests.rs
@@ -217,6 +217,30 @@ fn test_verify_cmd() {
     );
 }
 
+#[test]
+fn test_fips_cmd_api() {
+    let mut model = run_rom_test("mbox");
+    let expected_err = Err(ModelError::MailboxCmdFailed(0x000E0006));
+
+    model.step_until(|m| m.soc_mbox().status().read().mbox_fsm_ps().mbox_idle());
+
+    let cmd = [0u8; 4];
+
+    let resp = model.mailbox_execute(u32::from(CommandId::VERSION), &cmd);
+    assert_eq!(resp, expected_err);
+
+    let resp = model.mailbox_execute(u32::from(CommandId::SHUTDOWN), &cmd);
+    assert_eq!(resp, expected_err);
+
+    let resp = model.mailbox_execute(u32::from(CommandId::SELF_TEST), &cmd);
+    assert_eq!(resp, expected_err);
+
+    let expected_err = Err(ModelError::MailboxCmdFailed(0xe0002));
+    // Send something that is not a valid RT command.
+    let resp = model.mailbox_execute(0xAABBCCDD, &cmd);
+    assert_eq!(resp, expected_err);
+}
+
 #[test]
 fn test_unimplemented_cmds() {
     let mut model = run_rom_test("mbox");