diff --git a/ChangeLog b/ChangeLog index bad297632c..1f0eb7c99a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ -Version 2.1.0 [unreleased] +Version 2.1.0 * stable release, optional update +* Security improvements +* Upgraded to new storage format +* Ripple, Stellar, Cardano and NEM fixes +* New coins: ATS, AXE, FLO, GIN, KMD, NIX, + PIVX, REOSC, XPM, XSN, ZCL +* New ETH tokens Version 2.0.10 * stable release, optional update diff --git a/SConscript.bootloader b/SConscript.bootloader index 1d79537653..ec0ba8462c 100644 --- a/SConscript.bootloader +++ b/SConscript.bootloader @@ -83,6 +83,7 @@ SOURCE_TREZORHAL = [ 'embed/trezorhal/image.c', 'embed/trezorhal/flash.c', 'embed/trezorhal/mini_printf.c', + 'embed/trezorhal/mpu.c', 'embed/trezorhal/rng.c', 'embed/trezorhal/stm32.c', 'embed/trezorhal/touch.c', diff --git a/SConscript.firmware b/SConscript.firmware index 7b66b6fa68..fcc9dee2f9 100644 --- a/SConscript.firmware +++ b/SConscript.firmware @@ -29,7 +29,6 @@ CPPDEFINES_MOD += [ 'AES_128', 'AES_192', 'RAND_PLATFORM_INDEPENDENT', - ('USE_BIP39_CACHE', '0'), ('USE_KECCAK', '1'), ('USE_ETHEREUM', '1'), ('USE_MONERO', '1'), diff --git a/SConscript.unix b/SConscript.unix index a6b23ea024..3ba197eaa6 100644 --- a/SConscript.unix +++ b/SConscript.unix @@ -27,7 +27,6 @@ CPPPATH_MOD += [ CPPDEFINES_MOD += [ 'AES_128', 'AES_192', - ('USE_BIP39_CACHE', '0'), ('USE_KECCAK', '1'), ('USE_ETHEREUM', '1'), ('USE_MONERO', '1'), diff --git a/embed/boardloader/main.c b/embed/boardloader/main.c index d5ff4a4993..34db7c35b1 100644 --- a/embed/boardloader/main.c +++ b/embed/boardloader/main.c @@ -105,9 +105,9 @@ static secbool copy_sdcard(void) // erase all flash (except boardloader) static const uint8_t sectors[] = { - 3, FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_2, + 3, FLASH_SECTOR_BOOTLOADER, FLASH_SECTOR_FIRMWARE_START, 7, @@ -168,12 +168,8 @@ int main(void) periph_init(); if (sectrue != flash_configure_option_bytes()) { - static const uint8_t sectors[] = { - FLASH_SECTOR_STORAGE_1, - FLASH_SECTOR_STORAGE_2, - }; // display is not initialized so don't call ensure - secbool r = flash_erase_sectors(sectors, sizeof(sectors), NULL); + secbool r = flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL); (void)r; return 2; } diff --git a/embed/bootloader/main.c b/embed/bootloader/main.c index 61fa8df1ca..26e3285a77 100644 --- a/embed/bootloader/main.c +++ b/embed/bootloader/main.c @@ -21,6 +21,7 @@ #include #include "common.h" +#include "mpu.h" #include "image.h" #include "flash.h" #include "display.h" @@ -224,15 +225,18 @@ static void check_bootloader_version(void) int main(void) { -main_start: - display_clear(); + touch_init(); + touch_power_on(); + + mpu_config_bootloader(); #if PRODUCTION check_bootloader_version(); #endif - touch_init(); - touch_power_on(); +main_start: + + display_clear(); // delay to detect touch uint32_t touched = 0; @@ -258,7 +262,7 @@ main_start: firmware_present = load_image_header((const uint8_t *)(FIRMWARE_START + vhdr.hdrlen), FIRMWARE_IMAGE_MAGIC, FIRMWARE_IMAGE_MAXSIZE, vhdr.vsig_m, vhdr.vsig_n, vhdr.vpub, &hdr); } if (sectrue == firmware_present) { - firmware_present = check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, firmware_sectors, FIRMWARE_SECTORS_COUNT); + firmware_present = check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT); } // start the bootloader if no or broken firmware found ... @@ -282,11 +286,7 @@ main_start: ui_fadein(); // erase storage - static const uint8_t sectors_storage[] = { - FLASH_SECTOR_STORAGE_1, - FLASH_SECTOR_STORAGE_2, - }; - ensure(flash_erase_sectors(sectors_storage, sizeof(sectors_storage), NULL), NULL); + ensure(flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL), NULL); // and start the usb loop if (bootloader_usb_loop(NULL, NULL) != sectrue) { @@ -349,7 +349,7 @@ main_start: "invalid firmware header"); ensure( - check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, firmware_sectors, FIRMWARE_SECTORS_COUNT), + check_image_contents(&hdr, IMAGE_HEADER_SIZE + vhdr.hdrlen, FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT), "invalid firmware hash"); // if all VTRUST flags are unset = ultimate trust => skip the procedure @@ -379,9 +379,10 @@ main_start: ui_fadeout(); } - // mpu_config(); + // mpu_config_firmware(); // jump_to_unprivileged(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); + mpu_config_off(); jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); return 0; diff --git a/embed/bootloader/messages.c b/embed/bootloader/messages.c index 70cf066a19..faa0902811 100644 --- a/embed/bootloader/messages.c +++ b/embed/bootloader/messages.c @@ -39,22 +39,6 @@ #define MSG_HEADER1_LEN 9 #define MSG_HEADER2_LEN 1 -const uint8_t firmware_sectors[FIRMWARE_SECTORS_COUNT] = { - FLASH_SECTOR_FIRMWARE_START, - 7, - 8, - 9, - 10, - FLASH_SECTOR_FIRMWARE_END, - FLASH_SECTOR_FIRMWARE_EXTRA_START, - 18, - 19, - 20, - 21, - 22, - FLASH_SECTOR_FIRMWARE_EXTRA_END, -}; - secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id, uint32_t *msg_size) { if (buf[0] != '?' || buf[1] != '#' || buf[2] != '#') { @@ -479,13 +463,9 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu // if firmware is not upgrade, erase storage if (sectrue != is_upgrade) { - static const uint8_t sectors_storage[] = { - FLASH_SECTOR_STORAGE_1, - FLASH_SECTOR_STORAGE_2, - }; - ensure(flash_erase_sectors(sectors_storage, sizeof(sectors_storage), NULL), NULL); + ensure(flash_erase_sectors(STORAGE_SECTORS, STORAGE_SECTORS_COUNT, NULL), NULL); } - ensure(flash_erase_sectors(firmware_sectors, FIRMWARE_SECTORS_COUNT, ui_screen_install_progress_erase), NULL); + ensure(flash_erase_sectors(FIRMWARE_SECTORS, FIRMWARE_SECTORS_COUNT, ui_screen_install_progress_erase), NULL); firstskip = IMAGE_HEADER_SIZE + vhdr.hdrlen; } @@ -521,7 +501,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu const uint32_t * const src = (const uint32_t * const)chunk_buffer; for (int i = 0; i < chunk_size / sizeof(uint32_t); i++) { - ensure(flash_write_word(firmware_sectors[firmware_block], i * sizeof(uint32_t), src[i]), NULL); + ensure(flash_write_word(FIRMWARE_SECTORS[firmware_block], i * sizeof(uint32_t), src[i]), NULL); } ensure(flash_lock_write(), NULL); @@ -546,9 +526,9 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, uint8_t *bu int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf) { static const uint8_t sectors[] = { - 3, FLASH_SECTOR_STORAGE_1, FLASH_SECTOR_STORAGE_2, + // 3, // skip because of MPU protection FLASH_SECTOR_FIRMWARE_START, 7, 8, @@ -558,7 +538,7 @@ int process_msg_WipeDevice(uint8_t iface_num, uint32_t msg_size, uint8_t *buf) FLASH_SECTOR_UNUSED_START, 13, 14, - FLASH_SECTOR_UNUSED_END, + // FLASH_SECTOR_UNUSED_END, // skip because of MPU protection FLASH_SECTOR_FIRMWARE_EXTRA_START, 18, 19, diff --git a/embed/bootloader/messages.h b/embed/bootloader/messages.h index 1c0d514ee0..d509dd9e13 100644 --- a/embed/bootloader/messages.h +++ b/embed/bootloader/messages.h @@ -28,7 +28,6 @@ #define USB_PACKET_SIZE 64 #define FIRMWARE_UPLOAD_CHUNK_RETRY_COUNT 2 -extern const uint8_t firmware_sectors[FIRMWARE_SECTORS_COUNT]; secbool msg_parse_header(const uint8_t *buf, uint16_t *msg_id, uint32_t *msg_size); diff --git a/embed/extmod/modtrezorconfig/modtrezorconfig.c b/embed/extmod/modtrezorconfig/modtrezorconfig.c index 5d84d655b2..6dbe13e5a9 100644 --- a/embed/extmod/modtrezorconfig/modtrezorconfig.c +++ b/embed/extmod/modtrezorconfig/modtrezorconfig.c @@ -17,6 +17,8 @@ * along with this program. If not, see . */ +#include + #include "py/runtime.h" #include "py/mphal.h" #include "py/objstr.h" @@ -31,9 +33,13 @@ STATIC mp_obj_t ui_wait_callback = mp_const_none; -STATIC secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress) { +STATIC secbool wrapped_ui_wait_callback(uint32_t wait, uint32_t progress, const char* message) { if (mp_obj_is_callable(ui_wait_callback)) { - if (mp_call_function_2(ui_wait_callback, mp_obj_new_int(wait), mp_obj_new_int(progress)) == mp_const_true) { + mp_obj_t args[3]; + args[0] = mp_obj_new_int(wait); + args[1] = mp_obj_new_int(progress); + args[2] = mp_obj_new_str(message, strlen(message)); + if (mp_call_function_n_kw(ui_wait_callback, 3, 0, args) == mp_const_true) { return sectrue; } } diff --git a/embed/firmware/bl_check.c b/embed/firmware/bl_check.c index 6a967b53a3..65daf9b11f 100644 --- a/embed/firmware/bl_check.c +++ b/embed/firmware/bl_check.c @@ -38,6 +38,10 @@ static secbool known_bootloader(const uint8_t *hash, int len) { if (0 == memcmp(hash, "\x2e\xf7\x47\xf8\x49\x87\x1e\xc8\xc6\x01\x35\xd6\x32\xe5\x5a\xd1\x56\x18\xf8\x64\x87\xb7\xaa\x7c\x62\x0e\xc3\x0d\x25\x69\x4e\x18", 32)) return sectrue; // bootloader-2.0.2.bin (padded with 0xff) if (0 == memcmp(hash, "\xcc\x6b\x35\xc3\x8f\x29\x5c\xbd\x7d\x31\x69\xaf\xae\xf1\x61\x01\xef\xbe\x9f\x3b\x0a\xfd\xc5\x91\x70\x9b\xf5\xa0\xd5\xa4\xc5\xe0", 32)) return sectrue; + // bootloader-2.0.3.bin (padded with 0x00) + if (0 == memcmp(hash, "\xb1\x83\xd3\x31\xc7\xff\x3d\xcf\x54\x1e\x7e\x40\xf4\x9e\xc3\x53\x4c\xcc\xf3\x8c\x35\x39\x88\x81\x65\xc0\x5c\x25\xbd\xfc\xea\x14", 32)) return sectrue; + // bootloader-2.0.3.bin (padded with 0xff) + if (0 == memcmp(hash, "\xab\xdb\x7d\xe2\xef\x44\x66\xa7\xb7\x1f\x2b\x02\xf3\xe1\x40\xe7\xcd\xf2\x8e\xc0\xbb\x33\x04\xce\x0d\xa5\xca\x02\x57\xb6\xd4\x30", 32)) return sectrue; return secfalse; } */ @@ -45,9 +49,9 @@ static secbool known_bootloader(const uint8_t *hash, int len) { static secbool latest_bootloader(const uint8_t *hash, int len) { if (len != 32) return secfalse; // bootloader.bin (padded with 0x00) - if (0 == memcmp(hash, "\x2e\xf7\x47\xf8\x49\x87\x1e\xc8\xc6\x01\x35\xd6\x32\xe5\x5a\xd1\x56\x18\xf8\x64\x87\xb7\xaa\x7c\x62\x0e\xc3\x0d\x25\x69\x4e\x18", 32)) return sectrue; + if (0 == memcmp(hash, "\xb1\x83\xd3\x31\xc7\xff\x3d\xcf\x54\x1e\x7e\x40\xf4\x9e\xc3\x53\x4c\xcc\xf3\x8c\x35\x39\x88\x81\x65\xc0\x5c\x25\xbd\xfc\xea\x14", 32)) return sectrue; // bootloader.bin (padded with 0xff) - if (0 == memcmp(hash, "\xcc\x6b\x35\xc3\x8f\x29\x5c\xbd\x7d\x31\x69\xaf\xae\xf1\x61\x01\xef\xbe\x9f\x3b\x0a\xfd\xc5\x91\x70\x9b\xf5\xa0\xd5\xa4\xc5\xe0", 32)) return sectrue; + if (0 == memcmp(hash, "\xab\xdb\x7d\xe2\xef\x44\x66\xa7\xb7\x1f\x2b\x02\xf3\xe1\x40\xe7\xcd\xf2\x8e\xc0\xbb\x33\x04\xce\x0d\xa5\xca\x02\x57\xb6\xd4\x30", 32)) return sectrue; return secfalse; } diff --git a/embed/firmware/bootloader.bin b/embed/firmware/bootloader.bin index 4f34cb118c..aebb4eb720 100644 Binary files a/embed/firmware/bootloader.bin and b/embed/firmware/bootloader.bin differ diff --git a/embed/firmware/main.c b/embed/firmware/main.c index 5d517fcc01..e0b5f2cafd 100644 --- a/embed/firmware/main.c +++ b/embed/firmware/main.c @@ -54,7 +54,7 @@ int main(void) #if TREZOR_MODEL == T check_and_replace_bootloader(); // Enable MPU - mpu_config(); + mpu_config_firmware(); #endif // Init peripherals diff --git a/embed/trezorhal/common.c b/embed/trezorhal/common.c index c3afd92619..d0dc28f8d6 100644 --- a/embed/trezorhal/common.c +++ b/embed/trezorhal/common.c @@ -29,7 +29,8 @@ #include "stm32f4xx_ll_utils.h" -void shutdown(void); +// from util.s +extern void shutdown(void); #define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00) @@ -115,6 +116,24 @@ void hal_delay(uint32_t ms) HAL_Delay(ms); } +void delay_random(void) +{ + int wait = rng_get() & 0xff; + volatile int i = 0; + volatile int j = wait; + while (i < wait) { + if (i + j != wait) { + shutdown(); + } + ++i; + --j; + } + // Double-check loop completion. + if (i != wait || j != 0) { + shutdown(); + } +} + // reference RM0090 section 35.12.1 Figure 413 #define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U) #define USB_OTG_HS_DATA_FIFO_SIZE (4096U) diff --git a/embed/trezorhal/common.h b/embed/trezorhal/common.h index f886739e0e..3fac1dec62 100644 --- a/embed/trezorhal/common.h +++ b/embed/trezorhal/common.h @@ -26,11 +26,14 @@ #define XSTR(s) STR(s) #define STR(s) #s +#ifndef MIN_8bits +#define MIN_8bits(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? (_a & 0xFF) : (_b & 0xFF); }) +#endif #ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; }) #endif #ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; }) #endif void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func); @@ -40,6 +43,8 @@ void __attribute__((noreturn)) error_shutdown(const char *line1, const char *lin void hal_delay(uint32_t ms); +void delay_random(void); + void clear_otg_hs_memory(void); extern uint32_t __stack_chk_guard; diff --git a/embed/trezorhal/flash.c b/embed/trezorhal/flash.c index b270b7cc56..b91c2c8f96 100644 --- a/embed/trezorhal/flash.c +++ b/embed/trezorhal/flash.c @@ -54,6 +54,27 @@ static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = { [24] = 0x08200000, // last element - not a valid sector }; +const uint8_t FIRMWARE_SECTORS [FIRMWARE_SECTORS_COUNT] = { + FLASH_SECTOR_FIRMWARE_START, + 7, + 8, + 9, + 10, + FLASH_SECTOR_FIRMWARE_END, + FLASH_SECTOR_FIRMWARE_EXTRA_START, + 18, + 19, + 20, + 21, + 22, + FLASH_SECTOR_FIRMWARE_EXTRA_END, +}; + +const uint8_t STORAGE_SECTORS[STORAGE_SECTORS_COUNT] = { + FLASH_SECTOR_STORAGE_1, + FLASH_SECTOR_STORAGE_2, +}; + void flash_init(void) { } diff --git a/embed/trezorhal/flash.h b/embed/trezorhal/flash.h index dd707cf90f..285a1e76fc 100644 --- a/embed/trezorhal/flash.h +++ b/embed/trezorhal/flash.h @@ -60,6 +60,13 @@ // 22 #define FLASH_SECTOR_FIRMWARE_EXTRA_END 23 +#define BOOTLOADER_SECTORS_COUNT (1) +#define STORAGE_SECTORS_COUNT (2) +#define FIRMWARE_SECTORS_COUNT (6 + 7) + +extern const uint8_t STORAGE_SECTORS[STORAGE_SECTORS_COUNT]; +extern const uint8_t FIRMWARE_SECTORS[FIRMWARE_SECTORS_COUNT]; + // note: FLASH_SR_RDERR is STM32F42xxx and STM32F43xxx specific (STM32F427) (reference RM0090 section 3.7.5) #ifndef STM32F427xx #define FLASH_SR_RDERR 0 diff --git a/embed/trezorhal/image.h b/embed/trezorhal/image.h index c9153bf97f..7eef845317 100644 --- a/embed/trezorhal/image.h +++ b/embed/trezorhal/image.h @@ -27,9 +27,6 @@ #define BOOTLOADER_START 0x08020000 #define FIRMWARE_START 0x08040000 -#define BOOTLOADER_SECTORS_COUNT (1) -#define FIRMWARE_SECTORS_COUNT (6 + 7) - #define IMAGE_HEADER_SIZE 0x400 #define IMAGE_SIG_SIZE 65 #define IMAGE_CHUNK_SIZE (128 * 1024) diff --git a/embed/trezorhal/mpu.c b/embed/trezorhal/mpu.c index 17fc68cc2d..03effbb851 100644 --- a/embed/trezorhal/mpu.c +++ b/embed/trezorhal/mpu.c @@ -27,48 +27,49 @@ #define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos) -void mpu_config(void) +void mpu_config_off(void) +{ + // Disable MPU + HAL_MPU_Disable(); +} + +void mpu_config_bootloader(void) { // Disable MPU HAL_MPU_Disable(); -/* - // Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never) - MPU->RBAR = FLASH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER0; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO | MPU_RASR_XN_Msk; -*/ + // Note: later entries overwrite previous ones - // Bootloader (0x08020000 - 0x0803FFFF, 64 KiB, read-only) - MPU->RBAR = FLASH_BASE | 0x20000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER0; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO; + // Everything (0x00000000 - 0xFFFFFFFF, 4 GiB, read-write) + MPU->RNR = MPU_REGION_NUMBER0; + MPU->RBAR = 0; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_4GB | LL_MPU_REGION_FULL_ACCESS; - // Storage#1 (0x08010000 - 0x0801FFFF, 64 KiB, read-write, execute never) - MPU->RBAR = FLASH_BASE | 0x10000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER1; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; - // Storage#2 (0x08110000 - 0x0811FFFF, 64 KiB, read-write, execute never) - MPU->RBAR = FLASH_BASE | 0x110000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER2; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; + // Flash (0x0800C000 - 0x0800FFFF, 16 KiB, no access) + MPU->RNR = MPU_REGION_NUMBER1; + MPU->RBAR = FLASH_BASE + 0xC000; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS; - // Firmware (0x08040000 - 0x080FFFFF, 6 * 128 KiB = 1024 KiB except 2/8 at start = 768 KiB, read-only) - MPU->RBAR = FLASH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER3; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | MPU_SUBREGION_DISABLE(0x03); - - // Firmware extra (0x08120000 - 0x081FFFFF, 7 * 128 KiB = 1024 KiB except 1/8 at start = 896 KiB, read-only) - MPU->RBAR = FLASH_BASE | 0x100000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER4; - MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | MPU_SUBREGION_DISABLE(0x01); + // Flash (0x0810C000 - 0x0810FFFF, 16 KiB, no access) + MPU->RNR = MPU_REGION_NUMBER2; + MPU->RBAR = FLASH_BASE + 0x10C000; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS; // SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, read-write, execute never) - MPU->RBAR = SRAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER5; + MPU->RNR = MPU_REGION_NUMBER3; + MPU->RBAR = SRAM_BASE; MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0); // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) // External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never) - MPU->RBAR = PERIPH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER6; + MPU->RNR = MPU_REGION_NUMBER4; + MPU->RBAR = PERIPH_BASE; MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; #ifdef STM32F427xx // CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never) - MPU->RBAR = CCMDATARAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER7; + MPU->RNR = MPU_REGION_NUMBER5; + MPU->RBAR = CCMDATARAM_BASE; MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; #elif STM32F405xx // no CCMRAM @@ -77,5 +78,69 @@ void mpu_config(void) #endif // Enable MPU - HAL_MPU_Enable(0); + HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); +} + + +void mpu_config_firmware(void) +{ + // Disable MPU + HAL_MPU_Disable(); + + // Note: later entries overwrite previous ones + +/* + // Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never) + MPU->RBAR = FLASH_BASE | MPU_REGION_NUMBER0; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO | MPU_RASR_XN_Msk; +*/ + + // Bootloader (0x08020000 - 0x0803FFFF, 64 KiB, read-only) + MPU->RNR = MPU_REGION_NUMBER0; + MPU->RBAR = FLASH_BASE + 0x20000; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO; + + // Storage#1 (0x08010000 - 0x0801FFFF, 64 KiB, read-write, execute never) + MPU->RNR = MPU_REGION_NUMBER1; + MPU->RBAR = FLASH_BASE + 0x10000; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; + // Storage#2 (0x08110000 - 0x0811FFFF, 64 KiB, read-write, execute never) + MPU->RNR = MPU_REGION_NUMBER2; + MPU->RBAR = FLASH_BASE + 0x110000; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; + + // Firmware (0x08040000 - 0x080FFFFF, 6 * 128 KiB = 1024 KiB except 2/8 at start = 768 KiB, read-only) + MPU->RNR = MPU_REGION_NUMBER3; + MPU->RBAR = FLASH_BASE; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | MPU_SUBREGION_DISABLE(0x03); + + // Firmware extra (0x08120000 - 0x081FFFFF, 7 * 128 KiB = 1024 KiB except 1/8 at start = 896 KiB, read-only) + MPU->RNR = MPU_REGION_NUMBER4; + MPU->RBAR = FLASH_BASE + 0x100000; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | MPU_SUBREGION_DISABLE(0x01); + + // SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, read-write, execute never) + MPU->RNR = MPU_REGION_NUMBER5; + MPU->RBAR = SRAM_BASE; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0); + + // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) + // External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never) + MPU->RNR = MPU_REGION_NUMBER6; + MPU->RBAR = PERIPH_BASE; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; + +#ifdef STM32F427xx + // CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never) + MPU->RNR = MPU_REGION_NUMBER7; + MPU->RBAR = CCMDATARAM_BASE; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; +#elif STM32F405xx + // no CCMRAM +#else +#error Unsupported MCU +#endif + + // Enable MPU + HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); } diff --git a/embed/trezorhal/mpu.h b/embed/trezorhal/mpu.h index 2a7ccf6fcd..c7c136849e 100644 --- a/embed/trezorhal/mpu.h +++ b/embed/trezorhal/mpu.h @@ -20,6 +20,8 @@ #ifndef __MPU_H__ #define __MPU_H__ -void mpu_config(void); +void mpu_config_off(void); +void mpu_config_bootloader(void); +void mpu_config_firmware(void); #endif diff --git a/embed/trezorhal/stm32.c b/embed/trezorhal/stm32.c index 41de13aafb..5c74fd350a 100644 --- a/embed/trezorhal/stm32.c +++ b/embed/trezorhal/stm32.c @@ -79,7 +79,8 @@ void SysTick_Handler(void) uwTick++; } -void shutdown(void); +// from util.s +extern void shutdown(void); void PVD_IRQHandler(void) { diff --git a/embed/trezorhal/usb.c b/embed/trezorhal/usb.c index 57dff2b0f5..03ac2cd5b5 100644 --- a/embed/trezorhal/usb.c +++ b/embed/trezorhal/usb.c @@ -314,6 +314,7 @@ static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) { #define USB_WEBUSB_URL_SCHEME_HTTPS 1 static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) { + delay_random(); if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) && ((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) && ((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_VENDOR)) { @@ -330,7 +331,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme 't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[] }; - USBD_CtlSendData(dev, UNCONST(webusb_url), MIN(req->wLength, sizeof(webusb_url))); + USBD_CtlSendData(dev, UNCONST(webusb_url), MIN_8bits(req->wLength, sizeof(webusb_url))); return USBD_OK; } else { USBD_CtlError(dev, req); @@ -354,7 +355,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved }; - USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN(req->wLength, sizeof(winusb_wcid))); + USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN_8bits(req->wLength, sizeof(winusb_wcid))); return USBD_OK; } else { USBD_CtlError(dev, req); @@ -380,7 +381,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re 0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength '{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData }; - USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN(req->wLength, sizeof(winusb_guid))); + USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN_8bits(req->wLength, sizeof(winusb_guid))); return USBD_OK; } else { USBD_CtlError(dev, req); @@ -410,6 +411,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re } static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) { + delay_random(); for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { switch (usb_ifaces[i].type) { case USB_IFACE_TYPE_HID: @@ -429,6 +431,7 @@ static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) { } static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) { + delay_random(); for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { switch (usb_ifaces[i].type) { case USB_IFACE_TYPE_HID: @@ -448,6 +451,7 @@ static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) { } static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) { + delay_random(); for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) { switch (usb_ifaces[i].type) { case USB_IFACE_TYPE_VCP: diff --git a/embed/trezorhal/usb_hid-impl.h b/embed/trezorhal/usb_hid-impl.h index 084342557e..7b20c9beeb 100644 --- a/embed/trezorhal/usb_hid-impl.h +++ b/embed/trezorhal/usb_hid-impl.h @@ -254,7 +254,6 @@ static void usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state } static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) { - switch (req->bmRequest & USB_REQ_TYPE_MASK) { // Class request @@ -302,11 +301,11 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, switch (req->wValue >> 8) { case USB_DESC_TYPE_HID: - USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN(req->wLength, sizeof(state->desc_block->hid))); + USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN_8bits(req->wLength, sizeof(state->desc_block->hid))); return USBD_OK; case USB_DESC_TYPE_REPORT: - USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len)); + USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN_8bits(req->wLength, state->report_desc_len)); return USBD_OK; default: diff --git a/embed/trezorhal/usb_vcp-impl.h b/embed/trezorhal/usb_vcp-impl.h index 28aa63875d..9f8d81e2a8 100644 --- a/embed/trezorhal/usb_vcp-impl.h +++ b/embed/trezorhal/usb_vcp-impl.h @@ -364,13 +364,13 @@ static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state, if ((req->bmRequest & USB_REQ_DIR_MASK) == USB_REQ_DIR_D2H) { if (req->bRequest == USB_CDC_GET_LINE_CODING) { - USBD_CtlSendData(dev, UNCONST(&line_coding), MIN(req->wLength, sizeof(line_coding))); + USBD_CtlSendData(dev, UNCONST(&line_coding), MIN_8bits(req->wLength, sizeof(line_coding))); } else { - USBD_CtlSendData(dev, state->cmd_buffer, MIN(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN)); + USBD_CtlSendData(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN)); } } else { // USB_REQ_DIR_H2D if (req->wLength > 0) { - USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN)); + USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN)); } } diff --git a/embed/trezorhal/usbd_def.h b/embed/trezorhal/usbd_def.h index d3c3e5b991..e3da6243db 100644 --- a/embed/trezorhal/usbd_def.h +++ b/embed/trezorhal/usbd_def.h @@ -263,9 +263,12 @@ typedef struct _USBD_HandleTypeDef #define LOBYTE(x) ((uint8_t)(x & 0x00FF)) #define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8)) +#ifndef MIN #define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif +#ifndef MAX #define MAX(a, b) (((a) > (b)) ? (a) : (b)) - +#endif #if defined ( __GNUC__ ) #ifndef __weak diff --git a/embed/unix/common.h b/embed/unix/common.h index fd6c959495..e0bc6dde8f 100644 --- a/embed/unix/common.h +++ b/embed/unix/common.h @@ -27,10 +27,10 @@ #define STR(s) #s #ifndef MIN -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; }) #endif #ifndef MAX -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; }) #endif void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func); diff --git a/embed/unix/flash.c b/embed/unix/flash.c index 4e68a99538..8e4febe6ab 100644 --- a/embed/unix/flash.c +++ b/embed/unix/flash.c @@ -62,6 +62,27 @@ static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = { [24] = 0x08200000, // last element - not a valid sector }; +const uint8_t FIRMWARE_SECTORS[FIRMWARE_SECTORS_COUNT] = { + FLASH_SECTOR_FIRMWARE_START, + 7, + 8, + 9, + 10, + FLASH_SECTOR_FIRMWARE_END, + FLASH_SECTOR_FIRMWARE_EXTRA_START, + 18, + 19, + 20, + 21, + 22, + FLASH_SECTOR_FIRMWARE_EXTRA_END, +}; + +const uint8_t STORAGE_SECTORS[STORAGE_SECTORS_COUNT] = { + FLASH_SECTOR_STORAGE_1, + FLASH_SECTOR_STORAGE_2, +}; + static uint8_t *FLASH_BUFFER; static uint32_t FLASH_SIZE; diff --git a/src/apps/common/request_pin.py b/src/apps/common/request_pin.py index 82eb3eb77b..c0d9f091c2 100644 --- a/src/apps/common/request_pin.py +++ b/src/apps/common/request_pin.py @@ -36,6 +36,17 @@ async def request_pin( c.taint() c.render() + c = dialog.confirm + if matrix.pin: + if not c.is_enabled(): + c.enable() + c.taint() + else: + if c.is_enabled(): + c.disable() + c.taint() + c.render() + if label is None: label = "Enter your PIN" sublabel = None @@ -59,6 +70,8 @@ async def request_pin( else: result = await dialog if result == CONFIRMED: + if not matrix.pin: + continue return matrix.pin elif matrix.pin: # reset matrix.change("") diff --git a/src/apps/common/storage.py b/src/apps/common/storage.py index 92c2a0d13c..e30f263dce 100644 --- a/src/apps/common/storage.py +++ b/src/apps/common/storage.py @@ -195,7 +195,7 @@ def init_unlocked(): counter = config.get(_APP, _U2F_COUNTER) if counter is not None: config.set_counter( - _APP, _U2F_COUNTER, counter, True + _APP, _U2F_COUNTER, int.from_bytes(counter, "big"), True ) # writable when locked config.delete(_APP, _U2F_COUNTER) config.set(_APP, _VERSION, _STORAGE_VERSION) diff --git a/src/apps/fido_u2f/__init__.py b/src/apps/fido_u2f/__init__.py index fae31981c6..1825a3d259 100644 --- a/src/apps/fido_u2f/__init__.py +++ b/src/apps/fido_u2f/__init__.py @@ -353,7 +353,7 @@ class ConfirmState: return False return True - def setup(self, action: int, checksum: bytes, app_id: bytes) -> None: + def setup(self, action: int, checksum: bytes, app_id: bytes) -> bool: if workflow.workflows: return False @@ -379,6 +379,10 @@ class ConfirmState: @ui.layout async def confirm_layout(self) -> None: + workflow.fido_u2f_stop_signal.reset() + await loop.spawn(self.confirm_layout_inner(), workflow.fido_u2f_stop_signal) + + async def confirm_layout_inner(self) -> None: from trezor.ui.confirm import ConfirmDialog, CONFIRMED from trezor.ui.text import Text diff --git a/src/apps/management/change_pin.py b/src/apps/management/change_pin.py index b85a7e0338..bff28395a1 100644 --- a/src/apps/management/change_pin.py +++ b/src/apps/management/change_pin.py @@ -17,8 +17,10 @@ async def change_pin(ctx, msg): # get current pin, return failure if invalid if config.has_pin(): curpin = await request_pin_ack(ctx, "Enter old PIN", config.get_pin_rem()) - if not config.check_pin(pin_to_int(curpin)): - raise wire.PinInvalid("PIN invalid") + # if removing, defer check to change_pin() + if not msg.remove: + if not config.check_pin(pin_to_int(curpin)): + raise wire.PinInvalid("PIN invalid") else: curpin = "" diff --git a/src/apps/management/recovery_device.py b/src/apps/management/recovery_device.py index 07772b085b..271fc8de33 100644 --- a/src/apps/management/recovery_device.py +++ b/src/apps/management/recovery_device.py @@ -57,6 +57,8 @@ async def recovery_device(ctx, msg): # ask for pin repeatedly if msg.pin_protection: newpin = await request_pin_confirm(ctx, cancellable=False) + else: + newpin = "" # dry run if msg.dry_run: @@ -72,7 +74,7 @@ async def recovery_device(ctx, msg): ) # save into storage - if msg.pin_protection: + if newpin: config.change_pin(pin_to_int(""), pin_to_int(newpin)) storage.set_u2f_counter(msg.u2f_counter) storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection) diff --git a/src/apps/management/reset_device.py b/src/apps/management/reset_device.py index d711a7342f..becc2c27f9 100644 --- a/src/apps/management/reset_device.py +++ b/src/apps/management/reset_device.py @@ -73,8 +73,9 @@ async def reset_device(ctx, msg): await show_wrong_entry(ctx) # write PIN into storage - if not config.change_pin(pin_to_int(""), pin_to_int(newpin)): - raise wire.ProcessError("Could not change PIN") + if newpin: + if not config.change_pin(pin_to_int(""), pin_to_int(newpin)): + raise wire.ProcessError("Could not change PIN") # write settings and mnemonic into storage storage.load_settings(label=msg.label, use_passphrase=msg.passphrase_protection) diff --git a/src/apps/wallet/sign_tx/__init__.py b/src/apps/wallet/sign_tx/__init__.py index 2a6213fd6b..3c6fd7bc21 100644 --- a/src/apps/wallet/sign_tx/__init__.py +++ b/src/apps/wallet/sign_tx/__init__.py @@ -1,4 +1,4 @@ -from trezor import ui, wire +from trezor import wire from trezor.messages.MessageType import TxAck from trezor.messages.RequestType import TXFINISHED from trezor.messages.TxRequest import TxRequest @@ -16,7 +16,6 @@ from apps.wallet.sign_tx import ( ) -@ui.layout async def sign_tx(ctx, msg, keychain): signer = signing.sign_tx(msg, keychain) diff --git a/src/trezor/loop.py b/src/trezor/loop.py index 8075afbbd1..7d25e5583f 100644 --- a/src/trezor/loop.py +++ b/src/trezor/loop.py @@ -185,6 +185,9 @@ class signal(Syscall): """ def __init__(self): + self.reset() + + def reset(self): self.value = _NO_VALUE self.task = None diff --git a/src/trezor/pin.py b/src/trezor/pin.py index eb4faa96df..5c62b69ffe 100644 --- a/src/trezor/pin.py +++ b/src/trezor/pin.py @@ -5,11 +5,11 @@ def pin_to_int(pin: str) -> int: return int("1" + pin) -def show_pin_timeout(seconds: int, progress: int) -> bool: +def show_pin_timeout(seconds: int, progress: int, message: str) -> bool: if progress == 0: ui.display.bar(0, 0, ui.WIDTH, ui.HEIGHT, ui.BG) ui.display.text_center( - ui.WIDTH // 2, 37, "Verifying PIN", ui.BOLD, ui.FG, ui.BG, ui.WIDTH + ui.WIDTH // 2, 37, message, ui.BOLD, ui.FG, ui.BG, ui.WIDTH ) ui.display.loader(progress, 0, ui.FG, ui.BG) if seconds == 0: diff --git a/src/trezor/ui/button.py b/src/trezor/ui/button.py index 5d39410a77..75f5e427d2 100644 --- a/src/trezor/ui/button.py +++ b/src/trezor/ui/button.py @@ -36,6 +36,9 @@ class Button(Widget): self.state = BTN_DISABLED self.tainted = True + def is_enabled(self): + return self.state != BTN_DISABLED + def render(self): if not self.tainted: return diff --git a/src/trezor/workflow.py b/src/trezor/workflow.py index 8b6d32d83d..7e11d4c32c 100644 --- a/src/trezor/workflow.py +++ b/src/trezor/workflow.py @@ -5,6 +5,9 @@ layouts = [] default = None default_layout = None +# HACK: workaround way to stop the u2f layout from the outside +fido_u2f_stop_signal = loop.signal() + def onstart(w): workflows.append(w) @@ -44,6 +47,7 @@ def restartdefault(): def onlayoutstart(l): closedefault() layouts.append(l) + fido_u2f_stop_signal.send(None) def onlayoutclose(l): diff --git a/vendor/trezor-crypto b/vendor/trezor-crypto index 21391dc5be..4211ce389f 160000 --- a/vendor/trezor-crypto +++ b/vendor/trezor-crypto @@ -1 +1 @@ -Subproject commit 21391dc5be9917bc32a518cf98376f79103727af +Subproject commit 4211ce389f6795d844809b0ba66a84082038ca04 diff --git a/vendor/trezor-storage b/vendor/trezor-storage index e55737c4b1..511fc205b2 160000 --- a/vendor/trezor-storage +++ b/vendor/trezor-storage @@ -1 +1 @@ -Subproject commit e55737c4b1648c619d654eb25fa06fe381c5a1d4 +Subproject commit 511fc205b284605651348512c5c5c2c95a642fa1