From 7065885123c3786468f080f2e79afe083595cd75 Mon Sep 17 00:00:00 2001 From: Sree Revoori Date: Mon, 27 Nov 2023 21:34:34 +0000 Subject: [PATCH] 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 --- api/src/mailbox.rs | 133 +++++++++--------- builder/src/firmware.rs | 6 - .../test_idevid_derivation.rs | 12 +- runtime/README.md | 63 ++++++--- runtime/src/dice.rs | 25 ++-- runtime/src/lib.rs | 13 +- runtime/test-fw/Cargo.toml | 5 - runtime/test-fw/src/cert_tests.rs | 79 ----------- .../integration_tests.rs | 112 ++++++++++----- .../fake_collateral_boot_test.rs | 23 +-- .../caliptra_integration_tests/smoke_test.rs | 10 +- 11 files changed, 225 insertions(+), 256 deletions(-) delete mode 100644 runtime/test-fw/src/cert_tests.rs diff --git a/api/src/mailbox.rs b/api/src/mailbox.rs index 67645b4a03..fedb022db6 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 1bdc6f366c..65360de6ea 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/rom/dev/tests/rom_integration_tests/test_idevid_derivation.rs b/rom/dev/tests/rom_integration_tests/test_idevid_derivation.rs index 7719d61800..661fbb650f 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/README.md b/runtime/README.md index cfe7d7bf03..1976fdc7d2 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 c4e5592cc4..f025bbd20d 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 { 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 { - 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 { + 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 1128f6e509..ce1cfffee8 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 { 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 { 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 => { diff --git a/runtime/test-fw/Cargo.toml b/runtime/test-fw/Cargo.toml index 64298a2af7..ca8152d1cd 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 9f7e09020a..0000000000 --- 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 a0308cdd03..9729fa4ca6 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::()); + 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::()); + 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::()); + 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::()); + 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 5eafd59ef1..3fbec1551d 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::()); - let mut fmc_alias_cert_resp = TestGetFmcAliasCertResp::default(); + assert!(resp.len() <= std::mem::size_of::()); + 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 e6b8393e70..7736c968a0 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