feat(core/bootloader): check firmware padding

pull/3363/head
cepetr 7 months ago committed by matejcik
parent da7125f427
commit 02f34a2748

@ -243,35 +243,60 @@ secbool check_image_contents(const image_header *const hdr, uint32_t firstskip,
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(
area, firstskip, MIN(remaining, IMAGE_CHUNK_SIZE - firstskip));
if (!data) {
return secfalse;
}
if (sectrue !=
check_single_hash(hdr->hashes, data,
MIN(remaining, IMAGE_CHUNK_SIZE - firstskip))) {
return secfalse;
while (offset < end_offset) {
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) {
return secfalse;
}
size_t hash_offset = (offset / IMAGE_CHUNK_SIZE) * 32;
if (sectrue !=
check_single_hash(hdr->hashes + hash_offset, data, bytes_to_check)) {
return secfalse;
}
offset += bytes_to_check;
}
remaining -= IMAGE_CHUNK_SIZE - firstskip;
// Check the padding to the end of the area
end_offset = flash_area_get_size(area);
int chunk = 1;
if (offset < end_offset) {
// Use the first byte in the checked area as the expected padding byte
// 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)));
while (remaining > 0) {
data = flash_area_get_address(area, chunk * IMAGE_CHUNK_SIZE,
MIN(remaining, IMAGE_CHUNK_SIZE));
if (!data) {
if (expected_byte != 0x00 && expected_byte != 0xFF) {
return secfalse;
}
if (sectrue != check_single_hash(hdr->hashes + chunk * 32, data,
MIN(remaining, IMAGE_CHUNK_SIZE))) {
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) {
return secfalse;
}
for (size_t i = 0; i < bytes_to_check; i++) {
if (data[i] != expected_byte) {
return secfalse;
}
}
offset += bytes_to_check;
}
chunk++;
remaining -= IMAGE_CHUNK_SIZE;
}
return sectrue;

Loading…
Cancel
Save