Add support for PQC secure boot with MCXA 5xx family of MCUs - #36
Conversation
08f268c to
f185706
Compare
diondokter
left a comment
There was a problem hiding this comment.
Is there any split image support yet? If there is I can't find it (so please point me to it 😊)
Or are we assuming the ROM memory mapped it for us already?
The image header that the NXP ROM APIs/ROM Loader use has a section for identifying multiple images. The thought here is that it'd be a 'no-op' from an implementation perspective of the SBL firmware to support split-image, because it's already baked into the infra. The change then is in the build tooling to actually generate these additional fields and hashes. That's also where the open question is to NXP around if the secondary image(s) are simply hash verified or included in the full image signature block. |
@diondokter There is no split image support yet. From my understanding, the split image on the verification side should be opaque to the caller, IF the image is built correctly (The idea here is that the second executable occupies the area for the CRC binary and is hashed and verified automatically by the APIs). But that idea hasn't been validated yet partly because I haven't been able to generate a split image binary yet. We have reached out to NXP for further clarification and are awaiting their response. When we have a split binary, the API will use the single AHAB container to hash both binaries and validate them, so infrastructure needed is mostly on the artifact generation side (which is not published as part of this public PR yet but available in private repos). |
diondokter
left a comment
There was a problem hiding this comment.
Thanks for the responses so far!
What's the reason for trying to massage ec-slimloader into supporting both chips and a radically different way in how the code is executed?
The non-imxrt6xx parts are pretty small. All ec-slimloader does is a little bit of in-flash state management, verifying the image and then jump to it.
But for mcxa, the verification is different. And because we're gonna be running in flash, we need to be able to swap partitions, which means that the state management needs to change too. All that's left is doing the boot jump which is like 20 lines of code.
So why take on the complexity of making everything share the same codebase and structure?
|
Ok, I've been trying to build this PR and that just doesn't work.
|
This is a fair question. The main thing I think we want is a common interface to the boot sequencing, particularly the journal management and rollback behaviors we want to be 'the same'. We'd like to have a common 'entry point' for various products/OEM lines that give a standard set of behavioral guarantees, even if the underlying hardware mechanisms (secure signing checks, memory layouts, extra steps) are radically different. Almost all, or perhaps all, of this is achieved through the Journal and banking management. If the current structures/interfaces are too restrictive and getting in the way, then let's evolve. If that means a new interpretation of 'ec-slimloader' as just a trait and then some chip-specific impl's of that trait, I think that's fine. What do you see as the lowest friction approach here? From my "500-meter high" view, I'd think the basic bootloading process is 'the same', that is:
2&3 being 'the same' is the useful thing here. That could easily be a small helper function on top of a trait that consumes the journal and hardware instances, which I think isn't too far off from what we have today, but there might be too much coupling here if it adds friction. I'm totally open to restructuring to make our job here easier |
For 1, The embassy dependencies have not been updated in a while. Added gitignore. For 3, The CI build for that branch fails because chip JSON files in NXP-PAC are missing the SGI clock and power gating attributes. I was going to update them but never got the time. Once the SGI PAC is re-generated with the attributes, it will build successfully (does so in local). |
@alamfarjadf do you have a script lying around with which you did this? Or do you have it written down. |
@diondokter Are you interested in the AHAB signed image generation process? Yes, I have a CLI tool that does this. I just gave you access to the private repo with the tool (ahab-mbi-tool). Build it, run the .exe with the Caveats: You need ECDSA keys (public and the corresponding signer) and MLDSA-87 keys. The current MLDSA keys are from TSS' auto-signer CLI tool (which you would need to separately get access to). For signing the image, you can use the tool to sign ECDSA and MLDSA. OR are you simply interested in the signed binaries to flash? On an "un-provisioned" eval. kit, you can flash both binaries (BL and blinky app) in the corresponding flash locations and it should validate and boot (dev mode). To provision the MCU, refer to |
There was a problem hiding this comment.
All the examples should follow the same names. So this example should be called examples/mcxa-577/application and the bootloader should be examples/mcxa-577/bootloader
| embassy-sync = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-mcxa = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0", default-features = false } | ||
| embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0", default-features = false } | ||
| embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
|
|
||
| [patch.crates-io] | ||
| embassy-embedded-hal = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-executor-macros = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-futures = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-hal-internal = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-sync = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-time-driver = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } | ||
| embassy-time-queue-utils = { git = "https://github.com/embassy-rs/embassy", rev = "f21d63db2d104a3b4c070408e529c109a64e65b0" } |
There was a problem hiding this comment.
These should used released versions of embassy (when available, so only mcxa should be a git dep)
| cortex-m = { version = "0.7", features = ["critical-section-single-core"] } | ||
| cortex-m-rt = { version = "0.7", features = ["set-sp", "set-vtor"] } | ||
| defmt = "1.0" | ||
| defmt-rtt = "1.0" | ||
| embassy-mcxa = { workspace = true, features = ["rt", "defmt", "mcxa5xx"] } | ||
| embassy-executor = { workspace = true, features = ["platform-cortex-m", "executor-thread"] } | ||
| embassy-time = { workspace = true, features = ["defmt", "defmt-timestamp-uptime"] } | ||
| panic-probe = { version = "1.0", features = ["print-defmt"] } |
There was a problem hiding this comment.
This needs to be more consistent. Use the workspace or don't.
| } | ||
| } | ||
|
|
||
| pub type BootloaderTree = RomApi; |
| /// Helper function to get a pointer to the flash driver API from the ROM API tree. | ||
| pub fn flash_driver() -> FlashDriver { | ||
| // Match NXP usage: g_bootloaderTree->flashDriver->... | ||
| // The bootloader tree stores a direct pointer to the flash driver interface. | ||
| bootloader_tree().flash_api() | ||
| } |
There was a problem hiding this comment.
Useless helpers (below too). People can call rom_api().flash_api() themselves just fine and that's a lot clearer then what's actually being done
|
@alamfarjadf I realized that the CI broken, so I put up a PR to fix it: #46. |
|
Instead of piling on even more comments here, I've just done the things I want to see and made a PR against this branch here: alamfarjadf#1 It removes almost 2k lines of code |
|
BTW, this should probably get a run through |
|
@alamfarjadf There is a merge conflict, please resolve so CI can run. |
…evicePartnership#46) - Replace the silently passing clippy GH action with direct calls to clippy - Fix all the clippy warnings that came up - Lock down dependencies by checking Cargo.lock into source control and add `--locked` flag to all CI workflows where it is applicable
Merge conflict resolved in check.yml. |
…77-bootloader # Conflicts: # .github/workflows/check.yml
|
@alamfarjadf @gjpmsft @diondokter This PR has gone through a few iterations and has lots of comments. It has become a bit unwieldy. I created a branch: https://github.com/OpenDevicePartnership/ec-slimloader/tree/mcxa-secure-boot. Let's target this PR to that branch. Create issues for all the unresolved comments, and we can work through the issue in that branch. Then we can merge the final product into main. |
|
Yes sounds good |
7926ae3
into
OpenDevicePartnership:mcxa-secure-boot
Adding ROM API support for MCXA 5xx family with Post-Quantum Cryptography hybrid secure boot (ML-DSA-87 and EC-DSA P384).
Added ec-slimloader-mcxa under libs and mcxa-577 examples (bootloader and blinky).
Validated on MCXA577 eval kit with hybrid signed AHAB MBI images which successfully authenticate and boot up.
Not yet added to PR: Imaging tools for MCXA (being worked on as an independent library).
To-dos: