Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rolled up pr #1927

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

111 changes: 111 additions & 0 deletions api/src/mailbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ impl CommandId {

// The get IDevID CSR command.
pub const GET_IDEV_CSR: Self = Self(0x4944_4352); // "IDCR"

// The get FMC Alias CSR command.
pub const GET_FMC_ALIAS_CSR: Self = Self(0x464D_4352); // "FMCR"
//
// The sign with exported ecdsa command.
pub const SIGN_WITH_EXPORTED_ECDSA: Self = Self(0x5357_4545); // "SWEE"
}

impl From<u32> for CommandId {
Expand Down Expand Up @@ -153,6 +159,8 @@ pub enum MailboxResp {
CertifyKeyExtended(CertifyKeyExtendedResp),
AuthorizeAndStash(AuthorizeAndStashResp),
GetIdevCsr(GetIdevCsrResp),
GetFmcAliasCsr(GetFmcAliasCsrResp),
SignWithExportedEcdsa(SignWithExportedEcdsaResp),
}

impl MailboxResp {
Expand All @@ -174,6 +182,8 @@ impl MailboxResp {
MailboxResp::CertifyKeyExtended(resp) => Ok(resp.as_bytes()),
MailboxResp::AuthorizeAndStash(resp) => Ok(resp.as_bytes()),
MailboxResp::GetIdevCsr(resp) => Ok(resp.as_bytes()),
MailboxResp::GetFmcAliasCsr(resp) => Ok(resp.as_bytes()),
MailboxResp::SignWithExportedEcdsa(resp) => Ok(resp.as_bytes()),
}
}

Expand All @@ -195,6 +205,8 @@ impl MailboxResp {
MailboxResp::CertifyKeyExtended(resp) => Ok(resp.as_mut_bytes()),
MailboxResp::AuthorizeAndStash(resp) => Ok(resp.as_mut_bytes()),
MailboxResp::GetIdevCsr(resp) => Ok(resp.as_mut_bytes()),
MailboxResp::GetFmcAliasCsr(resp) => Ok(resp.as_mut_bytes()),
MailboxResp::SignWithExportedEcdsa(resp) => Ok(resp.as_mut_bytes()),
}
}

Expand Down Expand Up @@ -253,6 +265,7 @@ pub enum MailboxReq {
CertifyKeyExtended(CertifyKeyExtendedReq),
SetAuthManifest(SetAuthManifestReq),
AuthorizeAndStash(AuthorizeAndStashReq),
SignWithExportedEcdsa(SignWithExportedEcdsaReq),
}

impl MailboxReq {
Expand All @@ -278,6 +291,7 @@ impl MailboxReq {
MailboxReq::CertifyKeyExtended(req) => Ok(req.as_bytes()),
MailboxReq::SetAuthManifest(req) => Ok(req.as_bytes()),
MailboxReq::AuthorizeAndStash(req) => Ok(req.as_bytes()),
MailboxReq::SignWithExportedEcdsa(req) => Ok(req.as_bytes()),
}
}

Expand All @@ -303,6 +317,7 @@ impl MailboxReq {
MailboxReq::CertifyKeyExtended(req) => Ok(req.as_mut_bytes()),
MailboxReq::SetAuthManifest(req) => Ok(req.as_mut_bytes()),
MailboxReq::AuthorizeAndStash(req) => Ok(req.as_mut_bytes()),
MailboxReq::SignWithExportedEcdsa(req) => Ok(req.as_mut_bytes()),
}
}

Expand All @@ -328,6 +343,7 @@ impl MailboxReq {
MailboxReq::CertifyKeyExtended(_) => CommandId::CERTIFY_KEY_EXTENDED,
MailboxReq::SetAuthManifest(_) => CommandId::SET_AUTH_MANIFEST,
MailboxReq::AuthorizeAndStash(_) => CommandId::AUTHORIZE_AND_STASH,
MailboxReq::SignWithExportedEcdsa(_) => CommandId::SIGN_WITH_EXPORTED_ECDSA,
}
}

Expand Down Expand Up @@ -1010,6 +1026,101 @@ impl Default for GetIdevCsrResp {
}
}

// GET_FMC_ALIAS_CSR
#[repr(C)]
#[derive(Default, Debug, IntoBytes, FromBytes, KnownLayout, Immutable, PartialEq, Eq)]
pub struct GetFmcAliasCsrReq {
pub hdr: MailboxReqHeader,
}

impl Request for GetFmcAliasCsrReq {
const ID: CommandId = CommandId::GET_FMC_ALIAS_CSR;
type Resp = GetFmcAliasCsrResp;
}

#[repr(C)]
#[derive(Debug, IntoBytes, FromBytes, KnownLayout, Immutable, PartialEq, Eq)]
pub struct GetFmcAliasCsrResp {
pub hdr: MailboxRespHeader,
pub data_size: u32,
pub data: [u8; Self::DATA_MAX_SIZE],
}

impl Default for GetFmcAliasCsrResp {
fn default() -> Self {
Self {
hdr: MailboxRespHeader::default(),
data_size: 0,
data: [0u8; Self::DATA_MAX_SIZE],
}
}
}

impl GetFmcAliasCsrResp {
pub const DATA_MAX_SIZE: usize = 512;
}
impl ResponseVarSize for GetFmcAliasCsrResp {}

// SIGN_WITH_EXPORTED_ECDSA
#[repr(C)]
#[derive(Debug, IntoBytes, FromBytes, KnownLayout, Immutable, PartialEq, Eq)]
pub struct SignWithExportedEcdsaReq {
pub hdr: MailboxReqHeader,
pub exported_cdi_handle: [u8; Self::EXPORTED_CDI_MAX_SIZE],
pub tbs: [u8; Self::MAX_DIGEST_SIZE],
}

impl Default for SignWithExportedEcdsaReq {
fn default() -> Self {
Self {
hdr: MailboxReqHeader::default(),
exported_cdi_handle: [0u8; Self::EXPORTED_CDI_MAX_SIZE],
tbs: [0u8; Self::MAX_DIGEST_SIZE],
}
}
}

impl SignWithExportedEcdsaReq {
pub const EXPORTED_CDI_MAX_SIZE: usize = 32;
pub const MAX_DIGEST_SIZE: usize = 48;
}

impl Request for SignWithExportedEcdsaReq {
const ID: CommandId = CommandId::SIGN_WITH_EXPORTED_ECDSA;
type Resp = SignWithExportedEcdsaResp;
}

#[repr(C)]
#[derive(Debug, IntoBytes, FromBytes, KnownLayout, Immutable, PartialEq, Eq)]
pub struct SignWithExportedEcdsaResp {
pub hdr: MailboxRespHeader,
pub derived_pubkey_x: [u8; Self::X_SIZE],
pub derived_pubkey_y: [u8; Self::Y_SIZE],
pub signature_r: [u8; Self::R_SIZE],
pub signature_s: [u8; Self::S_SIZE],
}

impl SignWithExportedEcdsaResp {
pub const X_SIZE: usize = 48;
pub const Y_SIZE: usize = 48;
pub const R_SIZE: usize = 48;
pub const S_SIZE: usize = 48;
}

impl ResponseVarSize for SignWithExportedEcdsaResp {}

impl Default for SignWithExportedEcdsaResp {
fn default() -> Self {
Self {
hdr: MailboxRespHeader::default(),
signature_r: [0u8; Self::R_SIZE],
signature_s: [0u8; Self::S_SIZE],
derived_pubkey_x: [0u8; Self::X_SIZE],
derived_pubkey_y: [0u8; Self::Y_SIZE],
}
}
}

#[repr(u32)]
#[derive(Debug, PartialEq, Eq)]
pub enum ImageHashSource {
Expand Down
2 changes: 2 additions & 0 deletions common/src/keyids.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ pub const KEY_ID_RT_PRIV_KEY: KeyId = KeyId::KeyId5;
pub const KEY_ID_DPE_CDI: KeyId = KeyId::KeyId8;
#[cfg(feature = "runtime")]
pub const KEY_ID_DPE_PRIV_KEY: KeyId = KeyId::KeyId9;
#[cfg(feature = "runtime")]
pub const KEY_ID_EXPORTED_DPE_CDI: KeyId = KeyId::KeyId10;

pub const KEY_ID_TMP: KeyId = KeyId::KeyId3;
4 changes: 2 additions & 2 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ pub use fuse::{FuseLogEntry, FuseLogEntryId};
pub use pcr::{PcrLogEntry, PcrLogEntryId, RT_FW_CURRENT_PCR, RT_FW_JOURNEY_PCR};

pub const FMC_ORG: u32 = 0x40000000;
pub const FMC_SIZE: u32 = 20 * 1024;
pub const FMC_SIZE: u32 = 21 * 1024;
pub const RUNTIME_ORG: u32 = FMC_ORG + FMC_SIZE;
pub const RUNTIME_SIZE: u32 = 97 * 1024;
pub const RUNTIME_SIZE: u32 = 96 * 1024;

pub use memory_layout::{DATA_ORG, PERSISTENT_DATA_ORG};
pub use wdt::{restart_wdt, start_wdt, stop_wdt, WdtTimeout};
2 changes: 2 additions & 0 deletions drivers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,10 @@ pub use okref::okmutref;
pub use okref::okref;
pub use pcr_bank::{PcrBank, PcrId};
pub use pcr_reset::PcrResetCounter;
pub use persistent::fmc_alias_csr::FmcAliasCsr;
#[cfg(feature = "runtime")]
pub use persistent::AuthManifestImageMetadataList;

pub use persistent::{
FuseLogArray, IdevIdCsr, PcrLogArray, PersistentData, PersistentDataAccessor,
StashMeasurementArray, FUSE_LOG_MAX_COUNT, MAX_CSR_SIZE, MEASUREMENT_MAX_COUNT,
Expand Down
79 changes: 78 additions & 1 deletion drivers/src/persistent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ use crate::{
FirmwareHandoffTable,
};

use crate::FmcAliasCsr;

#[cfg(feature = "runtime")]
use crate::pcr_reset::PcrResetCounter;

Expand All @@ -38,7 +40,8 @@ pub const DPE_SIZE: u32 = 5 * 1024;
pub const PCR_RESET_COUNTER_SIZE: u32 = 1024;
pub const AUTH_MAN_IMAGE_METADATA_MAX_SIZE: u32 = 7 * 1024;
pub const IDEVID_CSR_SIZE: u32 = 1024;
pub const RESERVED_MEMORY_SIZE: u32 = 4 * 1024;
pub const FMC_ALIAS_CSR_SIZE: u32 = 1024;
pub const RESERVED_MEMORY_SIZE: u32 = 3 * 1024;

pub const PCR_LOG_MAX_COUNT: usize = 17;
pub const FUSE_LOG_MAX_COUNT: usize = 62;
Expand All @@ -61,6 +64,7 @@ pub type AuthManifestImageMetadataList =
[AuthManifestImageMetadata; AUTH_MANIFEST_IMAGE_METADATA_MAX_COUNT];

const _: () = assert!(MAX_CSR_SIZE < IDEVID_CSR_SIZE as usize);
const _: () = assert!(MAX_CSR_SIZE < FMC_ALIAS_CSR_SIZE as usize);

#[derive(Clone, TryFromBytes, IntoBytes, Zeroize)]
#[repr(C)]
Expand All @@ -69,6 +73,69 @@ pub struct IdevIdCsr {
csr: [u8; MAX_CSR_SIZE],
}

pub mod fmc_alias_csr {
use super::*;

const _: () = assert!(size_of::<FmcAliasCsr>() < FMC_ALIAS_CSR_SIZE as usize);

#[derive(Clone, TryFromBytes, IntoBytes, Zeroize)]
#[repr(C)]
pub struct FmcAliasCsr {
csr_len: u32,
csr: [u8; MAX_CSR_SIZE],
}

impl Default for FmcAliasCsr {
fn default() -> Self {
Self {
csr_len: Self::UNPROVISIONED_CSR,
csr: [0; MAX_CSR_SIZE],
}
}
}

impl FmcAliasCsr {
/// The `csr_len` field is set to this constant when a ROM image supports CSR generation but
/// the CSR generation flag was not enabled.
///
/// This is used by the runtime to distinguish ROM images that support CSR generation from
/// ones that do not.
///
/// u32::MAX is too large to be a valid CSR, so we use it to encode this state.
pub const UNPROVISIONED_CSR: u32 = u32::MAX;

/// Get the CSR buffer
pub fn get(&self) -> Option<&[u8]> {
self.csr.get(..self.csr_len as usize)
}

/// Create `Self` from a csr slice. `csr_len` MUST be the actual length of the csr.
pub fn new(csr_buf: &[u8], csr_len: usize) -> CaliptraResult<Self> {
if csr_len >= MAX_CSR_SIZE {
return Err(CaliptraError::FMC_ALIAS_INVALID_CSR);
}

let mut _self = Self {
csr_len: csr_len as u32,
csr: [0; MAX_CSR_SIZE],
};
_self.csr[..csr_len].copy_from_slice(&csr_buf[..csr_len]);

Ok(_self)
}

/// Get the length of the CSR in bytes.
pub fn get_csr_len(&self) -> u32 {
self.csr_len
}

/// Check if the CSR was unprovisioned
pub fn is_unprovisioned(&self) -> bool {
self.csr_len == Self::UNPROVISIONED_CSR
}
}
}

impl Default for IdevIdCsr {
fn default() -> Self {
Self {
Expand Down Expand Up @@ -193,6 +260,10 @@ pub struct PersistentData {
pub idevid_csr: IdevIdCsr,
reserved10: [u8; IDEVID_CSR_SIZE as usize - size_of::<IdevIdCsr>()],

pub fmc_alias_csr: FmcAliasCsr,

reserved11: [u8; FMC_ALIAS_CSR_SIZE as usize - size_of::<FmcAliasCsr>()],

// Reserved memory for future objects.
// New objects should always source memory from this range.
// Taking memory from this reserve does NOT break hitless updates.
Expand Down Expand Up @@ -282,6 +353,12 @@ impl PersistentData {
);

persistent_data_offset += IDEVID_CSR_SIZE;
assert_eq!(
addr_of!((*P).fmc_alias_csr) as u32,
memory_layout::PERSISTENT_DATA_ORG + persistent_data_offset
);

persistent_data_offset += FMC_ALIAS_CSR_SIZE;
assert_eq!(
addr_of!((*P).reserved_memory) as u32,
memory_layout::PERSISTENT_DATA_ORG + persistent_data_offset
Expand Down
24 changes: 24 additions & 0 deletions error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,20 @@ impl CaliptraError {
CaliptraError::new_const(0x000E0052);
pub const RUNTIME_AUTH_MANIFEST_IMAGE_METADATA_LIST_DUPLICATE_FIRMWARE_ID: CaliptraError =
CaliptraError::new_const(0x000E0053);
pub const RUNTIME_SIGN_WITH_EXPORTED_ECDSA_KEY_DERIVIATION_FAILED: CaliptraError =
CaliptraError::new_const(0x000E0054);
pub const RUNTIME_SIGN_WITH_EXPORTED_ECDSA_SIGNATURE_FAILED: CaliptraError =
CaliptraError::new_const(0x000E0055);
pub const RUNTIME_SIGN_WITH_EXPORTED_ECDSA_INVALID_DIGEST: CaliptraError =
CaliptraError::new_const(0x000E0056);
pub const RUNTIME_SIGN_WITH_EXPORTED_ECDSA_INVALID_SIGNATURE: CaliptraError =
CaliptraError::new_const(0x000E0057);

pub const RUNTIME_GET_FMC_CSR_UNPROVISIONED: CaliptraError =
CaliptraError::new_const(0x000E0054);

pub const RUNTIME_GET_FMC_CSR_UNSUPPORTED_FMC: CaliptraError =
CaliptraError::new_const(0x000E0055);

/// FMC Errors
pub const FMC_GLOBAL_NMI: CaliptraError = CaliptraError::new_const(0x000F0001);
Expand All @@ -466,6 +480,16 @@ impl CaliptraError {
pub const FMC_GLOBAL_WDT_EXPIRED: CaliptraError = CaliptraError::new_const(0x000F000D);
pub const FMC_UNKNOWN_RESET: CaliptraError = CaliptraError::new_const(0x000F000E);

/// FMC Alias CSR Errors
pub const FMC_ALIAS_CSR_BUILDER_INIT_FAILURE: CaliptraError =
CaliptraError::new_const(0x000F000F);
pub const FMC_ALIAS_CSR_BUILDER_BUILD_FAILURE: CaliptraError =
CaliptraError::new_const(0x000F0010);
pub const FMC_ALIAS_INVALID_CSR: CaliptraError = CaliptraError::new_const(0x000F0011);
pub const FMC_ALIAS_CSR_VERIFICATION_FAILURE: CaliptraError =
CaliptraError::new_const(0x000F0012);
pub const FMC_ALIAS_CSR_OVERFLOW: CaliptraError = CaliptraError::new_const(0x000F0013);

/// TRNG_EXT Errors
pub const DRIVER_TRNG_EXT_TIMEOUT: CaliptraError = CaliptraError::new_const(0x00100001);

Expand Down
1 change: 1 addition & 0 deletions fmc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ufmt.workspace = true
zerocopy.workspace = true
caliptra-cfi-lib = { workspace = true, default-features = false, features = ["cfi", "cfi-counter" ] }
caliptra-cfi-derive.workspace = true
zeroize.workspace = true


[build-dependencies]
Expand Down
Loading