Skip to content
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

Update RoT bootloader, a.k.a. stage0 #1675

Merged
merged 3 commits into from
Apr 30, 2024
Merged

Update RoT bootloader, a.k.a. stage0 #1675

merged 3 commits into from
Apr 30, 2024

Conversation

lzrd
Copy link
Contributor

@lzrd lzrd commented Mar 21, 2024

This PR has four commits to simplify reviewing.

  • The first is Laura's macro to manipulate the HASHCRYPT interrupt vector.
  • 2nd is pre-main kernel changes to create a staging area for Bootleby update and to validate the (now) four RoT flash banks and record those results for use by update_server.
  • 3rd are the API changes to support stage0 update including treating the bootloader as a separate component with A (active) and B (stage0next) banks.
  • last is the code in the RoT update_server to actually update stage0

Before merging this PR, Cargo.toml needs to be edited to reference the gateway-message-service main branch.
Merging needs to be coordinated with an MGS merge.

Closes #1043, #1404, #1548, #1353,

@lzrd
Copy link
Contributor Author

lzrd commented Mar 21, 2024

See https://github.com/oxidecomputer/sprot-e2e for test scripts

Cargo.toml Outdated Show resolved Hide resolved
Copy link
Member

@hawkw hawkw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not very familiar with the details of the LPC55 platform, so my review focuses more or less exclusively on the implementation. I've mostly left some code style suggestions, which you're welcome to ignore --- I hope they're helpful.

drv/lpc55-sprot-server/src/handler.rs Outdated Show resolved Hide resolved
lib/lpc55-hashcrypt/src/lib.rs Outdated Show resolved Hide resolved
lib/lpc55-hashcrypt/src/lib.rs Outdated Show resolved Hide resolved
lib/stage0-handoff/src/rot_update_details.rs Show resolved Hide resolved
lib/stage0-handoff/src/rot_update_details.rs Outdated Show resolved Hide resolved
drv/lpc55-update-server/src/main.rs Outdated Show resolved Hide resolved
drv/lpc55-update-server/src/main.rs Outdated Show resolved Hide resolved
drv/lpc55-update-server/src/main.rs Outdated Show resolved Hide resolved
drv/lpc55-update-server/src/main.rs Outdated Show resolved Hide resolved
drv/lpc55-update-server/src/main.rs Outdated Show resolved Hide resolved
@lzrd lzrd marked this pull request as ready for review March 26, 2024 23:28
drv/ksz8463/Cargo.toml Outdated Show resolved Hide resolved
drv/vsc-err/Cargo.toml Outdated Show resolved Hide resolved
app/donglet/app-g031-i2c.toml Outdated Show resolved Hide resolved
drv/lpc55-update-api/src/lib.rs Outdated Show resolved Hide resolved
drv/lpc55-update-api/src/lib.rs Outdated Show resolved Hide resolved
drv/lpc55-update-server/src/images.rs Show resolved Hide resolved
drv/sprot-api/src/lib.rs Outdated Show resolved Hide resolved
lib/lpc55-hashcrypt/src/lib.rs Outdated Show resolved Hide resolved
lib/lpc55-hashcrypt/src/lib.rs Outdated Show resolved Hide resolved
lib/lpc55-rot-startup/src/images.rs Outdated Show resolved Hide resolved
lzrd added a commit that referenced this pull request Mar 29, 2024
#1692)

…toml so that they will link.

oxcon2023g0 still fails

These changes were extraneous in #1675 and are being factored out to
here.
drv/lpc55-update-server/src/main.rs Show resolved Hide resolved
drv/lpc55-update-server/src/main.rs Outdated Show resolved Hide resolved
drv/lpc55-update-server/src/main.rs Outdated Show resolved Hide resolved
drv/lpc55-update-server/src/main.rs Outdated Show resolved Hide resolved
lib/lpc55-hashcrypt/src/lib.rs Outdated Show resolved Hide resolved
lib/lpc55-rot-startup/src/lib.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@aapoalas aapoalas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Random questions, please excuse my curiosity.

drv/lpc55-update-api/src/lib.rs Outdated Show resolved Hide resolved
// NXP LPC55's mixed header/vector table offsets
const RESET_VECTOR_OFFSET: usize = 0x04;
pub const LENGTH_OFFSET: usize = 0x20;
pub const HEADER_OFFSET: u32 = 0x130;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: This is used in the main file for len >= HEADER_OFFSET but around it len as usize is used, suggesting that len as usize >= HEADER_OFFSET would be okay as well. Would it then make more sense to just use usize for memory offsets?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be using ImageVectorsLpc55 which should be pulled out and made more available.

@labbott
Copy link
Collaborator

labbott commented Apr 17, 2024

LGTM! I'll give the final approval once the MGS portion is merged

@lzrd lzrd force-pushed the update-stage0 branch 6 times, most recently from e746839 to 549564a Compare April 23, 2024 23:46
Split the RoT bootloader flash slot into stage0 and stage0next.
Always calculate the firmware measurement even if there is no valid image.
Add Stage0 and Stage0Next boot-time information to RotBootInfo.

lib/lpc55-rot-startup/src/{lib,images}.rs:
Refactored startup code to distinguish between a flash slot that is always measured
and the image it contains being valid or not.

Update the Update APIs and messages to accommodate update of the RoT's bootloader
while maintaining backward compatibility for Hubris updates.

An older control plane should be able to use its known update APIs
to bring a newer RoT or SP Hubris image back into conformance (roll-back).

Use conversion functions to isolate SP to MGS data structure conversion code.

Treat the boot loader as a separate component located in the RoT.
Add Stage0 and Stage0Next boot-time information to RotBootInfo.
Add Stage0 and Stage0Next to update-api.
lpc55-update-server: moving image format and location knowledge to images.rs

Add a versioned rot boot info request so that an older control plane can
upgrade/rollback newer images.
The existing rot_state and rot_boot_info need to remain stable for roll forward
and roll back to work when RoT version is newer than SP version.

Add Component* versions of APIs to allow selection of boot loader component.
Use Fwid type to represent the SHA3_256 digest in case we change digest algo someday.
Fwid includes padding bytes and any subsequent programmed pages in a flash slot,
so don't just call it a digest which can be misleading to people who might expect that
a hash of the bytes of an image would match the RoT report.

Old messages are still supported, e.g.:

$ faux-mgs ... --log-level=CRITICAL state
hubris archive: 8be7b8a5ebfc9313
serial number:
model:
revision: 0
base MAC address: 0e:1d:62:cd:cc:62
power state: A2
RotStateV2 {
 active: A,
 persistent_boot_preference: A,
 pending_persistent_boot_preference: None,
 transient_boot_preference: None
 slot_a_sha3_256_digest: 004fec2b8f77c091384b6c506230f18f24fc1db6c4de91a18e01ac3a244f015d,
 slot_b_sha3_256_digest: 6161bfd3b013e18fd45b539a5ddc9faafe2f3a43882832e49db3dffe58c36eb5,
}

New messages provide information needed to drive bootloader updates (see rot-boot-info below).
Image status has a more descriptive error code enum.

$ faux-mgs ... --log-level=CRITICAL rot-boot-info
RotBootInfo {V3(RotStateV3 {
 active: A,
 persistent_boot_preference: A,
 pending_persistent_boot_preference: None,
 transient_boot_preference: None
 slot_a_fwid: Sha3_256( 004fec2b8f77c091384b6c506230f18f24fc1db6c4de91a18e01ac3a244f015d ),
 slot_b_fwid: Sha3_256( 6161bfd3b013e18fd45b539a5ddc9faafe2f3a43882832e49db3dffe58c36eb5 ),
 stage0_fwid: Sha3_256( 62ebe27addfd99e6f6e2ba75302bbb96f8a2d4b2d01b270cbff2ee4e4a2c1280 ),
 stage0next_fwid: Sha3_256( 62ebe27addfd99e6f6e2ba75302bbb96f8a2d4b2d01b270cbff2ee4e4a2c1280 ),
slot_a_status: Ok(()),
slot_b_status: Ok(()),
stage0_status: Ok(()),
stage0next_status: Ok(()),
})}

The `stage0next` contents is not copied to `stage0` unless its current hash matches
the hash of a valid signed image found at boot time.

Stage0 cache size is 8192 to accommodate previous 6000+ byte bootloaders.
That can be reduced when rollback protection is implemented and old bootloaders
are expunged from any spares and systems in use.

Remove #[derive(Debug) statements whose deletion does not cause compile errors.
@lzrd lzrd requested a review from labbott April 30, 2024 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Update RoT memory map to reserve RAM for updates
5 participants