-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lpc55-rot-startup: Use a better method to generate an FWID. #1500
Conversation
This can be tested in a few different ways if folks want to reproduce. The easiest is to (assuming we're using imagea on an RoT)
|
|
||
for start in IMAGE_FLASH.step_by(FLASH_PAGE_SIZE) { | ||
let start: u32 = start.try_into().unwrap_lite(); | ||
if lpc55_romapi::validate_programmed(start, PAGE_SIZE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this handle partially programmed pages correctly? I need to go review exactly how this would work on trailing pages (aside, I should sit down and finally rip out usage of this ROM API and just use the flash driver)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ROM API rip / replace: #1431
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this handle partially programmed pages correctly?
I think so, assuming my reading of UM11126 § 8.6.7 is correct. This implementation includes the 0xff
trailing data added by the write
command in the FWID hash.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran the tests you suggested and was able to get a reliable answer. Even longer term we might just want to write to the entire image length space.
lib/lpc55-rot-startup/src/images.rs
Outdated
pub fn get_fwid(&self) -> [u8; 32] { | ||
let mut hash = Sha3_256::new(); | ||
|
||
for start in IMAGE_FLASH.step_by(FLASH_PAGE_SIZE) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay while testing I realize this doesn't actually work. We need to be able to get the base of the other image, otherwise they both end up with the same hash:
$ humility -a target/rot-carrier/dist/a/build-rot-carrier-image-a.zip hiffy --call Update.rot_boot_info
humility: attached via CMSIS-DAP
Update.rot_boot_info() => RotBootInfo { active: A, persistent_boot_preference: A, pending_persistent_boot_preference: None, transient_boot_preference: None, slot_a_sha3_256_digest: Some([ 0x9d, 0xce, 0xc5, 0x7e, 0x78, 0xb8, 0x74, 0xb0, 0xc8, 0x78, 0x71, 0x7e, 0xf1, 0x58, 0x8b, 0x53, 0x88, 0xea, 0xc, 0x7, 0xb6, 0x23, 0x3, 0x69, 0x3b, 0x8f, 0xd4, 0xd8, 0x1d, 0x10, 0x8f, 0x1 ]), slot_b_sha3_256_digest: Some([ 0x9d, 0xce, 0xc5, 0x7e, 0x78, 0xb8, 0x74, 0xb0, 0xc8, 0x78, 0x71, 0x7e, 0xf1, 0x58, 0x8b, 0x53, 0x88, 0xea, 0xc, 0x7, 0xb6, 0x23, 0x3, 0x69, 0x3b, 0x8f, 0xd4, 0xd8, 0x1d, 0x10, 0x8f, 0x1 ]) }
I'll give this a think if there's another option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see what you mean. This doesn't become apparent until you've flashed the 'b' image before pulling the rot_boot_info
:
(hubris) [flihp@slag hubris]$ humility --target rot-carrier --archive-name imagea -- hiffy --call Update.rot_boot_info
humility: attached to 1fc9:0143:IYJ1NYJRCW2TC via CMSIS-DAP
Update.rot_boot_info() => RotBootInfo { active: B, persistent_boot_preference: A, pending_persistent_boot_preference: None, transient_boot_preference: None, slot_a_sha3_256_digest: Some([ 0x3d, 0x4d, 0x34, 0x69, 0x37, 0x24, 0x8b, 0xef, 0x93, 0xd7, 0x18, 0xd1, 0x25, 0xf3, 0xe0, 0xab, 0x15, 0xbc, 0x15, 0x98, 0x33, 0xaa, 0x46, 0x67, 0x91, 0xa4, 0x26, 0x53, 0xde, 0x53, 0x10, 0x41 ]), slot_b_sha3_256_digest: Some([ 0x3d, 0x4d, 0x34, 0x69, 0x37, 0x24, 0x8b, 0xef, 0x93, 0xd7, 0x18, 0xd1, 0x25, 0xf3, 0xe0, 0xab, 0x15, 0xbc, 0x15, 0x98, 0x33, 0xaa, 0x46, 0x67, 0x91, 0xa4, 0x26, 0x53, 0xde, 0x53, 0x10, 0x41 ]) }
It's pretty much impossible for the two images to have the same hash (and still be functional) so this is definitely wrong. I'll sort out some options and update the PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just pushed two commits with a new approach. Instead of exporting the range for the image being built we now export all flash ranges for the chip from xtask through the environment. This allows us to use the appropriate range for A or B images. This also duplicates data in the HUBRIS_DICE_MFG
env var so I've included another commit removing it.
Those recent changes went in after this PR was opened. I'll definitely rebase before merging but didn't want to do so while folks were actively reviewing. |
Ah that PR hasn't been merged yet. Either way there will be rebasing. |
296f6ad
to
576c06a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good solution!
I'm rebasing to clean up history from this review & will merge once those changes pass CI. |
dc62478
to
22b3557
Compare
The current implementation captures all of the RoT software. It does not however include other pages in the RoT image flash range. Expanding our definition for the RoT FWID as not only the expected image, but also any other programmed flash pages in the range of possible pages mitigates a potential persistence mechanism for an attacker. This commit: - adds a new environment variable HUBRIS_FLASH_OUTPUT that holds all config::Output structures for the flash regions assigned to the image being built - generates a Range for each flash region in HUBRIS_FLASH_OUTPUTS for use by the lpc55-rot-startup crate - uses the A & B Ranges to walk through all possible flash pages for the given image including each page that's been programmed in the FWID
HUBRIS_DICE_MFG is no longer needed.
The current implementation captures all of the RoT software. It does not however include other pages in the RoT image flash range. Expanding our definition for the RoT FWID as not only the expected image, but also any other programmed flash pages in the range of possible pages mitigates a potential persistence mechanism for an attacker.
This commit: