How to Secure Your Bootloader: Image Verification, Signature Authentication, and Memory Protection
This article explains essential bootloader security mechanisms—including image integrity checks, digital signature verification, hardware/software memory protection, and the use of read‑only storage—while highlighting practical implementation tips for STM32 and the trade‑offs between security and system complexity.
Image Verification
Bootloader should compute a checksum or hash of the firmware image stored in external flash before executing it. Options include:
Simple checksum : sum of all bytes modulo 2^32; easy to implement but vulnerable to intentional modifications.
CRC : 32‑bit CRC (e.g., polynomial 0x04C11DB7). STM32 provides a dedicated CRC peripheral that can be enabled by writing to the CRC control register; the peripheral processes 32‑bit words at up to 72 MHz, giving fast verification. If the device lacks the CRC unit, a software routine can be used; typical implementation iterates over the image buffer and updates the CRC register in software.
Cryptographic hash : SHA‑256 or SHA‑1. Requires a cryptographic library (e.g., mbed TLS) and more CPU cycles, but provides stronger collision resistance.
Typical flow:
// Pseudocode
uint32_t crc = HAL_CRC_Calculate(&hcrc, (uint32_t*)image_addr, image_len/4);
if (crc != stored_crc) {
abort_boot();
}If verification fails, the bootloader must refuse to load the image and optionally signal an error via LED or UART.
Signature Authentication
To guarantee both integrity and authenticity, the firmware image is signed with the developer’s private key. The bootloader stores the corresponding public key (e.g., an RSA‑2048 or ECDSA‑P‑256 key) in read‑only memory.
Signing process:
Compute a hash of the binary (e.g., SHA‑256).
Encrypt the hash with the private key → signature.
Append the signature (and optionally the hash) to the image flash layout.
Verification process in the bootloader:
// Pseudocode using mbed TLS
int verify_image(const uint8_t *img, size_t img_len,
const uint8_t *sig, size_t sig_len) {
mbedtls_sha256_context ctx;
uint8_t hash[32];
mbedtls_sha256_init(&ctx);
mbedtls_sha256_starts_ret(&ctx, 0);
mbedtls_sha256_update_ret(&ctx, img, img_len);
mbedtls_sha256_finish_ret(&ctx, hash);
return mbedtls_pk_verify(&pk, MBEDTLS_MD_SHA256,
hash, 0, sig, sig_len);
}Key management notes:
Private key never resides on the device; it is used only on the host that produces the firmware.
Public key must be programmed into a protected flash region or OTP memory to prevent tampering.
If the signature verification fails, the bootloader aborts the boot and may fall back to a recovery image.
Memory Protection
Preventing the application from overwriting the bootloader or other critical regions can be achieved with:
Hardware MPU (Memory Protection Unit) on Cortex‑M cores: define regions (e.g., bootloader region, vector table, peripheral registers) with read‑only or no‑execute attributes. Example configuration for STM32F4:
// Example MPU region for bootloader (0x08000000‑0x08007FFF)
MPU_Region_InitTypeDef MPU_InitStruct = {0};
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x08000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
MPU_InitStruct.AccessPermission = MPU_REGION_PRIV_RO_URO; // read‑only
MPU_InitStruct.IsExecutable = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);Software checks : before writing to flash, the bootloader validates the target address against a whitelist. This adds overhead and can be bypassed if the application runs with privileged access.
When an MMU is present (e.g., on Cortex‑A Linux boards), page tables can be set to make the bootloader pages read‑only and non‑executable.
Read‑Only Storage
Placing the bootloader in a non‑volatile, read‑only region (e.g., internal Flash locked with option bytes, OTP memory, or external ROM) ensures that the code cannot be altered after production. On STM32, the flash write‑protect bits can be set so that the bootloader sector is immutable unless a full mass erase is performed under a secure mode.
Design Trade‑offs
Security mechanisms increase flash usage, RAM consumption, and boot time. Designers should evaluate:
Resource constraints (CPU speed, RAM, flash size).
Threat model (physical access vs remote attacks).
Recovery strategy (fallback image, UART bootloader mode).
Balancing these factors yields a bootloader that protects the device without imposing unnecessary overhead.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Liangxu Linux
Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
