Repository: chipsalliance/caliptra-sw
Pull request #1109 (2023-11-28 14:25:45)

Modify RT cert related mbox cmds
1. Remove GET_IDEV_CSR mbox cmd
2. Make GET_LDEV_CERT and GET_FMC_ALIAS_CERT non test only mbox cmds
3. Implement GET_RT_ALIAS_CERT


Patch:
diff --git a/api/src/mailbox.rs b/api/src/mailbox.rs
index 67645b4a..fedb022d 100644
--- a/api/src/mailbox.rs
+++ b/api/src/mailbox.rs
@@ -8,11 +8,12 @@ use zerocopy::{AsBytes, FromBytes, LayoutVerified};
 pub struct CommandId(pub u32);
 impl CommandId {
     pub const FIRMWARE_LOAD: Self = Self(0x46574C44); // "FWLD"
-    pub const GET_IDEV_CSR: Self = Self(0x49444556); // "IDEV"
     pub const GET_IDEV_CERT: Self = Self(0x49444543); // "IDEC"
     pub const GET_IDEV_INFO: Self = Self(0x49444549); // "IDEI"
     pub const POPULATE_IDEV_CERT: Self = Self(0x49444550); // "IDEP"
     pub const GET_LDEV_CERT: Self = Self(0x4C444556); // "LDEV"
+    pub const GET_FMC_ALIAS_CERT: Self = Self(0x43455246); // "CERF"
+    pub const GET_RT_ALIAS_CERT: Self = Self(0x43455252); // "CERR"
     pub const ECDSA384_VERIFY: Self = Self(0x53494756); // "SIGV"
     pub const STASH_MEASUREMENT: Self = Self(0x4D454153); // "MEAS"
     pub const INVOKE_DPE: Self = Self(0x44504543); // "DPEC"
@@ -21,9 +22,6 @@ impl CommandId {
     pub const DPE_TAG_TCI: Self = Self(0x54514754); // "TAGT"
     pub const DPE_GET_TAGGED_TCI: Self = Self(0x47544744); // "GTGD"
 
-    // TODO: Remove this and merge with GET_LDEV_CERT once that is implemented
-    pub const TEST_ONLY_GET_LDEV_CERT: Self = Self(0x4345524c); // "CERL"
-    pub const TEST_ONLY_GET_FMC_ALIAS_CERT: Self = Self(0x43455246); // "CERF"
     pub const TEST_ONLY_HMAC384_VERIFY: Self = Self(0x484D4143); // "HMAC"
 
     /// FIPS module commands.
@@ -125,16 +123,16 @@ fn populate_checksum(msg: &mut [u8]) {
 pub enum MailboxResp {
     Header(MailboxRespHeader),
     GetIdevCert(GetIdevCertResp),
-    GetIdevCsr(GetIdevCsrResp),
     GetIdevInfo(GetIdevInfoResp),
     GetLdevCert(GetLdevCertResp),
     StashMeasurement(StashMeasurementResp),
     InvokeDpeCommand(InvokeDpeResp),
-    TestGetFmcAliasCert(TestGetFmcAliasCertResp),
+    GetFmcAliasCert(GetFmcAliasCertResp),
     FipsVersion(FipsVersionResp),
     FwInfo(FwInfoResp),
     Capabilities(CapabilitiesResp),
     GetTaggedTci(GetTaggedTciResp),
+    GetRtAliasCert(GetRtAliasCertResp),
 }
 
 impl MailboxResp {
@@ -142,16 +140,16 @@ impl MailboxResp {
         match self {
             MailboxResp::Header(resp) => Ok(resp.as_bytes()),
             MailboxResp::GetIdevCert(resp) => resp.as_bytes_partial(),
-            MailboxResp::GetIdevCsr(resp) => resp.as_bytes_partial(),
             MailboxResp::GetIdevInfo(resp) => Ok(resp.as_bytes()),
             MailboxResp::GetLdevCert(resp) => resp.as_bytes_partial(),
             MailboxResp::StashMeasurement(resp) => Ok(resp.as_bytes()),
             MailboxResp::InvokeDpeCommand(resp) => resp.as_bytes_partial(),
-            MailboxResp::TestGetFmcAliasCert(resp) => resp.as_bytes_partial(),
             MailboxResp::FipsVersion(resp) => Ok(resp.as_bytes()),
             MailboxResp::FwInfo(resp) => Ok(resp.as_bytes()),
             MailboxResp::Capabilities(resp) => Ok(resp.as_bytes()),
             MailboxResp::GetTaggedTci(resp) => Ok(resp.as_bytes()),
+            MailboxResp::GetFmcAliasCert(resp) => resp.as_bytes_partial(),
+            MailboxResp::GetRtAliasCert(resp) => resp.as_bytes_partial(),
         }
     }
 
@@ -159,16 +157,16 @@ impl MailboxResp {
         match self {
             MailboxResp::Header(resp) => Ok(resp.as_bytes_mut()),
             MailboxResp::GetIdevCert(resp) => resp.as_bytes_partial_mut(),
-            MailboxResp::GetIdevCsr(resp) => resp.as_bytes_partial_mut(),
             MailboxResp::GetIdevInfo(resp) => Ok(resp.as_bytes_mut()),
             MailboxResp::GetLdevCert(resp) => resp.as_bytes_partial_mut(),
             MailboxResp::StashMeasurement(resp) => Ok(resp.as_bytes_mut()),
             MailboxResp::InvokeDpeCommand(resp) => resp.as_bytes_partial_mut(),
-            MailboxResp::TestGetFmcAliasCert(resp) => resp.as_bytes_partial_mut(),
             MailboxResp::FipsVersion(resp) => Ok(resp.as_bytes_mut()),
             MailboxResp::FwInfo(resp) => Ok(resp.as_bytes_mut()),
             MailboxResp::Capabilities(resp) => Ok(resp.as_bytes_mut()),
             MailboxResp::GetTaggedTci(resp) => Ok(resp.as_bytes_mut()),
+            MailboxResp::GetFmcAliasCert(resp) => resp.as_bytes_partial_mut(),
+            MailboxResp::GetRtAliasCert(resp) => resp.as_bytes_partial_mut(),
         }
     }
 
@@ -210,8 +208,7 @@ impl Default for MailboxResp {
 #[allow(clippy::large_enum_variant)]
 pub enum MailboxReq {
     EcdsaVerify(EcdsaVerifyReq),
-    GetIdevCsr(MailboxReqHeader),
-    GetLdevCert(MailboxReqHeader),
+    GetLdevCert(GetLdevCertReq),
     StashMeasurement(StashMeasurementReq),
     InvokeDpeCommand(InvokeDpeReq),
     FipsVersion(MailboxReqHeader),
@@ -220,11 +217,11 @@ pub enum MailboxReq {
     GetIdevCert(GetIdevCertReq),
     TagTci(TagTciReq),
     GetTaggedTci(GetTaggedTciReq),
+    GetFmcAliasCert(GetFmcAliasCertReq),
+    GetRtAliasCert(GetRtAliasCertReq),
 
     #[cfg(feature = "test_only_commands")]
     TestHmacVerify(HmacVerifyReq),
-    #[cfg(feature = "test_only_commands")]
-    TestGetFmcAliasCert(MailboxReqHeader),
 }
 
 impl MailboxReq {
@@ -235,15 +232,14 @@ impl MailboxReq {
             MailboxReq::InvokeDpeCommand(req) => req.as_bytes_partial(),
             MailboxReq::FipsVersion(req) => Ok(req.as_bytes()),
             MailboxReq::FwInfo(req) => Ok(req.as_bytes()),
-            MailboxReq::GetIdevCsr(req) => Ok(req.as_bytes()),
             MailboxReq::GetLdevCert(req) => Ok(req.as_bytes()),
             MailboxReq::PopulateIdevCert(req) => req.as_bytes_partial(),
             MailboxReq::GetIdevCert(req) => req.as_bytes_partial(),
             MailboxReq::TagTci(req) => Ok(req.as_bytes()),
             MailboxReq::GetTaggedTci(req) => Ok(req.as_bytes()),
+            MailboxReq::GetFmcAliasCert(req) => Ok(req.as_bytes()),
+            MailboxReq::GetRtAliasCert(req) => Ok(req.as_bytes()),
 
-            #[cfg(feature = "test_only_commands")]
-            MailboxReq::TestGetFmcAliasCert(req) => Ok(req.as_bytes()),
             #[cfg(feature = "test_only_commands")]
             MailboxReq::TestHmacVerify(req) => Ok(req.as_bytes()),
         }
@@ -252,7 +248,6 @@ impl MailboxReq {
     pub fn as_bytes_mut(&mut self) -> CaliptraResult<&mut [u8]> {
         match self {
             MailboxReq::EcdsaVerify(req) => Ok(req.as_bytes_mut()),
-            MailboxReq::GetIdevCsr(req) => Ok(req.as_bytes_mut()),
             MailboxReq::GetLdevCert(req) => Ok(req.as_bytes_mut()),
             MailboxReq::StashMeasurement(req) => Ok(req.as_bytes_mut()),
             MailboxReq::InvokeDpeCommand(req) => req.as_bytes_partial_mut(),
@@ -262,18 +257,17 @@ impl MailboxReq {
             MailboxReq::GetIdevCert(req) => req.as_bytes_partial_mut(),
             MailboxReq::TagTci(req) => Ok(req.as_bytes_mut()),
             MailboxReq::GetTaggedTci(req) => Ok(req.as_bytes_mut()),
+            MailboxReq::GetFmcAliasCert(req) => Ok(req.as_bytes_mut()),
+            MailboxReq::GetRtAliasCert(req) => Ok(req.as_bytes_mut()),
 
             #[cfg(feature = "test_only_commands")]
             MailboxReq::TestHmacVerify(req) => Ok(req.as_bytes_mut()),
-            #[cfg(feature = "test_only_commands")]
-            MailboxReq::TestGetFmcAliasCert(req) => Ok(req.as_bytes_mut()),
         }
     }
 
     pub fn cmd_code(&self) -> CommandId {
         match self {
             MailboxReq::EcdsaVerify(_) => CommandId::ECDSA384_VERIFY,
-            MailboxReq::GetIdevCsr(_) => CommandId::GET_IDEV_CSR,
             MailboxReq::GetLdevCert(_) => CommandId::GET_LDEV_CERT,
             MailboxReq::StashMeasurement(_) => CommandId::STASH_MEASUREMENT,
             MailboxReq::InvokeDpeCommand(_) => CommandId::INVOKE_DPE,
@@ -283,11 +277,11 @@ impl MailboxReq {
             MailboxReq::GetIdevCert(_) => CommandId::GET_IDEV_CERT,
             MailboxReq::TagTci(_) => CommandId::DPE_TAG_TCI,
             MailboxReq::GetTaggedTci(_) => CommandId::DPE_GET_TAGGED_TCI,
+            MailboxReq::GetFmcAliasCert(_) => CommandId::GET_FMC_ALIAS_CERT,
+            MailboxReq::GetRtAliasCert(_) => CommandId::GET_RT_ALIAS_CERT,
 
             #[cfg(feature = "test_only_commands")]
             MailboxReq::TestHmacVerify(_) => CommandId::TEST_ONLY_HMAC384_VERIFY,
-            #[cfg(feature = "test_only_commands")]
-            MailboxReq::TestGetFmcAliasCert(_) => CommandId::TEST_ONLY_GET_FMC_ALIAS_CERT,
         }
     }
 
@@ -341,30 +335,6 @@ impl Default for MailboxRespHeader {
     }
 }
 
-// GET_IDEV_CSR
-// No command-specific input args
-#[repr(C)]
-#[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
-pub struct GetIdevCsrResp {
-    pub hdr: MailboxRespHeader,
-    pub data_size: u32,
-    pub data: [u8; GetIdevCsrResp::DATA_MAX_SIZE], // variable length
-}
-impl GetIdevCsrResp {
-    pub const DATA_MAX_SIZE: usize = 1024;
-}
-impl ResponseVarSize for GetIdevCsrResp {}
-
-impl Default for GetIdevCsrResp {
-    fn default() -> Self {
-        Self {
-            hdr: MailboxRespHeader::default(),
-            data_size: 0,
-            data: [0u8; GetIdevCsrResp::DATA_MAX_SIZE],
-        }
-    }
-}
-
 // GET_IDEV_CERT
 #[repr(C)]
 #[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
@@ -438,18 +408,17 @@ pub struct GetIdevInfoResp {
     pub idev_pub_y: [u8; 48],
 }
 
+// GET_LDEV_CERT
 #[repr(C)]
 #[derive(Default, Debug, AsBytes, FromBytes, PartialEq, Eq)]
-pub struct TestOnlyGetLdevCertReq {
+pub struct GetLdevCertReq {
     header: MailboxReqHeader,
 }
-impl Request for TestOnlyGetLdevCertReq {
-    const ID: CommandId = CommandId::TEST_ONLY_GET_LDEV_CERT;
+impl Request for GetLdevCertReq {
+    const ID: CommandId = CommandId::GET_LDEV_CERT;
     type Resp = GetLdevCertResp;
 }
 
-// GET_LDEV_CERT
-// No command-specific input args
 #[repr(C)]
 #[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
 pub struct GetLdevCertResp {
@@ -472,6 +441,43 @@ impl Default for GetLdevCertResp {
     }
 }
 
+// GET_RT_ALIAS_CERT
+#[repr(C)]
+#[derive(Default, Debug, AsBytes, FromBytes, PartialEq, Eq)]
+pub struct GetRtAliasCertReq {
+    header: MailboxReqHeader,
+}
+impl Request for GetRtAliasCertReq {
+    const ID: CommandId = CommandId::GET_RT_ALIAS_CERT;
+    type Resp = GetRtAliasCertResp;
+}
+
+#[repr(C)]
+#[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
+pub struct GetRtAliasCertResp {
+    pub hdr: MailboxRespHeader,
+    pub data_size: u32,
+    pub data: [u8; GetRtAliasCertResp::DATA_MAX_SIZE], // variable length
+}
+impl GetRtAliasCertResp {
+    pub const DATA_MAX_SIZE: usize = 1024;
+
+    pub fn data(&self) -> Option<&[u8]> {
+        self.data.get(..self.data_size as usize)
+    }
+}
+impl ResponseVarSize for GetRtAliasCertResp {}
+
+impl Default for GetRtAliasCertResp {
+    fn default() -> Self {
+        Self {
+            hdr: MailboxRespHeader::default(),
+            data_size: 0,
+            data: [0u8; GetRtAliasCertResp::DATA_MAX_SIZE],
+        }
+    }
+}
+
 // ECDSA384_SIGNATURE_VERIFY
 #[repr(C)]
 #[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
@@ -606,36 +612,35 @@ impl Default for InvokeDpeResp {
     }
 }
 
+// GET_FMC_ALIAS_CERT
 #[repr(C)]
 #[derive(Debug, Default, AsBytes, FromBytes, PartialEq, Eq)]
-pub struct TestOnlyGetFmcAliasCertReq {
+pub struct GetFmcAliasCertReq {
     header: MailboxReqHeader,
 }
-impl Request for TestOnlyGetFmcAliasCertReq {
-    const ID: CommandId = CommandId::TEST_ONLY_GET_FMC_ALIAS_CERT;
-    type Resp = TestGetFmcAliasCertResp;
+impl Request for GetFmcAliasCertReq {
+    const ID: CommandId = CommandId::GET_FMC_ALIAS_CERT;
+    type Resp = GetFmcAliasCertResp;
 }
 
-// TEST_ONLY_GET_FMC_ALIAS_CERT
-// No command-specific input args
 #[repr(C)]
 #[derive(Debug, AsBytes, FromBytes, PartialEq, Eq)]
-pub struct TestGetFmcAliasCertResp {
+pub struct GetFmcAliasCertResp {
     pub hdr: MailboxRespHeader,
     pub data_size: u32,
-    pub data: [u8; TestGetFmcAliasCertResp::DATA_MAX_SIZE], // variable length
+    pub data: [u8; GetFmcAliasCertResp::DATA_MAX_SIZE], // variable length
 }
-impl TestGetFmcAliasCertResp {
+impl GetFmcAliasCertResp {
     pub const DATA_MAX_SIZE: usize = 1024;
 }
-impl ResponseVarSize for TestGetFmcAliasCertResp {}
+impl ResponseVarSize for GetFmcAliasCertResp {}
 
-impl Default for TestGetFmcAliasCertResp {
+impl Default for GetFmcAliasCertResp {
     fn default() -> Self {
         Self {
             hdr: MailboxRespHeader::default(),
             data_size: 0,
-            data: [0u8; TestGetFmcAliasCertResp::DATA_MAX_SIZE],
+            data: [0u8; GetFmcAliasCertResp::DATA_MAX_SIZE],
         }
     }
 }
diff --git a/builder/src/firmware.rs b/builder/src/firmware.rs
index 1bdc6f36..65360de6 100644
--- a/builder/src/firmware.rs
+++ b/builder/src/firmware.rs
@@ -344,11 +344,6 @@ pub mod runtime_tests {
         bin_name: "boot",
         ..RUNTIME_TEST_FWID_BASE
     };
-
-    pub const CERT: FwId = FwId {
-        bin_name: "cert",
-        ..RUNTIME_TEST_FWID_BASE
-    };
 }
 
 pub const REGISTERED_FW: &[&FwId] = &[
@@ -406,5 +401,4 @@ pub const REGISTERED_FW: &[&FwId] = &[
     &fmc_tests::MOCK_RT_WITH_UART,
     &fmc_tests::MOCK_RT_INTERACTIVE,
     &runtime_tests::BOOT,
-    &runtime_tests::CERT,
 ];
diff --git a/runtime/README.md b/runtime/README.md
index cfe7d7bf..1976fdc7 100644
--- a/runtime/README.md
+++ b/runtime/README.md
@@ -166,70 +166,89 @@ Table: `POPULATE_IDEV_CERT` output arguments
 | 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
 
-### GET\_IDEV\_CSR
+### GET\_IDEV\_INFO
 
-ROM exposes a command to get a self-signed IDEVID CSR.
-GET\_IDEV\_CSR is not exposed by runtime firmware.
+Exposes a command to get a IDEVID public key.
 
-Command Code: `0x4944_4556` ("IDEV")
+Command Code: `0x4944_4549` ("IDEI")
 
-Table: `GET_IDEV_CSR` input arguments
+Table: `GET_IDEV_INFO` input arguments
 
 | **Name**  | **Type**      | **Description**
 | --------  | --------      | ---------------
 | chksum    | u32           | Checksum over other input arguments, computed by the caller. Little endian.
 
-Table: `GET_IDEV_CSR` output arguments
+Table: `GET_IDEV_INFO` 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
+| idev_pub_x  | u8[48]     | X portion of ECDSA IDevId key
+| idev_pub_y  | u8[48]     | Y portion of ECDSA IDevId key
+
+### GET\_LDEV\_CERT
+
+Exposes a command to get a self-signed LDevID Certificate signed by IDevID.
+
+Command Code: `0x4C44_4556` ("LDEV")
+
+Table: `GET_LDEV_CERT` input arguments
+
+| **Name**  | **Type**      | **Description**
+| --------  | --------      | ---------------
+| chksum    | u32           | Checksum over other input arguments, computed by the caller. Little endian.
+
+Table: `GET_LDEV_CERT` 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
 | data_size   | u32        | Length in bytes of the valid data in the data field
-| data        | u8[...]    | DER-encoded IDevID CSR
+| data        | u8[...]    | DER-encoded LDevID Certificate
 
-### GET\_IDEV\_INFO
+### GET\_FMC\_ALIAS\_CERT
 
-Exposes a command to get a IDEVID public key.
+Exposes a command to get a self-signed FMC alias Certificate signed by LDevID.
 
-Command Code: `0x4944_4549` ("IDEI")
+Command Code: `0x4345_5246` ("CERF")
 
-Table: `GET_IDEV_INFO` input arguments
+Table: `GET_FMC_ALIAS_CERT` input arguments
 
 | **Name**  | **Type**      | **Description**
 | --------  | --------      | ---------------
 | chksum    | u32           | Checksum over other input arguments, computed by the caller. Little endian.
 
-Table: `GET_IDEV_INFO` output arguments
+Table: `GET_FMC_ALIAS_CERT` 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
-| idev_pub_x  | u8[48]     | X portion of ECDSA IDevId key
-| idev_pub_y  | u8[48]     | Y portion of ECDSA IDevId key
+| data_size   | u32        | Length in bytes of the valid data in the data field
+| data        | u8[...]    | DER-encoded FMC alias Certificate
 
-### GET\_LDEV\_CERT
+### GET\_RT\_ALIAS\_CERT
 
-ROM exposes a command to get a self-signed LDevID Certificate signed by IDevID.
-GET\_LDEV\_CERT is not exposed by runtime firmware.
+Exposes a command to get a self-signed Runtime alias Certificate signed by the FMC alias.
 
-Command Code: `0x4C44_4556` ("LDEV")
+Command Code: `0x4345_5252` ("CERR")
 
-Table: `GET_LDEV_CERT` input arguments
+Table: `GET_RT_ALIAS_CERT` input arguments
 
 | **Name**  | **Type**      | **Description**
 | --------  | --------      | ---------------
 | chksum    | u32           | Checksum over other input arguments, computed by the caller. Little endian.
 
-Table: `GET_LDEV_CERT` output arguments
+Table: `GET_RT_ALIAS_CERT` 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
 | data_size   | u32        | Length in bytes of the valid data in the data field
-| data        | u8[...]    | DER-encoded LDevID Certificate
+| data        | u8[...]    | DER-encoded Runtime alias Certificate
 
 ### ECDSA384\_SIGNATURE\_VERIFY
 
@@ -698,7 +717,7 @@ The DPE Runtime Alias Key SHALL sign DPE leaf certificates and CSRs.
 
 The DPE `GET_CERTIFICATE_CHAIN` command shall return the following certificates:
 
-* IDevID
+* IDevID (Optionally added by the SoC via POPULATE_IDEV_CERT)
 * LDevID
 * FMC Alias
 * Runtime Alias
diff --git a/runtime/src/dice.rs b/runtime/src/dice.rs
index c4e5592c..f025bbd2 100644
--- a/runtime/src/dice.rs
+++ b/runtime/src/dice.rs
@@ -1,11 +1,9 @@
 // Licensed under the Apache-2.0 license
 
-#[cfg(feature = "test_only_commands")]
 use caliptra_common::mailbox_api::{
-    GetLdevCertResp, MailboxResp, MailboxRespHeader, TestGetFmcAliasCertResp,
+    GetFmcAliasCertResp, GetLdevCertResp, GetRtAliasCertResp, MailboxResp, MailboxRespHeader,
 };
 
-#[cfg(feature = "test_only_commands")]
 use crate::Drivers;
 
 use caliptra_drivers::{
@@ -16,7 +14,6 @@ use caliptra_x509::{Ecdsa384CertBuilder, Ecdsa384Signature};
 
 pub struct GetLdevCertCmd;
 impl GetLdevCertCmd {
-    #[cfg(feature = "test_only_commands")]
     pub(crate) fn execute(drivers: &mut Drivers) -> CaliptraResult<MailboxResp> {
         let mut resp = GetLdevCertResp::default();
 
@@ -30,11 +27,10 @@ impl GetLdevCertCmd {
     }
 }
 
-pub struct TestGetFmcAliasCertCmd;
-impl TestGetFmcAliasCertCmd {
-    #[cfg(feature = "test_only_commands")]
+pub struct GetFmcAliasCertCmd;
+impl GetFmcAliasCertCmd {
     pub(crate) fn execute(drivers: &mut Drivers) -> CaliptraResult<MailboxResp> {
-        let mut resp = TestGetFmcAliasCertResp::default();
+        let mut resp = GetFmcAliasCertResp::default();
 
         resp.data_size = copy_fmc_alias_cert(
             &drivers.data_vault,
@@ -42,7 +38,18 @@ impl TestGetFmcAliasCertCmd {
             &mut resp.data,
         )? as u32;
 
-        Ok(MailboxResp::TestGetFmcAliasCert(resp))
+        Ok(MailboxResp::GetFmcAliasCert(resp))
+    }
+}
+
+pub struct GetRtAliasCertCmd;
+impl GetRtAliasCertCmd {
+    pub(crate) fn execute(drivers: &mut Drivers) -> CaliptraResult<MailboxResp> {
+        let mut resp = GetRtAliasCertResp::default();
+
+        resp.data_size = copy_rt_alias_cert(drivers.persistent_data.get(), &mut resp.data)? as u32;
+
+        Ok(MailboxResp::GetRtAliasCert(resp))
     }
 }
 
diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs
index 1128f6e5..ce1cfffe 100644
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -20,8 +20,7 @@ pub use drivers::Drivers;
 use mailbox::Mailbox;
 
 pub use caliptra_common::fips::FipsVersionCmd;
-#[cfg(feature = "test_only_commands")]
-pub use dice::{GetLdevCertCmd, TestGetFmcAliasCertCmd};
+pub use dice::{GetFmcAliasCertCmd, GetLdevCertCmd};
 pub use disable::DisableAttestationCmd;
 use dpe_crypto::DpeCrypto;
 pub use dpe_platform::{DpePlatform, VENDOR_ID, VENDOR_SKU};
@@ -50,6 +49,7 @@ use dpe::{
     DPE_PROFILE,
 };
 
+use crate::dice::GetRtAliasCertCmd;
 #[cfg(feature = "test_only_commands")]
 use crate::verify::HmacVerifyCmd;
 
@@ -131,9 +131,8 @@ fn handle_command(drivers: &mut Drivers) -> CaliptraResult<MboxStatusE> {
     let mut resp = match CommandId::from(req_packet.cmd) {
         CommandId::FIRMWARE_LOAD => Err(CaliptraError::RUNTIME_UNIMPLEMENTED_COMMAND),
         CommandId::GET_IDEV_CERT => IDevIdCertCmd::execute(cmd_bytes),
-        CommandId::GET_IDEV_CSR => Err(CaliptraError::RUNTIME_UNIMPLEMENTED_COMMAND),
         CommandId::GET_IDEV_INFO => IDevIdInfoCmd::execute(drivers),
-        CommandId::GET_LDEV_CERT => Err(CaliptraError::RUNTIME_UNIMPLEMENTED_COMMAND),
+        CommandId::GET_LDEV_CERT => GetLdevCertCmd::execute(drivers),
         CommandId::INVOKE_DPE => InvokeDpeCmd::execute(drivers, cmd_bytes),
         CommandId::ECDSA384_VERIFY => EcdsaVerifyCmd::execute(drivers, cmd_bytes),
         CommandId::STASH_MEASUREMENT => StashMeasurementCmd::execute(drivers, cmd_bytes),
@@ -142,10 +141,8 @@ fn handle_command(drivers: &mut Drivers) -> CaliptraResult<MboxStatusE> {
         CommandId::DPE_TAG_TCI => TagTciCmd::execute(drivers, cmd_bytes),
         CommandId::DPE_GET_TAGGED_TCI => GetTaggedTciCmd::execute(drivers, cmd_bytes),
         CommandId::POPULATE_IDEV_CERT => PopulateIDevIdCertCmd::execute(drivers, cmd_bytes),
-        #[cfg(feature = "test_only_commands")]
-        CommandId::TEST_ONLY_GET_LDEV_CERT => GetLdevCertCmd::execute(drivers),
-        #[cfg(feature = "test_only_commands")]
-        CommandId::TEST_ONLY_GET_FMC_ALIAS_CERT => TestGetFmcAliasCertCmd::execute(drivers),
+        CommandId::GET_FMC_ALIAS_CERT => GetFmcAliasCertCmd::execute(drivers),
+        CommandId::GET_RT_ALIAS_CERT => GetRtAliasCertCmd::execute(drivers),
         #[cfg(feature = "test_only_commands")]
         CommandId::TEST_ONLY_HMAC384_VERIFY => HmacVerifyCmd::execute(drivers, cmd_bytes),
         CommandId::VERSION => {


Test patch:
diff --git a/rom/dev/tests/rom_integration_tests/test_idevid_derivation.rs b/rom/dev/tests/rom_integration_tests/test_idevid_derivation.rs
index 7719d618..661fbb65 100644
--- a/rom/dev/tests/rom_integration_tests/test_idevid_derivation.rs
+++ b/rom/dev/tests/rom_integration_tests/test_idevid_derivation.rs
@@ -108,16 +108,22 @@ fn test_generate_csr_stress() {
 
         let ldev_cert = verify_key(
             &mut hw,
-            u32::from(CommandId::TEST_ONLY_GET_LDEV_CERT),
+            u32::from(CommandId::GET_LDEV_CERT),
             &idevid_pubkey,
             &fuses.uds_seed,
         );
-        let _fmc_cert = verify_key(
+        let fmc_cert = verify_key(
             &mut hw,
-            u32::from(CommandId::TEST_ONLY_GET_FMC_ALIAS_CERT),
+            u32::from(CommandId::GET_FMC_ALIAS_CERT),
             &ldev_cert.public_key().unwrap(),
             &fuses.uds_seed,
         );
+        let _rt_cert = verify_key(
+            &mut hw,
+            u32::from(CommandId::GET_RT_ALIAS_CERT),
+            &fmc_cert.public_key().unwrap(),
+            &fuses.uds_seed,
+        );
     }
 }
 
diff --git a/runtime/test-fw/Cargo.toml b/runtime/test-fw/Cargo.toml
index 64298a2a..ca8152d1 100644
--- a/runtime/test-fw/Cargo.toml
+++ b/runtime/test-fw/Cargo.toml
@@ -24,11 +24,6 @@ name = "boot"
 path = "src/boot_tests.rs"
 required-features = ["riscv"]
 
-[[bin]]
-name = "cert"
-path = "src/cert_tests.rs"
-required-features = ["riscv"]
-
 [build-dependencies]
 caliptra_common = { workspace = true, default-features = false }
 caliptra-gen-linker-scripts.workspace = true
diff --git a/runtime/test-fw/src/cert_tests.rs b/runtime/test-fw/src/cert_tests.rs
deleted file mode 100644
index 9f7e0902..00000000
--- a/runtime/test-fw/src/cert_tests.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed under the Apache-2.0 license
-
-//! Send DICE certificates over the mailbox
-
-#![no_main]
-#![no_std]
-
-use caliptra_common::mailbox_api::CommandId;
-use caliptra_registers::mbox::enums::MboxStatusE;
-use caliptra_runtime::{dice, Drivers};
-use caliptra_test_harness::{runtime_handlers, test_suite};
-use zerocopy::AsBytes;
-
-fn mbox_responder() {
-    let drivers = unsafe { Drivers::new_from_registers().unwrap() };
-    assert!(drivers.persistent_data.get().fht.is_valid());
-    let mut mbox = drivers.mbox;
-
-    loop {
-        while !mbox.is_cmd_ready() {
-            // Wait for a request from the SoC.
-        }
-        let cmd = mbox.cmd();
-
-        match cmd {
-            // Send LDevID Cert
-            CommandId(0x1000_0000) => {
-                let mut ldev = [0u8; 1024];
-                dice::copy_ldevid_cert(
-                    &drivers.data_vault,
-                    drivers.persistent_data.get(),
-                    &mut ldev,
-                )
-                .unwrap();
-                mbox.write_response(&ldev).unwrap();
-                mbox.set_status(MboxStatusE::DataReady);
-            }
-            // Send FMC Alias Cert
-            CommandId(0x2000_0000) => {
-                let mut fmc = [0u8; 1024];
-                dice::copy_fmc_alias_cert(
-                    &drivers.data_vault,
-                    drivers.persistent_data.get(),
-                    &mut fmc,
-                )
-                .unwrap();
-                mbox.write_response(&fmc).unwrap();
-                mbox.set_status(MboxStatusE::DataReady);
-            }
-            // Send RT Alias Cert
-            CommandId(0x3000_0000) => {
-                let mut rt = [0u8; 1024];
-                dice::copy_rt_alias_cert(drivers.persistent_data.get(), &mut rt).unwrap();
-                mbox.write_response(&rt).unwrap();
-                mbox.set_status(MboxStatusE::DataReady);
-            }
-            // Send IDevID Public Key
-            CommandId(0x4000_0000) => {
-                mbox.write_response(
-                    drivers
-                        .persistent_data
-                        .get()
-                        .fht
-                        .idev_dice_pub_key
-                        .as_bytes(),
-                )
-                .unwrap();
-                mbox.set_status(MboxStatusE::DataReady);
-            }
-            _ => {
-                mbox.set_status(MboxStatusE::CmdFailure);
-            }
-        }
-    }
-}
-
-test_suite! {
-    mbox_responder,
-}
diff --git a/runtime/tests/runtime_integration_tests/integration_tests.rs b/runtime/tests/runtime_integration_tests/integration_tests.rs
index a0308cdd..9729fa4c 100644
--- a/runtime/tests/runtime_integration_tests/integration_tests.rs
+++ b/runtime/tests/runtime_integration_tests/integration_tests.rs
@@ -6,12 +6,12 @@ use caliptra_builder::{
     ImageOptions,
 };
 use caliptra_common::mailbox_api::{
-    CommandId, EcdsaVerifyReq, FipsVersionResp, FwInfoResp, GetIdevCertReq, GetIdevCertResp,
-    GetIdevInfoResp, GetTaggedTciReq, GetTaggedTciResp, InvokeDpeReq, InvokeDpeResp, MailboxReq,
-    MailboxReqHeader, MailboxRespHeader, PopulateIdevCertReq, StashMeasurementReq,
-    StashMeasurementResp, TagTciReq,
+    CommandId, EcdsaVerifyReq, FipsVersionResp, FwInfoResp, GetFmcAliasCertResp, GetIdevCertReq,
+    GetIdevCertResp, GetIdevInfoResp, GetLdevCertResp, GetRtAliasCertResp, GetTaggedTciReq,
+    GetTaggedTciResp, InvokeDpeReq, InvokeDpeResp, MailboxReq, MailboxReqHeader, MailboxRespHeader,
+    PopulateIdevCertReq, StashMeasurementReq, StashMeasurementResp, TagTciReq,
 };
-use caliptra_drivers::{CaliptraError, Ecc384PubKey};
+use caliptra_drivers::CaliptraError;
 use caliptra_hw_model::{DefaultHwModel, HwModel, ModelError, ShaAccMode};
 use caliptra_runtime::{
     FipsVersionCmd, InvokeDpeCmd, RtBootStatus, DPE_SUPPORT, VENDOR_ID, VENDOR_SKU,
@@ -128,12 +128,23 @@ fn test_rt_cert_with_custom_dates() {
 
     opts.owner_config = Some(own_config);
 
-    let mut model = run_rt_test(Some(&firmware::runtime_tests::CERT), Some(opts), None);
+    let mut model = run_rt_test(None, Some(opts), None);
 
-    let rt_resp = model.mailbox_execute(0x3000_0000, &[]).unwrap().unwrap();
-    let rt: &[u8] = rt_resp.as_bytes();
+    let payload = MailboxReqHeader {
+        chksum: caliptra_common::checksum::calc_checksum(
+            u32::from(CommandId::GET_RT_ALIAS_CERT),
+            &[],
+        ),
+    };
+    let resp = model
+        .mailbox_execute(u32::from(CommandId::GET_RT_ALIAS_CERT), payload.as_bytes())
+        .unwrap()
+        .unwrap();
+    assert!(resp.len() <= std::mem::size_of::<GetRtAliasCertResp>());
+    let mut rt_resp = GetRtAliasCertResp::default();
+    rt_resp.as_bytes_mut()[..resp.len()].copy_from_slice(&resp);
 
-    let rt_cert: X509 = X509::from_der(rt).unwrap();
+    let rt_cert: X509 = X509::from_der(&rt_resp.data[..rt_resp.data_size as usize]).unwrap();
 
     let not_before: Asn1Time = Asn1Time::from_str(OWNER_CONFIG.0).unwrap();
     let not_after: Asn1Time = Asn1Time::from_str(OWNER_CONFIG.1).unwrap();
@@ -144,32 +155,67 @@ fn test_rt_cert_with_custom_dates() {
 
 #[test]
 fn test_certs() {
-    let mut model = run_rt_test(Some(&firmware::runtime_tests::CERT), None, None);
+    let mut model = run_rt_test(None, None, None);
 
-    // Get certs over the mailbox
-    let ldev_resp = model.mailbox_execute(0x1000_0000, &[]).unwrap().unwrap();
-    let ldevid: &[u8] = ldev_resp.as_bytes();
+    // Get certs via mailbox commands
+    let payload = MailboxReqHeader {
+        chksum: caliptra_common::checksum::calc_checksum(u32::from(CommandId::GET_LDEV_CERT), &[]),
+    };
+    let resp = model
+        .mailbox_execute(u32::from(CommandId::GET_LDEV_CERT), payload.as_bytes())
+        .unwrap()
+        .unwrap();
+    assert!(resp.len() <= std::mem::size_of::<GetLdevCertResp>());
+    let mut ldev_resp = GetLdevCertResp::default();
+    ldev_resp.as_bytes_mut()[..resp.len()].copy_from_slice(&resp);
 
-    let fmc_resp = model.mailbox_execute(0x2000_0000, &[]).unwrap().unwrap();
-    let fmc: &[u8] = fmc_resp.as_bytes();
+    let payload = MailboxReqHeader {
+        chksum: caliptra_common::checksum::calc_checksum(
+            u32::from(CommandId::GET_FMC_ALIAS_CERT),
+            &[],
+        ),
+    };
+    let resp = model
+        .mailbox_execute(u32::from(CommandId::GET_FMC_ALIAS_CERT), payload.as_bytes())
+        .unwrap()
+        .unwrap();
+    assert!(resp.len() <= std::mem::size_of::<GetFmcAliasCertResp>());
+    let mut fmc_resp = GetFmcAliasCertResp::default();
+    fmc_resp.as_bytes_mut()[..resp.len()].copy_from_slice(&resp);
 
-    let rt_resp = model.mailbox_execute(0x3000_0000, &[]).unwrap().unwrap();
-    let rt: &[u8] = rt_resp.as_bytes();
+    let payload = MailboxReqHeader {
+        chksum: caliptra_common::checksum::calc_checksum(
+            u32::from(CommandId::GET_RT_ALIAS_CERT),
+            &[],
+        ),
+    };
+    let resp = model
+        .mailbox_execute(u32::from(CommandId::GET_RT_ALIAS_CERT), payload.as_bytes())
+        .unwrap()
+        .unwrap();
+    assert!(resp.len() <= std::mem::size_of::<GetRtAliasCertResp>());
+    let mut rt_resp = GetRtAliasCertResp::default();
+    rt_resp.as_bytes_mut()[..resp.len()].copy_from_slice(&resp);
 
     // Ensure certs are valid X.509
-    let ldev_cert: X509 = X509::from_der(ldevid).unwrap();
-    let fmc_cert: X509 = X509::from_der(fmc).unwrap();
-    let rt_cert: X509 = X509::from_der(rt).unwrap();
+    let ldev_cert: X509 = X509::from_der(&ldev_resp.data[..ldev_resp.data_size as usize]).unwrap();
+    let fmc_cert: X509 = X509::from_der(&fmc_resp.data[..fmc_resp.data_size as usize]).unwrap();
+    let rt_cert: X509 = X509::from_der(&rt_resp.data[..rt_resp.data_size as usize]).unwrap();
 
-    let idev_resp = model.mailbox_execute(0x4000_0000, &[]).unwrap().unwrap();
-    let idev_pub = Ecc384PubKey::read_from(idev_resp.as_bytes()).unwrap();
+    // Get IDev public key
+    let payload = MailboxReqHeader {
+        chksum: caliptra_common::checksum::calc_checksum(u32::from(CommandId::GET_IDEV_INFO), &[]),
+    };
+    let resp = model
+        .mailbox_execute(u32::from(CommandId::GET_IDEV_INFO), payload.as_bytes())
+        .unwrap()
+        .unwrap();
+    let idev_resp = GetIdevInfoResp::read_from(resp.as_slice()).unwrap();
 
     // Check the LDevID is signed by IDevID
     let group = EcGroup::from_curve_name(Nid::SECP384R1).unwrap();
-    let x_bytes: [u8; 48] = idev_pub.x.into();
-    let y_bytes: [u8; 48] = idev_pub.y.into();
-    let idev_x = &BigNum::from_slice(&x_bytes).unwrap();
-    let idev_y = &BigNum::from_slice(&y_bytes).unwrap();
+    let idev_x = &BigNum::from_slice(&idev_resp.idev_pub_x).unwrap();
+    let idev_y = &BigNum::from_slice(&idev_resp.idev_pub_y).unwrap();
 
     let idev_ec_key = EcKey::from_public_key_affine_coordinates(&group, idev_x, idev_y).unwrap();
     assert!(ldev_cert
@@ -1165,20 +1211,12 @@ fn test_unimplemented_cmds() {
 
     let expected_err = Err(ModelError::MailboxCmdFailed(0xe0002));
 
-    // GET_IDEV_CSR
+    // CAPABILITIES
     let payload = MailboxReqHeader {
-        chksum: caliptra_common::checksum::calc_checksum(u32::from(CommandId::GET_IDEV_CSR), &[]),
-    };
-
-    let mut resp = model.mailbox_execute(u32::from(CommandId::GET_IDEV_CSR), payload.as_bytes());
-    assert_eq!(resp, expected_err);
-
-    // GET_LDEV_CERT
-    let payload = MailboxReqHeader {
-        chksum: caliptra_common::checksum::calc_checksum(u32::from(CommandId::GET_LDEV_CERT), &[]),
+        chksum: caliptra_common::checksum::calc_checksum(u32::from(CommandId::CAPABILITIES), &[]),
     };
 
-    resp = model.mailbox_execute(u32::from(CommandId::GET_LDEV_CERT), payload.as_bytes());
+    let resp = model.mailbox_execute(u32::from(CommandId::CAPABILITIES), payload.as_bytes());
     assert_eq!(resp, expected_err);
 
     // Send something that is not a valid RT command.
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 5eafd59e..3fbec155 100755
--- a/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs
+++ b/test/tests/caliptra_integration_tests/fake_collateral_boot_test.rs
@@ -5,7 +5,7 @@ use caliptra_builder::{
     ImageOptions,
 };
 use caliptra_common::mailbox_api::{
-    CommandId, GetLdevCertResp, MailboxReqHeader, MailboxRespHeader, TestGetFmcAliasCertResp,
+    CommandId, GetFmcAliasCertResp, GetLdevCertResp, MailboxReqHeader, MailboxRespHeader,
 };
 use caliptra_hw_model::{BootParams, HwModel, InitParams, SecurityState};
 use caliptra_hw_model_types::Fuses;
@@ -103,18 +103,12 @@ fn fake_boot_test() {
     );
 
     let payload = MailboxReqHeader {
-        chksum: caliptra_common::checksum::calc_checksum(
-            u32::from(CommandId::TEST_ONLY_GET_LDEV_CERT),
-            &[],
-        ),
+        chksum: caliptra_common::checksum::calc_checksum(u32::from(CommandId::GET_LDEV_CERT), &[]),
     };
 
     // Execute the command
     let resp = hw
-        .mailbox_execute(
-            u32::from(CommandId::TEST_ONLY_GET_LDEV_CERT),
-            payload.as_bytes(),
-        )
+        .mailbox_execute(u32::from(CommandId::GET_LDEV_CERT), payload.as_bytes())
         .unwrap()
         .unwrap();
 
@@ -173,22 +167,19 @@ fn fake_boot_test() {
 
     let payload = MailboxReqHeader {
         chksum: caliptra_common::checksum::calc_checksum(
-            u32::from(CommandId::TEST_ONLY_GET_FMC_ALIAS_CERT),
+            u32::from(CommandId::GET_FMC_ALIAS_CERT),
             &[],
         ),
     };
 
     // Execute command
     let resp = hw
-        .mailbox_execute(
-            u32::from(CommandId::TEST_ONLY_GET_FMC_ALIAS_CERT),
-            payload.as_bytes(),
-        )
+        .mailbox_execute(u32::from(CommandId::GET_FMC_ALIAS_CERT), payload.as_bytes())
         .unwrap()
         .unwrap();
 
-    assert!(resp.len() <= std::mem::size_of::<TestGetFmcAliasCertResp>());
-    let mut fmc_alias_cert_resp = TestGetFmcAliasCertResp::default();
+    assert!(resp.len() <= std::mem::size_of::<GetFmcAliasCertResp>());
+    let mut fmc_alias_cert_resp = GetFmcAliasCertResp::default();
     fmc_alias_cert_resp.as_bytes_mut()[..resp.len()].copy_from_slice(&resp);
 
     // Verify checksum and FIPS approval
diff --git a/test/tests/caliptra_integration_tests/smoke_test.rs b/test/tests/caliptra_integration_tests/smoke_test.rs
index e6b8393e..7736c968 100644
--- a/test/tests/caliptra_integration_tests/smoke_test.rs
+++ b/test/tests/caliptra_integration_tests/smoke_test.rs
@@ -1,9 +1,7 @@
 // Licensed under the Apache-2.0 license
 
 use caliptra_builder::{firmware, ImageOptions};
-use caliptra_common::mailbox_api::{
-    ResponseVarSize, TestOnlyGetFmcAliasCertReq, TestOnlyGetLdevCertReq,
-};
+use caliptra_common::mailbox_api::{GetFmcAliasCertReq, GetLdevCertReq, ResponseVarSize};
 use caliptra_hw_model::{BootParams, HwModel, InitParams, SecurityState};
 use caliptra_hw_model_types::{DeviceLifecycle, Fuses};
 use caliptra_test::run_test;
@@ -186,9 +184,7 @@ fn smoke_test() {
         );
     }
 
-    let ldev_cert_resp = hw
-        .mailbox_execute_req(TestOnlyGetLdevCertReq::default())
-        .unwrap();
+    let ldev_cert_resp = hw.mailbox_execute_req(GetLdevCertReq::default()).unwrap();
 
     // Extract the certificate from the response
     let ldev_cert_der = ldev_cert_resp.data().unwrap();
@@ -230,7 +226,7 @@ fn smoke_test() {
 
     // Execute command
     let fmc_alias_cert_resp = hw
-        .mailbox_execute_req(TestOnlyGetFmcAliasCertReq::default())
+        .mailbox_execute_req(GetFmcAliasCertReq::default())
         .unwrap();
 
     // Extract the certificate from the response