diff --git a/core/Makefile b/core/Makefile index 84df1dbdb2..4e67e612b6 100644 --- a/core/Makefile +++ b/core/Makefile @@ -307,7 +307,7 @@ build_reflash: ## build reflash firmware + reflash image dd if=build/bootloader/bootloader.bin of=$(REFLASH_BUILD_DIR)/sdimage.bin bs=1 seek=49152 build_kernel: ## build kernel image - $(SCONS) PYOPT=1 $(KERNEL_BUILD_DIR)/kernel.bin + $(SCONS) $(KERNEL_BUILD_DIR)/kernel.bin build_firmware: templates build_cross build_kernel ## build firmware with frozen modules $(SCONS) $(FIRMWARE_BUILD_DIR)/firmware.bin diff --git a/core/embed/projects/kernel/main.c b/core/embed/projects/kernel/main.c index d209980f34..ae5584cfec 100644 --- a/core/embed/projects/kernel/main.c +++ b/core/embed/projects/kernel/main.c @@ -36,7 +36,6 @@ #include #include #include -#include "memzero.h" #ifdef USE_BUTTON #include @@ -51,8 +50,7 @@ #endif #ifdef USE_OPTIGA -#include -#include +#include #endif #ifdef USE_POWERCTL @@ -87,26 +85,6 @@ #include #endif -#ifdef USE_OPTIGA -#if !PYOPT -#include -#if 1 // color log -#define OPTIGA_LOG_FORMAT \ - "%" PRIu32 " \x1b[35moptiga\x1b[0m \x1b[32mDEBUG\x1b[0m %s: " -#else -#define OPTIGA_LOG_FORMAT "%" PRIu32 " optiga DEBUG %s: " -#endif -static void optiga_log_hex(const char *prefix, const uint8_t *data, - size_t data_size) { - printf(OPTIGA_LOG_FORMAT, hal_ticks_ms() * 1000, prefix); - for (size_t i = 0; i < data_size; i++) { - printf("%02x", data[i]); - } - printf("\n"); -} -#endif -#endif - void drivers_init() { #ifdef USE_POWERCTL powerctl_init(); @@ -150,11 +128,6 @@ void drivers_init() { secure_aes_init(); #endif -#ifdef USE_OPTIGA - uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0}; - secbool secret_ok = secret_optiga_get(secret); -#endif - entropy_init(); #if PRODUCTION || BOOTLOADER_QA @@ -186,27 +159,7 @@ void drivers_init() { #endif #ifdef USE_OPTIGA - -#if !PYOPT - // command log is relatively quiet so we enable it in debug builds - optiga_command_set_log_hex(optiga_log_hex); - // transport log can be spammy, uncomment if you want it: - // optiga_transport_set_log_hex(optiga_log_hex); -#endif - - optiga_init(); - if (sectrue == secret_ok) { - // If the shielded connection cannot be established, reset Optiga and - // continue without it. In this case, OID_KEY_FIDO and OID_KEY_DEV cannot be - // used, which means device and FIDO attestation will not work. - if (optiga_sec_chan_handshake(secret, sizeof(secret)) != OPTIGA_SUCCESS) { - optiga_soft_reset(); - } - } - memzero(secret, sizeof(secret)); - ensure(sectrue * (optiga_open_application() == OPTIGA_SUCCESS), - "Cannot initialize optiga."); - + optiga_init_and_configure(); #endif } diff --git a/core/embed/sec/optiga/inc/sec/optiga_config.h b/core/embed/sec/optiga/inc/sec/optiga_config.h new file mode 100644 index 0000000000..caeef1efa3 --- /dev/null +++ b/core/embed/sec/optiga/inc/sec/optiga_config.h @@ -0,0 +1,28 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#ifdef KERNEL_MODE + +// Initializes the optiga driver, establishes a secure channel by providing +// a shared secret and finally opens the application. +void optiga_init_and_configure(void); + +#endif // KERNEL_MODE diff --git a/core/embed/sec/optiga/inc/sec/optiga_hal.h b/core/embed/sec/optiga/inc/sec/optiga_hal.h index c744c1c09b..f581a9e6e0 100644 --- a/core/embed/sec/optiga/inc/sec/optiga_hal.h +++ b/core/embed/sec/optiga/inc/sec/optiga_hal.h @@ -1,3 +1,21 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #ifndef CORE_OPTIGA_HAL_H #define CORE_OPTIGA_HAL_H @@ -6,6 +24,8 @@ void optiga_hal_init(void); +void optiga_hal_deinit(void); + void optiga_reset(void); #endif // CORE_OPTIGA_HAL_H diff --git a/core/embed/sec/optiga/inc/sec/optiga_transport.h b/core/embed/sec/optiga/inc/sec/optiga_transport.h index 3d9b914f9c..8ddb3c5a3b 100644 --- a/core/embed/sec/optiga/inc/sec/optiga_transport.h +++ b/core/embed/sec/optiga/inc/sec/optiga_transport.h @@ -31,6 +31,8 @@ #define OPTIGA_MAX_APDU_SIZE 1557 optiga_result optiga_init(void); +void optiga_deinit(void); + optiga_result optiga_sec_chan_handshake(const uint8_t *secret, size_t secret_size); optiga_result optiga_execute_command(const uint8_t *command_data, diff --git a/core/embed/sec/optiga/optiga_config.c b/core/embed/sec/optiga/optiga_config.c new file mode 100644 index 0000000000..09de70202b --- /dev/null +++ b/core/embed/sec/optiga/optiga_config.c @@ -0,0 +1,76 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include +#include +#include +#include + +#include "memzero.h" + +#ifdef KERNEL_MODE + +#ifdef USE_OPTIGA_LOGGING +#include +#if 1 // color log +#define OPTIGA_LOG_FORMAT \ + "%" PRIu32 " \x1b[35moptiga\x1b[0m \x1b[32mDEBUG\x1b[0m %s: " +#else +#define OPTIGA_LOG_FORMAT "%" PRIu32 " optiga DEBUG %s: " +#endif +static void optiga_log_hex(const char *prefix, const uint8_t *data, + size_t data_size) { + printf(OPTIGA_LOG_FORMAT, hal_ticks_ms() * 1000, prefix); + for (size_t i = 0; i < data_size; i++) { + printf("%02x", data[i]); + } + printf("\n"); +} +#endif + +void optiga_init_and_configure(void) { +#ifdef USE_OPTIGA_LOGGING + // command log is relatively quiet so we enable it in debug builds + optiga_command_set_log_hex(optiga_log_hex); + // transport log can be spammy, uncomment if you want it: + // optiga_transport_set_log_hex(optiga_log_hex); +#endif + + optiga_init(); + + uint8_t secret[SECRET_OPTIGA_KEY_LEN] = {0}; + secbool secret_ok = secret_optiga_get(secret); + + if (sectrue == secret_ok) { + // If the shielded connection cannot be established, reset Optiga and + // continue without it. In this case, OID_KEY_FIDO and OID_KEY_DEV cannot be + // used, which means device and FIDO attestation will not work. + if (optiga_sec_chan_handshake(secret, sizeof(secret)) != OPTIGA_SUCCESS) { + optiga_soft_reset(); + } + } + memzero(secret, sizeof(secret)); + ensure(sectrue * (optiga_open_application() == OPTIGA_SUCCESS), + "Cannot initialize optiga."); +} + +#endif // KERNEL_MODE diff --git a/core/embed/sec/optiga/optiga_transport.c b/core/embed/sec/optiga/optiga_transport.c index 4b3011e38c..aaa7416a95 100644 --- a/core/embed/sec/optiga/optiga_transport.c +++ b/core/embed/sec/optiga/optiga_transport.c @@ -200,6 +200,25 @@ optiga_result optiga_init(void) { return optiga_set_data_reg_len(OPTIGA_DATA_REG_LEN); } +void optiga_deinit(void) { + i2c_bus_close(i2c_bus); + i2c_bus = NULL; + + frame_num_out = 0xff; + frame_num_in = 0xff; + memzero(frame_buffer, sizeof(frame_buffer)); + + sec_chan_established = false; + memzero(&sec_chan_encr_ctx, sizeof(sec_chan_encr_ctx)); + memzero(&sec_chan_decr_ctx, sizeof(sec_chan_decr_ctx)); + memzero(sec_chan_encr_nonce, sizeof(sec_chan_encr_nonce)); + memzero(sec_chan_decr_nonce, sizeof(sec_chan_decr_nonce)); + memzero(sec_chan_buffer, sizeof(sec_chan_buffer)); + sec_chan_size = 0; + + optiga_hal_deinit(); +} + static optiga_result optiga_i2c_write(const uint8_t *data, uint16_t data_size) { OPTIGA_LOG(">>>", data, data_size) diff --git a/core/embed/sec/optiga/stm32/optiga_hal.c b/core/embed/sec/optiga/stm32/optiga_hal.c index 7cc5919d16..607c312fbf 100644 --- a/core/embed/sec/optiga/stm32/optiga_hal.c +++ b/core/embed/sec/optiga/stm32/optiga_hal.c @@ -38,6 +38,24 @@ void optiga_hal_init(void) { hal_delay(20); } +void optiga_hal_deinit(void) { + GPIO_InitTypeDef GPIO_InitStructure = {0}; + + GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStructure.Pin = OPTIGA_RST_PIN; + HAL_GPIO_Init(OPTIGA_RST_PORT, &GPIO_InitStructure); + +#ifdef OPTIGA_PWR_PIN + GPIO_InitStructure.Mode = GPIO_MODE_ANALOG; + GPIO_InitStructure.Pull = GPIO_NOPULL; + GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_LOW; + GPIO_InitStructure.Pin = OPTIGA_PWR_PIN; + HAL_GPIO_Init(OPTIGA_PWR_PORT, &GPIO_InitStructure); +#endif +} + void optiga_reset(void) { HAL_GPIO_WritePin(OPTIGA_RST_PORT, OPTIGA_RST_PIN, GPIO_PIN_RESET); hal_delay(10); diff --git a/core/embed/sec/optiga/unix/optiga_hal.c b/core/embed/sec/optiga/unix/optiga_hal.c index 9bf346f028..6a817db42e 100644 --- a/core/embed/sec/optiga/unix/optiga_hal.c +++ b/core/embed/sec/optiga/unix/optiga_hal.c @@ -21,6 +21,10 @@ void optiga_hal_init(void) { // nothing to do } +void optiga_hal_deinit(void) { + // nothing to do +} + void optiga_reset(void) { // nothing to do } diff --git a/core/embed/sys/powerctl/stm32u5/powerctl_suspend.c b/core/embed/sys/powerctl/stm32u5/powerctl_suspend.c index 72188d94f6..b5ed21cef4 100644 --- a/core/embed/sys/powerctl/stm32u5/powerctl_suspend.c +++ b/core/embed/sys/powerctl/stm32u5/powerctl_suspend.c @@ -25,6 +25,11 @@ #include #include +#ifdef USE_OPTIGA +#include +#include +#endif + #ifdef USE_TOUCH #include #endif @@ -54,6 +59,9 @@ void powerctl_suspend(void) { // Deinitialize all drivers that are not required in low-power mode // (e.g., USB, display, touch, haptic, etc.). +#ifdef USE_OPTIGA + optiga_deinit(); +#endif #ifdef USE_USB usb_stop(); #endif @@ -130,6 +138,9 @@ void powerctl_suspend(void) { #ifdef USE_USB usb_start(); #endif +#ifdef USE_OPTIGA + optiga_init_and_configure(); +#endif } #endif // KERNEL_MODE diff --git a/core/site_scons/models/T2B1/trezor_r_v10.py b/core/site_scons/models/T2B1/trezor_r_v10.py index e4031c3975..98eb84a501 100644 --- a/core/site_scons/models/T2B1/trezor_r_v10.py +++ b/core/site_scons/models/T2B1/trezor_r_v10.py @@ -89,6 +89,7 @@ def configure( sources += ["embed/sec/optiga/stm32/optiga_hal.c"] sources += ["embed/sec/optiga/optiga.c"] sources += ["embed/sec/optiga/optiga_commands.c"] + sources += ["embed/sec/optiga/optiga_config.c"] sources += ["embed/sec/optiga/optiga_transport.c"] sources += ["vendor/trezor-crypto/hash_to_curve.c"] paths += ["embed/io/i2c_bus/inc"] diff --git a/core/site_scons/models/T3B1/trezor_t3b1_revB.py b/core/site_scons/models/T3B1/trezor_t3b1_revB.py index a734ae63fe..15c54182cb 100644 --- a/core/site_scons/models/T3B1/trezor_t3b1_revB.py +++ b/core/site_scons/models/T3B1/trezor_t3b1_revB.py @@ -80,6 +80,7 @@ def configure( sources += ["embed/sec/optiga/stm32/optiga_hal.c"] sources += ["embed/sec/optiga/optiga.c"] sources += ["embed/sec/optiga/optiga_commands.c"] + sources += ["embed/sec/optiga/optiga_config.c"] sources += ["embed/sec/optiga/optiga_transport.c"] sources += ["vendor/trezor-crypto/hash_to_curve.c"] paths += ["embed/io/i2c_bus/inc"] diff --git a/core/site_scons/models/T3T1/trezor_t3t1_revE.py b/core/site_scons/models/T3T1/trezor_t3t1_revE.py index 9aa2b9ea8d..709606b9e6 100644 --- a/core/site_scons/models/T3T1/trezor_t3t1_revE.py +++ b/core/site_scons/models/T3T1/trezor_t3t1_revE.py @@ -121,6 +121,7 @@ def configure( sources += ["embed/sec/optiga/stm32/optiga_hal.c"] sources += ["embed/sec/optiga/optiga.c"] sources += ["embed/sec/optiga/optiga_commands.c"] + sources += ["embed/sec/optiga/optiga_config.c"] sources += ["embed/sec/optiga/optiga_transport.c"] sources += ["vendor/trezor-crypto/hash_to_curve.c"] paths += ["embed/sec/optiga/inc"] diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revA.py b/core/site_scons/models/T3W1/trezor_t3w1_revA.py index 2eb7b9d8f2..43348ec0b7 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revA.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revA.py @@ -98,6 +98,7 @@ def configure( sources += ["embed/sec/optiga/stm32/optiga_hal.c"] sources += ["embed/sec/optiga/optiga.c"] sources += ["embed/sec/optiga/optiga_commands.c"] + sources += ["embed/sec/optiga/optiga_config.c"] sources += ["embed/sec/optiga/optiga_transport.c"] sources += ["vendor/trezor-crypto/hash_to_curve.c"] paths += ["embed/sec/optiga/inc"] diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revA0.py b/core/site_scons/models/T3W1/trezor_t3w1_revA0.py index b247b6bafe..3af1f067ca 100644 --- a/core/site_scons/models/T3W1/trezor_t3w1_revA0.py +++ b/core/site_scons/models/T3W1/trezor_t3w1_revA0.py @@ -97,6 +97,7 @@ def configure( sources += ["embed/sec/optiga/stm32/optiga_hal.c"] sources += ["embed/sec/optiga/optiga.c"] sources += ["embed/sec/optiga/optiga_commands.c"] + sources += ["embed/sec/optiga/optiga_config.c"] sources += ["embed/sec/optiga/optiga_transport.c"] sources += ["vendor/trezor-crypto/hash_to_curve.c"] paths += ["embed/sec/optiga/inc"]