From 4e72a62eb58d049883b246ab45a0cc37a3b94f80 Mon Sep 17 00:00:00 2001 From: Nick Quarton <139178705+nquarton@users.noreply.github.com> Date: Mon, 23 Oct 2023 11:22:40 -0700 Subject: [PATCH 1/6] Add pauser control during execution for verilator and FPGA (#927) --- hw-model/src/lib.rs | 52 ++++++++++++++++++++++++++--- hw-model/src/model_emulated.rs | 4 +++ hw-model/src/model_fpga_realtime.rs | 19 ++++++----- hw-model/src/model_verilated.rs | 8 ++++- 4 files changed, 70 insertions(+), 13 deletions(-) diff --git a/hw-model/src/lib.rs b/hw-model/src/lib.rs index 09a373082a..5ff08f3deb 100644 --- a/hw-model/src/lib.rs +++ b/hw-model/src/lib.rs @@ -145,9 +145,6 @@ pub struct InitParams<'a> { pub trng_mode: Option, pub wdt_timeout_cycles: u64, - - // PAUSER value used for APB read/write cycles from SoC->caliptra - pub soc_apb_pauser: u32, } impl<'a> Default for InitParams<'a> { @@ -178,7 +175,6 @@ impl<'a> Default for InitParams<'a> { etrng_responses, trng_mode: Default::default(), wdt_timeout_cycles: EXPECTED_CALIPTRA_BOOT_TIME_IN_CYCLES, - soc_apb_pauser: 0x1, } } } @@ -691,6 +687,8 @@ pub trait HwModel { fn ecc_error_injection(&mut self, _mode: ErrorInjectionMode) {} + fn set_apb_pauser(&mut self, pauser: u32); + /// Executes `cmd` with request data `buf`. Returns `Ok(Some(_))` if /// the uC responded with data, `Ok(None)` if the uC indicated success /// without data, Err(ModelError::MailboxCmdFailed) if the microcontroller @@ -1057,6 +1055,52 @@ mod tests { assert_eq!(buf, &[0, 0, 0]); } + #[test] + // Currently only possible on verilator + // SW emulator does not support pauser + // For FPGA, test case needs to be reworked to capture SIGBUS from linux environment + #[cfg(feature = "verilator")] + fn test_mbox_pauser() { + let mut model = caliptra_hw_model::new_unbooted(InitParams { + rom: &gen_image_hi(), + ..Default::default() + }) + .unwrap(); + + model.soc_ifc().cptra_fuse_wr_done().write(|w| w.done(true)); + model.soc_ifc().cptra_bootfsm_go().write(|w| w.go(true)); + + // Set up the PAUSER as valid for the mailbox (using index 0) + model + .soc_ifc() + .cptra_mbox_valid_pauser() + .at(0) + .write(|_| 0x1); + model + .soc_ifc() + .cptra_mbox_pauser_lock() + .at(0) + .write(|w| w.lock(true)); + + // Set the PAUSER to something invalid + model.set_apb_pauser(0x2); + + assert!(!model.soc_mbox().lock().read().lock()); + // Should continue to read 0 because the reads are being blocked by valid PAUSER + assert!(!model.soc_mbox().lock().read().lock()); + + // Set the PAUSER back to valid + model.set_apb_pauser(0x1); + + // Should read 0 the first time still for lock available + assert!(!model.soc_mbox().lock().read().lock()); + // Should read 1 now for lock taken + assert!(model.soc_mbox().lock().read().lock()); + + model.soc_mbox().cmd().write(|_| 4242); + assert_eq!(model.soc_mbox().cmd().read(), 4242); + } + #[test] fn test_execution() { let mut model = caliptra_hw_model::new(BootParams { diff --git a/hw-model/src/model_emulated.rs b/hw-model/src/model_emulated.rs index f14cb1f710..441d7b66eb 100644 --- a/hw-model/src/model_emulated.rs +++ b/hw-model/src/model_emulated.rs @@ -197,4 +197,8 @@ impl crate::HwModel for ModelEmulated { } } } + + fn set_apb_pauser(&mut self, _pauser: u32) { + unimplemented!(); + } } diff --git a/hw-model/src/model_fpga_realtime.rs b/hw-model/src/model_fpga_realtime.rs index cd2d414c56..58dabc1dc0 100644 --- a/hw-model/src/model_fpga_realtime.rs +++ b/hw-model/src/model_fpga_realtime.rs @@ -23,6 +23,8 @@ use crate::Output; const FPGA_WRAPPER_MAPPING: usize = 0; const CALIPTRA_MAPPING: usize = 1; +const DEFAULT_APB_PAUSER: u32 = 0x1; + fn fmt_uio_error(err: UioError) -> String { format!("{err:?}") } @@ -161,13 +163,6 @@ impl ModelFpgaRealtime { .write_volatile(val.0); } } - fn set_pauser(&mut self, pauser: u32) { - unsafe { - self.wrapper - .offset(FPGA_WRAPPER_PAUSER_OFFSET) - .write_volatile(pauser); - } - } fn clear_log_fifo(&mut self) { loop { @@ -275,7 +270,7 @@ impl HwModel for ModelFpgaRealtime { m.set_security_state(u32::from(params.security_state)); // Set initial PAUSER - m.set_pauser(params.soc_apb_pauser); + m.set_apb_pauser(DEFAULT_APB_PAUSER); // Set deobfuscation key for i in 0..8 { @@ -347,6 +342,14 @@ impl HwModel for ModelFpgaRealtime { fn tracing_hint(&mut self, _enable: bool) { // Do nothing; we don't support tracing yet } + + fn set_apb_pauser(&mut self, pauser: u32) { + unsafe { + self.wrapper + .offset(FPGA_WRAPPER_PAUSER_OFFSET) + .write_volatile(pauser); + } + } } impl Drop for ModelFpgaRealtime { fn drop(&mut self) { diff --git a/hw-model/src/model_verilated.rs b/hw-model/src/model_verilated.rs index 1dd0fd33dc..40009626df 100644 --- a/hw-model/src/model_verilated.rs +++ b/hw-model/src/model_verilated.rs @@ -15,6 +15,8 @@ use std::rc::Rc; use crate::Output; use std::env; +const DEFAULT_APB_PAUSER: u32 = 0x1; + // How many clock cycles before emitting a TRNG nibble const TRNG_DELAY: u32 = 4; @@ -212,7 +214,7 @@ impl crate::HwModel for ModelVerilated { log, - soc_apb_pauser: params.soc_apb_pauser, + soc_apb_pauser: DEFAULT_APB_PAUSER, }; m.tracing_hint(true); @@ -301,6 +303,10 @@ impl crate::HwModel for ModelVerilated { } } } + + fn set_apb_pauser(&mut self, pauser: u32) { + self.soc_apb_pauser = pauser; + } } impl ModelVerilated { fn process_trng(&mut self) { From a2d830807df4c751ecb58391926af837a25e41f4 Mon Sep 17 00:00:00 2001 From: Nick Quarton <139178705+nquarton@users.noreply.github.com> Date: Mon, 23 Oct 2023 14:00:30 -0700 Subject: [PATCH 2/6] Adding Fake ROM and FMC notes to readme files (#971) --- fmc/README.md | 13 +++++++++++++ rom/dev/README.md | 21 ++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/fmc/README.md b/fmc/README.md index cc407cd1a9..9feb20dde3 100644 --- a/fmc/README.md +++ b/fmc/README.md @@ -429,6 +429,19 @@ regardless of which reset path caused it to be executed. FMC does not participate in Caliptra update/recovery flows. FMC is designed such that it does not perform any different steps during update and simply behaves the same as it does during other cold/warm resets. +## Fake FMC + +Fake FMC is a variation of the FMC intended to be used in the verification/enabling stages of development. The purpose is to greatly reduce the boot time for pre-Si environments by eliminating certain steps from the boot flow. + +**Differences from normal FMC:** +Currently, Fake FMC directly proceeds to runtime without generating the RT Alias Cert. In the future, there will be a static cert and a corresponding private key will be used by runtime to support the DICE challenge flow. + +**How to use:** +- Fake FMC is provided in the release along with the normal collateral. +- The image builder exposes the argument "fake" that can be used to generate the fake versions + +Fake FMC should be used with the Fake ROM. Details can be found in the ROM readme. + ## Future - Current POR is for FIPS Crypto boundary to encompass all of Caliptra FW, including ROM, FMC, and Runtime. With this boundary, there is no need for any diff --git a/rom/dev/README.md b/rom/dev/README.md index 1c83d72c49..06ee4e581e 100644 --- a/rom/dev/README.md +++ b/rom/dev/README.md @@ -1,3 +1,4 @@ + # Caliptra - ROM Specification v0.5.2 ## 1. Version History @@ -106,7 +107,7 @@ Following are the main FUSE & Architectural Registers used by the Caliptra ROM f | FUSE_RUNTIME_SVN | 128 | Runtime Security Version Number | | FUSE_ANTI_ROLLBACK_DISABLE | 1 | Disable SVN checking for FMC & Runtime when bit is set | | FUSE_IDEVID_CERT_ATTR | 768 | FUSE containing information for generating IDEVID CSR
**Word 0**: X509 Key Id Algorithm (2 bits) 1: SHA1, 2: SHA256, 2: SHA384, 3: Fuse
**Word 1,2,3,4,5**: Subject Key Id
**Words 7,8**: Unique Endpoint ID | -| CPTRA_DBG_MANUF_SERVICE_REG | 16 | Manufacturing Services:
**Bit 0**: IDEVID CSR upload | +| CPTRA_DBG_MANUF_SERVICE_REG | 16 | Manufacturing Services:
**Bit 0**: IDEVID CSR upload
**Bit 31**: Fake ROM image verify enable | ## 7. Vaults @@ -755,3 +756,21 @@ The following are the pre-conditions that should be satisfied: - If validation fails during ROM boot, the new RT image will not be copied from the mailbox. ROM will boot the existing FMC/Runtime images. Validation errors will be reported via the CPTRA_FW_ERROR_NON_FATAL register. + +## 14. Fake ROM + +Fake ROM is a variation of the ROM intended to be used in the verification/enabling stages of development. The purpose is to greatly reduce the boot time for pre-Si environments by eliminating certain steps from the boot flow. Outside of these omissions, the behavior is intended to be the same as normal ROM. + +Fake ROM is not available in production mode as it is not secure and breaks/bypasses the core use-cases of Caliptra as a RoT. + +**Differences from normal ROM:** +Fake ROM reduces boot time by doing the following: +1. Skipping the DICE cert derivation and instead providing a static, "canned" cert chain for LDEV and FMC Alias +2. Skipping the known answer tests (KATs) +3. Skipping verification of the FW image received - This can optionally still be performed, see CPTRA_DBG_MANUF_SERVICE_REG + +**How to use:** +- Fake ROM is provided in the release along with the normal collateral. +- The image builder exposes the argument "fake" that can be used to generate the fake versions + +To fully boot to runtime, the fake version of FMC should also be used. Details can be found in the FMC readme. \ No newline at end of file From 180fd984e5c54362b1065149ecf5e49a72367e57 Mon Sep 17 00:00:00 2001 From: Kor Nielsen Date: Mon, 23 Oct 2023 14:32:07 -0700 Subject: [PATCH 3/6] Specialize RealMmioMut::read_volatile_array() for risc-v. Addresses #922. These specializations unroll register array reads for 12-word and 16-word reads; they were previously used for RealMmio, but I forgot to add them for RealMmioMut. This improves code size, and improves our glitch resistence (since there is no loop conditional to glitch). --- FROZEN_IMAGES.sha384sum | 4 ++-- ureg/src/lib.rs | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/FROZEN_IMAGES.sha384sum b/FROZEN_IMAGES.sha384sum index 75d3a0dfef..0ba776010a 100644 --- a/FROZEN_IMAGES.sha384sum +++ b/FROZEN_IMAGES.sha384sum @@ -1,3 +1,3 @@ # WARNING: Do not update this file without the approval of the Caliptra TAC -6c8651061bc86da0ab38a62631282112c30d78980ba9ae37f3148b264e520bc200ccf03a2b76f903a492746745ee0195 caliptra-rom-no-log.bin -6a5ed1989df5f11820534fbdebf71f6090c5a2784140506d31a008a347c7281eaf3db50f80846a122f91af2d42047672 caliptra-rom-with-log.bin +cf7dd392b5a978ab8e4cfce0a2087114720809cdc4571491f9aa17c5b2d76f68b4a58236eff738da5a262c0e33a14d85 caliptra-rom-no-log.bin +9a1119b2bf4bfffeebb02db2de7a664ffc4b6f6dde69e27c8c4f875315e856e0bcf52732c6fcce7d6579822e68132fe3 caliptra-rom-with-log.bin diff --git a/ureg/src/lib.rs b/ureg/src/lib.rs index 11de8b8f50..0a113924f8 100644 --- a/ureg/src/lib.rs +++ b/ureg/src/lib.rs @@ -237,6 +237,11 @@ impl Mmio for RealMmioMut<'_> { unsafe fn read_volatile(&self, src: *const T) -> T { core::ptr::read_volatile(src) } + + #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))] + unsafe fn read_volatile_array(&self, dst: *mut T, src: *mut T) { + opt_riscv::read_volatile_array::(dst, src) + } } impl MmioMut for RealMmioMut<'_> { /// Performs a volatile write of `src` to `dst`. From ac58d126869b8671f8288fae236c6ba85ba5ec53 Mon Sep 17 00:00:00 2001 From: Kor Nielsen Date: Mon, 23 Oct 2023 15:11:02 -0700 Subject: [PATCH 4/6] CSRNG driver: Remove implicit memcpy from generate(). Addresses #922. Calling memcpy before the CFI defenses are initialized is dangerous, as a glitch could lead to an out-of-bounds write. By unrolling the loop into uninitialized memory, we convince the optimizer to get rid of the memcpy call. --- FROZEN_IMAGES.sha384sum | 4 +- drivers/src/csrng.rs | 69 ++++++++------------------ drivers/test-fw/src/bin/csrng_tests.rs | 11 ++-- 3 files changed, 29 insertions(+), 55 deletions(-) diff --git a/FROZEN_IMAGES.sha384sum b/FROZEN_IMAGES.sha384sum index 0ba776010a..1903485b80 100644 --- a/FROZEN_IMAGES.sha384sum +++ b/FROZEN_IMAGES.sha384sum @@ -1,3 +1,3 @@ # WARNING: Do not update this file without the approval of the Caliptra TAC -cf7dd392b5a978ab8e4cfce0a2087114720809cdc4571491f9aa17c5b2d76f68b4a58236eff738da5a262c0e33a14d85 caliptra-rom-no-log.bin -9a1119b2bf4bfffeebb02db2de7a664ffc4b6f6dde69e27c8c4f875315e856e0bcf52732c6fcce7d6579822e68132fe3 caliptra-rom-with-log.bin +7e2c06d929577e439df7d8d3e6659d098e7416d41b01d4b523577bb91514ea8c3b512445512eef15cdac119f74eb8df5 caliptra-rom-no-log.bin +67f4c0ec7b003d0201af45651591bb6faa118e36dcc2d65f7f646e6d14d8fc15d253fee07a31b87b85fa262084e998d7 caliptra-rom-with-log.bin diff --git a/drivers/src/csrng.rs b/drivers/src/csrng.rs index ff846cd0e8..2ec38a0db9 100644 --- a/drivers/src/csrng.rs +++ b/drivers/src/csrng.rs @@ -26,21 +26,12 @@ use caliptra_registers::csrng::CsrngReg; use caliptra_registers::entropy_src::{self, regs::AlertFailCountsReadVal, EntropySrcReg}; use caliptra_registers::soc_ifc::{self, SocIfcReg}; -use core::array; +use core::mem::MaybeUninit; // https://opentitan.org/book/hw/ip/csrng/doc/theory_of_operation.html#command-description const MAX_SEED_WORDS: usize = 12; const WORDS_PER_BLOCK: usize = 4; -struct IsCompleteBlocks; - -impl IsCompleteBlocks { - const ASSERT: () = assert!( - NUM_WORDS != 0 && NUM_WORDS % WORDS_PER_BLOCK == 0, - "NUM_WORDS must be non-zero and divisible by WORDS_PER_BLOCK" - ); -} - /// A unique handle to the underlying CSRNG peripheral. pub struct Csrng { csrng: CsrngReg, @@ -141,51 +132,35 @@ impl Csrng { /// } /// ``` pub fn generate12(&mut self) -> CaliptraResult<[u32; 12]> { - self.generate() - } - - /// Return 16 randomly generated [`u32`]s. - /// - /// # Errors - /// - /// Returns an error if the internal generate command fails. - /// - /// # Examples - /// - /// ```no_run - /// let mut csrng = ...; - /// - /// let random_words: [u32; 16] = csrng.generate()?; - /// - /// for word in random_words { - /// // Do something with `word`. - /// } - /// ``` - pub fn generate16(&mut self) -> CaliptraResult<[u32; 16]> { - self.generate() - } - - fn generate(&mut self) -> CaliptraResult<[u32; N]> { - #[allow(clippy::let_unit_value)] - let _ = IsCompleteBlocks::::ASSERT; - check_for_alert_state(self.entropy_src.regs())?; send_command( &mut self.csrng, Command::Generate { - num_128_bit_blocks: N / WORDS_PER_BLOCK, + num_128_bit_blocks: 12 / WORDS_PER_BLOCK, }, )?; - Ok(array::from_fn(|i| { - if i % WORDS_PER_BLOCK == 0 { - // Wait for CSRNG to generate next block of words. - wait::until(|| self.csrng.regs().genbits_vld().read().genbits_vld()); - } - - self.csrng.regs().genbits().read() - })) + let mut result = MaybeUninit::<[u32; 12]>::uninit(); + let dest = result.as_mut_ptr() as *mut u32; + unsafe { + wait::until(|| self.csrng.regs().genbits_vld().read().genbits_vld()); + dest.add(0).write(self.csrng.regs().genbits().read()); + dest.add(1).write(self.csrng.regs().genbits().read()); + dest.add(2).write(self.csrng.regs().genbits().read()); + dest.add(3).write(self.csrng.regs().genbits().read()); + wait::until(|| self.csrng.regs().genbits_vld().read().genbits_vld()); + dest.add(4).write(self.csrng.regs().genbits().read()); + dest.add(5).write(self.csrng.regs().genbits().read()); + dest.add(6).write(self.csrng.regs().genbits().read()); + dest.add(7).write(self.csrng.regs().genbits().read()); + wait::until(|| self.csrng.regs().genbits_vld().read().genbits_vld()); + dest.add(8).write(self.csrng.regs().genbits().read()); + dest.add(9).write(self.csrng.regs().genbits().read()); + dest.add(10).write(self.csrng.regs().genbits().read()); + dest.add(11).write(self.csrng.regs().genbits().read()); + Ok(result.assume_init()) + } } pub fn reseed(&mut self, seed: Seed) -> CaliptraResult<()> { diff --git a/drivers/test-fw/src/bin/csrng_tests.rs b/drivers/test-fw/src/bin/csrng_tests.rs index 9ca549ad10..727f5134d4 100644 --- a/drivers/test-fw/src/bin/csrng_tests.rs +++ b/drivers/test-fw/src/bin/csrng_tests.rs @@ -31,10 +31,9 @@ fn test_ctr_drbg_ctr0_smoke() { 0x5600419c, 0xca79b0b0, 0xdda33b5c, 0xa468649e, 0xdf5d73fa, ]); - const EXPECTED_OUTPUT: [u32; 16] = [ - 0xe48bb8cb, 0x1012c84c, 0x5af8a7f1, 0xd1c07cd9, 0xdf82ab22, 0x771c619b, 0xd40fccb1, - 0x87189e99, 0x510494b3, 0x64f7ac0c, 0x2581f391, 0x80b1dc2f, 0x793e01c5, 0x87b107ae, - 0xdb17514c, 0xa43c41b7, + const EXPECTED_OUTPUT: [u32; 12] = [ + 0x725eda90, 0xc79b4a14, 0xe43b74ac, 0x9d9a938b, 0xc395a610, 0x4c5a1483, 0xa45f15e8, + 0x2708cbef, 0x89eb63a9, 0x70cdc6bc, 0x710daba1, 0xed39808c, ]; let mut csrng = @@ -42,12 +41,12 @@ fn test_ctr_drbg_ctr0_smoke() { // The original OpenTitan test tosses the first call to generate. let _ = csrng - .generate16() + .generate12() .expect("first call to generate should work"); assert_eq!( csrng - .generate16() + .generate12() .expect("second call to generate should work"), EXPECTED_OUTPUT ); From 8960eab5e33c86bbe9e4c8dc09c8a26e1746bfaa Mon Sep 17 00:00:00 2001 From: Vishal Mhatre <38512878+mhatrevi@users.noreply.github.com> Date: Mon, 23 Oct 2023 16:54:59 -0700 Subject: [PATCH 5/6] [fix] Return dpe_result for Stash Measurement command (#987) This fix addresses issue# https://github.com/chipsalliance/caliptra-sw/issues/978 --- FROZEN_IMAGES.sha384sum | 4 ++-- hw-model/src/lib.rs | 10 +++++----- rom/dev/src/flow/cold_reset/fw_processor.rs | 7 +++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/FROZEN_IMAGES.sha384sum b/FROZEN_IMAGES.sha384sum index 1903485b80..b6c71e695c 100644 --- a/FROZEN_IMAGES.sha384sum +++ b/FROZEN_IMAGES.sha384sum @@ -1,3 +1,3 @@ # WARNING: Do not update this file without the approval of the Caliptra TAC -7e2c06d929577e439df7d8d3e6659d098e7416d41b01d4b523577bb91514ea8c3b512445512eef15cdac119f74eb8df5 caliptra-rom-no-log.bin -67f4c0ec7b003d0201af45651591bb6faa118e36dcc2d65f7f646e6d14d8fc15d253fee07a31b87b85fa262084e998d7 caliptra-rom-with-log.bin +3b3d2e3fc803aebed8334ddb2db470403b232a7de70a1394e19149ae5280e6c357235cec2f64ebd8d229efa2f8f4cac9 caliptra-rom-no-log.bin +a309276ecd74586409d9f0c01a75c3c1ab43a72fa3a5fee6527a3dc6a3bfc5e6334ddf73e58dd2cb3ab142b273cb6b20 caliptra-rom-with-log.bin diff --git a/hw-model/src/lib.rs b/hw-model/src/lib.rs index 5ff08f3deb..7f714b2e5d 100644 --- a/hw-model/src/lib.rs +++ b/hw-model/src/lib.rs @@ -7,7 +7,7 @@ use std::{ io::{stdout, ErrorKind, Write}, }; -use caliptra_common::mailbox_api; +use caliptra_common::mailbox_api::{self, StashMeasurementResp}; use caliptra_emu_bus::Bus; use caliptra_hw_model_types::{ ErrorInjectionMode, EtrngResponse, RandomEtrngResponses, RandomNibbles, DEFAULT_CPTRA_OBF_KEY, @@ -889,19 +889,19 @@ pub trait HwModel { let response = response.ok_or(ModelError::UploadMeasurementResponseError)?; // Get response as a response header struct - let response = mailbox_api::MailboxRespHeader::read_from(response.as_slice()) + let response = StashMeasurementResp::read_from(response.as_slice()) .ok_or(ModelError::UploadMeasurementResponseError)?; // Verify checksum and FIPS status if !caliptra_common::checksum::verify_checksum( - response.chksum, + response.hdr.chksum, 0x0, - &response.as_bytes()[core::mem::size_of_val(&response.chksum)..], + &response.as_bytes()[core::mem::size_of_val(&response.hdr.chksum)..], ) { return Err(ModelError::UploadMeasurementResponseError); } - if response.fips_status != mailbox_api::MailboxRespHeader::FIPS_STATUS_APPROVED { + if response.hdr.fips_status != mailbox_api::MailboxRespHeader::FIPS_STATUS_APPROVED { return Err(ModelError::UploadMeasurementResponseError); } diff --git a/rom/dev/src/flow/cold_reset/fw_processor.rs b/rom/dev/src/flow/cold_reset/fw_processor.rs index f2c2515577..a63b32808b 100644 --- a/rom/dev/src/flow/cold_reset/fw_processor.rs +++ b/rom/dev/src/flow/cold_reset/fw_processor.rs @@ -23,7 +23,7 @@ use caliptra_common::capabilities::Capabilities; use caliptra_common::fips::FipsVersionCmd; use caliptra_common::mailbox_api::{ CapabilitiesResp, CommandId, MailboxReqHeader, MailboxResp, MailboxRespHeader, - StashMeasurementReq, + StashMeasurementReq, StashMeasurementResp, }; use caliptra_common::pcr::PCR_ID_STASH_MEASUREMENT; use caliptra_common::verifier::FirmwareImageVerificationEnv; @@ -279,7 +279,10 @@ impl FirmwareProcessor { Self::stash_measurement(pcr_bank, env.sha384, persistent_data, &mut txn)?; // Generate and send response (with FIPS approved status) - let mut resp = MailboxResp::default(); + let mut resp = MailboxResp::StashMeasurement(StashMeasurementResp { + hdr: MailboxRespHeader::default(), + dpe_result: 0, // DPE_STATUS_SUCCESS + }); resp.populate_chksum()?; txn.send_response(resp.as_bytes())?; } From 7279e28f4ee58ef07e9faabde83fe4883d32ed3a Mon Sep 17 00:00:00 2001 From: Kor Nielsen Date: Fri, 20 Oct 2023 16:35:24 -0700 Subject: [PATCH 6/6] Extract API logic from caliptra_common into new caliptra-api crate. Host libraries should not have transitive deps on caliptra-drivers. --- Cargo.lock | 12 +++++++++++- Cargo.toml | 2 ++ FROZEN_IMAGES.sha384sum | 4 ++-- api/Cargo.toml | 13 +++++++++++++ {common => api}/src/capabilities.rs | 0 {common => api}/src/checksum.rs | 0 api/src/lib.rs | 11 +++++++++++ common/src/mailbox_api.rs => api/src/mailbox.rs | 2 +- common/Cargo.toml | 1 + common/src/lib.rs | 10 +++++++--- hw-model/Cargo.toml | 2 +- hw-model/src/lib.rs | 8 ++++---- 12 files changed, 53 insertions(+), 12 deletions(-) create mode 100644 api/Cargo.toml rename {common => api}/src/capabilities.rs (100%) rename {common => api}/src/checksum.rs (100%) create mode 100644 api/src/lib.rs rename common/src/mailbox_api.rs => api/src/mailbox.rs (99%) diff --git a/Cargo.lock b/Cargo.lock index 0ba8c3d287..b2e847380f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,6 +187,15 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "caliptra-api" +version = "0.1.0" +dependencies = [ + "bitflags 2.4.0", + "caliptra-error", + "zerocopy", +] + [[package]] name = "caliptra-builder" version = "0.1.0" @@ -415,6 +424,7 @@ version = "0.1.0" dependencies = [ "bit-vec", "bitfield", + "caliptra-api", "caliptra-builder", "caliptra-emu-bus", "caliptra-emu-cpu", @@ -424,7 +434,6 @@ dependencies = [ "caliptra-registers", "caliptra-test-harness-types", "caliptra-verilated", - "caliptra_common", "libc", "nix 0.26.2", "rand", @@ -758,6 +767,7 @@ version = "0.1.0" dependencies = [ "bitfield", "bitflags 2.4.0", + "caliptra-api", "caliptra-cpu", "caliptra-drivers", "caliptra-image-types", diff --git a/Cargo.toml b/Cargo.toml index 1ecacc6850..ba1581392d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ exclude = [ ] members = [ + "api", "builder", "cfi/lib", "cfi/derive", @@ -83,6 +84,7 @@ asn1 = "0.13.0" bitfield = "0.14.0" bitflags = "2.0.1" bit-vec = "0.6.3" +caliptra-api = { path = "api" } caliptra-cfi-lib = { path = "cfi/lib", default-features = false, features = ["cfi", "cfi-counter" ] } caliptra-cfi-derive = { path = "cfi/derive" } caliptra_common = { path = "common", default-features = false } diff --git a/FROZEN_IMAGES.sha384sum b/FROZEN_IMAGES.sha384sum index b6c71e695c..5427bb1453 100644 --- a/FROZEN_IMAGES.sha384sum +++ b/FROZEN_IMAGES.sha384sum @@ -1,3 +1,3 @@ # WARNING: Do not update this file without the approval of the Caliptra TAC -3b3d2e3fc803aebed8334ddb2db470403b232a7de70a1394e19149ae5280e6c357235cec2f64ebd8d229efa2f8f4cac9 caliptra-rom-no-log.bin -a309276ecd74586409d9f0c01a75c3c1ab43a72fa3a5fee6527a3dc6a3bfc5e6334ddf73e58dd2cb3ab142b273cb6b20 caliptra-rom-with-log.bin +2c7b77ae40e6c760a26fe37d1a3b45910435196f642ef76f1df96e49eec5cf710fb7159d89189a0b4eae47007ddc2b98 caliptra-rom-no-log.bin +0c518139f1cd88acbd06ff4e24b28823008347ce5186e84af54adabedcd00c52b3ad9b6a0e6aaf8514b4dfafed5b64cb caliptra-rom-with-log.bin diff --git a/api/Cargo.toml b/api/Cargo.toml new file mode 100644 index 0000000000..f1d082579d --- /dev/null +++ b/api/Cargo.toml @@ -0,0 +1,13 @@ +# Licensed under the Apache-2.0 license + +[package] +name = "caliptra-api" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bitflags.workspace = true +caliptra-error.workspace = true +zerocopy.workspace = true diff --git a/common/src/capabilities.rs b/api/src/capabilities.rs similarity index 100% rename from common/src/capabilities.rs rename to api/src/capabilities.rs diff --git a/common/src/checksum.rs b/api/src/checksum.rs similarity index 100% rename from common/src/checksum.rs rename to api/src/checksum.rs diff --git a/api/src/lib.rs b/api/src/lib.rs new file mode 100644 index 0000000000..5bf5d67ac6 --- /dev/null +++ b/api/src/lib.rs @@ -0,0 +1,11 @@ +// Licensed under the Apache-2.0 license + +#![no_std] + +mod capabilities; +mod checksum; +pub mod mailbox; + +pub use caliptra_error as error; +pub use capabilities::Capabilities; +pub use checksum::{calc_checksum, verify_checksum}; diff --git a/common/src/mailbox_api.rs b/api/src/mailbox.rs similarity index 99% rename from common/src/mailbox_api.rs rename to api/src/mailbox.rs index 6580cd2346..eb745238dc 100644 --- a/common/src/mailbox_api.rs +++ b/api/src/mailbox.rs @@ -1,6 +1,6 @@ // Licensed under the Apache-2.0 license -use caliptra_drivers::{CaliptraError, CaliptraResult}; +use caliptra_error::{CaliptraError, CaliptraResult}; use core::mem::size_of; use zerocopy::{AsBytes, FromBytes, LayoutVerified}; diff --git a/common/Cargo.toml b/common/Cargo.toml index aee64dacfc..475d8593bd 100644 --- a/common/Cargo.toml +++ b/common/Cargo.toml @@ -13,6 +13,7 @@ caliptra-cpu.workspace = true caliptra-drivers.workspace = true caliptra-image-types = { workspace = true, default-features = false } caliptra-image-verify.workspace = true +caliptra-api.workspace = true caliptra-registers.workspace = true ufmt.workspace = true zerocopy.workspace = true diff --git a/common/src/lib.rs b/common/src/lib.rs index 37ae413126..c1ebd6f0c6 100644 --- a/common/src/lib.rs +++ b/common/src/lib.rs @@ -3,14 +3,17 @@ #![cfg_attr(not(feature = "std"), no_std)] pub mod boot_status; -pub mod capabilities; -pub mod checksum; +pub mod capabilities { + pub use caliptra_api::Capabilities; +} +pub mod checksum { + pub use caliptra_api::{calc_checksum, verify_checksum}; +} pub mod crypto; pub mod dice; pub mod error_handler; pub mod fips; pub mod keyids; -pub mod mailbox_api; pub mod verifier; pub mod wdt; @@ -21,6 +24,7 @@ pub use hand_off::{ }; pub use boot_status::RomBootStatus; +pub use caliptra_api::mailbox as mailbox_api; pub use caliptra_drivers::cprint; pub use caliptra_drivers::cprintln; pub use caliptra_drivers::fuse_log as fuse; diff --git a/hw-model/Cargo.toml b/hw-model/Cargo.toml index 206440064d..8b57295f60 100644 --- a/hw-model/Cargo.toml +++ b/hw-model/Cargo.toml @@ -16,12 +16,12 @@ itrng = ["caliptra-verilated?/itrng"] [dependencies] bitfield.workspace = true bit-vec.workspace = true -caliptra_common = { workspace = true, default-features = false } caliptra-emu-bus.workspace = true caliptra-emu-cpu.workspace = true caliptra-emu-periph.workspace = true caliptra-emu-types.workspace = true caliptra-hw-model-types.workspace = true +caliptra-api.workspace = true caliptra-registers.workspace = true caliptra-verilated = { workspace = true, optional = true } rand.workspace = true diff --git a/hw-model/src/lib.rs b/hw-model/src/lib.rs index 7f714b2e5d..fb51f961dc 100644 --- a/hw-model/src/lib.rs +++ b/hw-model/src/lib.rs @@ -7,7 +7,7 @@ use std::{ io::{stdout, ErrorKind, Write}, }; -use caliptra_common::mailbox_api::{self, StashMeasurementResp}; +use caliptra_api as api; use caliptra_emu_bus::Bus; use caliptra_hw_model_types::{ ErrorInjectionMode, EtrngResponse, RandomEtrngResponses, RandomNibbles, DEFAULT_CPTRA_OBF_KEY, @@ -889,11 +889,11 @@ pub trait HwModel { let response = response.ok_or(ModelError::UploadMeasurementResponseError)?; // Get response as a response header struct - let response = StashMeasurementResp::read_from(response.as_slice()) + let response = api::mailbox::StashMeasurementResp::read_from(response.as_slice()) .ok_or(ModelError::UploadMeasurementResponseError)?; // Verify checksum and FIPS status - if !caliptra_common::checksum::verify_checksum( + if !api::verify_checksum( response.hdr.chksum, 0x0, &response.as_bytes()[core::mem::size_of_val(&response.hdr.chksum)..], @@ -901,7 +901,7 @@ pub trait HwModel { return Err(ModelError::UploadMeasurementResponseError); } - if response.hdr.fips_status != mailbox_api::MailboxRespHeader::FIPS_STATUS_APPROVED { + if response.hdr.fips_status != api::mailbox::MailboxRespHeader::FIPS_STATUS_APPROVED { return Err(ModelError::UploadMeasurementResponseError); }