Repository: chipsalliance/caliptra-sw
Pull request #772 (2023-09-13 22:17:07)

Adding FIPS status to ROM capabilities command response


Patch:
diff --git a/common/src/capabilities.rs b/common/src/capabilities.rs
index 7e9d7510..af2082a5 100644
--- a/common/src/capabilities.rs
+++ b/common/src/capabilities.rs
@@ -21,7 +21,8 @@ bitflags::bitflags! {
 }
 
 impl Capabilities {
-    pub fn to_bytes(&self) -> [u8; 16] {
+    pub const SIZE_IN_BYTES: usize = 16;
+    pub fn to_bytes(&self) -> [u8; Capabilities::SIZE_IN_BYTES] {
         self.bits().to_be_bytes()
     }
 }
@@ -29,7 +30,7 @@ impl Capabilities {
 impl TryFrom<&[u8]> for Capabilities {
     type Error = ();
     fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
-        if value.len() != 16 {
+        if value.len() != Capabilities::SIZE_IN_BYTES {
             Err(())
         } else {
             let capabilities = u128::from_be_bytes(value.try_into().unwrap());
diff --git a/common/src/mailbox_api.rs b/common/src/mailbox_api.rs
index 78555f13..17852755 100644
--- a/common/src/mailbox_api.rs
+++ b/common/src/mailbox_api.rs
@@ -63,6 +63,7 @@ pub enum MailboxResp {
     TestGetFmcAliasCert(TestGetFmcAliasCertResp),
     FipsVersion(FipsVersionResp),
     FwInfo(FwInfoResp),
+    Capabilities(CapabilitiesResp),
 }
 
 impl MailboxResp {
@@ -78,6 +79,7 @@ impl MailboxResp {
             MailboxResp::TestGetFmcAliasCert(resp) => resp.as_bytes(),
             MailboxResp::FipsVersion(resp) => resp.as_bytes(),
             MailboxResp::FwInfo(resp) => resp.as_bytes(),
+            MailboxResp::Capabilities(resp) => resp.as_bytes(),
         }
     }
 
@@ -93,6 +95,7 @@ impl MailboxResp {
             MailboxResp::TestGetFmcAliasCert(resp) => resp.as_bytes_mut(),
             MailboxResp::FipsVersion(resp) => resp.as_bytes_mut(),
             MailboxResp::FwInfo(resp) => resp.as_bytes_mut(),
+            MailboxResp::Capabilities(resp) => resp.as_bytes_mut(),
         }
     }
 
@@ -363,3 +366,12 @@ pub struct FwInfoResp {
     // TODO: Decide what other information to report for general firmware
     // status.
 }
+
+// CAPABILITIES
+// No command-specific input args
+#[repr(C)]
+#[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
+pub struct CapabilitiesResp {
+    pub hdr: MailboxRespHeader,
+    pub capabilities: [u8; crate::capabilities::Capabilities::SIZE_IN_BYTES],
+}
diff --git a/rom/dev/src/flow/cold_reset/fw_processor.rs b/rom/dev/src/flow/cold_reset/fw_processor.rs
index 7ab316cc..9ea21dbe 100644
--- a/rom/dev/src/flow/cold_reset/fw_processor.rs
+++ b/rom/dev/src/flow/cold_reset/fw_processor.rs
@@ -22,9 +22,9 @@ use caliptra_cfi_derive::cfi_impl_fn;
 use caliptra_cfi_lib::CfiCounter;
 use caliptra_common::capabilities::Capabilities;
 use caliptra_common::fips::FipsVersionCmd;
-use caliptra_common::mailbox_api::CommandId;
-use caliptra_common::mailbox_api::MailboxResp;
-use caliptra_common::mailbox_api::StashMeasurementReq;
+use caliptra_common::mailbox_api::{
+    CapabilitiesResp, CommandId, MailboxResp, MailboxRespHeader, StashMeasurementReq,
+};
 use caliptra_common::pcr::PCR_ID_STASH_MEASUREMENT;
 use caliptra_common::verifier::FirmwareImageVerificationEnv;
 use caliptra_common::PcrLogEntry;
@@ -223,7 +223,14 @@ impl FirmwareProcessor {
                         let mut capabilities = Capabilities::default();
                         capabilities |= Capabilities::ROM_BASE;
 
-                        txn.start_txn().send_response(&capabilities.to_bytes())?;
+                        let mut resp = MailboxResp::Capabilities(CapabilitiesResp {
+                            hdr: MailboxRespHeader::default(),
+                            capabilities: capabilities.to_bytes(),
+                        });
+
+                        resp.populate_chksum()?;
+
+                        txn.start_txn().send_response(resp.as_bytes())?;
                         continue;
                     }
 


Test patch:
diff --git a/rom/dev/tests/test_capabilities.rs b/rom/dev/tests/test_capabilities.rs
index 3b4fb870..8b19bfdf 100644
--- a/rom/dev/tests/test_capabilities.rs
+++ b/rom/dev/tests/test_capabilities.rs
@@ -1,9 +1,10 @@
 // Licensed under the Apache-2.0 license
 
 use caliptra_builder::ImageOptions;
-use caliptra_common::{capabilities::Capabilities, mailbox_api::CommandId};
+use caliptra_common::capabilities::Capabilities;
+use caliptra_common::mailbox_api::{CapabilitiesResp, CommandId, MailboxRespHeader};
 use caliptra_hw_model::{Fuses, HwModel};
-use zerocopy::AsBytes;
+use zerocopy::{AsBytes, FromBytes};
 
 pub mod helpers;
 
@@ -17,7 +18,22 @@ fn test_capabilities() {
         .unwrap()
         .unwrap();
 
-    let caps = Capabilities::try_from(response.as_bytes()).unwrap();
+    let capabilities_resp = CapabilitiesResp::read_from(response.as_bytes()).unwrap();
 
+    // Verify response checksum
+    assert!(caliptra_common::checksum::verify_checksum(
+        capabilities_resp.hdr.chksum,
+        0x0,
+        &capabilities_resp.as_bytes()[core::mem::size_of_val(&capabilities_resp.hdr.chksum)..],
+    ));
+
+    // Verify FIPS status
+    assert_eq!(
+        capabilities_resp.hdr.fips_status,
+        MailboxRespHeader::FIPS_STATUS_APPROVED
+    );
+
+    // Verify Capabilities
+    let caps = Capabilities::try_from(capabilities_resp.capabilities.as_bytes()).unwrap();
     assert!(caps.contains(Capabilities::ROM_BASE));
 }