-
Notifications
You must be signed in to change notification settings - Fork 2k
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
sys/riotboot: add digest to header #17938
base: master
Are you sure you want to change the base?
Conversation
bb8362a
to
87963cb
Compare
3623df9
to
2fed5fa
Compare
@benpicco @kaspar030 I split some of the commits but did as suggested keeping a |
2fed5fa
to
7fb264f
Compare
No. There are also no 'gaps' between members, so no arch dependent padding will be inserted - you could use |
7fb264f
to
3a93045
Compare
LGTM. |
The failure is unrelated, but will wait for ACK before re-building @kaspar030 @benpicco |
3a93045
to
3da7e0c
Compare
3da7e0c
to
72258f9
Compare
I don't have much time to test this currently, but did you try updating a board with an old riotboot and firmware with an image that uses the new format? |
Flash current riotboot master:
Flash new applications (new headers), both slots boot correctly.
Flash new riotboot, application still boots:
Flash application with old headers, invalidates the slot (switches back to slot0), flashing the other slot results in no application booting, as epected.
Fash old bootloader again:
|
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.
Spotted a couple of nitpicks, I'll address when the CI is a bit more idle.
This increases the riotboot header size by 36 bytes, but this does not change firmware size since the header is already 256 aligned. An additional 4bytes are also added to keep a checksum_legacy field at the same position as the previous checksum to be compatible with previous riotboot_hdr versions.
388c338
to
f47ce92
Compare
@@ -52,6 +57,9 @@ typedef struct { | |||
uint32_t magic_number; /**< Header magic number (always "RIOT") */ | |||
uint32_t version; /**< Integer representing the partition version */ | |||
uint32_t start_addr; /**< Address after the allocated space for the header */ | |||
uint32_t chksum_legacy; /**< Checksum of riotboot_hdr digest excluded */ | |||
uint32_t img_size; /**< Firmware 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.
I was thinking about how we can avoid the chksum_legacy
situation in the future, how about
uint32_t img_size; /**< Firmware size */ | |
uint32_t img_size; /**< Firmware size */ | |
uint16_t header_len; /**< Size of the riotboot header, excluding the checksum */ | |
uint16_t flags; |
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.
What's the idea behind flags
?
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.
There will be two padding bytes anyway, might as well put them to some use
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'd use packed structs or call it reserved
or padding
with a comment why it's there. Or do we already have flags?
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.
If there is not use yet, I think reserver
makes sense, changing the name later would be free. The idea would be to use the header_len
field to known what to checksum?
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.
The idea would be to use the
header_len
field to known what to checksum?
Yes that's the idea
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.
Something to consider though if the hdr_len field is modified, it could eventually calculate the checksum upon random memory regions
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.
The same goes for img_size
. The implementation checking the image has to check if bounds aren't exceeded.
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.
Please squash!
I'm not squashing yet because #17938 (comment) makes me think that |
I added a check on the image area to verify, but I have second thoughts regarding this
|
Since The bootloader currently does not verify |
Hmm true
Do you think we need to worry about wrong header length and eventually checksumming invalid regions? This is my main concern, read to non accessible regions. |
Hm would it help to limit the header length to 256 bytes / uint8? |
Contribution description
This PR adds the firmware digest to the
riotboot_hdr
. Ifriotboot_slot_verify_sha256
is included thenriotboot_slot_validate
will also verify the digest.This increases the riotboot header size by 36 bytes, but this does not change firmware size since the header is already 256 aligned.
Enabling this feature will prevent booting into a corrupted firmware, and can be also used at runtime to check the state of the running firmware (something useful for example for firmware deployed in space, e.g. ThingSat)
This PR is somewhat of an API change, since it changes the location of the checksum. I could also change the location of the extra field to be after the
checksum
, and modifyriotboot_hdr_checksum
accordingly.Testing procedure
tests/riotboot
passes with or without,riotboot_slot_verify_slot