1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-21 05:48:23 +00:00
trezor-firmware/legacy/bootloader/bootloader.c
Ondrej Mikle e2abd2a9ad feat(legacy): bootloader with v3 SignMessage signatures + signatures debug
Removed oldest v1 style of firmware signature and presence checks.
Added debug helpers for T1 signatures.
Support for v2 and v3 signatures, but can only update FW to v3-style signed.
Support for debugging T1 signatures.
Scripts and README for debugging v2/v3 FW signing scheme.
Firmware in GetFeatures counts only v3 signatures as signed.
Add documentation and comments about signing schemes like a sane person
2022-11-22 15:00:19 +01:00

180 lines
5.1 KiB
C

/*
* This file is part of the Trezor project, https://trezor.io/
*
* Copyright (C) 2014 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 <string.h>
#include <libopencm3/cm3/scb.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/rcc.h>
#include "bootloader.h"
#include "buttons.h"
#include "compiler_traits.h"
#include "fw_signatures.h"
#include "layout.h"
#include "memory.h"
#include "oled.h"
#include "rng.h"
#include "setup.h"
#include "supervise.h"
#include "usb.h"
#include "util.h"
void layoutFirmwareFingerprint(const uint8_t *hash) {
char str[4][17] = {0};
for (int i = 0; i < 4; i++) {
data2hex(hash + i * 8, 8, str[i]);
}
layoutDialog(&bmp_icon_question, "Abort", "Continue", "Compare fingerprints",
str[0], str[1], str[2], str[3], NULL, NULL);
}
bool get_button_response(void) {
do {
delay(100000);
buttonUpdate();
} while (!button.YesUp && !button.NoUp);
return button.YesUp;
}
void show_halt(const char *line1, const char *line2) {
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, line1, line2, NULL,
"Unplug your Trezor,", "reinstall firmware.", NULL);
shutdown();
}
void show_unplug(const char *line1, const char *line2) {
layoutDialog(&bmp_icon_ok, NULL, NULL, NULL, line1, line2, NULL,
"You may now", "unplug your Trezor.", NULL);
}
static void show_unofficial_warning(const uint8_t *hash) {
// On production bootloader, show warning and wait for user
// to accept or reject it
// On non-production we only use unofficial firmwares,
// so just show hash for a while to see bootloader started
// but continue
#if PRODUCTION
layoutDialog(&bmp_icon_warning, "Abort", "I'll take the risk", NULL,
"WARNING!", NULL, "Unofficial firmware", "detected.", NULL,
NULL);
bool but = get_button_response();
if (!but) { // no button was pressed -> halt
show_halt("Unofficial firmware", "aborted.");
}
layoutFirmwareFingerprint(hash);
but = get_button_response();
if (!but) { // no button was pressed -> halt
show_halt("Unofficial firmware", "aborted.");
}
// everything is OK, user pressed 2x Continue -> continue program
#else
layoutFirmwareFingerprint(hash);
delay(100000000);
#endif
}
static void __attribute__((noreturn)) load_app(int signed_firmware) {
// zero out SRAM
memset_reg(_ram_start, _ram_end, 0);
jump_to_firmware((const vector_table_t *)FLASH_PTR(FLASH_APP_START),
signed_firmware);
}
static void bootloader_loop(void) {
oledClear();
oledDrawBitmap(0, 0, &bmp_logo64_half);
oledDrawBitmapFlip(24, 0, &bmp_logo64_half);
if (firmware_present_new()) {
oledDrawStringCenter(90, 10, "Trezor", FONT_STANDARD);
oledDrawStringCenter(90, 30, "Bootloader", FONT_STANDARD);
oledDrawStringCenter(90, 50,
VERSTR(VERSION_MAJOR) "." VERSTR(
VERSION_MINOR) "." VERSTR(VERSION_PATCH),
FONT_STANDARD);
} else {
oledDrawStringCenter(90, 10, "Welcome!", FONT_STANDARD);
oledDrawStringCenter(90, 30, "Please visit", FONT_STANDARD);
oledDrawStringCenter(90, 50, "trezor.io/start", FONT_STANDARD);
}
oledRefresh();
usbLoop();
}
int main(void) {
// grab "stay in bootloader" flag as soon as possible
register uint32_t r11 __asm__("r11");
volatile uint32_t stay_in_bootloader_flag = r11;
#ifndef APPVER
setup();
#endif
__stack_chk_guard = random32(); // this supports compiler provided
// unpredictable stack protection checks
#ifndef APPVER
memory_protect();
oledInit();
#endif
mpu_config_bootloader();
if (stay_in_bootloader_flag == STAY_IN_BOOTLOADER_FLAG) {
goto bootloader_loop_start;
}
#ifndef APPVER
bool left_pressed = (buttonRead() & BTN_PIN_NO) == 0;
if (firmware_present_new() && !left_pressed) {
oledClear();
oledDrawBitmap(40, 0, &bmp_logo64_empty_half);
oledDrawBitmapFlip(40 + 24, 0, &bmp_logo64_empty_half);
oledRefresh();
const image_header *hdr =
(const image_header *)FLASH_PTR(FLASH_FWHEADER_START);
uint8_t fingerprint[32] = {0};
int signed_firmware = signatures_match(hdr, fingerprint);
if (SIG_OK != signed_firmware) {
show_unofficial_warning(fingerprint);
}
if (SIG_OK != check_firmware_hashes(hdr)) {
show_halt("Broken firmware", "detected.");
}
mpu_config_off();
load_app(signed_firmware);
}
#endif
bootloader_loop_start:
bootloader_loop();
return 0;
}