Add pre-operational self tests for UNO firmware#511
Conversation
|
@microsoft-github-policy-service agree company="Microsoft" |
There was a problem hiding this comment.
Pull request overview
This PR introduces pre-operational Cryptographic Algorithm Self-Tests (CAST) for the Uno firmware, gating boot completion on known-answer test (KAT) success, while also extending the IO SRAM layout to reserve a dedicated IO slot for self-test buffers and tightening memory-ordering around AES/SHA/PKA command submission.
Changes:
- Reserve a dedicated GSRAM IO buffer slot for self-tests (CAST) and adjust related constants/overlays.
- Add a pre-op CAST suite (AES-CBC + per-PKA-engine RSA mod-exp; HKDF/KBKDF intended) and run it during boot before transitioning to
Running. - Add explicit
dmb()barriers before AES/SHA/UPKA doorbell writes to ensure descriptor write ordering on Cortex-M7.
Reviewed changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| fw/plat/uno/rdl/soc/gsram_map.rdl | Expands SRAM_IO_BUF to 34 slots and documents the dedicated self-test slot. |
| fw/plat/uno/rdl/soc/dtcm_map.rdl | Documents why DTCM scratch remains at 33 slots (host+admin only). |
| fw/plat/uno/fw/reg/soc/src/io_gsram.rs | Updates generated constants/overlay sizing for 34 SRAM_IO_BUF slots. |
| fw/plat/uno/fw/pal/src/self_test/vectors.rs | Adds fixed KAT vectors (AES-CBC, HKDF, KBKDF, RSA mod-exp). |
| fw/plat/uno/fw/pal/src/self_test/aes_cbc.rs | Implements AES-256-CBC CAST using the PAL AES path. |
| fw/plat/uno/fw/pal/src/self_test/pka.rs | Implements per-engine RSA-2048 mod-exp CAST using pinned UPKA engines. |
| fw/plat/uno/fw/pal/src/self_test/mod.rs | Defines the pre-op self-test suite entrypoint and module layout. |
| fw/plat/uno/fw/pal/src/pal.rs | Runs CAST during boot and adds polling-based wakeups for AES/SHA. |
| fw/plat/uno/fw/pal/src/lib.rs | Wires the self_test module into the Uno PAL crate. |
| fw/plat/uno/fw/pal/src/io.rs | Adds a dedicated UnoHsmIo::self_test() handle for the reserved slot. |
| fw/plat/uno/fw/pal/src/alloc.rs | Reassigns admin slot index and introduces a dedicated self-test slot index. |
| fw/plat/uno/fw/drivers/upka/src/executor.rs | Adds dmb() before UPKA doorbell submission for correct ordering. |
| fw/plat/uno/fw/drivers/upka/Cargo.toml | Adds cortex-m dependency for dmb(). |
| fw/plat/uno/fw/drivers/sha/src/api.rs | Adds dmb() before SHA doorbell submission and updates related comments. |
| fw/plat/uno/fw/drivers/sha/Cargo.toml | Adds cortex-m dependency for dmb(). |
| fw/plat/uno/fw/drivers/aes/src/api.rs | Adds dmb() before AES doorbell submission. |
| fw/plat/uno/fw/drivers/aes/Cargo.toml | Adds cortex-m dependency for dmb(). |
| fw/pal/traits/src/error.rs | Adds HsmError::SelfTestKatMismatch for CAST failures. |
| //! All tests run on a dedicated, reserved IO slot | ||
| //! ([`crate::alloc::SELF_TEST_IO_INDEX`]) obtained via | ||
| //! [`UnoHsmPal::self_test_io`]. KAT operands are bump-allocated from that | ||
| //! slot's `SRAM_IO_BUF`, so the self-tests never contend with host IO or | ||
| //! partition-provisioning crypto (which uses the separate admin slot). |
| /// Dedicated self-test (CAST) IO slot — the last of [`IO_SLOTS`]. | ||
| /// | ||
| /// Reserved for the pre-operational and periodic cryptographic | ||
| /// algorithm self-tests, separate from [`ADMIN_IO_INDEX`] so the | ||
| /// periodic self-test never races partition provisioning over a | ||
| /// shared bump heap. Same DMA/NonDma backing as any host slot. | ||
| pub(crate) const SELF_TEST_IO_INDEX: u16 = (IO_SLOTS - 1) as u16; |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (1)
fw/plat/uno/fw/pal/src/io.rs:111
UnoHsmIo::self_test()setsindex = SELF_TEST_IO_INDEX(33), butIO_METAis only 33 entries (0..=32). Any call topid()/queue_id()/queue_idx()on a self-test IO would indexIO_Q.io_meta[33]out of bounds (undefined behavior). Even if the current self-test path avoids these methods, it’s easy for shared code (logging, future refactors) to call them.
Consider either (a) special-casing pid/queue_* for the self-test IO to return fixed defaults without touching IO_META, or (b) making io_meta() map the self-test slot to a safe metadata entry.
/// Returns a reference to the IO_META entry for this slot.
#[inline]
fn io_meta(&self) -> &IoMetaEntry {
&IO_Q.io_meta[self.index as usize]
}
| /// Dedicated self-test (CAST) IO slot — the last of [`IO_SLOTS`]. | ||
| /// | ||
| /// Reserved for the pre-operational and periodic cryptographic | ||
| /// algorithm self-tests, separate from [`ADMIN_IO_INDEX`] so the | ||
| /// periodic self-test never races partition provisioning over a | ||
| /// shared bump heap. Same DMA/NonDma backing as any host slot. | ||
| pub(crate) const SELF_TEST_IO_INDEX: u16 = (IO_SLOTS - 1) as u16; |
No description provided.