From e0d02a2cd87f3852b442627bff7caeec56137e23 Mon Sep 17 00:00:00 2001 From: Vishal Mhatre Date: Sun, 8 Dec 2024 23:58:06 -0800 Subject: [PATCH] [feat] IDEVID CSR Envelope Signing This change creates the CSR envelope containing the ECC and MLDSA CSRs. --- common/src/boot_status.rs | 2 +- drivers/src/hmac.rs | 181 +++++++++++++----- drivers/src/persistent.rs | 8 +- image/types/src/lib.rs | 1 + rom/dev/README.md | 12 +- rom/dev/src/flow/cold_reset/idev_id.rs | 169 +++++++++++----- .../test_dice_derivations.rs | 2 +- sw-emulator/lib/periph/src/hmac.rs | 11 +- 8 files changed, 277 insertions(+), 109 deletions(-) diff --git a/common/src/boot_status.rs b/common/src/boot_status.rs index 23fa6f9553..d5303c5932 100644 --- a/common/src/boot_status.rs +++ b/common/src/boot_status.rs @@ -33,7 +33,7 @@ pub enum RomBootStatus { IDevIdSubjIdSnGenerationComplete = IDEVID_BOOT_STATUS_BASE + 5, IDevIdSubjKeyIdGenerationComplete = IDEVID_BOOT_STATUS_BASE + 6, IDevIdMakeCsrComplete = IDEVID_BOOT_STATUS_BASE + 7, - IDevIdSendCsrComplete = IDEVID_BOOT_STATUS_BASE + 8, + IDevIdSendCsrEnvelopComplete = IDEVID_BOOT_STATUS_BASE + 8, IDevIdDerivationComplete = IDEVID_BOOT_STATUS_BASE + 9, // Ldevid Statuses diff --git a/drivers/src/hmac.rs b/drivers/src/hmac.rs index ee6630c8e8..cfc8dbb5ee 100644 --- a/drivers/src/hmac.rs +++ b/drivers/src/hmac.rs @@ -106,6 +106,9 @@ pub enum HmacKey<'a> { // Key Key(KeyReadArgs), + + // CSR mode key + CsrMode(), } impl<'a> From<&'a Array4x12> for HmacKey<'a> { @@ -139,6 +142,16 @@ pub enum HmacMode { Hmac512 = 1, } +struct HmacParams<'a> { + slice: &'a [u8], + first: bool, + buf_size: usize, + key: Option, + dest_key: Option, + hmac_mode: HmacMode, + csr_mode: bool, +} + pub struct Hmac { hmac: HmacReg, } @@ -153,16 +166,20 @@ impl Hmac { /// /// * `key` - HMAC Key /// * `trng` - TRNG driver instance - /// /// * `tag` - The calculated tag + /// * `hmac_mode` - Hmac mode to use + /// + /// # Returns + /// * `HmacOp` - Hmac operation pub fn hmac_init<'a>( &'a mut self, key: &HmacKey, trng: &mut Trng, mut tag: HmacTag<'a>, - mode: HmacMode, + hmac_mode: HmacMode, ) -> CaliptraResult { let hmac = self.hmac.regs_mut(); + let mut csr_mode = false; // Configure the hardware so that the output tag is stored at a location specified by the // caller. @@ -181,6 +198,10 @@ impl Hmac { None } HmacKey::Key(key) => Some(*key), + HmacKey::CsrMode() => { + csr_mode = true; + None + } }; // Generate an LFSR seed and copy to key vault. @@ -194,7 +215,8 @@ impl Hmac { buf_idx: 0, data_size: 0, tag, - mode, + hmac_mode, + csr_mode, }; Ok(op) @@ -221,8 +243,11 @@ impl Hmac { /// * `key` - HMAC Key /// * `data` - Data to calculate the HMAC over /// * `trng` - TRNG driver instance - /// /// * `tag` - The calculated tag + /// * `hmac_mode` - Hmac mode to use + /// + /// # Returns + /// * `CaliptraResult<()>` - Result of the operation #[cfg_attr(not(feature = "no-cfi"), cfi_impl_fn)] pub fn hmac( &mut self, @@ -230,10 +255,11 @@ impl Hmac { data: &HmacData, trng: &mut Trng, tag: HmacTag, - mode: HmacMode, + hmac_mode: HmacMode, ) -> CaliptraResult<()> { let hmac = self.hmac.regs_mut(); let mut tag = tag; + let mut csr_mode: bool = false; // Configure the hardware so that the output tag is stored at a location specified by the // caller. @@ -259,14 +285,18 @@ impl Hmac { None } HmacKey::Key(key) => Some(key), + HmacKey::CsrMode() => { + csr_mode = true; + None + } }; // Generate an LFSR seed and copy to key vault. self.gen_lfsr_seed(trng)?; // Calculate the hmac match data { - HmacData::Slice(buf) => self.hmac_buf(buf, key, dest_key, mode)?, - HmacData::Key(data_key) => self.hmac_key(*data_key, key, dest_key, mode)?, + HmacData::Slice(buf) => self.hmac_buf(buf, key, dest_key, hmac_mode, csr_mode)?, + HmacData::Key(data_key) => self.hmac_key(*data_key, key, dest_key, hmac_mode)?, } let hmac = self.hmac.regs(); @@ -289,7 +319,7 @@ impl Hmac { self.hmac .regs_mut() .hmac512_ctrl() - .write(|w| w.zeroize(true).mode(false)); + .write(|w| w.zeroize(true).mode(false).csr_mode(false)); } /// Zeroize the hardware registers. @@ -306,7 +336,7 @@ impl Hmac { let mut hmac = HmacReg::new(); hmac.regs_mut() .hmac512_ctrl() - .write(|w| w.zeroize(true).mode(false)); + .write(|w| w.zeroize(true).mode(false).csr_mode(false)); } /// @@ -315,13 +345,20 @@ impl Hmac { /// # Arguments /// /// * `buf` - Buffer to calculate the hmac over + /// * `key` - Key to use for the hmac operation + /// * `dest_key` - Destination key to store the hmac tag + /// * `hmac_mode` - Hmac mode to use + /// * `csr_mode` - Flag indicating if the hmac operation is in CSR mode /// + /// # Returns + /// * `CaliptraResult<()>` - Result of the operation fn hmac_buf( &mut self, buf: &[u8], key: Option, dest_key: Option, - mode: HmacMode, + hmac_mode: HmacMode, + csr_mode: bool, ) -> CaliptraResult<()> { // Check if the buffer is within the size that we support if buf.len() > HMAC_MAX_DATA_SIZE { @@ -340,7 +377,16 @@ impl Hmac { // the panic. if let Some(slice) = buf.get(offset..) { - self.hmac_partial_block(slice, first, buf.len(), key, dest_key, mode)?; + let params = HmacParams { + slice, + first, + buf_size: buf.len(), + key, + dest_key, + hmac_mode, + csr_mode, + }; + self.hmac_partial_block(params)?; break; } else { return Err(CaliptraError::DRIVER_HMAC_INVALID_SLICE); @@ -353,7 +399,7 @@ impl Hmac { // the panic. if let Some(slice) = buf.get(offset..offset + HMAC_BLOCK_SIZE_BYTES) { let block = <&[u8; HMAC_BLOCK_SIZE_BYTES]>::try_from(slice).unwrap(); - self.hmac_block(block, first, key, dest_key, mode)?; + self.hmac_block(block, first, key, dest_key, hmac_mode, csr_mode)?; bytes_remaining -= HMAC_BLOCK_SIZE_BYTES; first = false; } else { @@ -378,7 +424,7 @@ impl Hmac { data_key: KeyReadArgs, key: Option, dest_key: Option, - mode: HmacMode, + hmac_mode: HmacMode, ) -> CaliptraResult<()> { let hmac = self.hmac.regs_mut(); @@ -389,18 +435,10 @@ impl Hmac { ) .map_err(|err| err.into_read_data_err())?; - self.hmac_op(true, key, dest_key, mode) + self.hmac_op(true, key, dest_key, hmac_mode, false) } - fn hmac_partial_block( - &mut self, - slice: &[u8], - first: bool, - buf_size: usize, - key: Option, - dest_key: Option, - mode: HmacMode, - ) -> CaliptraResult<()> { + fn hmac_partial_block(&mut self, params: HmacParams) -> CaliptraResult<()> { /// Set block length fn set_block_len(buf_size: usize, block: &mut [u8; HMAC_BLOCK_SIZE_BYTES]) { let bit_len = ((buf_size + HMAC_BLOCK_SIZE_BYTES) as u128) << 3; @@ -412,23 +450,37 @@ impl Hmac { // PANIC-FREE: Following check optimizes the out of bounds // panic in copy_from_slice - if slice.len() > block.len() - 1 { + if params.slice.len() > block.len() - 1 { return Err(CaliptraError::DRIVER_HMAC_INDEX_OUT_OF_BOUNDS); } - block[..slice.len()].copy_from_slice(slice); - block[slice.len()] = 0b1000_0000; - if slice.len() < HMAC_BLOCK_LEN_OFFSET { - set_block_len(buf_size, &mut block); + block[..params.slice.len()].copy_from_slice(params.slice); + block[params.slice.len()] = 0b1000_0000; + if params.slice.len() < HMAC_BLOCK_LEN_OFFSET { + set_block_len(params.buf_size, &mut block); } // Calculate the digest of the op - self.hmac_block(&block, first, key, dest_key, mode)?; + self.hmac_block( + &block, + params.first, + params.key, + params.dest_key, + params.hmac_mode, + params.csr_mode, + )?; // Add a padding block if one is needed - if slice.len() >= HMAC_BLOCK_LEN_OFFSET { + if params.slice.len() >= HMAC_BLOCK_LEN_OFFSET { block.fill(0); - set_block_len(buf_size, &mut block); - self.hmac_block(&block, false, key, dest_key, mode)?; + set_block_len(params.buf_size, &mut block); + self.hmac_block( + &block, + false, + params.key, + params.dest_key, + params.hmac_mode, + params.csr_mode, + )?; } Ok(()) @@ -441,18 +493,25 @@ impl Hmac { /// /// * `block`: Block to calculate the digest /// * `first` - Flag indicating if this is the first block + /// * `key` - Key vault slot to use for the hmac key + /// * `dest_key` - Destination key vault slot to store the hmac tag + /// * `hmac_mode` - Hmac mode to use + /// * `csr_mode` - Flag indicating if the hmac operation is in CSR mode /// + /// # Returns + /// * `CaliptraResult<()>` - Result of the operation fn hmac_block( &mut self, block: &[u8; HMAC_BLOCK_SIZE_BYTES], first: bool, key: Option, dest_key: Option, - mode: HmacMode, + hmac_mode: HmacMode, + csr_mode: bool, ) -> CaliptraResult<()> { let hmac = self.hmac.regs_mut(); Array4x32::from(block).write_to_reg(hmac.hmac512_block()); - self.hmac_op(first, key, dest_key, mode) + self.hmac_op(first, key, dest_key, hmac_mode, csr_mode) } /// @@ -461,13 +520,20 @@ impl Hmac { /// # Arguments /// /// * `first` - Flag indicating if this is the first block + /// * `key` - Key vault slot to use for the hmac key + /// * `dest_key` - Destination key vault slot to store the hmac tag + /// * `hmac_mode` - Hmac mode to use + /// * `csr_mode` - Flag indicating if the hmac operation is in CSR mode /// + /// # Returns + /// * `CaliptraResult<()>` - Result of the operation fn hmac_op( &mut self, first: bool, key: Option, dest_key: Option, - mode: HmacMode, + hmac_mode: HmacMode, + csr_mode: bool, ) -> CaliptraResult<()> { let hmac = self.hmac.regs_mut(); @@ -492,12 +558,20 @@ impl Hmac { if first { // Submit the first block - hmac.hmac512_ctrl() - .write(|w| w.init(true).next(false).mode(mode == HmacMode::Hmac512)); + hmac.hmac512_ctrl().write(|w| { + w.init(true) + .next(false) + .mode(hmac_mode == HmacMode::Hmac512) + .csr_mode(csr_mode) + }); } else { // Submit next block in existing hashing chain - hmac.hmac512_ctrl() - .write(|w| w.init(false).next(true).mode(mode == HmacMode::Hmac512)); + hmac.hmac512_ctrl().write(|w| { + w.init(false) + .next(true) + .mode(hmac_mode == HmacMode::Hmac512) + .csr_mode(csr_mode) + }); } // Wait for the hmac operation to finish @@ -547,8 +621,11 @@ pub struct HmacOp<'a> { /// Tag tag: HmacTag<'a>, - /// Mode - mode: HmacMode, + /// Hmac Mode + hmac_mode: HmacMode, + + /// CSR mode + csr_mode: bool, } impl<'a> HmacOp<'a> { @@ -588,7 +665,8 @@ impl<'a> HmacOp<'a> { self.is_first(), self.key, self.dest_key(), - self.mode, + self.hmac_mode, + self.csr_mode, )?; self.reset_buf_state(); } @@ -618,14 +696,17 @@ impl<'a> HmacOp<'a> { ) }; - self.hmac_engine.hmac_partial_block( - buf, - self.is_first(), - self.data_size, - self.key, - self.dest_key(), - self.mode, - )?; + let params = HmacParams { + slice: buf, + first: self.is_first(), + buf_size: self.data_size, + key: self.key, + dest_key: self.dest_key(), + hmac_mode: self.hmac_mode, + csr_mode: self.csr_mode, + }; + + self.hmac_engine.hmac_partial_block(params)?; // Set the state of the operation to final self.state = HmacOpState::Final; diff --git a/drivers/src/persistent.rs b/drivers/src/persistent.rs index 61faf9e1ba..3afd8767bc 100644 --- a/drivers/src/persistent.rs +++ b/drivers/src/persistent.rs @@ -49,15 +49,15 @@ pub type AuthManifestImageMetadataList = #[derive(Clone, FromBytes, AsBytes, Zeroize)] #[repr(C)] pub struct Ecc384IdevIdCsr { - csr_len: u32, - csr: [u8; ECC384_MAX_CSR_SIZE], + pub csr_len: u32, + pub csr: [u8; ECC384_MAX_CSR_SIZE], } #[derive(Clone, FromBytes, AsBytes, Zeroize)] #[repr(C)] pub struct Mldsa87IdevIdCsr { - csr_len: u32, - csr: [u8; MLDSA87_MAX_CSR_SIZE], + pub csr_len: u32, + pub csr: [u8; MLDSA87_MAX_CSR_SIZE], } impl Default for Ecc384IdevIdCsr { diff --git a/image/types/src/lib.rs b/image/types/src/lib.rs index a9f124d5f8..832fc9ec7e 100644 --- a/image/types/src/lib.rs +++ b/image/types/src/lib.rs @@ -41,6 +41,7 @@ pub const SHA256_DIGEST_WORD_SIZE: usize = 8; pub const SHA384_DIGEST_WORD_SIZE: usize = 12; pub const SHA384_DIGEST_BYTE_SIZE: usize = 48; pub const SHA512_DIGEST_WORD_SIZE: usize = 16; +pub const SHA512_DIGEST_BYTE_SIZE: usize = 64; pub const IMAGE_LMS_OTS_P_PARAM: usize = 51; pub const IMAGE_LMS_KEY_HEIGHT: usize = 15; pub const IMAGE_BYTE_SIZE: usize = 128 * 1024; diff --git a/rom/dev/README.md b/rom/dev/README.md index 7e5b85de1a..b7a59bd935 100644 --- a/rom/dev/README.md +++ b/rom/dev/README.md @@ -483,12 +483,12 @@ Initial Device ID Layer is used to generate Manufacturer CDI & Private Keys. Thi |----------------|--------------|-------------------------------------------------------------------------------------------------| | Marker | 4 | Magic Number marking the start of the CSR payload. The value must be 0x435352 (‘CSR’ in ASCII). | | Size | 4 | Size of the entire CSR payload. | -| ECC CSR Size | 4 | Size of the ECC CSR (m bytes) | -| ECC CSR MAC | 48 | ECC CSR HMAC-384 MAC. | -| MLDSA CSR Size | 4 | Size of the ECC CSR (n bytes) | -| MLDSA CSR MAC | 64 | ECC CSR HMAC-512 MAC. | -| ECC CSR | m | ECC CSR bytes. | -| MLDSA CSR | n | MLDSA CSR bytes. | +| ECC CSR Size | 4 | Size of the ECC CSR in bytes. | +| ECC CSR | 512 | ECC CSR buffer. Actual CSR size is indicated by 'ECC CSR Size'. | +| ECC CSR MAC | 48 | ECC CSR HMAC-384 MAC. MAC is computed over actual CSR bytes. | +| MLDSA CSR Size | 4 | Size of the ECC CSR in bytes. | +| MLDSA CSR | n | MLDSA CSR bytes. Actual CSR size is indicated by 'MLDSA CSR Size'. | +| MLDSA CSR MAC | 64 | MLDSA CSR HMAC-512 MAC. MAC is computed over actual CSR bytes. | **Post-conditions:** diff --git a/rom/dev/src/flow/cold_reset/idev_id.rs b/rom/dev/src/flow/cold_reset/idev_id.rs index e5ec865c28..4637ea8b9c 100644 --- a/rom/dev/src/flow/cold_reset/idev_id.rs +++ b/rom/dev/src/flow/cold_reset/idev_id.rs @@ -28,13 +28,56 @@ use caliptra_common::keyids::{ }; use caliptra_common::RomBootStatus::*; use caliptra_drivers::*; -use caliptra_drivers::{ECC384_MAX_CSR_SIZE, MLDSA87_MAX_CSR_SIZE}; +use caliptra_image_types::{SHA384_DIGEST_BYTE_SIZE, SHA512_DIGEST_BYTE_SIZE}; use caliptra_x509::*; +use core::mem::size_of; +use zerocopy::AsBytes; use zeroize::Zeroize; /// Initialization Vector used by Deobfuscation Engine during UDS / field entropy decryption. const DOE_IV: Array4x4 = Array4xN::<4, 16>([0xfb10365b, 0xa1179741, 0xfba193a1, 0x0f406d7e]); +pub type Hmac384Tag = [u8; SHA384_DIGEST_BYTE_SIZE]; +pub type Hmac512Tag = [u8; SHA512_DIGEST_BYTE_SIZE]; + +pub const IDEVID_CSR_ENVELOP_MARKER: u32 = 0x43_5352; + +/// Calipatra IDEVID CSR Envelop +#[repr(C)] +#[derive(AsBytes, Clone, Zeroize)] +pub struct InitDevIdCsrEnvelop { + /// Marker + pub marker: u32, + + /// Size of the CSR Envelop + pub size: u32, + + /// ECC CSR + pub ecc_csr: Ecc384IdevIdCsr, + + /// ECC CSR MAC + pub ecc_csr_mac: Hmac384Tag, + + /// MLDSA CSR + pub mldsa_csr: Mldsa87IdevIdCsr, + + /// MLDSA CSR MAC + pub mldsa_csr_mac: Hmac512Tag, +} + +impl Default for InitDevIdCsrEnvelop { + fn default() -> Self { + InitDevIdCsrEnvelop { + marker: IDEVID_CSR_ENVELOP_MARKER, + size: size_of::() as u32, + ecc_csr: Ecc384IdevIdCsr::default(), + ecc_csr_mac: [0u8; SHA384_DIGEST_BYTE_SIZE], + mldsa_csr: Mldsa87IdevIdCsr::default(), + mldsa_csr_mac: [0u8; SHA512_DIGEST_BYTE_SIZE], + } + } +} + /// Dice Initial Device Identity (IDEVID) Layer pub enum InitDevIdLayer {} @@ -242,8 +285,8 @@ impl InitDevIdLayer { // // A flag is asserted via JTAG interface to enable the generation of CSR if !env.soc_ifc.mfg_flag_gen_idev_id_csr() { - let dev_id_csr = Ecc384IdevIdCsr::default(); - Self::write_ecc384_csr_to_peristent_storage(env, &dev_id_csr)?; + let csr_envelop = InitDevIdCsrEnvelop::default(); + Self::write_csrs_to_persistent_storage(env, &csr_envelop)?; return Ok(()); } @@ -260,6 +303,30 @@ impl InitDevIdLayer { /// * `env` - ROM Environment /// * `output` - DICE Output fn make_csr(env: &mut RomEnv, output: &DiceOutput) -> CaliptraResult<()> { + let mut csr_envelop = InitDevIdCsrEnvelop::default(); + + // Generate ECC CSR. + Self::make_ecc_csr(env, output, &mut csr_envelop)?; + + // Generate MLDSA CSR. + Self::make_mldsa_csr(env, output, &mut csr_envelop)?; + + // Execute Send CSR Flow + let mut result = Self::send_csr_envelop(env, &csr_envelop); + if result.is_ok() { + result = Self::write_csrs_to_persistent_storage(env, &csr_envelop); + } + csr_envelop.zeroize(); + result?; + report_boot_status(IDevIdMakeCsrComplete.into()); + Ok(()) + } + + fn make_ecc_csr( + env: &mut RomEnv, + output: &DiceOutput, + csr_envelop: &mut InitDevIdCsrEnvelop, + ) -> CaliptraResult<()> { let key_pair = &output.ecc_subj_key_pair; // CSR `To Be Signed` Parameters @@ -298,7 +365,6 @@ impl InitDevIdLayer { cprintln!("[idev] ECC SIG.S = {}", HexBytes(&_sig_s)); // Build the CSR with `To Be Signed` & `Signature` - let mut ecc384_csr_buf = [0; ECC384_MAX_CSR_SIZE]; let ecdsa384_sig = sig.to_ecdsa(); let result = Ecdsa384CsrBuilder::new(tbs.tbs(), &ecdsa384_sig) .ok_or(CaliptraError::ROM_IDEVID_CSR_BUILDER_INIT_FAILURE); @@ -306,27 +372,41 @@ impl InitDevIdLayer { let csr_bldr = result?; let csr_len = csr_bldr - .build(&mut ecc384_csr_buf) + .build(&mut csr_envelop.ecc_csr.csr) .ok_or(CaliptraError::ROM_IDEVID_CSR_BUILDER_BUILD_FAILURE)?; - if csr_len > ecc384_csr_buf.len() { + if csr_len > csr_envelop.ecc_csr.csr.len() { return Err(CaliptraError::ROM_IDEVID_CSR_OVERFLOW); } + csr_envelop.ecc_csr.csr_len = csr_len as u32; - cprintln!("[idev] CSR = {}", HexBytes(&ecc384_csr_buf[..csr_len])); + cprintln!( + "[idev] CSR = {}", + HexBytes(&csr_envelop.ecc_csr.csr[..csr_len]) + ); - let dev_id_csr = Ecc384IdevIdCsr::new(&ecc384_csr_buf, csr_len)?; + // Generate the CSR MAC. + let mut tag = Array4x12::default(); + let csr_slice = &csr_envelop.ecc_csr.csr[..csr_len]; + env.hmac.hmac( + &HmacKey::CsrMode(), + &HmacData::Slice(csr_slice), + &mut env.trng, + (&mut tag).into(), + HmacMode::Hmac384, + )?; - // Execute Send CSR Flow - let mut result = Self::send_ecc384_csr(env, &dev_id_csr); - if result.is_ok() { - result = Self::write_ecc384_csr_to_peristent_storage(env, &dev_id_csr); - } - ecc384_csr_buf.zeroize(); + // Copy the tag to the CSR envelop. + csr_envelop.ecc_csr_mac = tag.into(); - result?; + Ok(()) + } - // Generate MLDSA CSR. + fn make_mldsa_csr( + env: &mut RomEnv, + output: &DiceOutput, + csr_envelop: &mut InitDevIdCsrEnvelop, + ) -> CaliptraResult<()> { let key_pair = &output.mldsa_subj_key_pair; let params = InitDevIdCsrTbsMlDsa87Params { @@ -359,7 +439,6 @@ impl InitDevIdLayer { let mut sig: [u8; 4627] = sig[..4627].try_into().unwrap(); // Build the CSR with `To Be Signed` & `Signature` - let mut mldsa87_csr_buf = [0; MLDSA87_MAX_CSR_SIZE]; let mldsa87_signature = caliptra_x509::Mldsa87Signature { sig }; let result = MlDsa87CsrBuilder::new(tbs.tbs(), &mldsa87_signature) .ok_or(CaliptraError::ROM_IDEVID_CSR_BUILDER_INIT_FAILURE); @@ -367,39 +446,39 @@ impl InitDevIdLayer { let csr_bldr = result?; let csr_len = csr_bldr - .build(&mut mldsa87_csr_buf) + .build(&mut csr_envelop.mldsa_csr.csr) .ok_or(CaliptraError::ROM_IDEVID_CSR_BUILDER_BUILD_FAILURE)?; - if csr_len > mldsa87_csr_buf.len() { + if csr_len > csr_envelop.mldsa_csr.csr.len() { return Err(CaliptraError::ROM_IDEVID_CSR_OVERFLOW); } + csr_envelop.mldsa_csr.csr_len = csr_len as u32; + + // Generate the CSR MAC. + let mut tag = Array4x16::default(); + let csr_slice = &csr_envelop.mldsa_csr.csr[..csr_len]; + env.hmac.hmac( + &HmacKey::CsrMode(), + &HmacData::Slice(csr_slice), + &mut env.trng, + (&mut tag).into(), + HmacMode::Hmac512, + )?; - let dev_id_csr = Mldsa87IdevIdCsr::new(&mldsa87_csr_buf, csr_len)?; - - let result = Self::write_mldsa87_csr_to_peristent_storage(env, &dev_id_csr); - mldsa87_csr_buf.zeroize(); - - report_boot_status(IDevIdMakeCsrComplete.into()); - - result + // Copy the tag to the CSR envelop. + csr_envelop.mldsa_csr_mac = tag.into(); + Ok(()) } - fn write_ecc384_csr_to_peristent_storage( + fn write_csrs_to_persistent_storage( env: &mut RomEnv, - csr: &Ecc384IdevIdCsr, + csr_envelop: &InitDevIdCsrEnvelop, ) -> CaliptraResult<()> { let csr_persistent_mem = &mut env.persistent_data.get_mut().ecc384_idevid_csr; - *csr_persistent_mem = csr.clone(); - - Ok(()) - } + *csr_persistent_mem = csr_envelop.ecc_csr.clone(); - fn write_mldsa87_csr_to_peristent_storage( - env: &mut RomEnv, - csr: &Mldsa87IdevIdCsr, - ) -> CaliptraResult<()> { let csr_persistent_mem = &mut env.persistent_data.get_mut().mldsa87_idevid_csr; - *csr_persistent_mem = csr.clone(); + *csr_persistent_mem = csr_envelop.mldsa_csr.clone(); Ok(()) } @@ -409,15 +488,15 @@ impl InitDevIdLayer { /// # Argument /// /// * `env` - ROM Environment - /// * `csr` - ificate Signing Request to send to SOC - fn send_ecc384_csr(env: &mut RomEnv, csr: &Ecc384IdevIdCsr) -> CaliptraResult<()> { + /// * `csr_envelop` - Envelop containing the ECC and MLDSA CSRs + fn send_csr_envelop(env: &mut RomEnv, csr_envelop: &InitDevIdCsrEnvelop) -> CaliptraResult<()> { loop { - // Create Mailbox send transaction to send the CSR + // Create Mailbox send transaction to send the CSR envelop if let Some(mut txn) = env.mbox.try_start_send_txn() { // Copy the CSR to mailbox - txn.send_request(0, csr.get().ok_or(CaliptraError::ROM_IDEVID_INVALID_CSR)?)?; + txn.send_request(0, csr_envelop.as_bytes())?; - // Signal the JTAG/SOC that Initial Device ID CSR is ready + // Signal the JTAG/SOC that Initial Device ID CSR envelop is ready env.soc_ifc.flow_status_set_idevid_csr_ready(); // Wait for JTAG/SOC to consume the mailbox @@ -426,8 +505,8 @@ impl InitDevIdLayer { // Release access to the mailbox txn.complete()?; - cprintln!("[idev] CSR uploaded"); - report_boot_status(IDevIdSendCsrComplete.into()); + cprintln!("[idev] CSR envelop uploaded"); + report_boot_status(IDevIdSendCsrEnvelopComplete.into()); // exit the loop break Ok(()); diff --git a/rom/dev/tests/rom_integration_tests/test_dice_derivations.rs b/rom/dev/tests/rom_integration_tests/test_dice_derivations.rs index b6f2f2ca84..baab7bdddd 100644 --- a/rom/dev/tests/rom_integration_tests/test_dice_derivations.rs +++ b/rom/dev/tests/rom_integration_tests/test_dice_derivations.rs @@ -31,7 +31,7 @@ fn test_cold_reset_status_reporting() { hw.step_until_boot_status(IDevIdSubjIdSnGenerationComplete.into(), false); hw.step_until_boot_status(IDevIdSubjKeyIdGenerationComplete.into(), false); // step_until_boot_status(IdevIdMakeCsrComplete, false); - // step_until_boot_status(IdevIdSendCsrComplete, false); + // step_until_boot_status(IDevIdSendCsrEnvelopComplete, false); hw.step_until_boot_status(IDevIdDerivationComplete.into(), false); hw.step_until_boot_status(LDevIdCdiDerivationComplete.into(), false); hw.step_until_boot_status(LDevIdKeyPairDerivationComplete.into(), false); diff --git a/sw-emulator/lib/periph/src/hmac.rs b/sw-emulator/lib/periph/src/hmac.rs index 1d29d2168a..5067123385 100644 --- a/sw-emulator/lib/periph/src/hmac.rs +++ b/sw-emulator/lib/periph/src/hmac.rs @@ -215,6 +215,9 @@ pub struct HmacSha { /// Tag write complete action op_tag_write_complete_action: Option, + + /// CSR Key + csr_key: [u32; HMAC_KEY_SIZE_DWORD_512], } impl HmacSha { @@ -268,6 +271,7 @@ impl HmacSha { op_key_read_complete_action: None, op_block_read_complete_action: None, op_tag_write_complete_action: None, + csr_key: Default::default(), } } @@ -343,6 +347,11 @@ impl HmacSha { let mode512 = self.control.reg.is_set(Control::MODE); + // If CSR mode is set, use the pre-defined key. + if self.control.reg.is_set(Control::CSR_MODE) { + self.key = self.csr_key; + } + if self.control.reg.is_set(Control::INIT) { if mode512 { self.hmac = @@ -380,8 +389,6 @@ impl HmacSha { self.zeroize(); } - // [TODO][CAP2] if CSR Mode is set, use a pre-defined key. - Ok(()) }