mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-05-27 19:28:47 +00:00
feat(core): enable tropic in firmware/kernel on hw
[no changelog]
This commit is contained in:
parent
aecaf306f3
commit
b7b8e77ccb
@ -45,7 +45,7 @@ FEATURE_FLAGS = {
|
||||
"AES_GCM": BENCHMARK or THP,
|
||||
}
|
||||
|
||||
FEATURES_WANTED = ["input", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic", "ble"]
|
||||
FEATURES_WANTED = ["input", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic", "ble", "tropic"]
|
||||
if DISABLE_OPTIGA:
|
||||
if PYOPT != '0':
|
||||
raise RuntimeError("DISABLE_OPTIGA requires PYOPT=0")
|
||||
|
@ -27,10 +27,10 @@ FEATURE_FLAGS = {
|
||||
"RDI": True,
|
||||
"SECP256K1_ZKP": True, # required for trezor.crypto.curve.bip340 (BIP340/Taproot)
|
||||
"SYSTEM_VIEW": False,
|
||||
"AES_GCM": False,
|
||||
"AES_GCM": True,
|
||||
}
|
||||
|
||||
FEATURES_WANTED = ["input", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic", "ble"]
|
||||
FEATURES_WANTED = ["input", "sd_card", "rgb_led", "dma2d", "consumption_mask", "usb" ,"optiga", "haptic", "ble", "tropic"]
|
||||
if DISABLE_OPTIGA:
|
||||
# TODO use PYOPT instead of PRODUCTION, same as in firmware, blocked on #4253
|
||||
if PRODUCTION:
|
||||
@ -177,17 +177,6 @@ if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
||||
'vendor/trezor-crypto/zkp_bip340.c',
|
||||
]
|
||||
|
||||
# AES-GCM
|
||||
if FEATURE_FLAGS["AES_GCM"]:
|
||||
CPPDEFINES_MOD += [
|
||||
'USE_AES_GCM',
|
||||
'AES_VAR',
|
||||
]
|
||||
SOURCE_MOD_CRYPTO += [
|
||||
'vendor/trezor-crypto/aes/gf128mul.c',
|
||||
'vendor/trezor-crypto/aes/aesgcm.c',
|
||||
]
|
||||
|
||||
SOURCE_MOD += [
|
||||
'embed/gfx/bitblt/gfx_bitblt.c',
|
||||
'embed/gfx/bitblt/gfx_bitblt_rgb565.c',
|
||||
@ -258,6 +247,19 @@ env = Environment(
|
||||
|
||||
FEATURES_AVAILABLE = models.configure_board(TREZOR_MODEL, HW_REVISION, FEATURES_WANTED, env, CPPDEFINES_HAL, SOURCE_HAL, PATH_HAL)
|
||||
|
||||
FEATURE_FLAGS["AES_GCM"] = FEATURE_FLAGS["AES_GCM"] or "tropic" in FEATURES_AVAILABLE
|
||||
|
||||
# AES-GCM
|
||||
if FEATURE_FLAGS["AES_GCM"]:
|
||||
CPPDEFINES_MOD += [
|
||||
'USE_AES_GCM',
|
||||
'AES_VAR',
|
||||
]
|
||||
SOURCE_MOD_CRYPTO += [
|
||||
'vendor/trezor-crypto/aes/gf128mul.c',
|
||||
'vendor/trezor-crypto/aes/aesgcm.c',
|
||||
]
|
||||
|
||||
SOURCE_FIRMWARE = [
|
||||
'embed/projects/kernel/main.c',
|
||||
]
|
||||
|
@ -10,6 +10,10 @@ BOOTLOADER_DEVEL = ARGUMENTS.get('BOOTLOADER_DEVEL', '0') == '1'
|
||||
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
|
||||
UI_DEBUG_OVERLAY = ARGUMENTS.get('UI_DEBUG_OVERLAY', '0') == '1'
|
||||
|
||||
FEATURE_FLAGS = {
|
||||
"AES_GCM": True,
|
||||
}
|
||||
|
||||
FEATURES_WANTED = ["input", "sbu", "nfc", "sd_card", "rgb_led", "usb", "consumption_mask", "optiga", "haptic", "tropic", "ble", "hw_revision"]
|
||||
|
||||
CCFLAGS_MOD = ''
|
||||
@ -41,22 +45,50 @@ SOURCE_MOD_CRYPTO += [
|
||||
'vendor/trezor-crypto/aes/aeskey.c',
|
||||
'vendor/trezor-crypto/aes/aestab.c',
|
||||
'vendor/trezor-crypto/bignum.c',
|
||||
'vendor/trezor-crypto/blake256.c',
|
||||
'vendor/trezor-crypto/blake2b.c',
|
||||
'vendor/trezor-crypto/buffer.c',
|
||||
'vendor/trezor-crypto/chacha_drbg.c',
|
||||
'vendor/trezor-crypto/chacha20poly1305/chacha_merged.c',
|
||||
'vendor/trezor-crypto/der.c',
|
||||
'vendor/trezor-crypto/ecdsa.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/curve25519-donna-32bit.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/curve25519-donna-helpers.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/curve25519-donna-scalarmult-base.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/ed25519-donna-32bit-tables.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/ed25519-donna-basepoint-table.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/ed25519-donna-impl-base.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/ed25519-keccak.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/ed25519-sha3.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/ed25519.c',
|
||||
'vendor/trezor-crypto/ed25519-donna/modm-donna-32bit.c',
|
||||
'vendor/trezor-crypto/groestl.c',
|
||||
'vendor/trezor-crypto/hasher.c',
|
||||
'vendor/trezor-crypto/hmac.c',
|
||||
'vendor/trezor-crypto/hmac_drbg.c',
|
||||
'vendor/trezor-crypto/memzero.c',
|
||||
'vendor/trezor-crypto/nist256p1.c',
|
||||
'vendor/trezor-crypto/rand.c',
|
||||
'vendor/trezor-crypto/ripemd160.c',
|
||||
'vendor/trezor-crypto/rfc6979.c',
|
||||
'vendor/trezor-crypto/secp256k1.c',
|
||||
'vendor/trezor-crypto/sha2.c',
|
||||
'vendor/trezor-crypto/sha3.c',
|
||||
'vendor/trezor-crypto/tls_prf.c',
|
||||
]
|
||||
|
||||
# AES-GCM
|
||||
if FEATURE_FLAGS["AES_GCM"]:
|
||||
CPPDEFINES_MOD += [
|
||||
'USE_AES_GCM',
|
||||
'AES_VAR',
|
||||
]
|
||||
SOURCE_MOD_CRYPTO += [
|
||||
'vendor/trezor-crypto/aes/gf128mul.c',
|
||||
'vendor/trezor-crypto/aes/aesgcm.c',
|
||||
]
|
||||
|
||||
|
||||
# modtrezorui
|
||||
CPPPATH_MOD += [
|
||||
'vendor/micropython/lib/uzlib'
|
||||
|
@ -51,7 +51,6 @@ SOURCE_MOD = [
|
||||
'vendor/micropython/extmod/vfs_posix_file.c',
|
||||
]
|
||||
SOURCE_MOD_CRYPTO = []
|
||||
SOURCE_MOD_TROPIC = []
|
||||
RUST_UI_FEATURES = []
|
||||
|
||||
# modtrezorconfig
|
||||
@ -255,13 +254,8 @@ SOURCE_MOD += [
|
||||
'embed/upymod/modutime.c',
|
||||
]
|
||||
|
||||
SOURCE_MOD_TROPIC += [
|
||||
'vendor/libtropic/src/libtropic.c',
|
||||
]
|
||||
|
||||
CPPDEFINES_MOD += ['USE_TREZOR_CRYPTO']
|
||||
|
||||
CPPPATH_MOD += ['vendor/libtropic/src/', 'vendor/libtropic/include/']
|
||||
|
||||
SOURCE_MICROPYTHON = [
|
||||
'vendor/micropython/extmod/modubinascii.c',
|
||||
@ -790,7 +784,7 @@ if FROZEN:
|
||||
#
|
||||
|
||||
obj_program = []
|
||||
source_files = SOURCE_MOD + SOURCE_MOD_CRYPTO + SOURCE_MOD_TROPIC + SOURCE_MICROPYTHON + SOURCE_UNIX
|
||||
source_files = SOURCE_MOD + SOURCE_MOD_CRYPTO + SOURCE_MICROPYTHON + SOURCE_UNIX
|
||||
obj_program.extend(env.Object(source=SOURCE_MOD))
|
||||
obj_program.extend(env.Object(source=SOURCE_MOD_CRYPTO, CCFLAGS='$CCFLAGS -ftrivial-auto-var-init=zero'))
|
||||
if FEATURE_FLAGS["SECP256K1_ZKP"]:
|
||||
|
@ -57,6 +57,10 @@
|
||||
#include <sec/optiga_config.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_TROPIC
|
||||
#include <sec/tropic.h>
|
||||
#endif
|
||||
|
||||
#ifdef USE_POWERCTL
|
||||
#include <sys/powerctl.h>
|
||||
#endif
|
||||
@ -167,6 +171,10 @@ void drivers_init() {
|
||||
#ifdef USE_OPTIGA
|
||||
optiga_init_and_configure();
|
||||
#endif
|
||||
|
||||
#ifdef USE_TROPIC
|
||||
tropic_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
// defined in linker script
|
||||
|
@ -58,7 +58,7 @@
|
||||
|
||||
#ifdef USE_TROPIC
|
||||
#include <sec/secret.h>
|
||||
#include <sec/tropic_transport.h>
|
||||
#include <sec/tropic.h>
|
||||
#endif
|
||||
|
||||
#include "py/builtin.h"
|
||||
|
@ -295,6 +295,16 @@ static void secret_optiga_uncache(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_TROPIC
|
||||
secbool secret_tropic_get_trezor_privkey(uint8_t dest[SECRET_TROPIC_KEY_LEN]) {
|
||||
return secfalse;
|
||||
}
|
||||
|
||||
secbool secret_tropic_get_tropic_pubkey(uint8_t dest[SECRET_TROPIC_KEY_LEN]) {
|
||||
return secfalse;
|
||||
}
|
||||
#endif
|
||||
|
||||
void secret_optiga_erase(void) {
|
||||
uint8_t value[SECRET_OPTIGA_KEY_LEN] = {0};
|
||||
secret_write(value, SECRET_OPTIGA_KEY_OFFSET, SECRET_OPTIGA_KEY_LEN);
|
||||
|
@ -21,6 +21,8 @@
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#define TROPIC_CHIP_ID_SIZE 128
|
||||
#define TROPIC_RISCV_FW_SIZE 4
|
||||
#define TROPIC_SPECT_FW_SIZE 4
|
||||
@ -34,3 +36,14 @@ bool tropic_get_spect_fw_version(uint8_t* version_buffer, uint16_t max_len);
|
||||
bool tropic_get_riscv_fw_version(uint8_t* version_buffer, uint16_t max_len);
|
||||
|
||||
bool tropic_get_chip_id(uint8_t* chip_id, uint16_t max_len);
|
||||
|
||||
#endif
|
||||
|
||||
bool tropic_ping(const uint8_t* msg_out, uint8_t* msg_in, uint16_t msg_len);
|
||||
|
||||
bool tropic_get_cert(uint8_t* buf, uint16_t buf_size);
|
||||
|
||||
bool tropic_ecc_key_generate(uint16_t slot_index);
|
||||
|
||||
bool tropic_ecc_sign(uint16_t key_slot_index, const uint8_t* dig,
|
||||
uint16_t dig_len, uint8_t* sig, uint16_t sig_len);
|
||||
|
@ -16,6 +16,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
@ -50,10 +51,9 @@
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
SPI_HandleTypeDef spi;
|
||||
lt_handle_t handle;
|
||||
} tropic01_driver_t;
|
||||
} tropic01_hal_driver_t;
|
||||
|
||||
static tropic01_driver_t g_tropic01_driver = {.initialized = false};
|
||||
static tropic01_hal_driver_t g_tropic01_hal_driver = {.initialized = false};
|
||||
|
||||
void tropic01_reset(void) {
|
||||
HAL_GPIO_WritePin(TROPIC01_PWR_PORT, TROPIC01_PWR_PIN, GPIO_PIN_SET);
|
||||
@ -62,8 +62,8 @@ void tropic01_reset(void) {
|
||||
systick_delay_ms(10);
|
||||
}
|
||||
|
||||
bool tropic_init(void) {
|
||||
tropic01_driver_t *drv = &g_tropic01_driver;
|
||||
bool tropic_hal_init(void) {
|
||||
tropic01_hal_driver_t *drv = &g_tropic01_hal_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return true;
|
||||
@ -137,24 +137,13 @@ bool tropic_init(void) {
|
||||
|
||||
HAL_SPI_Init(&drv->spi);
|
||||
|
||||
if (LT_OK != lt_init(&drv->handle)) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
drv->initialized = true;
|
||||
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
tropic_deinit();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void tropic_deinit(void) {
|
||||
tropic01_driver_t *drv = &g_tropic01_driver;
|
||||
|
||||
lt_deinit(&drv->handle);
|
||||
void tropic_hal_deinit(void) {
|
||||
tropic01_hal_driver_t *drv = &g_tropic01_hal_driver;
|
||||
|
||||
HAL_SPI_DeInit(&drv->spi);
|
||||
__HAL_RCC_SPI2_FORCE_RESET();
|
||||
@ -202,7 +191,7 @@ lt_ret_t lt_port_spi_csn_high(lt_handle_t *h) {
|
||||
|
||||
lt_ret_t lt_port_spi_transfer(lt_handle_t *h, uint8_t offset, uint16_t tx_len,
|
||||
uint32_t timeout) {
|
||||
tropic01_driver_t *drv = &g_tropic01_driver;
|
||||
tropic01_hal_driver_t *drv = &g_tropic01_hal_driver;
|
||||
|
||||
if (offset + tx_len > LT_L1_LEN_MAX) {
|
||||
return LT_L1_DATA_LEN_ERROR;
|
||||
@ -235,46 +224,4 @@ lt_ret_t lt_port_random_bytes(uint32_t *buff, uint16_t len) {
|
||||
return LT_OK;
|
||||
}
|
||||
|
||||
bool tropic_get_spect_fw_version(uint8_t *version_buffer, uint16_t max_len) {
|
||||
tropic01_driver_t *drv = &g_tropic01_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LT_OK != lt_get_info_spect_fw_ver(&drv->handle, (uint8_t *)version_buffer,
|
||||
max_len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tropic_get_riscv_fw_version(uint8_t *version_buffer, uint16_t max_len) {
|
||||
tropic01_driver_t *drv = &g_tropic01_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LT_OK != lt_get_info_riscv_fw_ver(&drv->handle, (uint8_t *)version_buffer,
|
||||
max_len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tropic_get_chip_id(uint8_t *chip_id, uint16_t max_len) {
|
||||
tropic01_driver_t *drv = &g_tropic01_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LT_OK != lt_get_info_chip_id(&drv->handle, (uint8_t *)chip_id, max_len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
207
core/embed/sec/tropic/tropic.c
Normal file
207
core/embed/sec/tropic/tropic.c
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#include <trezor_rtl.h>
|
||||
#include <trezor_types.h>
|
||||
|
||||
#include <sec/secret.h>
|
||||
#include <sec/tropic.h>
|
||||
|
||||
#include <libtropic.h>
|
||||
|
||||
#include "ed25519-donna/ed25519.h"
|
||||
#include "memzero.h"
|
||||
#include "tropic_internal.h"
|
||||
|
||||
#define PKEY_INDEX_BYTE PAIRING_KEY_SLOT_INDEX_0
|
||||
|
||||
typedef struct {
|
||||
bool initialized;
|
||||
bool sec_chan_established;
|
||||
lt_handle_t handle;
|
||||
} tropic_driver_t;
|
||||
|
||||
static tropic_driver_t g_tropic_driver = {0};
|
||||
|
||||
bool tropic_init(void) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
if (drv->initialized) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint8_t tropic_secret_tropic_pubkey[SECRET_TROPIC_KEY_LEN] = {0};
|
||||
uint8_t tropic_secret_trezor_privkey[SECRET_TROPIC_KEY_LEN] = {0};
|
||||
|
||||
if (!tropic_hal_init()) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (lt_init(&drv->handle) != LT_OK) {
|
||||
tropic_hal_deinit();
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
secbool pubkey_ok =
|
||||
secret_tropic_get_tropic_pubkey(tropic_secret_tropic_pubkey);
|
||||
secbool privkey_ok =
|
||||
secret_tropic_get_trezor_privkey(tropic_secret_trezor_privkey);
|
||||
|
||||
if (pubkey_ok == sectrue && privkey_ok == sectrue) {
|
||||
uint8_t trezor_pubkey[SECRET_TROPIC_KEY_LEN] = {0};
|
||||
curve25519_scalarmult_basepoint(trezor_pubkey,
|
||||
tropic_secret_trezor_privkey);
|
||||
|
||||
lt_ret_t ret = lt_session_start(
|
||||
&drv->handle, tropic_secret_tropic_pubkey, PKEY_INDEX_BYTE,
|
||||
tropic_secret_trezor_privkey, trezor_pubkey);
|
||||
|
||||
// todo delete the ensure
|
||||
ensure((ret == LT_OK) * sectrue, "lt_session_start failed");
|
||||
drv->sec_chan_established = (ret == LT_OK);
|
||||
}
|
||||
|
||||
memzero(tropic_secret_trezor_privkey, sizeof(tropic_secret_trezor_privkey));
|
||||
memzero(tropic_secret_trezor_privkey, sizeof(tropic_secret_tropic_pubkey));
|
||||
|
||||
drv->initialized = true;
|
||||
|
||||
return true;
|
||||
|
||||
cleanup:
|
||||
tropic_deinit();
|
||||
return false;
|
||||
}
|
||||
|
||||
void tropic_deinit(void) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
lt_deinit(&drv->handle);
|
||||
|
||||
tropic_hal_deinit();
|
||||
|
||||
memset(drv, 0, sizeof(*drv));
|
||||
}
|
||||
|
||||
bool tropic_get_spect_fw_version(uint8_t *version_buffer, uint16_t max_len) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LT_OK != lt_get_info_spect_fw_ver(&drv->handle, (uint8_t *)version_buffer,
|
||||
max_len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tropic_get_riscv_fw_version(uint8_t *version_buffer, uint16_t max_len) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LT_OK != lt_get_info_riscv_fw_ver(&drv->handle, (uint8_t *)version_buffer,
|
||||
max_len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tropic_get_chip_id(uint8_t *chip_id, uint16_t max_len) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (LT_OK != lt_get_info_chip_id(&drv->handle, (uint8_t *)chip_id, max_len)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool tropic_ping(const uint8_t *msg_out, uint8_t *msg_in, uint16_t msg_len) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lt_ret_t res = lt_ping(&drv->handle, msg_out, msg_in, msg_len);
|
||||
return res == LT_OK;
|
||||
}
|
||||
|
||||
bool tropic_get_cert(uint8_t *buf, uint16_t buf_size) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lt_ret_t res = lt_get_info_cert(&drv->handle, buf, buf_size);
|
||||
return res == LT_OK;
|
||||
}
|
||||
|
||||
bool tropic_ecc_key_generate(uint16_t slot_index) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (slot_index > ECC_SLOT_31) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lt_ret_t ret = lt_ecc_key_generate(&drv->handle, slot_index, CURVE_ED25519);
|
||||
return ret == LT_OK;
|
||||
}
|
||||
|
||||
bool tropic_ecc_sign(uint16_t key_slot_index, const uint8_t *dig,
|
||||
uint16_t dig_len, uint8_t *sig, uint16_t sig_len) {
|
||||
tropic_driver_t *drv = &g_tropic_driver;
|
||||
|
||||
if (!drv->initialized) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (key_slot_index > ECC_SLOT_31) {
|
||||
return false;
|
||||
}
|
||||
|
||||
lt_ret_t res = lt_ecc_eddsa_sign(&drv->handle, key_slot_index, dig, dig_len,
|
||||
sig, sig_len);
|
||||
if (res != LT_OK) {
|
||||
memzero(sig, sig_len);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
@ -17,9 +17,10 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_TROPIC_TRANSPORT_H
|
||||
#define TREZORHAL_TROPIC_TRANSPORT_H
|
||||
#pragma once
|
||||
|
||||
void tropic_init(void);
|
||||
#include <trezor_types.h>
|
||||
|
||||
#endif
|
||||
bool tropic_hal_init(void);
|
||||
|
||||
void tropic_hal_deinit(void);
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* 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 <sec/secret.h>
|
||||
#include <sec/tropic_transport.h>
|
||||
#include <trezor_rtl.h>
|
||||
#include <trezor_types.h>
|
||||
#include "ed25519-donna/ed25519.h"
|
||||
#include "libtropic.h"
|
||||
#include "memzero.h"
|
||||
|
||||
#define PKEY_INDEX_BYTE PAIRING_KEY_SLOT_INDEX_0
|
||||
|
||||
STATIC lt_handle_t lt_handle = {0};
|
||||
|
||||
void tropic_init(void) {
|
||||
uint8_t tropic_secret_tropic_pubkey[SECRET_TROPIC_KEY_LEN] = {0};
|
||||
uint8_t tropic_secret_trezor_privkey[SECRET_TROPIC_KEY_LEN] = {0};
|
||||
|
||||
ensure((lt_init(<_handle) == LT_OK) * sectrue, "lt_init failed");
|
||||
|
||||
ensure(secret_tropic_get_tropic_pubkey(tropic_secret_tropic_pubkey),
|
||||
"secret_tropic_get_tropic_pubkey failed");
|
||||
ensure(secret_tropic_get_trezor_privkey(tropic_secret_trezor_privkey),
|
||||
"secret_tropic_get_trezor_privkey failed");
|
||||
|
||||
uint8_t trezor_pubkey[SECRET_TROPIC_KEY_LEN] = {};
|
||||
curve25519_scalarmult_basepoint(trezor_pubkey, tropic_secret_trezor_privkey);
|
||||
|
||||
lt_ret_t ret = LT_FAIL;
|
||||
ret =
|
||||
lt_session_start(<_handle, tropic_secret_tropic_pubkey, PKEY_INDEX_BYTE,
|
||||
tropic_secret_trezor_privkey, trezor_pubkey);
|
||||
memzero(tropic_secret_trezor_privkey, sizeof(tropic_secret_trezor_privkey));
|
||||
|
||||
ensure((ret == LT_OK) * sectrue, "lt_session_start failed");
|
||||
}
|
27
core/embed/sec/tropic/unix/tropic01.c
Normal file
27
core/embed/sec/tropic/unix/tropic01.c
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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/>.
|
||||
*/
|
||||
#ifdef KERNEL_MODE
|
||||
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
bool tropic_hal_init(void) { return true; }
|
||||
|
||||
void tropic_hal_deinit(void) {}
|
||||
|
||||
#endif
|
@ -825,6 +825,37 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
|
||||
} break;
|
||||
#endif // USE_DMA2D
|
||||
|
||||
#ifdef USE_TROPIC
|
||||
case SYSCALL_TROPIC_PING: {
|
||||
const uint8_t *msg_out = (const uint8_t *)args[0];
|
||||
uint8_t *msg_in = (uint8_t *)args[1];
|
||||
uint16_t msg_len = (uint16_t)args[2];
|
||||
args[0] = tropic_ping__verified(msg_out, msg_in, msg_len);
|
||||
} break;
|
||||
|
||||
case SYSCALL_TROPIC_GET_CERT: {
|
||||
uint8_t *buf = (uint8_t *)args[0];
|
||||
uint16_t buf_size = (uint16_t)args[1];
|
||||
args[0] = tropic_get_cert__verified(buf, buf_size);
|
||||
} break;
|
||||
case SYSCALL_TROPIC_ECC_KEY_GENERATE: {
|
||||
uint16_t slot_index = (uint16_t)args[0];
|
||||
args[0] = tropic_ecc_key_generate__verified(slot_index);
|
||||
|
||||
} break;
|
||||
case SYSCALL_TROPIC_ECC_SIGN: {
|
||||
uint16_t key_slot_index = (uint16_t)args[0];
|
||||
const uint8_t *dig = (const uint8_t *)args[1];
|
||||
uint16_t dig_len = (uint16_t)args[2];
|
||||
uint8_t *sig = (uint8_t *)args[3];
|
||||
uint16_t sig_len = (uint16_t)args[4];
|
||||
|
||||
args[0] =
|
||||
tropic_ecc_sign__verified(key_slot_index, dig, dig_len, sig, sig_len);
|
||||
|
||||
} break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
system_exit_fatal("Invalid syscall", __FILE__, __LINE__);
|
||||
break;
|
||||
|
@ -169,4 +169,9 @@ typedef enum {
|
||||
SYSCALL_DMA2D_RGBA8888_BLEND_MONO4,
|
||||
SYSCALL_DMA2D_RGBA8888_BLEND_MONO8,
|
||||
|
||||
SYSCALL_TROPIC_PING,
|
||||
SYSCALL_TROPIC_GET_CERT,
|
||||
SYSCALL_TROPIC_ECC_KEY_GENERATE,
|
||||
SYSCALL_TROPIC_ECC_SIGN,
|
||||
|
||||
} syscall_number_t;
|
||||
|
@ -783,4 +783,29 @@ bool dma2d_rgba8888_blend_mono8(const gfx_bitblt_t *bb) {
|
||||
|
||||
#endif // USE_DMA2D
|
||||
|
||||
#ifdef USE_TROPIC
|
||||
|
||||
bool tropic_ping(const uint8_t *msg_in, uint8_t *msg_out, uint16_t msg_len) {
|
||||
return (bool)syscall_invoke3((uint32_t)msg_in, (uint32_t)msg_out, msg_len,
|
||||
SYSCALL_TROPIC_PING);
|
||||
}
|
||||
|
||||
bool tropic_get_cert(uint8_t *buf, uint16_t buf_size) {
|
||||
return (bool)syscall_invoke2((uint32_t)buf, buf_size,
|
||||
SYSCALL_TROPIC_GET_CERT);
|
||||
}
|
||||
|
||||
bool tropic_ecc_key_generate(uint16_t slot_index) {
|
||||
return (bool)syscall_invoke1((uint32_t)slot_index,
|
||||
SYSCALL_TROPIC_ECC_KEY_GENERATE);
|
||||
}
|
||||
|
||||
bool tropic_ecc_sign(uint16_t key_slot_index, const uint8_t *dig,
|
||||
uint16_t dig_len, uint8_t *sig, uint16_t sig_len) {
|
||||
return (bool)syscall_invoke5((uint32_t)key_slot_index, (uint32_t)dig, dig_len,
|
||||
(uint32_t)sig, sig_len, SYSCALL_TROPIC_ECC_SIGN);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // KERNEL_MODE
|
||||
|
@ -1072,4 +1072,56 @@ access_violation:
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_TROPIC
|
||||
#include <sec/tropic.h>
|
||||
|
||||
bool tropic_ping__verified(const uint8_t *msg_out, uint8_t *msg_in,
|
||||
uint16_t msg_len) {
|
||||
if (!probe_read_access(msg_out, msg_len)) {
|
||||
goto access_violation;
|
||||
}
|
||||
|
||||
if (!probe_write_access(msg_in, msg_len)) {
|
||||
goto access_violation;
|
||||
}
|
||||
|
||||
return tropic_ping(msg_out, msg_in, msg_len);
|
||||
access_violation:
|
||||
apptask_access_violation();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tropic_get_cert__verified(uint8_t *buf, uint16_t buf_size) {
|
||||
if (!probe_write_access(buf, buf_size)) {
|
||||
goto access_violation;
|
||||
}
|
||||
|
||||
return tropic_get_cert(buf, buf_size);
|
||||
access_violation:
|
||||
apptask_access_violation();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool tropic_ecc_key_generate__verified(uint16_t slot_index) {
|
||||
return tropic_ecc_key_generate(slot_index);
|
||||
}
|
||||
|
||||
bool tropic_ecc_sign__verified(uint16_t key_slot_index, const uint8_t *dig,
|
||||
uint16_t dig_len, uint8_t *sig,
|
||||
uint16_t sig_len) {
|
||||
if (!probe_read_access(dig, dig_len)) {
|
||||
goto access_violation;
|
||||
}
|
||||
|
||||
if (!probe_write_access(sig, sig_len)) {
|
||||
goto access_violation;
|
||||
}
|
||||
|
||||
return tropic_ecc_sign(key_slot_index, dig, dig_len, sig, sig_len);
|
||||
access_violation:
|
||||
apptask_access_violation();
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SYSCALL_DISPATCH
|
||||
|
@ -264,4 +264,20 @@ bool button_get_event__verified(button_event_t *event);
|
||||
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
#ifdef USE_TROPIC
|
||||
|
||||
bool tropic_ping__verified(const uint8_t *msg_out, uint8_t *msg_in,
|
||||
uint16_t msg_len);
|
||||
|
||||
bool tropic_get_cert__verified(uint8_t *buf, uint16_t buf_size);
|
||||
|
||||
bool tropic_ecc_key_generate__verified(uint16_t slot_index);
|
||||
|
||||
bool tropic_ecc_sign__verified(uint16_t key_slot_index, const uint8_t *dig,
|
||||
uint16_t dig_len, uint8_t *sig,
|
||||
uint16_t sig_len);
|
||||
|
||||
#endif
|
||||
|
||||
#endif // SYSCALL_DISPATCH
|
||||
|
@ -20,10 +20,7 @@
|
||||
#if USE_TROPIC
|
||||
|
||||
#include <sec/secret.h>
|
||||
#include <sec/tropic_transport.h>
|
||||
#include "libtropic.h"
|
||||
|
||||
extern STATIC lt_handle_t lt_handle;
|
||||
#include <sec/tropic.h>
|
||||
|
||||
/// package: trezorcrypto.tropic
|
||||
|
||||
@ -42,16 +39,13 @@ MP_DEFINE_EXCEPTION(TropicError, Exception)
|
||||
/// Test the session by pinging the chip.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorcrypto_tropic_ping(mp_obj_t message) {
|
||||
lt_ret_t ret = LT_FAIL;
|
||||
|
||||
mp_buffer_info_t message_b = {0};
|
||||
mp_get_buffer_raise(message, &message_b, MP_BUFFER_READ);
|
||||
|
||||
uint8_t msg_in[message_b.len];
|
||||
ret = lt_ping(<_handle, (uint8_t *)message_b.buf, (uint8_t *)msg_in,
|
||||
message_b.len);
|
||||
if (ret != LT_OK) {
|
||||
mp_raise_msg(&mp_type_TropicError, "lt_ping failed.");
|
||||
bool ret = tropic_ping(message_b.buf, msg_in, message_b.len);
|
||||
if (!ret) {
|
||||
mp_raise_msg(&mp_type_TropicError, "tropic_ping failed.");
|
||||
}
|
||||
|
||||
vstr_t result = {0};
|
||||
@ -69,12 +63,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_trezorcrypto_tropic_ping_obj,
|
||||
/// Return the chip's certificate.
|
||||
/// """
|
||||
STATIC mp_obj_t mod_trezorcrypto_tropic_get_certificate() {
|
||||
lt_ret_t ret = LT_FAIL;
|
||||
|
||||
uint8_t X509_cert[CERT_SIZE] = {0};
|
||||
ret = lt_get_info_cert(<_handle, X509_cert, CERT_SIZE);
|
||||
if (ret != LT_OK) {
|
||||
mp_raise_msg(&mp_type_TropicError, "lt_get_info_cert failed.");
|
||||
bool ret = tropic_get_cert(X509_cert, CERT_SIZE);
|
||||
if (!ret) {
|
||||
mp_raise_msg(&mp_type_TropicError, "tropic_get_cert failed.");
|
||||
}
|
||||
|
||||
vstr_t vstr = {0};
|
||||
@ -99,11 +91,9 @@ STATIC mp_obj_t mod_trezorcrypto_tropic_key_generate(mp_obj_t key_index) {
|
||||
mp_raise_ValueError("Invalid index.");
|
||||
}
|
||||
|
||||
lt_ret_t ret = LT_FAIL;
|
||||
|
||||
ret = lt_ecc_key_generate(<_handle, idx, CURVE_ED25519);
|
||||
if (ret != LT_OK) {
|
||||
mp_raise_msg(&mp_type_TropicError, "lt_ecc_key_generate failed.");
|
||||
bool ret = tropic_ecc_key_generate(idx);
|
||||
if (!ret) {
|
||||
mp_raise_msg(&mp_type_TropicError, "tropic_ecc_key_generate failed.");
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
@ -131,14 +121,12 @@ STATIC mp_obj_t mod_trezorcrypto_tropic_sign(mp_obj_t key_index,
|
||||
mp_raise_ValueError("Invalid length of digest.");
|
||||
}
|
||||
|
||||
lt_ret_t ret = LT_FAIL;
|
||||
|
||||
vstr_t sig = {0};
|
||||
vstr_init_len(&sig, SIG_SIZE);
|
||||
|
||||
ret = lt_ecc_eddsa_sign(<_handle, idx, (const uint8_t *)dig.buf, dig.len,
|
||||
((uint8_t *)sig.buf), SIG_SIZE);
|
||||
if (ret != LT_OK) {
|
||||
bool ret = tropic_ecc_sign(idx, (const uint8_t *)dig.buf, dig.len,
|
||||
((uint8_t *)sig.buf), SIG_SIZE);
|
||||
if (!ret) {
|
||||
vstr_clear(&sig);
|
||||
mp_raise_msg(&mp_type_TropicError, "lt_ecc_eddsa_sign failed.");
|
||||
}
|
||||
|
@ -55,7 +55,8 @@ def configure(
|
||||
if "tropic" in features_wanted:
|
||||
sources += [
|
||||
"embed/sec/secret/unix/secret.c",
|
||||
"embed/sec/tropic/tropic_transport.c",
|
||||
"embed/sec/tropic/tropic.c",
|
||||
"embed/sec/tropic/unix/tropic01.c",
|
||||
"vendor/libtropic/src/libtropic.c",
|
||||
"vendor/libtropic/src/lt_crc16.c",
|
||||
"vendor/libtropic/src/lt_hkdf.c",
|
||||
@ -72,6 +73,8 @@ def configure(
|
||||
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_x25519.c",
|
||||
]
|
||||
paths += ["embed/sec/tropic/inc"]
|
||||
paths += ["vendor/libtropic/include"]
|
||||
paths += ["vendor/libtropic/src"]
|
||||
defines += ["USE_TREZOR_CRYPTO"]
|
||||
features_available.append("tropic")
|
||||
defines += ["USE_TROPIC=1"]
|
||||
|
@ -137,6 +137,7 @@ def configure(
|
||||
defines += [("USE_OPTIGA", "1")]
|
||||
|
||||
if "tropic" in features_wanted:
|
||||
sources += ["embed/sec/tropic/tropic.c"]
|
||||
sources += ["embed/sec/tropic/stm32/tropic01.c"]
|
||||
sources += ["vendor/libtropic/src/libtropic.c"]
|
||||
sources += ["vendor/libtropic/src/lt_crc16.c"]
|
||||
|
@ -137,6 +137,7 @@ def configure(
|
||||
defines += [("USE_OPTIGA", "1")]
|
||||
|
||||
if "tropic" in features_wanted:
|
||||
sources += ["embed/sec/tropic/tropic.c"]
|
||||
sources += ["embed/sec/tropic/stm32/tropic01.c"]
|
||||
sources += ["vendor/libtropic/src/libtropic.c"]
|
||||
sources += ["vendor/libtropic/src/lt_crc16.c"]
|
||||
|
@ -137,6 +137,7 @@ def configure(
|
||||
defines += [("USE_OPTIGA", "1")]
|
||||
|
||||
if "tropic" in features_wanted:
|
||||
sources += ["embed/sec/tropic/tropic.c"]
|
||||
sources += ["embed/sec/tropic/stm32/tropic01.c"]
|
||||
sources += ["vendor/libtropic/src/libtropic.c"]
|
||||
sources += ["vendor/libtropic/src/lt_crc16.c"]
|
||||
|
Loading…
Reference in New Issue
Block a user