Skip to content

Commit

Permalink
feat(core): introduce optiga deinit and suspending
Browse files Browse the repository at this point in the history
[no changelog]
  • Loading branch information
cepetr committed Jan 14, 2025
1 parent 80e2cea commit 2426e63
Show file tree
Hide file tree
Showing 15 changed files with 186 additions and 50 deletions.
2 changes: 1 addition & 1 deletion core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
51 changes: 2 additions & 49 deletions core/embed/projects/kernel/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}

Expand Down
28 changes: 28 additions & 0 deletions core/embed/sec/optiga/inc/sec/optiga_config.h
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions core/embed/sec/optiga/inc/sec/optiga_hal.h
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -6,6 +24,8 @@

void optiga_hal_init(void);

void optiga_hal_deinit(void);

void optiga_reset(void);

#endif // CORE_OPTIGA_HAL_H
2 changes: 2 additions & 0 deletions core/embed/sec/optiga/inc/sec/optiga_transport.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
76 changes: 76 additions & 0 deletions core/embed/sec/optiga/optiga_config.c
Original file line number Diff line number Diff line change
@@ -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
19 changes: 19 additions & 0 deletions core/embed/sec/optiga/optiga_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
18 changes: 18 additions & 0 deletions core/embed/sec/optiga/stm32/optiga_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions core/embed/sec/optiga/unix/optiga_hal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
11 changes: 11 additions & 0 deletions core/embed/sys/powerctl/stm32u5/powerctl_suspend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
1 change: 1 addition & 0 deletions core/site_scons/models/T2B1/trezor_r_v10.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
1 change: 1 addition & 0 deletions core/site_scons/models/T3B1/trezor_t3b1_revB.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
1 change: 1 addition & 0 deletions core/site_scons/models/T3T1/trezor_t3t1_revE.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
1 change: 1 addition & 0 deletions core/site_scons/models/T3W1/trezor_t3w1_revA.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down
1 change: 1 addition & 0 deletions core/site_scons/models/T3W1/trezor_t3w1_revA0.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
Expand Down

0 comments on commit 2426e63

Please sign in to comment.