mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-27 00:28:10 +00:00
update bootloader to 1.4.0 via firmware, run unsigned firmware in unprivileged mode
This commit is contained in:
parent
d6f41dba9e
commit
9588e8f273
@ -78,12 +78,10 @@ void show_unofficial_warning(const uint8_t *hash)
|
|||||||
|
|
||||||
void __attribute__((noreturn)) load_app(int signed_firmware)
|
void __attribute__((noreturn)) load_app(int signed_firmware)
|
||||||
{
|
{
|
||||||
(void)signed_firmware;
|
|
||||||
|
|
||||||
// zero out SRAM
|
// zero out SRAM
|
||||||
memset_reg(_ram_start, _ram_end, 0);
|
memset_reg(_ram_start, _ram_end, 0);
|
||||||
|
|
||||||
load_vector_table((const vector_table_t *) FLASH_APP_START);
|
jump_to_firmware((const vector_table_t *) FLASH_APP_START, signed_firmware);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool firmware_present(void)
|
bool firmware_present(void)
|
||||||
|
2
firmware/.gitignore
vendored
2
firmware/.gitignore
vendored
@ -2,3 +2,5 @@ coins_array.h
|
|||||||
coins_count.h
|
coins_count.h
|
||||||
|
|
||||||
nem_mosaics.[ch]
|
nem_mosaics.[ch]
|
||||||
|
|
||||||
|
bl_data.h
|
||||||
|
@ -13,6 +13,7 @@ else
|
|||||||
OBJS += usb.o
|
OBJS += usb.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
OBJS += bl_check.o
|
||||||
OBJS += u2f.o
|
OBJS += u2f.o
|
||||||
OBJS += messages.o
|
OBJS += messages.o
|
||||||
OBJS += storage.o
|
OBJS += storage.o
|
||||||
@ -120,6 +121,10 @@ coins_array.h: coins-gen.py coins.json
|
|||||||
nem_mosaics.c nem_mosaics.h: nem_mosaics.py nem_mosaics.json
|
nem_mosaics.c nem_mosaics.h: nem_mosaics.py nem_mosaics.json
|
||||||
$(PYTHON) $<
|
$(PYTHON) $<
|
||||||
|
|
||||||
|
bl_data.h: bl_data-gen.py ../bootloader/bootloader.bin
|
||||||
|
$(PYTHON) $<
|
||||||
|
|
||||||
clean::
|
clean::
|
||||||
rm -f coins_count.h coins_array.h
|
rm -f coins_count.h coins_array.h
|
||||||
rm -f nem_mosaics.c nem_mosaics.h
|
rm -f nem_mosaics.c nem_mosaics.h
|
||||||
|
rm -f bl_data.h
|
||||||
|
75
firmware/bl_check.c
Normal file
75
firmware/bl_check.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the TREZOR project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 Pavol Rusnak <stick@satoshilabs.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <libopencm3/stm32/flash.h>
|
||||||
|
#include "bl_data.h"
|
||||||
|
#include "memory.h"
|
||||||
|
#include "layout.h"
|
||||||
|
#include "gettext.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
int known_bootloader(int r, const uint8_t *hash) {
|
||||||
|
if (r != 32) return 0;
|
||||||
|
if (0 == memcmp(hash, "\xbf\x72\xe2\x5e\x2c\x2f\xc1\xba\x57\x04\x50\xfa\xdf\xb6\x6f\xaa\x5a\x71\x6d\xcd\xc0\x33\x35\x88\x55\x7b\x77\x54\x0a\xb8\x7e\x98", 32)) return 1; // 1.2.0a
|
||||||
|
if (0 == memcmp(hash, "\x77\xb8\xe2\xf2\x5f\xaa\x8e\x8c\x7d\x9f\x5b\x32\x3b\x27\xce\x05\x6c\xa3\xdb\xc2\x3f\x56\xc3\x7e\xe3\x3f\x97\x7c\xa6\xeb\x4d\x3e", 32)) return 1; // 1.2.0b
|
||||||
|
if (0 == memcmp(hash, "\xc4\xc3\x25\x39\xb4\xa0\x25\xa8\xe7\x53\xa4\xc4\x62\x64\x28\x59\x11\xa4\x5f\xcb\x14\xf4\x71\x81\x79\xe7\x11\xb1\xce\x99\x05\x24", 32)) return 1; // 1.2.5
|
||||||
|
if (0 == memcmp(hash, "\x42\x59\x66\x94\xa0\xf2\x9d\x1e\xc2\x35\x71\x29\x2d\x54\x39\xd8\x2f\xa1\x8c\x07\x37\xcb\x10\x7e\x98\xf6\x1e\xf5\x93\x4d\xe7\x16", 32)) return 1; // 1.3.0a
|
||||||
|
if (0 == memcmp(hash, "\x3a\xcf\x2e\x51\x0b\x0f\xe1\x56\xb5\x58\xbb\xf7\x9c\x7e\x48\x5e\xb0\x26\xe5\xe0\x8c\xb4\x4d\x15\x2d\x44\xd6\x4e\x0c\x6a\x41\x37", 32)) return 1; // 1.3.0b
|
||||||
|
if (0 == memcmp(hash, "\x15\x85\x21\x5b\xc6\xe5\x5a\x34\x07\xa8\xb3\xee\xe2\x79\x03\x4e\x95\xb9\xc4\x34\x00\x33\xe1\xb6\xae\x16\x0c\xe6\x61\x19\x67\x15", 32)) return 1; // 1.3.1
|
||||||
|
if (0 == memcmp(hash, "\x76\x51\xb7\xca\xba\x5a\xae\x0c\xc1\xc6\x5c\x83\x04\xf7\x60\x39\x6f\x77\x60\x6c\xd3\x99\x0c\x99\x15\x98\xf0\xe2\x2a\x81\xe0\x07", 32)) return 1; // 1.3.2
|
||||||
|
if (0 == memcmp(hash, "\x8c\xe8\xd7\x9e\xdf\x43\x0c\x03\x42\x64\x68\x6c\xa9\xb1\xd7\x8d\x26\xed\xb2\xac\xab\x71\x39\xbe\x8f\x98\x5c\x2a\x3c\x6c\xae\x11", 32)) return 1; // 1.3.3
|
||||||
|
if (0 == memcmp(hash, "\x63\x30\xfc\xec\x16\x72\xfa\xd3\x0b\x42\x1b\x60\xf7\x4f\x83\x9a\x39\x39\x33\x45\x65\xcb\x70\x3b\x2b\xd7\x18\x2e\xa2\xdd\xa0\x19", 32)) return 1; // 1.4.0
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_bootloader(void)
|
||||||
|
{
|
||||||
|
uint8_t hash[32];
|
||||||
|
int r = memory_bootloader_hash(hash);
|
||||||
|
|
||||||
|
if (!known_bootloader(r, hash)) {
|
||||||
|
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Unknown bootloader", "detected.", NULL, "Unplug your TREZOR", "contact our support.", NULL);
|
||||||
|
system_halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r == 32 && 0 == memcmp(hash, bl_hash, 32)) {
|
||||||
|
// all OK -> done
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// unlock sectors
|
||||||
|
memory_write_unlock();
|
||||||
|
|
||||||
|
// replace bootloader
|
||||||
|
flash_unlock();
|
||||||
|
for (int i = FLASH_BOOT_SECTOR_FIRST; i <= FLASH_BOOT_SECTOR_LAST; i++) {
|
||||||
|
flash_erase_sector(i, FLASH_CR_PROGRAM_X32);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < FLASH_BOOT_LEN / 4; i++) {
|
||||||
|
const uint32_t *w = (const uint32_t *)(bl_data + i * 4);
|
||||||
|
flash_program_word(FLASH_BOOT_START + i * 4, *w);
|
||||||
|
}
|
||||||
|
flash_lock();
|
||||||
|
|
||||||
|
// show info and halt
|
||||||
|
layoutDialog(&bmp_icon_info, NULL, NULL, NULL, _("Update finished"), _("successfully."), NULL, _("Please reconnect"), _("the device."), NULL);
|
||||||
|
system_halt();
|
||||||
|
}
|
25
firmware/bl_check.h
Normal file
25
firmware/bl_check.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the TREZOR project, https://trezor.io/
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 Pavol Rusnak <stick@satoshilabs.com>
|
||||||
|
*
|
||||||
|
* This library is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __BL_CHECK_H__
|
||||||
|
#define __BL_CHECK_H__
|
||||||
|
|
||||||
|
void check_bootloader(void);
|
||||||
|
|
||||||
|
#endif
|
19
firmware/bl_data-gen.py
Executable file
19
firmware/bl_data-gen.py
Executable file
@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from hashlib import sha256
|
||||||
|
|
||||||
|
fn = '../bootloader/bootloader.bin'
|
||||||
|
|
||||||
|
data = open(fn, 'rb').read()
|
||||||
|
if len(data) > 32768:
|
||||||
|
raise Exception('bootloader has to be smaller than 32768 bytes')
|
||||||
|
|
||||||
|
data += b'\x00' * (32768 - len(data))
|
||||||
|
|
||||||
|
h = sha256(sha256(data).digest()).digest()
|
||||||
|
|
||||||
|
bl_hash = ', '.join('0x%02x' % x for x in bytearray(h))
|
||||||
|
bl_data = ', '.join('0x%02x' % x for x in bytearray(data))
|
||||||
|
|
||||||
|
with open('bl_data.h', 'wt') as f:
|
||||||
|
f.write('static const uint8_t bl_hash[32] = {%s};\n' % bl_hash)
|
||||||
|
f.write('static const uint8_t bl_data[32768] = {%s};\n' % bl_data)
|
@ -37,5 +37,5 @@ void __attribute__((noreturn)) run_bootloader(void)
|
|||||||
// copy bootloader
|
// copy bootloader
|
||||||
memcpy(bootloader_vec, __bootloader_start__, (size_t) __bootloader_size__);
|
memcpy(bootloader_vec, __bootloader_start__, (size_t) __bootloader_size__);
|
||||||
|
|
||||||
load_vector_table(bootloader_vec);
|
jump_to_firmware(bootloader_vec, FW_TRUSTED);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "buttons.h"
|
#include "buttons.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
#include "bl_check.h"
|
||||||
#include "fastflash.h"
|
#include "fastflash.h"
|
||||||
|
|
||||||
/* Screen timeout */
|
/* Screen timeout */
|
||||||
@ -91,6 +92,7 @@ int main(void)
|
|||||||
__stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks
|
__stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks
|
||||||
oledInit();
|
oledInit();
|
||||||
#else
|
#else
|
||||||
|
check_bootloader();
|
||||||
setupApp();
|
setupApp();
|
||||||
__stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks
|
__stack_chk_guard = random32(); // this supports compiler provided unpredictable stack protection checks
|
||||||
#endif
|
#endif
|
||||||
|
18
memory.c
18
memory.c
@ -49,7 +49,25 @@ void memory_protect(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Remove write-protection on all flash sectors.
|
||||||
|
//
|
||||||
|
// This is an undocumented feature/bug of STM32F205/F405 microcontrollers,
|
||||||
|
// where flash controller reads its write protection bits from FLASH_OPTCR
|
||||||
|
// register not from OPTION_BYTES, rendering write protection useless.
|
||||||
|
// This behaviour is fixed in future designs of flash controller used for
|
||||||
|
// example in STM32F427, where the protection bits are read correctly
|
||||||
|
// from OPTION_BYTES and not form FLASH_OPCTR register.
|
||||||
|
//
|
||||||
|
// Read protection is unaffected and always stays locked to the desired value.
|
||||||
|
void memory_write_unlock(void)
|
||||||
|
{
|
||||||
|
flash_unlock_option_bytes();
|
||||||
|
flash_program_option_bytes(0x0FFFCCEC);
|
||||||
|
flash_lock_option_bytes();
|
||||||
|
}
|
||||||
|
|
||||||
int memory_bootloader_hash(uint8_t *hash)
|
int memory_bootloader_hash(uint8_t *hash)
|
||||||
|
|
||||||
{
|
{
|
||||||
sha256_Raw((const uint8_t *)FLASH_BOOT_START, FLASH_BOOT_LEN, hash);
|
sha256_Raw((const uint8_t *)FLASH_BOOT_START, FLASH_BOOT_LEN, hash);
|
||||||
sha256_Raw(hash, 32, hash);
|
sha256_Raw(hash, 32, hash);
|
||||||
|
1
memory.h
1
memory.h
@ -103,6 +103,7 @@
|
|||||||
#define FLASH_CODE_SECTOR_LAST 7
|
#define FLASH_CODE_SECTOR_LAST 7
|
||||||
|
|
||||||
void memory_protect(void);
|
void memory_protect(void);
|
||||||
|
void memory_write_unlock(void);
|
||||||
int memory_bootloader_hash(uint8_t *hash);
|
int memory_bootloader_hash(uint8_t *hash);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
13
util.h
13
util.h
@ -21,6 +21,7 @@
|
|||||||
#define __UTIL_H_
|
#define __UTIL_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <setup.h>
|
||||||
|
|
||||||
#if !EMULATOR
|
#if !EMULATOR
|
||||||
#include <libopencm3/cm3/scb.h>
|
#include <libopencm3/cm3/scb.h>
|
||||||
@ -52,10 +53,16 @@ extern uint8_t _ram_start[], _ram_end[];
|
|||||||
// defined in startup.s
|
// defined in startup.s
|
||||||
extern void memset_reg(void *start, void *stop, uint32_t val);
|
extern void memset_reg(void *start, void *stop, uint32_t val);
|
||||||
|
|
||||||
static inline void __attribute__((noreturn)) load_vector_table(const vector_table_t *vector_table)
|
#define FW_SIGNED 0x5A3CA5C3
|
||||||
|
#define FW_UNTRUSTED 0x00000000
|
||||||
|
|
||||||
|
static inline void __attribute__((noreturn)) jump_to_firmware(const vector_table_t *vector_table, int trust)
|
||||||
{
|
{
|
||||||
// Relocate vector table
|
if (FW_SIGNED == trust) { // trusted signed firmware
|
||||||
SCB_VTOR = (uint32_t)vector_table;
|
SCB_VTOR = (uint32_t)vector_table; // * relocate vector table
|
||||||
|
} else { // untrusted firmware
|
||||||
|
mpu_config(); // * configure MPU
|
||||||
|
}
|
||||||
|
|
||||||
// Set stack pointer
|
// Set stack pointer
|
||||||
__asm__ volatile("msr msp, %0" :: "r" (vector_table->initial_sp_value));
|
__asm__ volatile("msr msp, %0" :: "r" (vector_table->initial_sp_value));
|
||||||
|
Loading…
Reference in New Issue
Block a user