1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-19 05:58:09 +00:00

feat(core): support optiga handling on U5

[no changelog]
This commit is contained in:
tychovrahe 2023-11-23 22:07:19 +01:00 committed by TychoVrahe
parent 72dc8f57e8
commit 5106ac7aa3
16 changed files with 136 additions and 51 deletions

View File

@ -329,6 +329,8 @@ void real_jump_to_firmware(void) {
if (sectrue == secret_optiga_present()) { if (sectrue == secret_optiga_present()) {
secret_optiga_backup(); secret_optiga_backup();
secret_hide(); secret_hide();
} else {
secret_optiga_hide();
} }
#else #else
secret_hide(); secret_hide();

View File

@ -49,7 +49,12 @@
#endif #endif
#include "memzero.h" #include "memzero.h"
#ifdef STM32U5
#include "stm32u5xx_ll_utils.h"
#else
#include "stm32f4xx_ll_utils.h" #include "stm32f4xx_ll_utils.h"
#endif
#ifdef TREZOR_MODEL_T #ifdef TREZOR_MODEL_T
#define MODEL_IDENTIFIER "TREZOR2-" #define MODEL_IDENTIFIER "TREZOR2-"
@ -429,10 +434,10 @@ power_off:
static void test_wipe(void) { static void test_wipe(void) {
// erase start of the firmware (metadata) -> invalidate FW // erase start of the firmware (metadata) -> invalidate FW
ensure(flash_unlock_write(), NULL); ensure(flash_unlock_write(), NULL);
for (int i = 0; i < 1024 / sizeof(uint32_t); i++) { for (int i = 0; i < (1024 / FLASH_BLOCK_SIZE); i += FLASH_BLOCK_SIZE) {
ensure( flash_block_t data = {0};
flash_area_write_word(&FIRMWARE_AREA, i * sizeof(uint32_t), 0x00000000), ensure(flash_area_write_block(&FIRMWARE_AREA, i * FLASH_BLOCK_SIZE, data),
NULL); NULL);
} }
ensure(flash_lock_write(), NULL); ensure(flash_lock_write(), NULL);
display_clear(); display_clear();
@ -565,6 +570,8 @@ int main(void) {
#endif #endif
usb_init_all(); usb_init_all();
mpu_config_prodtest_initial();
#ifdef USE_OPTIGA #ifdef USE_OPTIGA
optiga_init(); optiga_init();
optiga_open_application(); optiga_open_application();

View File

@ -126,35 +126,40 @@ void pair_optiga(void) {
// pairing procedure is determined by optiga_sec_chan_handshake(). Therefore // pairing procedure is determined by optiga_sec_chan_handshake(). Therefore
// it is OK for some of the intermediate operations to fail. // 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}; uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0};
optiga_result ret = optiga_get_random(secret, sizeof(secret)); optiga_result ret = OPTIGA_SUCCESS;
if (OPTIGA_SUCCESS != ret) {
optiga_pairing_state = OPTIGA_PAIRING_ERR_RNG;
return;
}
// Store pairing secret. if (secret_optiga_extract(secret) != sectrue) {
ret = optiga_set_data_object(OID_KEY_PAIRING, false, secret, sizeof(secret)); // Enable writing the pairing secret to OPTIGA.
if (OPTIGA_SUCCESS == ret) { optiga_metadata metadata = {0};
secret_erase(); metadata.change = OPTIGA_META_ACCESS_ALWAYS;
secret_write_header(); metadata.execute = OPTIGA_META_ACCESS_ALWAYS;
secret_write(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN); metadata.data_type = TYPE_PTFBIND;
} set_metadata(OID_KEY_PAIRING, &metadata); // Ignore result.
// Verify whether the secret was stored correctly in flash and OPTIGA. // Generate pairing secret.
memzero(secret, sizeof(secret)); ret = optiga_get_random(secret, sizeof(secret));
if (secret_read(secret, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN) != if (OPTIGA_SUCCESS != ret) {
sectrue) { optiga_pairing_state = OPTIGA_PAIRING_ERR_RNG;
optiga_pairing_state = OPTIGA_PAIRING_ERR_READ; return;
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)); ret = optiga_sec_chan_handshake(secret, sizeof(secret));

View File

@ -51,5 +51,8 @@
#define I2C_INSTANCE_0_RESET_FLG RCC_APB1RSTR_I2C2RST #define I2C_INSTANCE_0_RESET_FLG RCC_APB1RSTR_I2C2RST
#define OPTIGA_I2C_INSTANCE 0 #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 #endif //_TREZOR_R_V10_H

View File

@ -77,6 +77,9 @@
#define HAPTIC_ACTUATOR "actuators/vg1040003d.h" #define HAPTIC_ACTUATOR "actuators/vg1040003d.h"
#define OPTIGA_I2C_INSTANCE 1 #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_PORT GPIOC
#define SD_DETECT_PIN GPIO_PIN_13 #define SD_DETECT_PIN GPIO_PIN_13

View File

@ -25,6 +25,7 @@ void mpu_config_boardloader(void);
void mpu_config_bootloader(void); void mpu_config_bootloader(void);
void mpu_config_firmware_initial(void); void mpu_config_firmware_initial(void);
void mpu_config_firmware(void); void mpu_config_firmware(void);
void mpu_config_prodtest_initial(void);
void mpu_config_prodtest(void); void mpu_config_prodtest(void);
#endif #endif

View File

@ -212,6 +212,8 @@ void mpu_config_firmware(void) {
__asm__ volatile("isb"); __asm__ volatile("isb");
} }
void mpu_config_prodtest_initial(void) {}
void mpu_config_prodtest(void) { void mpu_config_prodtest(void) {
// Disable MPU // Disable MPU
HAL_MPU_Disable(); HAL_MPU_Disable();

View File

@ -3,26 +3,27 @@
#include TREZOR_BOARD #include TREZOR_BOARD
void optiga_hal_init(void) { void optiga_hal_init(void) {
OPTIGA_RST_CLK_EN();
// init reset pin // init reset pin
GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL; GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStructure.Alternate = 0; GPIO_InitStructure.Alternate = 0;
GPIO_InitStructure.Pin = GPIO_PIN_9; GPIO_InitStructure.Pin = OPTIGA_RST_PIN;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure); HAL_GPIO_Init(OPTIGA_RST_PORT, &GPIO_InitStructure);
// perform reset on every initialization // 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_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 // warm reset startup time min 15ms
hal_delay(20); hal_delay(20);
} }
void optiga_reset(void) { 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_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 // warm reset startup time min 15ms
hal_delay(20); hal_delay(20);
} }

View File

@ -157,6 +157,17 @@ void __assert_func(const char *file, int line, const char *func,
void hal_delay(uint32_t ms) { HAL_Delay(ms); } void hal_delay(uint32_t ms) { HAL_Delay(ms); }
uint32_t hal_ticks_ms() { return HAL_GetTick(); } 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; uint32_t __stack_chk_guard = 0;

View File

@ -96,7 +96,7 @@ static inline uint32_t mpu_permission_lookup(bool write, bool unpriv) {
MPU->RLAR = 0; \ MPU->RLAR = 0; \
} while (0) } while (0)
static void mpu_set_attributes() { static void mpu_set_attributes(void) {
// Attr[0] - FLASH - Not-Transient, Write-Through, Read Allocation // Attr[0] - FLASH - Not-Transient, Write-Through, Read Allocation
MPU->MAIR0 = 0xAA; MPU->MAIR0 = 0xAA;
// Attr[1] - SRAM - Non-cacheable // Attr[1] - SRAM - Non-cacheable
@ -107,13 +107,13 @@ static void mpu_set_attributes() {
MPU->MAIR0 |= 0x44 << 24; MPU->MAIR0 |= 0x44 << 24;
} }
#define SECRET_START FLASH_BASE_S #define SECRET_START FLASH_BASE
#define SECRET_SIZE SIZE_16K #define SECRET_SIZE SIZE_16K
#define BOARDLOADER_SIZE SIZE_48K #define BOARDLOADER_SIZE SIZE_48K
#define BOOTLOADER_SIZE BOOTLOADER_IMAGE_MAXSIZE #define BOOTLOADER_SIZE BOOTLOADER_IMAGE_MAXSIZE
#define FIRMWARE_SIZE FIRMWARE_IMAGE_MAXSIZE #define FIRMWARE_SIZE FIRMWARE_IMAGE_MAXSIZE
#define STORAGE_START \ #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 #define STORAGE_SIZE NORCOW_SECTOR_SIZE* STORAGE_AREAS_COUNT
#if defined STM32U5A9xx #if defined STM32U5A9xx
@ -132,6 +132,9 @@ static void mpu_set_attributes() {
#define L2_REST_SIZE \ #define L2_REST_SIZE \
(FLASH_SIZE - (BOOTLOADER_SIZE + BOARDLOADER_SIZE + SECRET_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_START (FIRMWARE_START + FIRMWARE_SIZE)
#define ASSETS_SIZE \ #define ASSETS_SIZE \
(FLASH_SIZE - (FIRMWARE_SIZE + BOOTLOADER_SIZE + BOARDLOADER_SIZE + \ (FLASH_SIZE - (FIRMWARE_SIZE + BOOTLOADER_SIZE + BOARDLOADER_SIZE + \
@ -147,7 +150,7 @@ static void mpu_set_attributes() {
#define GRAPHICS_SIZE SIZE_16M #define GRAPHICS_SIZE SIZE_16M
#endif #endif
void mpu_config_boardloader() { void mpu_config_boardloader(void) {
HAL_MPU_Disable(); HAL_MPU_Disable();
mpu_set_attributes(); mpu_set_attributes();
// clang-format off // clang-format off
@ -164,7 +167,7 @@ void mpu_config_boardloader() {
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
} }
void mpu_config_bootloader() { void mpu_config_bootloader(void) {
HAL_MPU_Disable(); HAL_MPU_Disable();
mpu_set_attributes(); mpu_set_attributes();
// clang-format off // clang-format off
@ -181,7 +184,7 @@ void mpu_config_bootloader() {
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
} }
void mpu_config_firmware_initial() { void mpu_config_firmware_initial(void) {
HAL_MPU_Disable(); HAL_MPU_Disable();
mpu_set_attributes(); mpu_set_attributes();
// clang-format off // 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( 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( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
SET_REGION( 6, FLASH_OTP_BASE, SIZE_2K, FLASH_DATA, YES, YES ); // OTP 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 // clang-format on
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI); 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(); HAL_MPU_Disable();
mpu_set_attributes(); mpu_set_attributes();
// clang-format off // clang-format off

View File

@ -0,0 +1 @@
../stm32f4/optiga_hal.c

View File

@ -22,12 +22,11 @@ static secbool verify_header(void) {
} }
secbool secret_bootloader_locked(void) { secbool secret_bootloader_locked(void) {
if (bootloader_locked_set != sectrue) { #ifdef FIRMWARE
// Set bootloader_locked. return TAMP->BKP8R != 0 * sectrue;
verify_header(); #else
} return sectrue;
#endif
return bootloader_locked;
} }
void secret_write_header(void) { void secret_write_header(void) {
@ -161,3 +160,7 @@ void secret_optiga_hide(void) {
reg1++; reg1++;
} }
} }
void secret_erase(void) {
ensure(flash_area_erase(&SECRET_AREA, NULL), "secret erase");
}

View File

@ -6,7 +6,7 @@
"version": [0, 0], "version": [0, 0],
"sig_m": 2, "sig_m": 2,
"trust": { "trust": {
"allow_run_with_secret": false, "allow_run_with_secret": true,
"show_vendor_string": false, "show_vendor_string": false,
"require_user_click": false, "require_user_click": false,
"red_background": false, "red_background": false,

View File

@ -87,6 +87,15 @@ def configure(
sources += ["embed/trezorhal/stm32u5/dma2d.c"] sources += ["embed/trezorhal/stm32u5/dma2d.c"]
features_available.append("dma2d") 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")["TREZOR_BOARD"] = board
env.get("ENV")["MCU_TYPE"] = mcu env.get("ENV")["MCU_TYPE"] = mcu
env.get("ENV")["LINKER_SCRIPT"] = linker_script env.get("ENV")["LINKER_SCRIPT"] = linker_script