1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2025-01-15 09:50:57 +00:00

feat(core): introduce optiga deinit and suspending

[no changelog]
This commit is contained in:
cepetr 2025-01-13 19:08:16 +01:00 committed by cepetr
parent 80e2cea2b5
commit 2426e637b3
15 changed files with 186 additions and 50 deletions

View File

@ -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

View File

@ -36,7 +36,6 @@
#include <util/option_bytes.h>
#include <util/rsod.h>
#include <util/unit_properties.h>
#include "memzero.h"
#ifdef USE_BUTTON
#include <io/button.h>
@ -51,8 +50,7 @@
#endif
#ifdef USE_OPTIGA
#include <sec/optiga_commands.h>
#include <sec/optiga_transport.h>
#include <sec/optiga_config.h>
#endif
#ifdef USE_POWERCTL
@ -87,26 +85,6 @@
#include <sys/trustzone.h>
#endif
#ifdef USE_OPTIGA
#if !PYOPT
#include <inttypes.h>
#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
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#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

View File

@ -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,

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
#include <trezor_rtl.h>
#include <sec/optiga.h>
#include <sec/optiga_commands.h>
#include <sec/optiga_transport.h>
#include <sec/secret.h>
#include <sys/systick.h>
#include "memzero.h"
#ifdef KERNEL_MODE
#ifdef USE_OPTIGA_LOGGING
#include <inttypes.h>
#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

View File

@ -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)

View File

@ -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);

View File

@ -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
}

View File

@ -25,6 +25,11 @@
#include <sys/irq.h>
#include <sys/wakeup_flags.h>
#ifdef USE_OPTIGA
#include <sec/optiga_config.h>
#include <sec/optiga_transport.h>
#endif
#ifdef USE_TOUCH
#include <io/touch.h>
#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

View File

@ -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"]

View File

@ -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"]

View File

@ -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"]

View File

@ -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"]

View File

@ -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"]