-
Notifications
You must be signed in to change notification settings - Fork 46
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
Self Signed FMC Alias Csr #1863
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this decreasing? |
||
|
||
pub use memory_layout::{DATA_ORG, PERSISTENT_DATA_ORG}; | ||
pub use wdt::{restart_wdt, start_wdt, stop_wdt, WdtTimeout}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,8 @@ use crate::{ | |
FirmwareHandoffTable, | ||
}; | ||
|
||
use crate::FmcAliasCsr; | ||
|
||
#[cfg(feature = "runtime")] | ||
use crate::pcr_reset::PcrResetCounter; | ||
|
||
|
@@ -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 = 19 * 1024; | ||
pub const FMC_ALIAS_CSR_SIZE: u32 = 1024; | ||
pub const RESERVED_MEMORY_SIZE: u32 = 18 * 1024; | ||
|
||
pub const PCR_LOG_MAX_COUNT: usize = 17; | ||
pub const FUSE_LOG_MAX_COUNT: usize = 62; | ||
|
@@ -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)] | ||
|
@@ -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 { | ||
|
@@ -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, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this also need to be accessible in RT? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Correct. The feature is now renamed to fmc-alias-csr. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need a new feature for this? Can you simply use the runtime feature? |
||
|
||
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. | ||
|
@@ -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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,12 @@ File Name: | |
Abstract: | ||
Crypto helper routines | ||
--*/ | ||
use caliptra_x509::Ecdsa384Signature; | ||
|
||
use crate::fmc_env::FmcEnv; | ||
use caliptra_drivers::okmutref; | ||
use zeroize::Zeroize; | ||
|
||
use caliptra_cfi_derive::cfi_impl_fn; | ||
use caliptra_common::{crypto::Ecc384KeyPair, keyids::KEY_ID_TMP}; | ||
use caliptra_drivers::{ | ||
|
@@ -14,6 +19,21 @@ use caliptra_drivers::{ | |
KeyWriteArgs, Sha256Alg, | ||
}; | ||
|
||
pub trait Ecdsa384SignatureAdapter { | ||
/// Convert to ECDSA Signature | ||
fn to_ecdsa(&self) -> Ecdsa384Signature; | ||
} | ||
|
||
impl Ecdsa384SignatureAdapter for Ecc384Signature { | ||
/// Convert to ECDSA Signatuure | ||
fn to_ecdsa(&self) -> Ecdsa384Signature { | ||
Ecdsa384Signature { | ||
r: (&self.r).into(), | ||
s: (&self.s).into(), | ||
} | ||
} | ||
} | ||
|
||
pub enum Crypto {} | ||
|
||
impl Crypto { | ||
|
@@ -187,4 +207,36 @@ impl Crypto { | |
let digest = okref(&digest)?; | ||
env.ecc384.verify(pub_key, digest, sig) | ||
} | ||
|
||
/// Sign the data using ECC Private Key. | ||
/// Verify the signature using the ECC Public Key. | ||
/// | ||
/// This routine calculates the digest of the `data`, signs the hash and returns the signature. | ||
/// This routine also verifies the signature using the public key. | ||
/// | ||
/// # Arguments | ||
/// | ||
/// * `env` - FMC Environment | ||
/// * `priv_key` - Key slot to retrieve the private key | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It was. Thanks. |
||
/// * `pub_key` - Public key to verify with | ||
/// * `data` - Input data to hash | ||
/// | ||
/// # Returns | ||
/// | ||
/// * `Ecc384Signature` - Signature | ||
#[inline(always)] | ||
pub fn ecdsa384_sign_and_verify( | ||
env: &mut FmcEnv, | ||
priv_key: KeyId, | ||
pub_key: &Ecc384PubKey, | ||
data: &[u8], | ||
) -> CaliptraResult<Ecc384Signature> { | ||
let mut digest = Self::sha384_digest(env, data); | ||
let digest = okmutref(&mut digest)?; | ||
let priv_key_args = KeyReadArgs::new(priv_key); | ||
let priv_key = Ecc384PrivKeyIn::Key(priv_key_args); | ||
let result = env.ecc384.sign(&priv_key, pub_key, digest, &mut env.trng); | ||
digest.0.zeroize(); | ||
result | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the size-history CI job, we're still only using ~18KiB in FMC. Do we need to change the size here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to increase it. If I keep it the same it won't fit:
rust-lld: error: section '.rodata' will not fit in region 'ICCM': overflowed by 312 bytes
rust-lld: error: section '.rodata' will not fit in region 'ICCM': overflowed by 961 bytes
rust-lld: error: section '.rodata' will not fit in region 'ICCM': overflowed by 964 bytes
rust-lld: error: section '.rodata' will not fit in region 'ICCM': overflowed by 976 bytes
rust-lld: error: section '.rodata' will not fit in region 'ICCM': overflowed by 988 bytes
rust-lld: error: section '.rodata' will not fit in region 'ICCM': overflowed by 988 bytes