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

calculate image hash including padding between header and code #4521

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

TychoVrahe
Copy link
Contributor

@TychoVrahe TychoVrahe commented Jan 20, 2025

This PR alters the way image hashes are calculated.

Padding between headers and code is now included into hashed area.

In practice, this affects only U5G models, as image and vendor headers are aligned to 512B and such is also is the code alignment on F4 and U585.

T3W1, even though running on U5G, both its image headers and vendor headers are aligned to 1024B, by coincidence, so existing boardloaders and bootloaders should continue to work.

Therefore, only D002 will break and needs reflashing of board+bootloader to work.

Thanks to this change, code alignment can be omitted from trezorctl.

@TychoVrahe TychoVrahe self-assigned this Jan 20, 2025
Copy link

github-actions bot commented Jan 20, 2025

core UI changes device test click test persistence test
T2T1 Model T test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
T3B1 Safe 3 test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
T3T1 Safe 5 test(screens) main(screens) test(screens) main(screens) test(screens) main(screens)
All main(screens)

@TychoVrahe TychoVrahe marked this pull request as ready for review January 21, 2025 07:56
@TychoVrahe TychoVrahe requested review from cepetr and removed request for prusnak January 21, 2025 07:56
@matejcik
Copy link
Contributor

why doesn't the same change apply to bootloader image?
(doesn't that break trezorlib parsing of bootloader btw?)

@TychoVrahe
Copy link
Contributor Author

it does apply to bootloader, in trezorlib bootloader uses FirmwareImage struct too, and on embedded side bootloader linker script is modified, along with image content check

Comment on lines 186 to 196
const uint32_t headers_end_offset = hdr->hdrlen;
const uint32_t code_start_offset = IMAGE_CODE_ALIGN(headers_end_offset);
const uint32_t padding_end = IMAGE_CODE_ALIGN(headers_end_offset);

for (uint32_t i = headers_end_offset; i < code_start_offset; i++) {
for (uint32_t i = headers_end_offset; i < padding_end; i++) {
if (((uint8_t *)sdcard_buf)[i] != 0) {
return 0;
}
}

const uint32_t code_start_offset = IMAGE_CODE_ALIGN(headers_end_offset);

Copy link
Contributor

Choose a reason for hiding this comment

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

if that's the case, i don't understand this change.

it seems to me that you're (a) still checking explicitly for zero value padding (that's fine i guess) but also check_single_hash(..., code_start_offset) which is IMAGE_CODE_ALIGN(headers_end_offset)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah that is a bug 40bcbd8

Copy link
Contributor

@matejcik matejcik left a comment

Choose a reason for hiding this comment

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

looked briefly at the C code and it seems ok but I'll leave the main review to @cepetr

note: any reason to keep the padding-is-zero check? it seems that we don't have to now (contents are signed) and it may bite us later (e.g., if we want to fill empty spaces with random data, we may not be able to)

@@ -264,7 +264,6 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip,

// Check the firmware integrity, calculate and compare hashes
size_t offset = IMAGE_CODE_ALIGN(firstskip);
Copy link
Contributor

Choose a reason for hiding this comment

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

this should probably be const size_t something_else = ... ...

@@ -276,6 +275,11 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip,
}
}

// check hashes of image chunks
// we hash the image including the padding to the end of the area
offset = firstskip;
Copy link
Contributor

Choose a reason for hiding this comment

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

...and this should be size_t offset, otherwise it's rather confusing why the same variable is redefined this way

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 🔎 Needs review
Development

Successfully merging this pull request may close these issues.

2 participants