mirror of
https://github.com/status-im/hardwallet-bootloader.git
synced 2025-02-20 02:38:25 +00:00
add code to protect the bootloader and the recovery firmware
This commit is contained in:
parent
977242cf3d
commit
2287acead4
@ -94,9 +94,6 @@
|
||||
</tool>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<fileInfo id="fr.ac6.managedbuild.config.gnu.cross.exe.debug.671366655.1713612907" name="startup_stm32l476xx.s" rcbsApplicability="disable" resourcePath="startup/startup_stm32l476xx.s" toolsToInvoke="fr.ac6.managedbuild.tool.gnu.cross.assembler.1808416181.796708243">
|
||||
<tool id="fr.ac6.managedbuild.tool.gnu.cross.assembler.1808416181.796708243" name="MCU GCC Assembler" superClass="fr.ac6.managedbuild.tool.gnu.cross.assembler.1808416181"/>
|
||||
</fileInfo>
|
||||
<sourceEntries>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="startup"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Drivers"/>
|
||||
@ -145,6 +142,7 @@
|
||||
</option>
|
||||
<option id="gnu.c.compiler.option.preprocessor.def.symbols.2096171234" name="Defined symbols (-D)" superClass="gnu.c.compiler.option.preprocessor.def.symbols" useByScannerDiscovery="false" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="__weak="__attribute__((weak))""/>
|
||||
<listOptionValue builtIn="false" value="-DBOOTLOADER_RELEASE"/>
|
||||
<listOptionValue builtIn="false" value="__packed="__attribute__((__packed__))""/>
|
||||
<listOptionValue builtIn="false" value="STM32L476xx"/>
|
||||
</option>
|
||||
@ -232,4 +230,5 @@
|
||||
<configuration configurationName="Release"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets"/>
|
||||
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
|
||||
</cproject>
|
||||
|
21
Inc/flash.h
21
Inc/flash.h
@ -7,9 +7,19 @@
|
||||
#define FLASH_KEYR1 0x45670123
|
||||
#define FLASH_KEYR2 0xCDEF89AB
|
||||
|
||||
#define FLASH_OPTKEYR1 0x08192A3B
|
||||
#define FLASH_OPTKEYR2 0x4C5D6E7F
|
||||
|
||||
#define FLASH_BANK1 0
|
||||
#define FLASH_BANK2 1
|
||||
|
||||
#define RDP2 0xcc
|
||||
|
||||
#define FLASH_IS_RDP2() ((FLASH->OPTR & 0xff) == RDP2)
|
||||
#define FLASH_SET_RDP2() FLASH->OPTR |= RDP2
|
||||
#define FLASH_WP(reg, start, end) reg = (0xFF00FF00 | end << 16 | start)
|
||||
|
||||
|
||||
/**
|
||||
* Unlocks the flash, allowing writing.
|
||||
*/
|
||||
@ -31,4 +41,15 @@ int flash_copy(uint32_t* src, __IO uint32_t* dst, uint32_t size);
|
||||
*/
|
||||
int flash_lock();
|
||||
|
||||
/**
|
||||
* Unlock the option bytes
|
||||
*/
|
||||
int flash_optunlock();
|
||||
|
||||
/**
|
||||
* Write and reload the option bytes
|
||||
*/
|
||||
void flash_optprogram();
|
||||
|
||||
|
||||
#endif /* FLASH_H_ */
|
||||
|
11
Inc/main.h
11
Inc/main.h
@ -8,9 +8,12 @@
|
||||
|
||||
// The constants below define the memory layout documented in the README.md file
|
||||
#define BOOTLOADER_SIZE 0x2000
|
||||
#define BOOTLOADER_FIRST_PAGE 0
|
||||
#define BOOTLOADER_LAST_PAGE ((BOOTLOADER_SIZE / FLASH_PAGE_SIZE) - 1)
|
||||
|
||||
#define FIRMWARE_SIZE ((FLASH_BANK_SIZE - BOOTLOADER_SIZE) / 2)
|
||||
#define FIRMWARE_HEADER_SIZE 0x200
|
||||
#define FIRMWARE_FIRST_PAGE (BOOTLOADER_SIZE / FLASH_PAGE_SIZE)
|
||||
#define FIRMWARE_FIRST_PAGE (BOOTLOADER_LAST_PAGE + 1)
|
||||
#define FIRMWARE_PAGE_COUNT (FIRMWARE_SIZE / FLASH_PAGE_SIZE)
|
||||
|
||||
#define FIRMWARE_START (FLASH_START_BANK1 + BOOTLOADER_SIZE)
|
||||
@ -21,6 +24,8 @@
|
||||
|
||||
#define RECOVERY_FW_START (FIRMWARE_START + FIRMWARE_SIZE)
|
||||
#define RECOVERY_FW_FIRST_PAGE (FIRMWARE_FIRST_PAGE + FIRMWARE_PAGE_COUNT)
|
||||
#define RECOVERY_FW_LAST_PAGE (RECOVERY_FW_FIRST_PAGE + FIRMWARE_PAGE_COUNT - 1)
|
||||
|
||||
|
||||
#define SIGNATURE_HEADER_OFFSET 8
|
||||
#define SIGNATURE_LENGTH 64
|
||||
@ -28,6 +33,10 @@
|
||||
#define SIGNATURE_COUNT 1
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the bootloader and recovery are write protected, if not protect them. Also enables the Read Protection level 2. Since this is irreversible, the code is disabled during development
|
||||
*/
|
||||
void protect_flash();
|
||||
|
||||
/**
|
||||
* Checks the firmware a the given address. It checks the magic number, validates the size and checks the signature(s).
|
||||
|
15
Src/flash.c
15
Src/flash.c
@ -18,6 +18,15 @@ int flash_unlock() {
|
||||
return READ_BIT(FLASH->CR, FLASH_CR_LOCK);
|
||||
}
|
||||
|
||||
int flash_optunlock() {
|
||||
flash_unlock();
|
||||
|
||||
FLASH->OPTKEYR = FLASH_OPTKEYR1;
|
||||
FLASH->OPTKEYR = FLASH_OPTKEYR2;
|
||||
|
||||
return READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK);
|
||||
}
|
||||
|
||||
int _flash_erase_page(uint8_t bank, uint8_t pg) {
|
||||
if(bank == FLASH_BANK1) {
|
||||
CLEAR_BIT(FLASH->CR, FLASH_CR_BKER);
|
||||
@ -77,3 +86,9 @@ int flash_lock() {
|
||||
SET_BIT(FLASH->CR, FLASH_CR_LOCK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void flash_optprogram() {
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT);
|
||||
_flash_wait();
|
||||
SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH);
|
||||
}
|
||||
|
19
Src/main.c
19
Src/main.c
@ -6,6 +6,8 @@
|
||||
uint8_t fw_public_key[] = { 0xfe, 0xcb, 0x28, 0xb9, 0x50, 0xdd, 0x8b, 0x2f, 0xc7, 0x34, 0xd3, 0x60, 0x5b, 0x1a, 0xc6, 0xed, 0x02, 0x50, 0xf2, 0x4a, 0xc4, 0x75, 0xd1, 0x28, 0x7f, 0x7c, 0xb5, 0xce, 0x61, 0xd6, 0x95, 0xb9, 0xb5, 0x27, 0x0b, 0x52, 0x77, 0x42, 0x4b, 0xf3, 0xb4, 0x3c, 0xef, 0xcb, 0x56, 0xd1, 0x98, 0x22, 0x11, 0xc2, 0xe5, 0xd3, 0xf0, 0x22, 0x87, 0xb9, 0xe8, 0x20, 0xdc, 0xee, 0x9f, 0xc2, 0xad, 0x22, };
|
||||
|
||||
int main(void) {
|
||||
protect_flash();
|
||||
|
||||
if (!check_firmware(UPGRADE_FW_START)) {
|
||||
upgrade_firmware();
|
||||
} else if (check_firmware(FIRMWARE_START)) {
|
||||
@ -43,6 +45,23 @@ int check_firmware(uintptr_t addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void protect_flash() {
|
||||
#ifdef BOOTLOADER_RELEASE
|
||||
if (FLASH_IS_RDP2()) {
|
||||
return;
|
||||
}
|
||||
|
||||
flash_optunlock();
|
||||
|
||||
FLASH_SET_RDP2();
|
||||
FLASH_WP(FLASH->WRP1AR, BOOTLOADER_FIRST_PAGE, BOOTLOADER_LAST_PAGE);
|
||||
FLASH_WP(FLASH->WRP1BR, RECOVERY_FW_FIRST_PAGE, RECOVERY_FW_LAST_PAGE);
|
||||
|
||||
// This resets the MCU
|
||||
flash_optprogram();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void _load_firmware(uintptr_t newfw, uint8_t newfw_bank, uint8_t newfw_page, uint8_t remove_newfw) {
|
||||
flash_unlock();
|
||||
|
Loading…
x
Reference in New Issue
Block a user