diff --git a/core/embed/bootloader/main.c b/core/embed/bootloader/main.c index 3c5c1b347..307d77cce 100644 --- a/core/embed/bootloader/main.c +++ b/core/embed/bootloader/main.c @@ -329,6 +329,8 @@ void real_jump_to_firmware(void) { if (sectrue == secret_optiga_present()) { secret_optiga_backup(); secret_hide(); + } else { + secret_optiga_hide(); } #else secret_hide(); diff --git a/core/embed/prodtest/main.c b/core/embed/prodtest/main.c index f4f00d385..c8978462f 100644 --- a/core/embed/prodtest/main.c +++ b/core/embed/prodtest/main.c @@ -49,7 +49,12 @@ #endif #include "memzero.h" + +#ifdef STM32U5 +#include "stm32u5xx_ll_utils.h" +#else #include "stm32f4xx_ll_utils.h" +#endif #ifdef TREZOR_MODEL_T #define MODEL_IDENTIFIER "TREZOR2-" @@ -429,10 +434,10 @@ power_off: static void test_wipe(void) { // erase start of the firmware (metadata) -> invalidate FW ensure(flash_unlock_write(), NULL); - for (int i = 0; i < 1024 / sizeof(uint32_t); i++) { - ensure( - flash_area_write_word(&FIRMWARE_AREA, i * sizeof(uint32_t), 0x00000000), - NULL); + for (int i = 0; i < (1024 / FLASH_BLOCK_SIZE); i += FLASH_BLOCK_SIZE) { + flash_block_t data = {0}; + ensure(flash_area_write_block(&FIRMWARE_AREA, i * FLASH_BLOCK_SIZE, data), + NULL); } ensure(flash_lock_write(), NULL); display_clear(); @@ -565,6 +570,8 @@ int main(void) { #endif usb_init_all(); + mpu_config_prodtest_initial(); + #ifdef USE_OPTIGA optiga_init(); optiga_open_application(); diff --git a/core/embed/prodtest/optiga_prodtest.c b/core/embed/prodtest/optiga_prodtest.c index 78943aa81..87e45317e 100644 --- a/core/embed/prodtest/optiga_prodtest.c +++ b/core/embed/prodtest/optiga_prodtest.c @@ -126,35 +126,40 @@ void pair_optiga(void) { // pairing procedure is determined by optiga_sec_chan_handshake(). Therefore // it is OK for some of the intermediate operations to fail. - // Enable writing the pairing secret to OPTIGA. - optiga_metadata metadata = {0}; - metadata.change = OPTIGA_META_ACCESS_ALWAYS; - metadata.execute = OPTIGA_META_ACCESS_ALWAYS; - metadata.data_type = TYPE_PTFBIND; - set_metadata(OID_KEY_PAIRING, &metadata); // Ignore result. - - // Generate pairing secret. uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0}; - optiga_result ret = optiga_get_random(secret, sizeof(secret)); - if (OPTIGA_SUCCESS != ret) { - optiga_pairing_state = OPTIGA_PAIRING_ERR_RNG; - return; - } + optiga_result ret = OPTIGA_SUCCESS; - // Store pairing secret. - ret = optiga_set_data_object(OID_KEY_PAIRING, false, secret, sizeof(secret)); - if (OPTIGA_SUCCESS == ret) { - secret_erase(); - secret_write_header(); - secret_write(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN); - } + if (secret_optiga_extract(secret) != sectrue) { + // Enable writing the pairing secret to OPTIGA. + optiga_metadata metadata = {0}; + metadata.change = OPTIGA_META_ACCESS_ALWAYS; + metadata.execute = OPTIGA_META_ACCESS_ALWAYS; + metadata.data_type = TYPE_PTFBIND; + set_metadata(OID_KEY_PAIRING, &metadata); // Ignore result. - // Verify whether the secret was stored correctly in flash and OPTIGA. - memzero(secret, sizeof(secret)); - if (secret_read(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN) != - sectrue) { - optiga_pairing_state = OPTIGA_PAIRING_ERR_READ; - return; + // Generate pairing secret. + ret = optiga_get_random(secret, sizeof(secret)); + if (OPTIGA_SUCCESS != ret) { + optiga_pairing_state = OPTIGA_PAIRING_ERR_RNG; + return; + } + + // Store pairing secret. + ret = + optiga_set_data_object(OID_KEY_PAIRING, false, secret, sizeof(secret)); + if (OPTIGA_SUCCESS == ret) { + secret_erase(); + secret_write_header(); + secret_write(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN); + } + + // Verify whether the secret was stored correctly in flash and OPTIGA. + memzero(secret, sizeof(secret)); + if (secret_read(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN) != + sectrue) { + optiga_pairing_state = OPTIGA_PAIRING_ERR_READ; + return; + } } ret = optiga_sec_chan_handshake(secret, sizeof(secret)); diff --git a/core/embed/trezorhal/boards/trezor_r_v10.h b/core/embed/trezorhal/boards/trezor_r_v10.h index d896cc4bd..be44e5585 100644 --- a/core/embed/trezorhal/boards/trezor_r_v10.h +++ b/core/embed/trezorhal/boards/trezor_r_v10.h @@ -51,5 +51,8 @@ #define I2C_INSTANCE_0_RESET_FLG RCC_APB1RSTR_I2C2RST #define OPTIGA_I2C_INSTANCE 0 +#define OPTIGA_RST_PORT GPIOD +#define OPTIGA_RST_PIN GPIO_PIN_9 +#define OPTIGA_RST_CLK_EN __HAL_RCC_GPIOD_CLK_ENABLE #endif //_TREZOR_R_V10_H diff --git a/core/embed/trezorhal/boards/trezor_t3t1_v4.h b/core/embed/trezorhal/boards/trezor_t3t1_v4.h index 4fbf5868f..19f4cc054 100644 --- a/core/embed/trezorhal/boards/trezor_t3t1_v4.h +++ b/core/embed/trezorhal/boards/trezor_t3t1_v4.h @@ -77,6 +77,9 @@ #define HAPTIC_ACTUATOR "actuators/vg1040003d.h" #define OPTIGA_I2C_INSTANCE 1 +#define OPTIGA_RST_PORT GPIOB +#define OPTIGA_RST_PIN GPIO_PIN_1 +#define OPTIGA_RST_CLK_EN __HAL_RCC_GPIOB_CLK_ENABLE #define SD_DETECT_PORT GPIOC #define SD_DETECT_PIN GPIO_PIN_13 diff --git a/core/embed/trezorhal/mpu.h b/core/embed/trezorhal/mpu.h index 5fd9abfea..a4aa03728 100644 --- a/core/embed/trezorhal/mpu.h +++ b/core/embed/trezorhal/mpu.h @@ -25,6 +25,7 @@ void mpu_config_boardloader(void); void mpu_config_bootloader(void); void mpu_config_firmware_initial(void); void mpu_config_firmware(void); +void mpu_config_prodtest_initial(void); void mpu_config_prodtest(void); #endif diff --git a/core/embed/trezorhal/stm32f4/mpu.c b/core/embed/trezorhal/stm32f4/mpu.c index c93297d1f..af40d3814 100644 --- a/core/embed/trezorhal/stm32f4/mpu.c +++ b/core/embed/trezorhal/stm32f4/mpu.c @@ -212,6 +212,8 @@ void mpu_config_firmware(void) { __asm__ volatile("isb"); } +void mpu_config_prodtest_initial(void) {} + void mpu_config_prodtest(void) { // Disable MPU HAL_MPU_Disable(); diff --git a/core/embed/trezorhal/stm32f4/optiga_hal.c b/core/embed/trezorhal/stm32f4/optiga_hal.c index 0a3f92acb..8f9fd7734 100644 --- a/core/embed/trezorhal/stm32f4/optiga_hal.c +++ b/core/embed/trezorhal/stm32f4/optiga_hal.c @@ -3,26 +3,27 @@ #include TREZOR_BOARD void optiga_hal_init(void) { + OPTIGA_RST_CLK_EN(); // init reset pin GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStructure.Alternate = 0; - GPIO_InitStructure.Pin = GPIO_PIN_9; - HAL_GPIO_Init(GPIOD, &GPIO_InitStructure); + GPIO_InitStructure.Pin = OPTIGA_RST_PIN; + HAL_GPIO_Init(OPTIGA_RST_PORT, &GPIO_InitStructure); // perform reset on every initialization - HAL_GPIO_WritePin(GPIOD, GPIO_PIN_9, GPIO_PIN_RESET); + HAL_GPIO_WritePin(OPTIGA_RST_PORT, OPTIGA_RST_PIN, GPIO_PIN_RESET); hal_delay(10); - HAL_GPIO_WritePin(GPIOD, GPIO_PIN_9, GPIO_PIN_SET); + HAL_GPIO_WritePin(OPTIGA_RST_PORT, OPTIGA_RST_PIN, GPIO_PIN_SET); // warm reset startup time min 15ms hal_delay(20); } void optiga_reset(void) { - HAL_GPIO_WritePin(GPIOD, GPIO_PIN_9, GPIO_PIN_RESET); + HAL_GPIO_WritePin(OPTIGA_RST_PORT, OPTIGA_RST_PIN, GPIO_PIN_RESET); hal_delay(10); - HAL_GPIO_WritePin(GPIOD, GPIO_PIN_9, GPIO_PIN_SET); + HAL_GPIO_WritePin(OPTIGA_RST_PORT, OPTIGA_RST_PIN, GPIO_PIN_SET); // warm reset startup time min 15ms hal_delay(20); } diff --git a/core/embed/trezorhal/stm32u5/common.c b/core/embed/trezorhal/stm32u5/common.c index 242e7e8ae..dfe50cfcd 100644 --- a/core/embed/trezorhal/stm32u5/common.c +++ b/core/embed/trezorhal/stm32u5/common.c @@ -157,6 +157,17 @@ void __assert_func(const char *file, int line, const char *func, void hal_delay(uint32_t ms) { HAL_Delay(ms); } uint32_t hal_ticks_ms() { return HAL_GetTick(); } +void hal_delay_us(uint16_t delay_us) { + uint32_t val = svc_get_systick_val(); + uint32_t t = hal_ticks_ms() * 1000 + + (((SystemCoreClock / 1000) - val) / (SystemCoreClock / 1000000)); + uint32_t t2 = t; + do { + val = svc_get_systick_val(); + t2 = hal_ticks_ms() * 1000 + + (((SystemCoreClock / 1000) - val) / (SystemCoreClock / 1000000)); + } while ((t2 - t) < delay_us); +} uint32_t __stack_chk_guard = 0; diff --git a/core/embed/trezorhal/stm32u5/mpu.c b/core/embed/trezorhal/stm32u5/mpu.c index 37ddd9918..8829c3e13 100644 --- a/core/embed/trezorhal/stm32u5/mpu.c +++ b/core/embed/trezorhal/stm32u5/mpu.c @@ -96,7 +96,7 @@ static inline uint32_t mpu_permission_lookup(bool write, bool unpriv) { MPU->RLAR = 0; \ } while (0) -static void mpu_set_attributes() { +static void mpu_set_attributes(void) { // Attr[0] - FLASH - Not-Transient, Write-Through, Read Allocation MPU->MAIR0 = 0xAA; // Attr[1] - SRAM - Non-cacheable @@ -107,13 +107,13 @@ static void mpu_set_attributes() { MPU->MAIR0 |= 0x44 << 24; } -#define SECRET_START FLASH_BASE_S +#define SECRET_START FLASH_BASE #define SECRET_SIZE SIZE_16K #define BOARDLOADER_SIZE SIZE_48K #define BOOTLOADER_SIZE BOOTLOADER_IMAGE_MAXSIZE #define FIRMWARE_SIZE FIRMWARE_IMAGE_MAXSIZE #define STORAGE_START \ - (FLASH_BASE_S + SECRET_SIZE + BOARDLOADER_SIZE + BOOTLOADER_SIZE) + (FLASH_BASE + SECRET_SIZE + BOARDLOADER_SIZE + BOOTLOADER_SIZE) #define STORAGE_SIZE NORCOW_SECTOR_SIZE* STORAGE_AREAS_COUNT #if defined STM32U5A9xx @@ -132,6 +132,9 @@ static void mpu_set_attributes() { #define L2_REST_SIZE \ (FLASH_SIZE - (BOOTLOADER_SIZE + BOARDLOADER_SIZE + SECRET_SIZE)) +#define L3_PREV_SIZE \ + (STORAGE_SIZE + BOOTLOADER_SIZE + BOARDLOADER_SIZE + SECRET_SIZE) + #define ASSETS_START (FIRMWARE_START + FIRMWARE_SIZE) #define ASSETS_SIZE \ (FLASH_SIZE - (FIRMWARE_SIZE + BOOTLOADER_SIZE + BOARDLOADER_SIZE + \ @@ -147,7 +150,7 @@ static void mpu_set_attributes() { #define GRAPHICS_SIZE SIZE_16M #endif -void mpu_config_boardloader() { +void mpu_config_boardloader(void) { HAL_MPU_Disable(); mpu_set_attributes(); // clang-format off @@ -164,7 +167,7 @@ void mpu_config_boardloader() { HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); } -void mpu_config_bootloader() { +void mpu_config_bootloader(void) { HAL_MPU_Disable(); mpu_set_attributes(); // clang-format off @@ -181,7 +184,7 @@ void mpu_config_bootloader() { HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); } -void mpu_config_firmware_initial() { +void mpu_config_firmware_initial(void) { HAL_MPU_Disable(); mpu_set_attributes(); // clang-format off @@ -193,12 +196,46 @@ void mpu_config_firmware_initial() { SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals SET_REGION( 6, FLASH_OTP_BASE, SIZE_2K, FLASH_DATA, YES, YES ); // OTP - DIS_REGION( 7 ); + SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4 // clang-format on HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); } -void mpu_config_firmware() { +void mpu_config_firmware(void) { + HAL_MPU_Disable(); + mpu_set_attributes(); + // clang-format off + // REGION ADDRESS SIZE TYPE WRITE UNPRIV + SET_REGION( 0, STORAGE_START, STORAGE_SIZE, FLASH_DATA, YES, YES ); // Storage + SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware + SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets + SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5 + SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface + SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals + SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP + SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4 + // clang-format on + HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); +} + +void mpu_config_prodtest_initial(void) { + HAL_MPU_Disable(); + mpu_set_attributes(); + // clang-format off + // REGION ADDRESS SIZE TYPE WRITE UNPRIV + SET_REGION( 0, FLASH_BASE, L3_PREV_SIZE, FLASH_DATA, YES, YES ); // Secret, Bld, Storage + SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware + SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets + SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5 + SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface + SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals + SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP + SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4 + // clang-format on + HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); +} + +void mpu_config_prodtest(void) { HAL_MPU_Disable(); mpu_set_attributes(); // clang-format off diff --git a/core/embed/trezorhal/stm32u5/optiga_hal.c b/core/embed/trezorhal/stm32u5/optiga_hal.c new file mode 120000 index 000000000..bd07df704 --- /dev/null +++ b/core/embed/trezorhal/stm32u5/optiga_hal.c @@ -0,0 +1 @@ +../stm32f4/optiga_hal.c \ No newline at end of file diff --git a/core/embed/trezorhal/stm32u5/secret.c b/core/embed/trezorhal/stm32u5/secret.c index db1837964..7fd3c08e9 100644 --- a/core/embed/trezorhal/stm32u5/secret.c +++ b/core/embed/trezorhal/stm32u5/secret.c @@ -22,12 +22,11 @@ static secbool verify_header(void) { } secbool secret_bootloader_locked(void) { - if (bootloader_locked_set != sectrue) { - // Set bootloader_locked. - verify_header(); - } - - return bootloader_locked; +#ifdef FIRMWARE + return TAMP->BKP8R != 0 * sectrue; +#else + return sectrue; +#endif } void secret_write_header(void) { @@ -161,3 +160,7 @@ void secret_optiga_hide(void) { reg1++; } } + +void secret_erase(void) { + ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase"); +} diff --git a/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.json b/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.json index a5b5b3bb1..d4854f27f 100644 --- a/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.json +++ b/core/embed/vendorheader/T3T1/vendor_dev_DO_NOT_SIGN.json @@ -6,7 +6,7 @@ "version": [0, 0], "sig_m": 2, "trust": { - "allow_run_with_secret": false, + "allow_run_with_secret": true, "show_vendor_string": false, "require_user_click": false, "red_background": false, diff --git a/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin b/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin index 1d71c401c..c0f6e3576 100644 Binary files a/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin and b/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_signed_dev.bin differ diff --git a/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_unsigned.bin b/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_unsigned.bin index 167ca00b8..577f6dd6e 100644 Binary files a/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_unsigned.bin and b/core/embed/vendorheader/T3T1/vendorheader_dev_DO_NOT_SIGN_unsigned.bin differ diff --git a/core/site_scons/boards/trezor_t3t1_v4.py b/core/site_scons/boards/trezor_t3t1_v4.py index 98c23985c..1a3b314d4 100644 --- a/core/site_scons/boards/trezor_t3t1_v4.py +++ b/core/site_scons/boards/trezor_t3t1_v4.py @@ -87,6 +87,15 @@ def configure( sources += ["embed/trezorhal/stm32u5/dma2d.c"] features_available.append("dma2d") + if "optiga" in features_wanted: + defines += ["USE_OPTIGA=1"] + sources += ["embed/trezorhal/stm32u5/optiga_hal.c"] + sources += ["embed/trezorhal/optiga/optiga.c"] + sources += ["embed/trezorhal/optiga/optiga_commands.c"] + sources += ["embed/trezorhal/optiga/optiga_transport.c"] + sources += ["vendor/trezor-crypto/hash_to_curve.c"] + features_available.append("optiga") + env.get("ENV")["TREZOR_BOARD"] = board env.get("ENV")["MCU_TYPE"] = mcu env.get("ENV")["LINKER_SCRIPT"] = linker_script