diff --git a/api/src/capabilities.rs b/api/src/capabilities.rs
index af2082a591..db5bdf185c 100644
--- a/api/src/capabilities.rs
+++ b/api/src/capabilities.rs
@@ -17,6 +17,8 @@ bitflags::bitflags! {
pub struct Capabilities : u128 {
// Represents base capabilities present in Caliptra ROM v1.0
const ROM_BASE = 0b0001;
+ // Represents base capabilities present in Caliptra Runtime v1.0
+ const RT_BASE = 0b0001;
}
}
diff --git a/runtime/README.md b/runtime/README.md
index d37f009558..270c9c1224 100644
--- a/runtime/README.md
+++ b/runtime/README.md
@@ -111,6 +111,26 @@ Command Code: `0x4657_4C44` ("FWLD")
| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
+### CAPABILITIES
+
+Exposes a command to retrieve firmware capabilities
+
+Command Code: `0x4341_5053` ("CAPS")
+
+*Table: `CAPABILITIES` input arguments*
+
+| **Name** | **Type** | **Description**
+| -------- | -------- | ---------------
+| chksum | u32 | Checksum over other input arguments, computed by the caller. Little endian.
+
+*Table: `CAPABILITIES` output arguments*
+
+| **Name** | **Type** | **Description**
+| -------- | -------- | ---------------
+| chksum | u32 | Checksum over other output arguments, computed by Caliptra. Little endian.
+| fips\_status | u32 | Indicates if the command is FIPS approved or an error.
+| capabilities | u8[16] | Firmware capabilities
+
### GET\_IDEV\_CERT
Exposes a command to reconstruct the IDEVID CERT.
diff --git a/runtime/doc/test-coverage.md b/runtime/doc/test-coverage.md
index 391e9486d7..9ff47f9a5d 100644
--- a/runtime/doc/test-coverage.md
+++ b/runtime/doc/test-coverage.md
@@ -41,7 +41,7 @@ Checks that the stash_measurement mailbox command succeeds | **test_stash_measur
Test Scenario| Test Name | Runtime Error Code
---|---|---
Check that the error register is cleared when a successful mailbox command runs after a failed mailbox command | **test_error_cleared** | RUNTIME_MAILBOX_INVALID_PARAMS
-Checks that the unimplemented mailbox command capabilities fails | **test_unimplemented_cmds** | RUNTIME_UNIMPLEMENTED_COMMAND
+Checks that executing unimplemented mailbox commands fails | **test_unimplemented_cmds** | RUNTIME_UNIMPLEMENTED_COMMAND
# **Cryptography Verification Tests**
@@ -73,6 +73,7 @@ Test Scenario| Test Name | Runtime Error Code
---|---|---
Checks that the fw_info mailbox command succeeds and validates the response | **test_fw_info** | N/A
Checks that the get_idev_info mailbox command succeeds | **test_idev_id_info** | N/A
+Checks that the capabilities mailbox command succeeds | **test_capabilities** | N/A
# **DPE Tests**
diff --git a/runtime/src/capabilities.rs b/runtime/src/capabilities.rs
new file mode 100644
index 0000000000..9ff9cf1b85
--- /dev/null
+++ b/runtime/src/capabilities.rs
@@ -0,0 +1,32 @@
+/*++
+
+Licensed under the Apache-2.0 license.
+
+File Name:
+
+ capabilities.rs
+
+Abstract:
+
+ File contains Capabilities mailbox command.
+
+--*/
+
+use caliptra_common::{
+ capabilities::Capabilities,
+ mailbox_api::{CapabilitiesResp, MailboxResp, MailboxRespHeader},
+};
+use caliptra_error::CaliptraResult;
+
+pub struct CapabilitiesCmd;
+impl CapabilitiesCmd {
+ pub(crate) fn execute() -> CaliptraResult {
+ let mut capabilities = Capabilities::default();
+ capabilities |= Capabilities::RT_BASE;
+
+ Ok(MailboxResp::Capabilities(CapabilitiesResp {
+ hdr: MailboxRespHeader::default(),
+ capabilities: capabilities.to_bytes(),
+ }))
+ }
+}
diff --git a/runtime/src/dice.rs b/runtime/src/dice.rs
index bcece09ef9..a8eb178b48 100644
--- a/runtime/src/dice.rs
+++ b/runtime/src/dice.rs
@@ -1,4 +1,16 @@
-// Licensed under the Apache-2.0 license
+/*++
+
+Licensed under the Apache-2.0 license.
+
+File Name:
+
+ dice.rs
+
+Abstract:
+
+ File contains mailbox commands related to DICE certificates.
+
+--*/
use caliptra_common::mailbox_api::{
GetFmcAliasCertResp, GetIdevCertReq, GetIdevCertResp, GetLdevCertResp, GetRtAliasCertResp,
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index 776eb627b3..6b4b10375a 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -13,6 +13,7 @@ Abstract:
--*/
#![cfg_attr(not(feature = "fip-self-test"), allow(unused))]
#![no_std]
+mod capabilities;
pub mod dice;
mod disable;
mod dpe_crypto;
@@ -36,6 +37,7 @@ use caliptra_registers::soc_ifc::SocIfcReg;
pub use drivers::Drivers;
use mailbox::Mailbox;
+use crate::capabilities::CapabilitiesCmd;
pub use crate::hmac::Hmac;
pub use caliptra_common::fips::FipsVersionCmd;
pub use dice::{GetFmcAliasCertCmd, GetLdevCertCmd, IDevIdCertCmd};
@@ -188,6 +190,7 @@ fn handle_command(drivers: &mut Drivers) -> CaliptraResult {
CommandId::VERSION => {
FipsVersionCmd::execute(&drivers.soc_ifc).map(MailboxResp::FipsVersion)
}
+ CommandId::CAPABILITIES => CapabilitiesCmd::execute(),
#[cfg(feature = "fips_self_test")]
CommandId::SELF_TEST_START => match drivers.self_test_status {
SelfTestStatus::Idle => {
diff --git a/runtime/tests/runtime_integration_tests/test_info.rs b/runtime/tests/runtime_integration_tests/test_info.rs
index fa026979ef..83796b713e 100644
--- a/runtime/tests/runtime_integration_tests/test_info.rs
+++ b/runtime/tests/runtime_integration_tests/test_info.rs
@@ -5,8 +5,12 @@ use caliptra_builder::{
firmware::{self, APP_WITH_UART, FMC_WITH_UART},
ImageOptions,
};
-use caliptra_common::mailbox_api::{
- CommandId, FwInfoResp, GetIdevInfoResp, MailboxReqHeader, MailboxRespHeader,
+use caliptra_common::{
+ capabilities::Capabilities,
+ mailbox_api::{
+ CapabilitiesResp, CommandId, FwInfoResp, GetIdevInfoResp, MailboxReqHeader,
+ MailboxRespHeader,
+ },
};
use caliptra_hw_model::{BootParams, DefaultHwModel, HwModel, InitParams};
use caliptra_image_types::RomInfo;
@@ -163,3 +167,18 @@ fn test_idev_id_info() {
.unwrap();
GetIdevInfoResp::read_from(resp.as_slice()).unwrap();
}
+
+#[test]
+fn test_capabilities() {
+ let mut model = run_rt_test(None, None, None);
+ let payload = MailboxReqHeader {
+ chksum: caliptra_common::checksum::calc_checksum(u32::from(CommandId::CAPABILITIES), &[]),
+ };
+ let resp = model
+ .mailbox_execute(u32::from(CommandId::CAPABILITIES), payload.as_bytes())
+ .unwrap()
+ .unwrap();
+ let capabilities_resp = CapabilitiesResp::read_from(resp.as_slice()).unwrap();
+ let capabilities = Capabilities::try_from(capabilities_resp.capabilities.as_bytes()).unwrap();
+ assert!(capabilities.contains(Capabilities::RT_BASE));
+}
diff --git a/runtime/tests/runtime_integration_tests/test_mailbox.rs b/runtime/tests/runtime_integration_tests/test_mailbox.rs
index 3f56e29f0a..4684f8fca3 100644
--- a/runtime/tests/runtime_integration_tests/test_mailbox.rs
+++ b/runtime/tests/runtime_integration_tests/test_mailbox.rs
@@ -40,20 +40,6 @@ fn test_unimplemented_cmds() {
model.step_until(|m| m.soc_mbox().status().read().mbox_fsm_ps().mbox_idle());
- // CAPABILITIES
- let payload = MailboxReqHeader {
- chksum: caliptra_common::checksum::calc_checksum(u32::from(CommandId::CAPABILITIES), &[]),
- };
-
- let resp = model
- .mailbox_execute(u32::from(CommandId::CAPABILITIES), payload.as_bytes())
- .unwrap_err();
- assert_error(
- &mut model,
- caliptra_drivers::CaliptraError::RUNTIME_UNIMPLEMENTED_COMMAND,
- resp,
- );
-
// Send something that is not a valid RT command.
const INVALID_CMD: u32 = 0xAABBCCDD;
let payload = MailboxReqHeader {