Skip to content

Commit

Permalink
Improved flash image validation (#1916)
Browse files Browse the repository at this point in the history
  • Loading branch information
NotherNgineer committed Feb 18, 2024
1 parent a1f7010 commit cd80da5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 4 deletions.
30 changes: 26 additions & 4 deletions firmware/application/apps/ui_flash_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,27 +28,49 @@ namespace ui {

static const char16_t* firmware_folder = u"/FIRMWARE";

// Firmware image validation
static const char* hackrf_magic = "HACKRFFW";
#define FIRMWARE_INFO_AREA_OFFSET 0x400
#define FIRST_CHECKSUM_NIGHTLY 240125

Thread* FlashUtilityView::thread{nullptr};
static constexpr size_t max_filename_length = 26;

bool valid_firmware_file(std::filesystem::path::string_type path) {
File firmware_file;
bool require_checksum{false};
uint32_t read_buffer[128];
uint32_t checksum{(uint32_t)~FLASH_EXPECTED_CHECKSUM}; // initializing to invalid checksum in case file can't be read
uint32_t checksum{FLASH_CHECKSUM_ERROR}; // initializing to invalid checksum in case file can't be read

static_assert((FIRMWARE_INFO_AREA_OFFSET % sizeof(read_buffer)) == 0, "Read buffer size must divide evenly into FIRMWARE_INFO_AREA_OFFSET");

// test read of the whole file just to validate checksum (baseband flash code will re-read when flashing)
auto result = firmware_file.open(path.c_str());
if (!result.is_valid()) {
checksum = 0;
for (uint32_t i = 0; i < FLASH_ROM_SIZE / sizeof(read_buffer); i++) {
for (uint32_t offset = 0; offset < FLASH_ROM_SIZE; offset += sizeof(read_buffer)) {
auto readResult = firmware_file.read(&read_buffer, sizeof(read_buffer));

// if file is smaller than 1MB, assume it's a downgrade to an old FW version and ignore the checksum
if ((!readResult) || (readResult.value() != sizeof(read_buffer))) {
checksum = FLASH_EXPECTED_CHECKSUM;
// File was smaller than 1MB:
// If version is such that the file SHOULD have been 1MB, call it a checksum error (otherwise say it's OK).
checksum = (require_checksum) ? FLASH_CHECKSUM_ERROR : FLASH_EXPECTED_CHECKSUM;
break;
}

// Did we just read the firmware info area?
if (offset == FIRMWARE_INFO_AREA_OFFSET) {
// If there's no info area (missing HACKRFFW signature), it could be an ancient FW version (so skipping check)
if (memcmp(read_buffer, hackrf_magic, 8) == 0) {
char* version_string = (char*)&read_buffer[4];

// Require a 1MB firmware image with a valid checksum if release version >=v2.x or nightly >n_240125
if (((version_string[0] == 'v') && (std::atoi(&version_string[1]) >= 2)) ||
((version_string[0] == 'n') && (version_string[1] == '_') && (std::atoi(&version_string[2]) >= FIRST_CHECKSUM_NIGHTLY)))
require_checksum = true;
}
}

checksum += simple_checksum((uint32_t)read_buffer, sizeof(read_buffer));
}
}
Expand Down
1 change: 1 addition & 0 deletions firmware/application/apps/ui_flash_utility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define FLASH_ROM_SIZE 1048576
#define FLASH_STARTING_ADDRESS 0x00000000
#define FLASH_EXPECTED_CHECKSUM 0x00000000
#define FLASH_CHECKSUM_ERROR 0xFFFFFFFF

namespace ui {

Expand Down

0 comments on commit cd80da5

Please sign in to comment.