mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-22 14:28:07 +00:00
feat(core/bootloader): check firmware padding
This commit is contained in:
parent
da7125f427
commit
02f34a2748
@ -243,35 +243,60 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip,
|
|||||||
return secfalse;
|
return secfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
int remaining = hdr->codelen;
|
// Check the firmware integrity, calculate and compare hashes
|
||||||
|
size_t offset = firstskip;
|
||||||
|
size_t end_offset = offset + hdr->codelen;
|
||||||
|
|
||||||
const void *data = flash_area_get_address(
|
while (offset < end_offset) {
|
||||||
area, firstskip, MIN(remaining, IMAGE_CHUNK_SIZE - firstskip));
|
size_t bytes_to_check = MIN(IMAGE_CHUNK_SIZE - (offset % IMAGE_CHUNK_SIZE),
|
||||||
|
end_offset - offset);
|
||||||
|
|
||||||
|
const void *data = flash_area_get_address(area, offset, bytes_to_check);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return secfalse;
|
return secfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t hash_offset = (offset / IMAGE_CHUNK_SIZE) * 32;
|
||||||
if (sectrue !=
|
if (sectrue !=
|
||||||
check_single_hash(hdr->hashes, data,
|
check_single_hash(hdr->hashes + hash_offset, data, bytes_to_check)) {
|
||||||
MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) {
|
|
||||||
return secfalse;
|
return secfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
remaining -= IMAGE_CHUNK_SIZE - firstskip;
|
offset += bytes_to_check;
|
||||||
|
}
|
||||||
|
|
||||||
int chunk = 1;
|
// Check the padding to the end of the area
|
||||||
|
end_offset = flash_area_get_size(area);
|
||||||
|
|
||||||
while (remaining > 0) {
|
if (offset < end_offset) {
|
||||||
data = flash_area_get_address(area, chunk * IMAGE_CHUNK_SIZE,
|
// Use the first byte in the checked area as the expected padding byte
|
||||||
MIN(remaining, IMAGE_CHUNK_SIZE));
|
// Firmware is always padded with 0xFF, while the bootloader might be
|
||||||
|
// padded with 0x00 as well
|
||||||
|
uint8_t expected_byte = *(
|
||||||
|
(const uint8_t *)flash_area_get_address(area, offset, sizeof(uint8_t)));
|
||||||
|
|
||||||
|
if (expected_byte != 0x00 && expected_byte != 0xFF) {
|
||||||
|
return secfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (offset < end_offset) {
|
||||||
|
size_t bytes_to_check = MIN(
|
||||||
|
IMAGE_CHUNK_SIZE - (offset % IMAGE_CHUNK_SIZE), end_offset - offset);
|
||||||
|
|
||||||
|
const uint8_t *data =
|
||||||
|
(const uint8_t *)flash_area_get_address(area, offset, bytes_to_check);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
return secfalse;
|
return secfalse;
|
||||||
}
|
}
|
||||||
if (sectrue != check_single_hash(hdr->hashes + chunk * 32, data,
|
|
||||||
MIN(remaining, IMAGE_CHUNK_SIZE))) {
|
for (size_t i = 0; i < bytes_to_check; i++) {
|
||||||
|
if (data[i] != expected_byte) {
|
||||||
return secfalse;
|
return secfalse;
|
||||||
}
|
}
|
||||||
chunk++;
|
}
|
||||||
remaining -= IMAGE_CHUNK_SIZE;
|
|
||||||
|
offset += bytes_to_check;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sectrue;
|
return sectrue;
|
||||||
|
Loading…
Reference in New Issue
Block a user