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. |
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]
}
* Clean up unused APIs
* Modify the driver to support this test
The issue is fixed on the mainline (SHA error interrupt was not enabled)
be2d534 to
4fc2fc2
Compare
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Hardware-validated fixes and API cleanup for ecc_sign_with_k (A4), plus a throwaway on-device known-answer test. KAT PASSes on the EVB. Production (ecc_sign_with_k, crypto/ecc.rs): - Fix modular reduction: it is a DOUBLE-WIDTH PKA primitive, so stage xR into a zeroed 2*field buffer (xR || 0). The bare 48-byte input reduced xR || garbage and produced a wrong r; found by comparing to PR #511's run_ecdsa_on_engine. - Zero-copy DMA I/O: take k/digest/d as &DmaBuf and r/s as &mut DmaBuf (caller-owned GSRAM), matching ecc_verify / ecdh_derive -- no operand or result copies; only internal scratch + the flash constants are staged. - Take `curve` as a parameter and reject anything but P-384 with HsmError::UnsupportedCmd. - Drop redundant zero-init: only xr_wide needs it (its zeroed high half is the reduction padding); every other scratch buffer is fully overwritten by its producing PKA op. Confirmed by the KAT. Rename the PKA step primitives to the ecc_* prefix (matching PR #511): ecc_mont_const_calc, ecc_point_mul, ecc_mod_reduction, ecc_mont_repr_in, ecc_mont_repr_out, ecc_mod_inverse, ecc_mod_mul, ecc_mod_add -- engine.rs definitions, opcode.rs doc, ecc.rs call sites. Throwaway (to be removed once the cert-chain path is up): - ecdsa_sign_self_test: NIST CAVP 186-3 P-384 SigGen KAT (same vector as #511), run once at boot from main.rs; logs PASS/FAIL over the trace UART. - Enable trace-uart by default so the self-test result is visible on COM6. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: cfbdfe3b-9b89-4ff3-9657-57d6cc0d3c11
No description provided.