void check_bootloader(void) { #if MEMORY_PROTECT 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); shutdown(); } if (is_mode_unprivileged()) { return; } if (r == 32 && 0 == memcmp(hash, bl_hash, 32)) { // all OK -> done return; } // ENABLE THIS AT YOUR OWN RISK // ATTEMPTING TO OVERWRITE BOOTLOADER WITH UNSIGNED FIRMWARE MAY BRICK // YOUR DEVICE. layoutDialog(&bmp_icon_warning, NULL, NULL, NULL, _("Updating bootloader"), NULL, NULL, _("DO NOT UNPLUG"), _("YOUR TREZOR!"), NULL); // unlock sectors memory_write_unlock(); for (int tries = 0; tries < 10; tries++) { // 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(); // check whether the write was OK r = memory_bootloader_hash(hash); if (r == 32 && 0 == memcmp(hash, bl_hash, 32)) { // OK -> show info and halt layoutDialog(&bmp_icon_info, NULL, NULL, NULL, _("Update finished"), _("successfully."), NULL, _("Please reconnect"), _("the device."), NULL); shutdown(); return; } } // show info and halt layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Bootloader update"), _("broken."), NULL, _("Unplug your TREZOR"), _("contact our support."), NULL); shutdown(); #endif }
void show_unofficial_warning(uint8_t *hash) { layoutDialog(&bmp_icon_warning, "Abort", "I'll take the risk", NULL, "WARNING!", NULL, "Unofficial firmware", "detected.", NULL, NULL); do { delay(100000); buttonUpdate(); } while (!button.YesUp && !button.NoUp); if (button.NoUp) { show_halt(); // no button was pressed -> halt } layoutFirmwareHash(hash); do { delay(100000); buttonUpdate(); } while (!button.YesUp && !button.NoUp); if (button.NoUp) { show_halt(); // no button was pressed -> halt } // everything is OK, user pressed 2x Continue -> continue program }
void show_unofficial_warning(const uint8_t *hash) { layoutDialog(&bmp_icon_warning, str_abort, str_continue, NULL, "WARNING!", NULL, "Unofficial fware.", "detected.", NULL, NULL,OLED_WHITE); do { delay(100000); buttonUpdate(); } while (!button.YesUp && !button.NoUp); if (button.NoUp) { show_halt(); // no button was pressed -> halt } layoutFirmwareHash(hash); do { delay(100000); buttonUpdate(); } while (!button.YesUp && !button.NoUp); if (button.NoUp) { show_halt(); // no button was pressed -> halt } // everything is OK, user pressed 2x Continue -> continue program }
void storage_commit(void) { int i; uint32_t *w; // backup meta memcpy(meta_backup, (void *)FLASH_META_START, FLASH_META_LEN); flash_clear_status_flags(); flash_unlock(); // erase storage for (i = FLASH_META_SECTOR_FIRST; i <= FLASH_META_SECTOR_LAST; i++) { flash_erase_sector(i, FLASH_CR_PROGRAM_X32); } // modify storage memcpy(meta_backup + FLASH_META_DESC_LEN, "stor", 4); memcpy(meta_backup + FLASH_META_DESC_LEN + 4, storage_uuid, sizeof(storage_uuid)); memcpy(meta_backup + FLASH_META_DESC_LEN + 4 + sizeof(storage_uuid), &storage, sizeof(Storage)); // copy it back for (i = 0; i < FLASH_META_LEN / 4; i++) { w = (uint32_t *)(meta_backup + i * 4); flash_program_word(FLASH_META_START + i * 4, *w); } flash_lock(); // flash operation failed if (FLASH_SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_WRPERR)) { layoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Storage failure", "detected.", NULL, "Please unplug", "the device.", NULL); for (;;) { } } }
void show_unofficial_warning(void) { layoutDialog(DIALOG_ICON_WARNING, "Abort", "I'll take the risk", NULL, "WARNING!", NULL, "Unofficial firmware", "detected.", NULL, NULL); do { delay(100000); buttonUpdate(); } while (!button.YesUp && !button.NoUp); if (button.YesUp) { return; // yes button was pressed -> return } layoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Unofficial firmware", "aborted.", NULL, "Unplug your TREZOR", "and see our support", "page at mytrezor.com"); system_halt(); }
void layoutFirmwareHash(const uint8_t *hash) { char str[4][17]; 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); }
static void protectCheckMaxTry(uint32_t wait) { if (wait < (1 << MAX_WRONG_PINS)) return; storage_wipe(); layoutDialog(&bmp_icon_error, NULL, NULL, NULL, _("Too many wrong PIN"), _("attempts. Storage has"), _("been wiped."), NULL, _("Please unplug"), _("the device.")); for (;;) {} // loop forever }
void layoutFirmwareHash(const uint8_t *hash) { char str[4][17]; for (int i = 0; i < 4; i++) { data2hex(hash + i * 8, 8, str[i]); } layoutDialog(NULL, str_abort, str_continue, "Comp. fingerprints", str[0], str[1], str[2], str[3], NULL, NULL, OLED_RED); }
void layoutFirmwareHash(uint8_t *hash) { char str[4][17]; int i; for (i = 0; i < 4; i++) { data2hex(hash + i * 8, 8, str[i]); } layoutDialog(DIALOG_ICON_QUESTION, "Abort", "Continue", "Compare fingerprints", str[0], str[1], str[2], str[3], NULL, NULL); }
bool protectPin(bool use_cached) { if (!storage.has_pin || storage.pin[0] == 0 || (use_cached && session_isPinCached())) { return true; } uint32_t *fails = storage_getPinFailsPtr(); uint32_t wait = ~*fails; protectCheckMaxTry(wait); usbTiny(1); while (wait > 0) { // convert wait to secstr string char secstrbuf[20]; strlcpy(secstrbuf, _("________0 seconds"), sizeof(secstrbuf)); char *secstr = secstrbuf + 9; uint32_t secs = wait; while (secs > 0 && secstr >= secstrbuf) { secstr--; *secstr = (secs % 10) + '0'; secs /= 10; } if (wait == 1) { secstrbuf[16] = 0; } layoutDialog(&bmp_icon_info, NULL, NULL, NULL, _("Wrong PIN entered"), NULL, _("Please wait"), secstr, _("to continue ..."), NULL); // wait one second usbSleep(1000); if (msg_tiny_id == MessageType_MessageType_Initialize) { protectAbortedByInitialize = true; msg_tiny_id = 0xFFFF; usbTiny(0); fsm_sendFailure(FailureType_Failure_PinCancelled, NULL); return false; } wait--; } usbTiny(0); const char *pin; pin = requestPin(PinMatrixRequestType_PinMatrixRequestType_Current, _("Please enter current PIN:")); if (!pin) { fsm_sendFailure(FailureType_Failure_PinCancelled, NULL); return false; } if (!storage_increasePinFails(fails)) { fsm_sendFailure(FailureType_Failure_PinInvalid, NULL); return false; } if (storage_containsPin(pin)) { session_cachePin(); storage_resetPinFails(fails); return true; } else { protectCheckMaxTry(~*fails); fsm_sendFailure(FailureType_Failure_PinInvalid, NULL); return false; } }
void check_firmware_sanity(void) { int broken = 0; if (memcmp((void *)FLASH_META_MAGIC, "TRZR", 4)) { // magic does not match broken++; } if (*((uint32_t *)FLASH_META_CODELEN) < 4096) { // firmware reports smaller size than 4kB broken++; } if (*((uint32_t *)FLASH_META_CODELEN) > FLASH_TOTAL_SIZE - (FLASH_APP_START - FLASH_ORIGIN)) { // firmware reports bigger size than flash size broken++; } if (broken) { layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Firmware appears", "to be broken.", NULL, "Unplug your TREZOR", "and see our support", "page at mytrezor.com"); system_halt(); } }
static inline void __attribute__((noreturn)) fault_handler(const char *line1) { layoutDialog(&bmp_icon_error, NULL, NULL, NULL, line1, "detected.", NULL, "Please unplug", "the device.", NULL); for (;;) {} // loop forever }
void layoutU2FDialog(const char *verb, const char *appname, const BITMAP *appicon) { if (!appicon) { appicon = &bmp_icon_question; } layoutDialog(appicon, NULL, verb, NULL, verb, _("U2F security key?"), NULL, appname, NULL, NULL); }
void show_halt(void) { layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Unofficial fware.", "aborted.", NULL, "Unplug TREZOR", "contact support.", NULL, OLED_WHITE); shutdown(); }
error_shutdown(const char *line1, const char *line2, const char *line3, const char *line4) { layoutDialog(&bmp_icon_error, NULL, NULL, NULL, line1, line2, line3, line4, "Please unplug", "the device."); shutdown(); }
void show_halt(void) { layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Unofficial firmware", "aborted.", NULL, "Unplug your TREZOR", "contact our support.", NULL); shutdown(); }
void show_halt(void) { layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Unofficial firmware", "aborted.", NULL, "Unplug your TREZOR", "and see our support", "page at mytrezor.com"); system_halt(); }
void __attribute__((noreturn)) __stack_chk_fail(void) { layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Stack smashing", "detected.", NULL, "Please unplug", "the device.", NULL); for (;;) {} // loop forever }
void show_halt(void) { layoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Unofficial firmware", "aborted.", NULL, "Unplug your TREZOR", "and see our support", "page at mytrezor.com"); system_halt(); }
void layoutDialogSwipe(const BITMAP *icon, const char *btnNo, const char *btnYes, const char *desc, const char *line1, const char *line2, const char *line3, const char *line4, const char *line5, const char *line6) { layoutLast = layoutDialogSwipe; layoutSwipe(); layoutDialog(icon, btnNo, btnYes, desc, line1, line2, line3, line4, line5, line6); }
void __attribute__((noreturn)) __stack_chk_fail(void) { layoutDialog(DIALOG_ICON_ERROR, NULL, NULL, NULL, "Stack smashing", "detected.", NULL, "Please unplug", "the device.", NULL); for (;;) {} // loop forever }