Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reorganize boardloader code #4564

Merged
merged 5 commits into from
Feb 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/SConscript.boardloader
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,13 @@ FEATURES_AVAILABLE = models.configure_board(TREZOR_MODEL, HW_REVISION, FEATURES_

SOURCE_BOARDLOADER = [
'embed/projects/boardloader/main.c',
'embed/projects/boardloader/bld_version.c',
]

if 'sd_card' in FEATURES_AVAILABLE:
SOURCE_MOD += [
'embed/projects/boardloader/sd_update.c',
]

env.Replace(
CAT='cat',
Expand Down
1 change: 1 addition & 0 deletions core/embed/models/T2B1/model_T2B1.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define IMAGE_HASH_BLAKE2S

#define DISPLAY_JUMP_BEHAVIOR DISPLAY_RETAIN_CONTENT
#define RSOD_INFINITE_LOOP 1

// SHARED WITH MAKEFILE
// common
Expand Down
1 change: 1 addition & 0 deletions core/embed/models/T2T1/model_T2T1.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define IMAGE_HASH_BLAKE2S

#define DISPLAY_JUMP_BEHAVIOR DISPLAY_RETAIN_CONTENT
#define RSOD_INFINITE_LOOP 1

// SHARED WITH MAKEFILE
// common
Expand Down
1 change: 1 addition & 0 deletions core/embed/models/T3B1/model_T3B1.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define IMAGE_HASH_SHA256

#define DISPLAY_JUMP_BEHAVIOR DISPLAY_RETAIN_CONTENT
#define RSOD_INFINITE_LOOP 1

// SHARED WITH MAKEFILE, LINKER SCRIPT etc.
// misc
Expand Down
1 change: 1 addition & 0 deletions core/embed/models/T3T1/model_T3T1.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#define IMAGE_HASH_SHA256

#define DISPLAY_JUMP_BEHAVIOR DISPLAY_RETAIN_CONTENT
#define RSOD_INFINITE_LOOP 1

// SHARED WITH MAKEFILE, LINKER SCRIPT etc.
// misc
Expand Down
36 changes: 36 additions & 0 deletions core/embed/projects/boardloader/bld_version.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <trezor_model.h>
#include <trezor_rtl.h>

#include <sec/monoctr.h>

#include "bld_version.h"

uint8_t get_bootloader_min_version(void) {
uint8_t version = 0;
ensure(monoctr_read(MONOCTR_BOOTLOADER_VERSION, &version), "monoctr read");
return version;
}

void write_bootloader_min_version(uint8_t version) {
if (version > get_bootloader_min_version()) {
ensure(monoctr_write(MONOCTR_BOOTLOADER_VERSION, version), "monoctr write");
}
}
28 changes: 28 additions & 0 deletions core/embed/projects/boardloader/bld_version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (c) SatoshiLabs
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <trezor_types.h>

// Read the minimum version of the bootloader that is allowed to run.
uint8_t get_bootloader_min_version(void);

// Write the minimum version of the bootloader that is allowed to run.
void write_bootloader_min_version(uint8_t version);
178 changes: 11 additions & 167 deletions core/embed/projects/boardloader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,11 @@
#include <trezor_model.h>
#include <trezor_rtl.h>

#include <gfx/gfx_bitblt.h>
#include <gfx/gfx_draw.h>
#include <gfx/terminal.h>
#include <io/display.h>
#include <sec/monoctr.h>
#include <sec/rng.h>
#include <sec/secret.h>
#include <sys/bootutils.h>
#include <sys/mpu.h>
#include <sys/reset_flags.h>
#include <sys/system.h>
#include <sys/systick.h>
#include <util/board_capabilities.h>
#include <util/flash.h>
#include <util/flash_utils.h>
Expand All @@ -47,10 +40,6 @@
#include <sys/pvd.h>
#endif

#ifdef USE_SD_CARD
#include <io/sdcard.h>
#endif

#ifdef USE_HASH_PROCESSOR
#include <sec/hash_processor.h>
#endif
Expand All @@ -63,9 +52,13 @@
#include <sys/tamper.h>
#endif

#include "memzero.h"
#include "bld_version.h"
#include "version.h"

#ifdef USE_SD_CARD
#include "sd_update.h"
#endif

const uint8_t BOARDLOADER_KEY_M = 2;
const uint8_t BOARDLOADER_KEY_N = 3;
static const uint8_t * const BOARDLOADER_KEYS[] = {
Expand All @@ -92,9 +85,11 @@ static void drivers_init(void) {
#ifdef USE_HASH_PROCESSOR
hash_processor_init();
#endif
#ifndef FIXED_HW_DEINIT
// only skip this if deinit was fixed,
// as some old bootloaders rely on display being initialized
// (skipping alows faster boot time so generally a good idea)
display_init(DISPLAY_RESET_CONTENT);
#ifdef USE_SD_CARD
sdcard_init();
#endif
}

Expand All @@ -108,18 +103,6 @@ static void drivers_deinit(void) {
#endif
}

static uint8_t get_bootloader_min_version(void) {
uint8_t version = 0;
ensure(monoctr_read(MONOCTR_BOOTLOADER_VERSION, &version), "monoctr read");
return version;
}

static void write_bootloader_min_version(uint8_t version) {
if (version > get_bootloader_min_version()) {
ensure(monoctr_write(MONOCTR_BOOTLOADER_VERSION, version), "monoctr write");
}
}

struct BoardCapabilities capabilities
__attribute__((section(".capabilities_section"))) = {
.header = CAPABILITIES_HEADER,
Expand All @@ -135,127 +118,6 @@ struct BoardCapabilities capabilities
.terminator_tag = TAG_TERMINATOR,
.terminator_length = 0};

// we use SRAM as SD card read buffer (because DMA can't access the CCMRAM)
__attribute__((section(".buf")))
uint32_t sdcard_buf[BOOTLOADER_MAXSIZE / sizeof(uint32_t)];

#if defined USE_SD_CARD
static uint32_t check_sdcard(void) {
if (sectrue != sdcard_power_on()) {
return 0;
}

uint64_t cap = sdcard_get_capacity_in_bytes();
if (cap < 1024 * 1024) {
sdcard_power_off();
return 0;
}

memzero(sdcard_buf, IMAGE_HEADER_SIZE);

const secbool read_status =
sdcard_read_blocks(sdcard_buf, 0, BOOTLOADER_MAXSIZE / SDCARD_BLOCK_SIZE);

sdcard_power_off();

if (sectrue == read_status) {
const image_header *hdr =
read_image_header((const uint8_t *)sdcard_buf, BOOTLOADER_IMAGE_MAGIC,
BOOTLOADER_MAXSIZE);

if (hdr != (const image_header *)sdcard_buf) {
return 0;
}

if (sectrue != check_image_model(hdr)) {
return 0;
}

if (sectrue != check_image_header_sig(hdr, BOARDLOADER_KEY_M,
BOARDLOADER_KEY_N,
BOARDLOADER_KEYS)) {
return 0;
}

_Static_assert(IMAGE_CHUNK_SIZE >= BOOTLOADER_MAXSIZE,
"BOOTLOADER IMAGE MAXSIZE too large for IMAGE_CHUNK_SIZE");

const uint32_t code_start_offset = hdr->hdrlen;

if (sectrue !=
(check_single_hash(hdr->hashes,
(const uint8_t *)sdcard_buf + code_start_offset,
hdr->codelen))) {
return 0;
}

for (int i = IMAGE_HASH_DIGEST_LENGTH; i < sizeof(hdr->hashes); i++) {
if (hdr->hashes[i] != 0) {
return 0;
}
}

if (hdr->monotonic < get_bootloader_min_version()) {
return 0;
}

return hdr->codelen;
}

return 0;
}

static void progress_callback(int pos, int len) { term_printf("."); }

static secbool copy_sdcard(void) {
display_set_backlight(255);

term_printf("Trezor Boardloader\n");
term_printf("==================\n\n");

term_printf("bootloader found on the SD card\n\n");
term_printf("applying bootloader in 10 seconds\n\n");
term_printf("unplug now if you want to abort\n\n");

uint32_t codelen;

for (int i = 10; i >= 0; i--) {
term_printf("%d ", i);
hal_delay(1000);
codelen = check_sdcard();
if (0 == codelen) {
term_printf("\n\nno SD card, aborting\n");
return secfalse;
}
}

term_printf("\n\nerasing flash:\n\n");

// erase all flash (except boardloader)
if (sectrue != erase_device(progress_callback)) {
term_printf(" failed\n");
return secfalse;
}
term_printf(" done\n\n");

ensure(flash_unlock_write(), NULL);

// copy bootloader from SD card to Flash
term_printf("copying new bootloader from SD card\n\n");

ensure(flash_area_write_data(&BOOTLOADER_AREA, 0, sdcard_buf,
IMAGE_HEADER_SIZE + codelen),
NULL);

ensure(flash_lock_write(), NULL);

term_printf("\ndone\n\n");
term_printf("Unplug the device and remove the SD card\n");

return sectrue;
}
#endif

int main(void) {
system_init(&rsod_panic_handler);

Expand All @@ -274,26 +136,8 @@ int main(void) {
drivers_init();

#ifdef USE_SD_CARD
// If the bootloader is being updated from SD card, we need to preserve the
// monotonic counter from the old bootloader. This is in case that the old
// bootloader did not have the chance yet to write its monotonic counter to
// the secret area - which normally happens later in the flow.
const image_header *old_hdr = read_image_header(
(const uint8_t *)BOOTLOADER_START, BOOTLOADER_IMAGE_MAGIC,
flash_area_get_size(&BOOTLOADER_AREA));

if ((old_hdr != NULL) &&
(sectrue == check_image_header_sig(old_hdr, BOARDLOADER_KEY_M,
BOARDLOADER_KEY_N,
BOARDLOADER_KEYS)) &&
(sectrue ==
check_image_contents(old_hdr, IMAGE_HEADER_SIZE, &BOOTLOADER_AREA))) {
write_bootloader_min_version(old_hdr->monotonic);
}

if (check_sdcard()) {
return copy_sdcard() == sectrue ? 0 : 3;
}
sd_update_check_and_update(BOARDLOADER_KEYS, BOARDLOADER_KEY_M,
BOARDLOADER_KEY_N);
#endif

const image_header *hdr = read_image_header(
Expand Down
Loading
Loading