diff --git a/core/.changelog.d/4747.changed b/core/.changelog.d/4747.changed new file mode 100644 index 0000000000..61fe714793 --- /dev/null +++ b/core/.changelog.d/4747.changed @@ -0,0 +1 @@ +Migrate storage to version 6. diff --git a/core/embed/models/D001/memory.ld b/core/embed/models/D001/memory.ld index f73327a7ed..075cccbacc 100644 --- a/core/embed/models/D001/memory.ld +++ b/core/embed/models/D001/memory.ld @@ -1,7 +1,8 @@ /* Auto-generated file, do not edit.*/ -NORCOW_SECTOR_SIZE = 0x10000; FLASH_START = 0x8000000; +NORCOW_SECTOR_SIZE = 0x10000; +NORCOW_MIN_VERSION = 0x0; BOARDLOADER_START = 0x8000000; BOARDLOADER_MAXSIZE = 0xc000; BOARDLOADER_SECTOR_START = 0x0; diff --git a/core/embed/models/D001/model_D001.h b/core/embed/models/D001/model_D001.h index 152ab8bbc6..a44f443193 100644 --- a/core/embed/models/D001/model_D001.h +++ b/core/embed/models/D001/model_D001.h @@ -31,8 +31,9 @@ // SHARED WITH MAKEFILE // common -#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB #define FLASH_START 0x08000000 +#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB +#define NORCOW_MIN_VERSION 0x00000000 // FLASH layout #define BOARDLOADER_START 0x08000000 diff --git a/core/embed/models/D002/memory.ld b/core/embed/models/D002/memory.ld index a5c9e5170c..82056cd7a5 100644 --- a/core/embed/models/D002/memory.ld +++ b/core/embed/models/D002/memory.ld @@ -2,6 +2,7 @@ FLASH_START = 0xc004000; NORCOW_SECTOR_SIZE = 0x20000; +NORCOW_MIN_VERSION = 0x6; SECRET_START = 0xc000000; SECRET_MAXSIZE = 0x4000; SECRET_SECTOR_START = 0x0; @@ -26,7 +27,6 @@ FIRMWARE_SECTOR_START = 0x22; FIRMWARE_SECTOR_END = 0x1cf; KERNEL_START = 0xc044000; KERNEL_MAXSIZE = 0x80000; -KERNEL_U_FLASH_SIZE = 0x200; STORAGE_1_START = 0xc3a0000; STORAGE_1_MAXSIZE = 0x20000; STORAGE_1_SECTOR_START = 0x1d0; @@ -44,9 +44,7 @@ BOOTARGS_SIZE = 0x200; FB1_RAM_START = 0x30000200; FB1_RAM_SIZE = 0xbfe00; MAIN_RAM_START = 0x300c0000; -MAIN_RAM_SIZE = 0xfe00; -SAES_RAM_START = 0x300cfe00; -SAES_RAM_SIZE = 0x200; +MAIN_RAM_SIZE = 0x10000; FB2_RAM_START = 0x300d0000; FB2_RAM_SIZE = 0xc0000; AUX1_RAM_START = 0x30190000; diff --git a/core/embed/models/D002/model_D002.h b/core/embed/models/D002/model_D002.h index 0f23e22b3c..34a21371f3 100644 --- a/core/embed/models/D002/model_D002.h +++ b/core/embed/models/D002/model_D002.h @@ -34,6 +34,7 @@ // misc #define FLASH_START 0x0C004000 #define NORCOW_SECTOR_SIZE (16 * 8 * 1024) // 128 kB +#define NORCOW_MIN_VERSION 0x00000006 // FLASH layout #define SECRET_START 0x0C000000 @@ -66,7 +67,6 @@ #define FIRMWARE_SECTOR_END 0x1CF #define KERNEL_START 0x0C044000 #define KERNEL_MAXSIZE (512 * 1024) // 512 kB -#define KERNEL_U_FLASH_SIZE 512 #define STORAGE_1_START 0x0C3A0000 #define STORAGE_1_MAXSIZE (16 * 8 * 1024) // 128 kB @@ -91,10 +91,7 @@ #define FB1_RAM_SIZE (768 * 1024 - 512) #define MAIN_RAM_START 0x300C0000 -#define MAIN_RAM_SIZE (64 * 1024 - 512) - -#define SAES_RAM_START 0x300CFE00 -#define SAES_RAM_SIZE 512 +#define MAIN_RAM_SIZE (64 * 1024) #define FB2_RAM_START 0x300D0000 #define FB2_RAM_SIZE (768 * 1024) diff --git a/core/embed/models/T2B1/memory.ld b/core/embed/models/T2B1/memory.ld index 0509d49883..bcdbef4add 100644 --- a/core/embed/models/T2B1/memory.ld +++ b/core/embed/models/T2B1/memory.ld @@ -1,7 +1,8 @@ /* Auto-generated file, do not edit.*/ -NORCOW_SECTOR_SIZE = 0x10000; FLASH_START = 0x8000000; +NORCOW_SECTOR_SIZE = 0x10000; +NORCOW_MIN_VERSION = 0x0; BOARDLOADER_START = 0x8000000; BOARDLOADER_MAXSIZE = 0xc000; BOARDLOADER_SECTOR_START = 0x0; diff --git a/core/embed/models/T2B1/model_T2B1.h b/core/embed/models/T2B1/model_T2B1.h index 1222d1b03a..b556d0b78e 100644 --- a/core/embed/models/T2B1/model_T2B1.h +++ b/core/embed/models/T2B1/model_T2B1.h @@ -32,8 +32,9 @@ // SHARED WITH MAKEFILE // common -#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB #define FLASH_START 0x08000000 +#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB +#define NORCOW_MIN_VERSION 0x00000000 // FLASH layout #define BOARDLOADER_START 0x08000000 diff --git a/core/embed/models/T2T1/memory.ld b/core/embed/models/T2T1/memory.ld index f73327a7ed..075cccbacc 100644 --- a/core/embed/models/T2T1/memory.ld +++ b/core/embed/models/T2T1/memory.ld @@ -1,7 +1,8 @@ /* Auto-generated file, do not edit.*/ -NORCOW_SECTOR_SIZE = 0x10000; FLASH_START = 0x8000000; +NORCOW_SECTOR_SIZE = 0x10000; +NORCOW_MIN_VERSION = 0x0; BOARDLOADER_START = 0x8000000; BOARDLOADER_MAXSIZE = 0xc000; BOARDLOADER_SECTOR_START = 0x0; diff --git a/core/embed/models/T2T1/model_T2T1.h b/core/embed/models/T2T1/model_T2T1.h index d67ad192dd..978cfe0d55 100644 --- a/core/embed/models/T2T1/model_T2T1.h +++ b/core/embed/models/T2T1/model_T2T1.h @@ -32,8 +32,9 @@ // SHARED WITH MAKEFILE // common -#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB #define FLASH_START 0x08000000 +#define NORCOW_SECTOR_SIZE (1 * 64 * 1024) // 64 kB +#define NORCOW_MIN_VERSION 0x00000000 // FLASH layout #define BOARDLOADER_START 0x08000000 diff --git a/core/embed/models/T3B1/memory.ld b/core/embed/models/T3B1/memory.ld index 2065664c94..bd48ee2797 100644 --- a/core/embed/models/T3B1/memory.ld +++ b/core/embed/models/T3B1/memory.ld @@ -2,6 +2,7 @@ FLASH_START = 0xc004000; NORCOW_SECTOR_SIZE = 0x10000; +NORCOW_MIN_VERSION = 0x0; SECRET_START = 0xc000000; SECRET_MAXSIZE = 0x4000; SECRET_SECTOR_START = 0x0; diff --git a/core/embed/models/T3B1/model_T3B1.h b/core/embed/models/T3B1/model_T3B1.h index 2ab765869f..fd3bd8d2d1 100644 --- a/core/embed/models/T3B1/model_T3B1.h +++ b/core/embed/models/T3B1/model_T3B1.h @@ -34,6 +34,7 @@ // misc #define FLASH_START 0x0C004000 #define NORCOW_SECTOR_SIZE (8 * 8 * 1024) // 64 kB +#define NORCOW_MIN_VERSION 0x00000000 // FLASH layout #define SECRET_START 0x0C000000 diff --git a/core/embed/models/T3T1/memory.ld b/core/embed/models/T3T1/memory.ld index 89dd8c5dcf..ccec1b04d4 100644 --- a/core/embed/models/T3T1/memory.ld +++ b/core/embed/models/T3T1/memory.ld @@ -2,6 +2,7 @@ FLASH_START = 0xc004000; NORCOW_SECTOR_SIZE = 0x10000; +NORCOW_MIN_VERSION = 0x0; SECRET_START = 0xc000000; SECRET_MAXSIZE = 0x4000; SECRET_SECTOR_START = 0x0; diff --git a/core/embed/models/T3T1/model_T3T1.h b/core/embed/models/T3T1/model_T3T1.h index d98f8c81e3..2c7d972c58 100644 --- a/core/embed/models/T3T1/model_T3T1.h +++ b/core/embed/models/T3T1/model_T3T1.h @@ -34,6 +34,7 @@ // misc #define FLASH_START 0x0C004000 #define NORCOW_SECTOR_SIZE (8 * 8 * 1024) // 64 kB +#define NORCOW_MIN_VERSION 0x00000000 // FLASH layout #define SECRET_START 0x0C000000 diff --git a/core/embed/models/T3W1/memory.ld b/core/embed/models/T3W1/memory.ld index a5c9e5170c..82056cd7a5 100644 --- a/core/embed/models/T3W1/memory.ld +++ b/core/embed/models/T3W1/memory.ld @@ -2,6 +2,7 @@ FLASH_START = 0xc004000; NORCOW_SECTOR_SIZE = 0x20000; +NORCOW_MIN_VERSION = 0x6; SECRET_START = 0xc000000; SECRET_MAXSIZE = 0x4000; SECRET_SECTOR_START = 0x0; @@ -26,7 +27,6 @@ FIRMWARE_SECTOR_START = 0x22; FIRMWARE_SECTOR_END = 0x1cf; KERNEL_START = 0xc044000; KERNEL_MAXSIZE = 0x80000; -KERNEL_U_FLASH_SIZE = 0x200; STORAGE_1_START = 0xc3a0000; STORAGE_1_MAXSIZE = 0x20000; STORAGE_1_SECTOR_START = 0x1d0; @@ -44,9 +44,7 @@ BOOTARGS_SIZE = 0x200; FB1_RAM_START = 0x30000200; FB1_RAM_SIZE = 0xbfe00; MAIN_RAM_START = 0x300c0000; -MAIN_RAM_SIZE = 0xfe00; -SAES_RAM_START = 0x300cfe00; -SAES_RAM_SIZE = 0x200; +MAIN_RAM_SIZE = 0x10000; FB2_RAM_START = 0x300d0000; FB2_RAM_SIZE = 0xc0000; AUX1_RAM_START = 0x30190000; diff --git a/core/embed/models/T3W1/model_T3W1.h b/core/embed/models/T3W1/model_T3W1.h index 83bf16f7a6..8c3d9d6de1 100644 --- a/core/embed/models/T3W1/model_T3W1.h +++ b/core/embed/models/T3W1/model_T3W1.h @@ -33,6 +33,7 @@ // misc #define FLASH_START 0x0C004000 #define NORCOW_SECTOR_SIZE (16 * 8 * 1024) // 128 kB +#define NORCOW_MIN_VERSION 0x00000006 // FLASH layout #define SECRET_START 0x0C000000 @@ -65,7 +66,6 @@ #define FIRMWARE_SECTOR_END 0x1CF #define KERNEL_START 0x0C044000 #define KERNEL_MAXSIZE (512 * 1024) // 512 kB -#define KERNEL_U_FLASH_SIZE 512 #define STORAGE_1_START 0x0C3A0000 #define STORAGE_1_MAXSIZE (16 * 8 * 1024) // 128 kB @@ -90,10 +90,7 @@ #define FB1_RAM_SIZE (768 * 1024 - 512) #define MAIN_RAM_START 0x300C0000 -#define MAIN_RAM_SIZE (64 * 1024 - 512) - -#define SAES_RAM_START 0x300CFE00 -#define SAES_RAM_SIZE 512 +#define MAIN_RAM_SIZE (64 * 1024) #define FB2_RAM_START 0x300D0000 #define FB2_RAM_SIZE (768 * 1024) diff --git a/core/embed/projects/firmware/version.h b/core/embed/projects/firmware/version.h index f927aa3c95..53f8cb3549 100644 --- a/core/embed/projects/firmware/version.h +++ b/core/embed/projects/firmware/version.h @@ -3,11 +3,11 @@ #include "model_version.h" #define VERSION_MAJOR 2 -#define VERSION_MINOR 8 -#define VERSION_PATCH 10 +#define VERSION_MINOR 9 +#define VERSION_PATCH 0 #define VERSION_BUILD 0 #define FIX_VERSION_MAJOR 2 -#define FIX_VERSION_MINOR 8 +#define FIX_VERSION_MINOR 9 #define FIX_VERSION_PATCH 0 #define FIX_VERSION_BUILD 0 diff --git a/core/embed/sec/secure_aes/stm32u5/secure_aes.c b/core/embed/sec/secure_aes/stm32u5/secure_aes.c index f9b13f8e8a..41def5a319 100644 --- a/core/embed/sec/secure_aes/stm32u5/secure_aes.c +++ b/core/embed/sec/secure_aes/stm32u5/secure_aes.c @@ -24,12 +24,6 @@ #include #include -#include -#include - -#ifdef USE_TRUSTZONE -#include -#endif #include "memzero.h" @@ -38,8 +32,6 @@ #ifdef KERNEL_MODE -#include - static void secure_aes_load_bhk(void) { TAMP->BKP0R; TAMP->BKP1R; @@ -76,8 +68,18 @@ static secbool is_key_supported(secure_aes_keysel_t key) { } } +#if NORCOW_MIN_VERSION <= 5 #ifdef SYSCALL_DISPATCH +#include +#include + +#ifdef USE_TRUSTZONE +#include +#endif + +#include + __attribute__((section(".udata"))) uint32_t saes_input[SAES_DATA_SIZE_WITH_UPRIV_KEY / sizeof(uint32_t)]; @@ -220,13 +222,16 @@ secbool unpriv_encrypt(const uint8_t* input, size_t size, uint8_t* output, return retval; } #endif +#endif secbool secure_aes_ecb_encrypt_hw(const uint8_t* input, size_t size, uint8_t* output, secure_aes_keysel_t key) { +#if NORCOW_MIN_VERSION <= 5 #ifdef SYSCALL_DISPATCH if (key == SECURE_AES_KEY_XORK_SN) { return unpriv_encrypt(input, size, output, key); } +#endif #endif if (sectrue != is_key_supported(key)) { diff --git a/core/embed/sys/linker/stm32u5g/boardloader.ld b/core/embed/sys/linker/stm32u5g/boardloader.ld index df63d1203b..f32f17c0a7 100644 --- a/core/embed/sys/linker/stm32u5g/boardloader.ld +++ b/core/embed/sys/linker/stm32u5g/boardloader.ld @@ -9,7 +9,6 @@ MEMORY { MAIN_RAM (wal) : ORIGIN = MAIN_RAM_START, LENGTH = MAIN_RAM_SIZE AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE BOOT_ARGS (wal) : ORIGIN = BOOTARGS_START, LENGTH = BOOTARGS_SIZE - SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } diff --git a/core/embed/sys/linker/stm32u5g/bootloader.ld b/core/embed/sys/linker/stm32u5g/bootloader.ld index ce1557ce7e..b7c75e16c4 100644 --- a/core/embed/sys/linker/stm32u5g/bootloader.ld +++ b/core/embed/sys/linker/stm32u5g/bootloader.ld @@ -8,7 +8,6 @@ MEMORY { MAIN_RAM (wal) : ORIGIN = MAIN_RAM_START, LENGTH = MAIN_RAM_SIZE AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE BOOT_ARGS (wal) : ORIGIN = BOOTARGS_START, LENGTH = BOOTARGS_SIZE - SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } diff --git a/core/embed/sys/linker/stm32u5g/kernel.ld b/core/embed/sys/linker/stm32u5g/kernel.ld index 9ae4b177dc..97c5538043 100644 --- a/core/embed/sys/linker/stm32u5g/kernel.ld +++ b/core/embed/sys/linker/stm32u5g/kernel.ld @@ -7,7 +7,6 @@ MEMORY { MAIN_RAM (wal) : ORIGIN = MAIN_RAM_START, LENGTH = MAIN_RAM_SIZE BOOT_ARGS (wal) : ORIGIN = BOOTARGS_START, LENGTH = BOOTARGS_SIZE - SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } @@ -15,11 +14,6 @@ MEMORY { _stack_section_start = ADDR(.stack); _stack_section_end = ADDR(.stack) + SIZEOF(.stack); - -ustack_base = ADDR(.udata) + 512; -_sustack = ADDR(.udata) + 256; -_eustack = ustack_base; - _data_section_loadaddr = LOADADDR(.data); _data_section_start = ADDR(.data); _data_section_end = ADDR(.data) + SIZEOF(.data); @@ -39,13 +33,10 @@ _accessible_ram_1_end = MCU_SRAM4 + MCU_SRAM4_SIZE; _bootargs_ram_start = BOOTARGS_START; _bootargs_ram_end = BOOTARGS_START + BOOTARGS_SIZE; -_codelen = SIZEOF(.vendorheader) + SIZEOF(.header) + SIZEOF(.flash) + SIZEOF(.uflash) + SIZEOF(.data) + SIZEOF(.confidential); +_codelen = SIZEOF(.vendorheader) + SIZEOF(.header) + SIZEOF(.flash) + SIZEOF(.data) + SIZEOF(.confidential); _flash_start = ORIGIN(FLASH); _flash_end = ORIGIN(FLASH) + LENGTH(FLASH); -_uflash_start = ADDR(.uflash); -_uflash_end = ADDR(.uflash) + SIZEOF(.uflash); - SECTIONS { .vendorheader : ALIGN(4) { KEEP(*(.vendorheader)) @@ -87,23 +78,11 @@ SECTIONS { . = ALIGN(4); } >MAIN_RAM - /* unprivileged data and stack for SAES */ - .udata : ALIGN(512) { - *(.udata*); - . = ALIGN(256); - . = 256; /* Overflow causes UsageFault */ - } >SAES_RAM - .confidential : ALIGN(512) { *(.confidential*); . = ALIGN(512); } >MAIN_RAM AT>FLASH - .uflash : ALIGN(512) { - *(.uflash*); - . = ALIGN(COREAPP_ALIGNMENT); - } >FLASH AT>FLASH - .fb1 : ALIGN(4) { *(.fb1*); . = ALIGN(4); diff --git a/core/embed/sys/linker/stm32u5g/prodtest.ld b/core/embed/sys/linker/stm32u5g/prodtest.ld index efc2f4ab56..a8ad81890a 100644 --- a/core/embed/sys/linker/stm32u5g/prodtest.ld +++ b/core/embed/sys/linker/stm32u5g/prodtest.ld @@ -8,7 +8,6 @@ MEMORY { MAIN_RAM (wal) : ORIGIN = MAIN_RAM_START, LENGTH = MAIN_RAM_SIZE AUX1_RAM (wal) : ORIGIN = AUX1_RAM_START, LENGTH = AUX1_RAM_SIZE BOOT_ARGS (wal) : ORIGIN = BOOTARGS_START, LENGTH = BOOTARGS_SIZE - SAES_RAM (wal) : ORIGIN = SAES_RAM_START, LENGTH = SAES_RAM_SIZE FB1_RAM (wal) : ORIGIN = FB1_RAM_START, LENGTH = FB1_RAM_SIZE FB2_RAM (wal) : ORIGIN = FB2_RAM_START, LENGTH = FB2_RAM_SIZE } diff --git a/core/embed/sys/mpu/stm32u5/mpu.c b/core/embed/sys/mpu/stm32u5/mpu.c index 1f61e62169..3e8b61fb21 100644 --- a/core/embed/sys/mpu/stm32u5/mpu.c +++ b/core/embed/sys/mpu/stm32u5/mpu.c @@ -143,6 +143,7 @@ _Static_assert(NORCOW_SECTOR_SIZE == STORAGE_2_MAXSIZE, "norcow misconfigured"); #ifdef KERNEL +#ifdef KERNEL_FLASH_U_START extern uint8_t _uflash_start; extern uint8_t _uflash_end; #define KERNEL_FLASH_U_START (uint32_t) & _uflash_start @@ -159,6 +160,20 @@ extern uint32_t _codelen; #define COREAPP_FLASH_SIZE \ (FIRMWARE_MAXSIZE - (COREAPP_FLASH_START - KERNEL_FLASH_START)) +#else + +extern uint32_t _codelen; +#define KERNEL_SIZE (uint32_t) & _codelen + +#define KERNEL_FLASH_START KERNEL_START +#define KERNEL_FLASH_SIZE KERNEL_SIZE + +#define COREAPP_FLASH_START \ + (COREAPP_CODE_ALIGN(KERNEL_FLASH_START + KERNEL_SIZE)) +#define COREAPP_FLASH_SIZE \ + (FIRMWARE_MAXSIZE - (COREAPP_FLASH_START - KERNEL_FLASH_START)) +#endif + #endif typedef struct { @@ -402,7 +417,9 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) { // REGION ADDRESS SIZE TYPE WRITE UNPRIV #ifdef KERNEL case MPU_MODE_SAES: +#ifdef SAES_RAM_START SET_REGION( 7, SAES_RAM_START, SAES_RAM_SIZE, SRAM, YES, YES ); // Unprivileged kernel SRAM +#endif break; #endif default: diff --git a/core/embed/upymod/modtrezorconfig/norcow_config.h b/core/embed/upymod/modtrezorconfig/norcow_config.h index 5cb12bdc14..1b5775ef6c 100644 --- a/core/embed/upymod/modtrezorconfig/norcow_config.h +++ b/core/embed/upymod/modtrezorconfig/norcow_config.h @@ -31,6 +31,6 @@ /* * Current storage version. */ -#define NORCOW_VERSION ((uint32_t)0x00000005) +#define NORCOW_VERSION ((uint32_t)0x00000006) #endif diff --git a/core/translations/cs.json b/core/translations/cs.json index ae20e24635..f188b29ad3 100644 --- a/core/translations/cs.json +++ b/core/translations/cs.json @@ -43,7 +43,7 @@ }, "header": { "language": "cs-CZ", - "version": "2.8.10" + "version": "2.9.0" }, "translations": { "addr_mismatch__contact_support_at": "Kontaktujte naši podporu na", diff --git a/core/translations/de.json b/core/translations/de.json index c6bb89b5ca..9932516a62 100644 --- a/core/translations/de.json +++ b/core/translations/de.json @@ -43,7 +43,7 @@ }, "header": { "language": "de-DE", - "version": "2.8.10" + "version": "2.9.0" }, "translations": { "addr_mismatch__contact_support_at": "Kontaktiere den Trezor Support unter", diff --git a/core/translations/en.json b/core/translations/en.json index cb51816904..2c60496cae 100644 --- a/core/translations/en.json +++ b/core/translations/en.json @@ -1,7 +1,7 @@ { "header": { "language": "en-US", - "version": "2.8.10" + "version": "2.9.0" }, "translations": { "addr_mismatch__contact_support_at": "Please contact Trezor support at", diff --git a/core/translations/es.json b/core/translations/es.json index e4fd055c7d..f59ce0ab02 100644 --- a/core/translations/es.json +++ b/core/translations/es.json @@ -43,7 +43,7 @@ }, "header": { "language": "es-ES", - "version": "2.8.10" + "version": "2.9.0" }, "translations": { "addr_mismatch__contact_support_at": "Contacta con atención al cliente de Trezor en", diff --git a/core/translations/fr.json b/core/translations/fr.json index 56c5ec0c81..2881079f96 100644 --- a/core/translations/fr.json +++ b/core/translations/fr.json @@ -43,7 +43,7 @@ }, "header": { "language": "fr-FR", - "version": "2.8.10" + "version": "2.9.0" }, "translations": { "addr_mismatch__contact_support_at": "Contactez l'assistance Trezor à l'adr.", diff --git a/core/translations/it.json b/core/translations/it.json index d3db89913c..fa464fb9d2 100644 --- a/core/translations/it.json +++ b/core/translations/it.json @@ -43,7 +43,7 @@ }, "header": { "language": "it-IT", - "version": "2.8.10" + "version": "2.9.0" }, "translations": { "addr_mismatch__contact_support_at": "Contatta l'Assistenza di Trezor all'indirizzo", diff --git a/core/translations/pt.json b/core/translations/pt.json index 707fe7d01d..be3cc09db5 100644 --- a/core/translations/pt.json +++ b/core/translations/pt.json @@ -43,7 +43,7 @@ }, "header": { "language": "pt-BR", - "version": "2.8.10" + "version": "2.9.0" }, "translations": { "addr_mismatch__contact_support_at": "Entre em contato com o suporte Trezor em", diff --git a/core/translations/signatures.json b/core/translations/signatures.json index e6183c76bb..a3fe09086f 100644 --- a/core/translations/signatures.json +++ b/core/translations/signatures.json @@ -1,8 +1,8 @@ { "current": { - "merkle_root": "f00c1c603fb911b9b65dbe30261310c4ed90ac1ff90f9c5e52e0ce34acce2745", - "datetime": "2025-03-06T16:38:48.918299", - "commit": "6509d2b3f29d5bd3ee24a3843a6f3e6d9877cf30" + "merkle_root": "1d498d74141d129493b1625901df1ce796eccf167c08bbb1dca7fc29854fe3ac", + "datetime": "2025-03-12T02:14:31.796699", + "commit": "719972c8178865c10cfc78dac25d79e19da40d90" }, "history": [ { diff --git a/core/translations/tr.json b/core/translations/tr.json index 8db59c23a9..23528b3643 100644 --- a/core/translations/tr.json +++ b/core/translations/tr.json @@ -43,7 +43,7 @@ }, "header": { "language": "tr-TR", - "version": "2.8.10" + "version": "2.9.0" }, "translations": { "addr_mismatch__contact_support_at": "Lütfen Trezor support ile iletişime geçin:", diff --git a/legacy/norcow_config.h b/legacy/norcow_config.h index 2f03ecd0c0..62142aa909 100644 --- a/legacy/norcow_config.h +++ b/legacy/norcow_config.h @@ -38,6 +38,7 @@ extern const flash_area_t STORAGE_AREAS[NORCOW_SECTOR_COUNT]; /* * Current storage version. */ -#define NORCOW_VERSION ((uint32_t)0x00000005) +#define NORCOW_VERSION ((uint32_t)0x00000006) +#define NORCOW_MIN_VERSION 0x00000000 #endif diff --git a/storage/storage.c b/storage/storage.c index e3c54dadb0..1f1e956957 100644 --- a/storage/storage.c +++ b/storage/storage.c @@ -160,7 +160,9 @@ static const uint32_t FALSE_WORD = 0x3CA5965A; static void __handle_fault(const char *msg, const char *file, int line); #define handle_fault(msg) (__handle_fault(msg, __FILE_NAME__, __LINE__)) +#if NORCOW_MIN_VERSION < 2 static uint32_t pin_to_int(const uint8_t *pin, size_t pin_len); +#endif static secbool storage_upgrade(void); static secbool storage_upgrade_unlocked(const uint8_t *pin, size_t pin_len, const uint8_t *ext_salt); @@ -529,6 +531,7 @@ static void ui_progress_finish(void) { } } +#if NORCOW_MIN_VERSION <= 4 #if !USE_OPTIGA static void derive_kek_v4(const uint8_t *pin, size_t pin_len, const uint8_t *storage_salt, const uint8_t *ext_salt, @@ -579,11 +582,13 @@ static void derive_kek_v4(const uint8_t *pin, size_t pin_len, memzero(&salt, sizeof(salt)); } #endif +#endif -static void stretch_pin(const uint8_t *pin, size_t pin_len, - const uint8_t storage_salt[STORAGE_SALT_SIZE], - const uint8_t *ext_salt, - uint8_t stretched_pin[SHA256_DIGEST_LENGTH]) { +#if NORCOW_MIN_VERSION <= 5 +static void stretch_pin_v4(const uint8_t *pin, size_t pin_len, + const uint8_t storage_salt[STORAGE_SALT_SIZE], + const uint8_t *ext_salt, + uint8_t stretched_pin[SHA256_DIGEST_LENGTH]) { // Combining the PIN with the storage salt aims to ensure that if the // MCU-Optiga communication is compromised, then a user with a low-entropy PIN // remains protected against an attacker who is not able to read the contents @@ -627,7 +632,57 @@ static void stretch_pin(const uint8_t *pin, size_t pin_len, #endif memzero(&ctx, sizeof(ctx)); } +#endif +static void stretch_pin(const uint8_t *pin, size_t pin_len, + const uint8_t storage_salt[STORAGE_SALT_SIZE], + const uint8_t *ext_salt, + uint8_t stretched_pin[SHA256_DIGEST_LENGTH]) { + // Combining the PIN with the storage salt aims to ensure that if the + // MCU-Optiga communication is compromised, then a user with a low-entropy PIN + // remains protected against an attacker who is not able to read the contents + // of the MCU storage. Stretching the PIN with PBKDF2 ensures that even if + // Optiga itself is completely compromised, it will not reduce the security + // of the device below that of earlier Trezor models which also use PBKDF2 + // with the same number of iterations. + + uint8_t salt[HARDWARE_SALT_SIZE + STORAGE_SALT_SIZE + EXTERNAL_SALT_SIZE] = { + 0}; + size_t salt_len = 0; + + memcpy(salt + salt_len, hardware_salt, HARDWARE_SALT_SIZE); + salt_len += HARDWARE_SALT_SIZE; + + memcpy(salt + salt_len, storage_salt, STORAGE_SALT_SIZE); + salt_len += STORAGE_SALT_SIZE; + + if (ext_salt != NULL) { + memcpy(salt + salt_len, ext_salt, EXTERNAL_SALT_SIZE); + salt_len += EXTERNAL_SALT_SIZE; + } + + PBKDF2_HMAC_SHA256_CTX ctx = {0}; + pbkdf2_hmac_sha256_Init(&ctx, pin, pin_len, salt, salt_len, 1); + memzero(&salt, sizeof(salt)); + + for (int i = 1; i <= 10; i++) { + pbkdf2_hmac_sha256_Update(&ctx, PIN_ITER_COUNT / 10); + ui_progress(); + } +#ifdef USE_STORAGE_HWKEY + uint8_t stretched_pin_tmp[SHA256_DIGEST_LENGTH] = {0}; + pbkdf2_hmac_sha256_Final(&ctx, stretched_pin_tmp); + ensure(secure_aes_ecb_encrypt_hw(stretched_pin_tmp, SHA256_DIGEST_LENGTH, + stretched_pin, SECURE_AES_KEY_XORK_SP), + "secure_aes pin stretch failed"); + memzero(stretched_pin_tmp, sizeof(stretched_pin_tmp)); +#else + pbkdf2_hmac_sha256_Final(&ctx, stretched_pin); +#endif + memzero(&ctx, sizeof(ctx)); +} + +#if NORCOW_MIN_VERSION <= 4 #if USE_OPTIGA static void derive_kek_optiga_v4( // Legacy PIN verification method used in storage versions 3 and 4. @@ -647,6 +702,7 @@ static void derive_kek_optiga_v4( memzero(&ctx, sizeof(ctx)); } #endif +#endif static secbool __wur derive_kek_set( const uint8_t *pin, size_t pin_len, const uint8_t *storage_salt, @@ -661,6 +717,7 @@ static secbool __wur derive_kek_set( return sectrue; } +#if NORCOW_MIN_VERSION <= 4 static secbool __wur derive_kek_unlock_v4(const uint8_t *pin, size_t pin_len, const uint8_t *storage_salt, const uint8_t *ext_salt, @@ -670,7 +727,7 @@ static secbool __wur derive_kek_unlock_v4(const uint8_t *pin, size_t pin_len, #if USE_OPTIGA uint8_t optiga_secret[OPTIGA_PIN_SECRET_SIZE] = {0}; uint8_t stretched_pin[OPTIGA_PIN_SECRET_SIZE] = {0}; - stretch_pin(pin, pin_len, storage_salt, ext_salt, stretched_pin); + stretch_pin_v4(pin, pin_len, storage_salt, ext_salt, stretched_pin); optiga_pin_result ret = optiga_pin_verify_v4(ui_progress, stretched_pin, optiga_secret); memzero(stretched_pin, sizeof(stretched_pin)); @@ -692,6 +749,31 @@ static secbool __wur derive_kek_unlock_v4(const uint8_t *pin, size_t pin_len, #endif return sectrue; } +#endif + +#if NORCOW_MIN_VERSION <= 5 +static secbool __wur derive_kek_unlock_v5( + const uint8_t *pin, size_t pin_len, const uint8_t *storage_salt, + const uint8_t *ext_salt, uint8_t stretched_pin[SHA256_DIGEST_LENGTH]) { + stretch_pin_v4(pin, pin_len, storage_salt, ext_salt, stretched_pin); +#if USE_OPTIGA + optiga_pin_result ret = optiga_pin_verify(ui_progress, stretched_pin); + if (ret != OPTIGA_PIN_SUCCESS) { + memzero(stretched_pin, SHA256_DIGEST_LENGTH); + + if (ret == OPTIGA_PIN_COUNTER_EXCEEDED) { + // Unreachable code. Wipe should have already been triggered in unlock(). + storage_wipe(); + show_pin_too_many_screen(); + } + ensure(ret == OPTIGA_PIN_INVALID ? sectrue : secfalse, + "optiga_pin_verify failed"); + return secfalse; + } +#endif + return sectrue; +} +#endif static secbool __wur derive_kek_unlock( const uint8_t *pin, size_t pin_len, const uint8_t *storage_salt, @@ -925,17 +1007,32 @@ static secbool __wur decrypt_dek(const uint8_t *pin, size_t pin_len, // Derive the key encryption key and IV. uint8_t kek[SHA256_DIGEST_LENGTH] = {0}; uint8_t keiv[SHA256_DIGEST_LENGTH] = {0}; - if (get_lock_version() >= 5) { + uint32_t lock_version = get_lock_version(); + if (lock_version >= 6) { if (sectrue != derive_kek_unlock(pin, pin_len, storage_salt, ext_salt, kek)) { return secfalse; } - } else { + } +#if NORCOW_MIN_VERSION <= 5 + else if (lock_version == 5) { + if (sectrue != + derive_kek_unlock_v5(pin, pin_len, storage_salt, ext_salt, kek)) { + return secfalse; + } + } +#endif +#if NORCOW_MIN_VERSION <= 4 + else if (lock_version <= 4) { if (sectrue != derive_kek_unlock_v4(pin, pin_len, storage_salt, ext_salt, kek, keiv)) { return secfalse; }; } +#endif + else { + handle_fault("Unsupported lock version"); + } uint8_t keys[KEYS_SIZE] = {0}; uint8_t tag[POLY1305_TAG_SIZE] __attribute__((aligned(sizeof(uint32_t)))); @@ -972,19 +1069,21 @@ static secbool unlock(const uint8_t *pin, size_t pin_len, const uint8_t *ext_salt) { const uint8_t *unlock_pin = pin; size_t unlock_pin_len = pin_len; + uint32_t legacy_pin = 0; +#if NORCOW_MIN_VERSION <= 2 // In case of an upgrade from version 1 or 2, encode the PIN to the old // format. - uint32_t legacy_pin = 0; if (get_lock_version() <= 2) { legacy_pin = pin_to_int(pin, pin_len); unlock_pin = (const uint8_t *)&legacy_pin; unlock_pin_len = sizeof(legacy_pin); } +#endif - // In case of an upgrade from version 4 or earlier bump the total time of UI + // In case of an upgrade from version 5 or earlier bump the total time of UI // progress to account for the set_pin() call in storage_upgrade_unlocked(). - if (get_lock_version() <= 4) { + if (get_lock_version() <= 5) { ui_progress_add(ui_estimate_time_ms(STORAGE_PIN_OP_SET)); } @@ -1401,6 +1500,7 @@ end: } void storage_ensure_not_wipe_code(const uint8_t *pin, size_t pin_len) { +#if NORCOW_MIN_VERSION <= 2 // If we are unlocking the storage during upgrade from version 2 or lower, // then encode the PIN to the old format. uint32_t legacy_pin = 0; @@ -1409,9 +1509,12 @@ void storage_ensure_not_wipe_code(const uint8_t *pin, size_t pin_len) { pin = (const uint8_t *)&legacy_pin; pin_len = sizeof(legacy_pin); } +#endif ensure_not_wipe_code(pin, pin_len); +#if NORCOW_MIN_VERSION <= 2 memzero(&legacy_pin, sizeof(legacy_pin)); +#endif } secbool storage_has_wipe_code(void) { @@ -1487,6 +1590,7 @@ static void __handle_fault(const char *msg, const char *file, int line) { __fatal_error(msg, file, line); } +#if NORCOW_MIN_VERSION == 0 /* * Reads the PIN fail counter in version 0 format. Returns the current number of * failed PIN entries. @@ -1518,7 +1622,9 @@ static secbool v0_pin_get_fails(uint32_t *ctr) { *ctr = 0; return sectrue; } +#endif +#if NORCOW_MIN_VERSION <= 2 // Legacy conversion of PIN to the uint32 scheme that was used prior to storage // version 3. static uint32_t pin_to_int(const uint8_t *pin, size_t pin_len) { @@ -1583,6 +1689,7 @@ static char *int_to_wipe_code(uint32_t val) { } return &wipe_code[pos]; } +#endif static secbool storage_upgrade(void) { // Storage version 0: plaintext norcow @@ -1591,14 +1698,16 @@ static secbool storage_upgrade(void) { // Storage version 3: adds variable length PIN and wipe code // Storage version 4: changes data structure of encrypted data // Storage version 5: unifies KEK derivation for non-Optiga and Optiga + // Storage version 6: changes BHK key from unprivileged to privileged - const uint16_t V0_PIN_KEY = 0x0000; - const uint16_t V0_PIN_FAIL_KEY = 0x0001; uint16_t key = 0; uint16_t len = 0; const void *val = NULL; - secbool ret = secfalse; +#if NORCOW_MIN_VERSION == 0 + const uint16_t V0_PIN_KEY = 0x0000; + const uint16_t V0_PIN_FAIL_KEY = 0x0001; + secbool ret = secfalse; if (norcow_active_version == 0) { random_buffer(cached_keys, sizeof(cached_keys)); @@ -1651,7 +1760,11 @@ static secbool storage_upgrade(void) { unlocked = secfalse; memzero(cached_keys, sizeof(cached_keys)); - } else if (norcow_active_version < 4) { + } else +#endif + +#if NORCOW_MIN_VERSION < 4 + if (norcow_active_version < 4) { // Change data structure for encrypted entries. uint32_t offset = 0; while (sectrue == norcow_get_next(&offset, &key, &val, &len)) { @@ -1676,7 +1789,9 @@ static secbool storage_upgrade(void) { } } } - } else { + } else +#endif + { // Copy all entries. uint32_t offset = 0; while (sectrue == norcow_get_next(&offset, &key, &val, &len)) { @@ -1737,15 +1852,18 @@ static secbool storage_upgrade_unlocked(const uint8_t *pin, size_t pin_len, } secbool ret = sectrue; - if (version <= 4) { - // Upgrade EDEK_PVC_KEY from the uint32 PIN scheme (versions 1 and 2) or - // from the version 3 and 4 variable-length PIN scheme to the unified PIN - // scheme. +#if NORCOW_MIN_VERSION <= 5 + if (version <= 5) { + // Versions 1 and 2: Upgrade EDEK_PVC_KEY from the uint32 PIN scheme + // Versions 3 and 4: variable-length PIN scheme to the unified PIN + // Version 5: unprivilged to privilged BHK key if (sectrue != set_pin(pin, pin_len, ext_salt)) { return secfalse; } } +#endif +#if NORCOW_MIN_VERSION <= 2 if (version == 2) { // Upgrade WIPE_CODE_DATA_KEY from the old uint32 scheme to the new // variable-length scheme. @@ -1766,6 +1884,7 @@ static secbool storage_upgrade_unlocked(const uint8_t *pin, size_t pin_len, ret = set_wipe_code((const uint8_t *)wipe_code, wipe_code_len); memzero(wipe_code, wipe_code_len); } +#endif return ret; } diff --git a/storage/tests/c/norcow_config.h b/storage/tests/c/norcow_config.h index 04792c335d..0c1cbc40ea 100644 --- a/storage/tests/c/norcow_config.h +++ b/storage/tests/c/norcow_config.h @@ -41,6 +41,6 @@ /* * Current storage version. */ -#define NORCOW_VERSION ((uint32_t)0x00000005) +#define NORCOW_VERSION ((uint32_t)0x00000006) #endif diff --git a/storage/tests/python/src/consts.py b/storage/tests/python/src/consts.py index baa0da83ff..dae6e577ac 100644 --- a/storage/tests/python/src/consts.py +++ b/storage/tests/python/src/consts.py @@ -113,7 +113,7 @@ NORCOW_SECTOR_SIZE = 64 * 1024 NORCOW_MAGIC = b"NRC2" # Norcow version, set in the storage header, but also as an encrypted item. -NORCOW_VERSION = b"\x05\x00\x00\x00" +NORCOW_VERSION = b"\x06\x00\x00\x00" # Norcow magic combined with the version, which is stored as its negation. NORCOW_MAGIC_AND_VERSION = NORCOW_MAGIC + bytes(