-
Notifications
You must be signed in to change notification settings - Fork 45
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; | ||
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. According to the size-history CI job, we're still only using ~18KiB in FMC. Do we need to change the size here? |
||
pub const FMC_SIZE: u32 = 22 * 1024 - 512; | ||
pub const RUNTIME_ORG: u32 = FMC_ORG + FMC_SIZE; | ||
pub const RUNTIME_SIZE: u32 = 97 * 1024; | ||
pub const RUNTIME_SIZE: u32 = 95 * 1024 + 512; | ||
|
||
pub use memory_layout::{DATA_ORG, FHT_ORG, FHT_SIZE, MAN1_ORG}; | ||
pub use wdt::{restart_wdt, start_wdt, stop_wdt, WdtTimeout}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,7 +41,8 @@ pub const DPE_ORG: u32 = 0x50005400; | |
pub const PCR_RESET_COUNTER_ORG: u32 = 0x50006800; | ||
pub const AUTH_MAN_IMAGE_METADATA_LIST_ORG: u32 = 0x50006C00; | ||
pub const IDEVID_CSR_ORG: u32 = 0x50008800; | ||
pub const DATA_ORG: u32 = 0x50008C00; | ||
pub const FMC_ALIAS_CSR_ORG: u32 = 0x50008C00; | ||
pub const DATA_ORG: u32 = 0x50009000; | ||
|
||
pub const STACK_ORG: u32 = 0x5000f800; | ||
pub const ROM_STACK_ORG: u32 = 0x5001C000; | ||
|
@@ -74,7 +75,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 DATA_SIZE: u32 = 27 * 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. nit: now that #1722 is merged, should be able to just add to the PersistentData driver and leave memory layout as-is |
||
pub const FMC_ALIAS_CSR_SIZE: u32 = 1024; | ||
pub const DATA_SIZE: u32 = 26 * 1024; | ||
pub const STACK_SIZE: u32 = 64 * 1024; | ||
pub const ROM_STACK_SIZE: u32 = 14 * 1024; | ||
pub const ESTACK_SIZE: u32 = 1024; | ||
|
@@ -158,7 +160,13 @@ fn mem_layout_test_pcr_reset_counter() { | |
#[test] | ||
#[allow(clippy::assertions_on_constants)] | ||
fn mem_layout_test_idevid_csr() { | ||
assert_eq!((DATA_ORG - IDEVID_CSR_ORG), IDEVID_CSR_SIZE); | ||
assert_eq!((DATA_ORG - FMC_ALIAS_CSR_ORG), FMC_ALIAS_CSR_SIZE); | ||
} | ||
|
||
#[test] | ||
#[allow(clippy::assertions_on_constants)] | ||
fn mem_layout_test_fmc_alias_csr() { | ||
assert_eq!((FMC_ALIAS_CSR_ORG - IDEVID_CSR_ORG), IDEVID_CSR_SIZE); | ||
} | ||
|
||
#[test] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,9 @@ use crate::{ | |
FirmwareHandoffTable, | ||
}; | ||
|
||
#[cfg(feature = "fmc")] | ||
use crate::FmcAliasCsr; | ||
|
||
#[cfg(feature = "runtime")] | ||
use crate::pcr_reset::PcrResetCounter; | ||
|
||
|
@@ -52,6 +55,70 @@ pub struct IdevIdCsr { | |
csr: [u8; MAX_CSR_SIZE], | ||
} | ||
|
||
#[cfg(feature = "fmc")] | ||
pub mod fmc_alias_csr { | ||
use super::*; | ||
|
||
const _: () = assert!(size_of::<FmcAliasCsr>() < memory_layout::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 { | ||
|
@@ -164,6 +231,12 @@ pub struct PersistentData { | |
|
||
pub idevid_csr: IdevIdCsr, | ||
reserved10: [u8; memory_layout::IDEVID_CSR_SIZE as usize - size_of::<IdevIdCsr>()], | ||
|
||
#[cfg(feature = "fmc")] | ||
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? |
||
|
||
#[cfg(feature = "fmc")] | ||
reserved11: [u8; memory_layout::FMC_ALIAS_CSR_SIZE as usize - size_of::<FmcAliasCsr>()], | ||
Comment on lines
+238
to
+239
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. When the |
||
} | ||
|
||
impl PersistentData { | ||
|
@@ -196,10 +269,29 @@ impl PersistentData { | |
addr_of!((*P).idevid_csr) as u32, | ||
memory_layout::IDEVID_CSR_ORG | ||
); | ||
|
||
assert_eq!( | ||
addr_of!((*P).idevid_csr) as u32, | ||
memory_layout::IDEVID_CSR_ORG | ||
); | ||
|
||
#[cfg(not(feature = "fmc"))] | ||
assert_eq!( | ||
P.add(1) as u32, | ||
memory_layout::IDEVID_CSR_ORG + memory_layout::IDEVID_CSR_SIZE | ||
); | ||
|
||
#[cfg(feature = "fmc")] | ||
assert_eq!( | ||
addr_of!((*P).fmc_alias_csr) as u32, | ||
memory_layout::FMC_ALIAS_CSR_ORG | ||
); | ||
|
||
#[cfg(feature = "fmc")] | ||
assert_eq!( | ||
P.add(1) as u32, | ||
memory_layout::FMC_ALIAS_CSR_ORG + memory_layout::FMC_ALIAS_CSR_SIZE | ||
); | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -450,6 +450,9 @@ impl CaliptraError { | |
pub const RUNTIME_AUTH_MANIFEST_IMAGE_METADATA_LIST_DUPLICATE_FIRMWARE_ID: CaliptraError = | ||
CaliptraError::new_const(0x000E0053); | ||
|
||
pub const RUNTIME_GET_FMC_CSR_UNPROVISIONED: CaliptraError = | ||
CaliptraError::new_const(0x000E0053); | ||
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.
|
||
|
||
/// FMC Errors | ||
pub const FMC_GLOBAL_NMI: CaliptraError = CaliptraError::new_const(0x000F0001); | ||
pub const FMC_GLOBAL_EXCEPTION: CaliptraError = CaliptraError::new_const(0x000F0002); | ||
|
@@ -466,6 +469,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); | ||
|
||
|
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,35 @@ 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 |
||
/// * `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.
nit: Minor copy paste error