fix(core): tropic fixes after libtropic update
What changed, and why it matters
This commit updates Trezor firmware to match a newer version of an external security chip library called libtropic. Most changes are mechanical: renaming internal fields (h->l2_buff to h->l2.buff), adding newly required source files to build scripts, and adjusting function signatures. One function that reads a device certificate is temporarily stubbed out with a TODO comment and always returns success without actually fetching the certificate. The commit is marked [no changelog] and does not describe itself as a security fix.
Treat as a routine compatibility/maintenance patch, but verify that the TODO-stubbed tropic_get_cert() is properly implemented in a follow-up commit before release, since returning unconditional success for certificate retrieval could mask secure-element attestation failures. No immediate security action is indicated by this commit alone.
Security signals we found
Secure-element API adaptation (libtropic update)
Temporary stub of certificate retrieval function (tropic_get_cert) with TODO comment
Signature function signature change (lt_ecc_eddsa_sign output length parameter removed)
Build system additions for ASN.1 DER, L3 processing, and ECDSA support
Evidence from the diff
The patch adapts the Tropic secure-element integration to an updated libtropic API. Key changes: (1) prodtest_tropic.c switches from a raw byte buffer to lt_chip_id_t struct and prints silicon revision. (2) tropic01.c updates SPI transfer to use h->l2.buff instead of h->l2_buff. (3) tropic.c comments out lt_get_info_cert() with a TODO, making tropic_get_cert() unconditionally return true; also updates lt_ecc_eddsa_sign() call to remove the sig_len output parameter. (4) Build model files add lt_asn1_der.c, lt_l3_process.c, and lt_crypto_trezor_ecdsa.c sources. No explicit security relevance, CVE, or researcher attribution is present.
Changed components
core/embed/projects/prodtest/cmd/prodtest_tropic.ccore/embed/sec/tropic/stm32/tropic01.ccore/embed/sec/tropic/tropic.ccore/site_scons/models/T3W1/emulator.pycore/site_scons/models/T3W1/trezor_t3w1_revA.pycore/site_scons/models/T3W1/trezor_t3w1_revB.pycore/site_scons/models/T3W1/trezor_t3w1_revC.pyvendor/libtropic integrationInspect captured patch +31 / −8
diff --git a/core/embed/projects/prodtest/cmd/prodtest_tropic.c b/core/embed/projects/prodtest/cmd/prodtest_tropic.c
index 49b50682a..466aafcd3 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_tropic.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_tropic.c
@@ -89,12 +89,16 @@ static void prodtest_tropic_get_chip_id(cli_t* cli) {
lt_handle_t* handle = tropic_get_handle();
- uint8_t chip_id[LT_L2_GET_INFO_CHIP_ID_SIZE] = {0};
- if (lt_get_info_chip_id(handle, chip_id, sizeof(chip_id)) != LT_OK) {
+ lt_chip_id_t chip_id = {0};
+ if (lt_get_info_chip_id(handle, &chip_id) != LT_OK) {
cli_error(cli, CLI_ERROR, "Unable to get CHIP ID");
return;
}
+ cli_trace(cli, "Silicon revision: %c%c%c%c", chip_id.silicon_rev[0],
+ chip_id.silicon_rev[1], chip_id.silicon_rev[2],
+ chip_id.silicon_rev[3]);
+
// Respond with an OK message and chip ID
cli_ok_hexdata(cli, &chip_id, sizeof(chip_id));
}
diff --git a/core/embed/sec/tropic/stm32/tropic01.c b/core/embed/sec/tropic/stm32/tropic01.c
index de51f48cb..c7dfd52ed 100644
--- a/core/embed/sec/tropic/stm32/tropic01.c
+++ b/core/embed/sec/tropic/stm32/tropic01.c
@@ -166,8 +166,8 @@ lt_ret_t lt_port_spi_transfer(lt_handle_t *h, uint8_t offset, uint16_t tx_len,
if (offset + tx_len > LT_L1_LEN_MAX) {
return LT_L1_DATA_LEN_ERROR;
}
- int ret = HAL_SPI_TransmitReceive(&drv->spi, h->l2_buff + offset,
- h->l2_buff + offset, tx_len, timeout);
+ int ret = HAL_SPI_TransmitReceive(&drv->spi, h->l2.buff + offset,
+ h->l2.buff + offset, tx_len, timeout);
if (ret != HAL_OK) {
return LT_FAIL;
}
diff --git a/core/embed/sec/tropic/tropic.c b/core/embed/sec/tropic/tropic.c
index 2d21a06ca..95f464413 100644
--- a/core/embed/sec/tropic/tropic.c
+++ b/core/embed/sec/tropic/tropic.c
@@ -113,8 +113,9 @@ bool tropic_get_cert(uint8_t *buf, uint16_t buf_size) {
return false;
}
- lt_ret_t res = lt_get_info_cert(&drv->handle, buf, buf_size);
- return res == LT_OK;
+ // TODO what is the new function
+ // lt_ret_t res = lt_get_info_cert(&drv->handle, buf, buf_size);
+ return LT_OK;
}
bool tropic_ecc_key_generate(uint16_t slot_index) {
@@ -144,8 +145,8 @@ bool tropic_ecc_sign(uint16_t key_slot_index, const uint8_t *dig,
return false;
}
- lt_ret_t res = lt_ecc_eddsa_sign(&drv->handle, key_slot_index, dig, dig_len,
- sig, sig_len);
+ lt_ret_t res =
+ lt_ecc_eddsa_sign(&drv->handle, key_slot_index, dig, dig_len, sig);
if (res != LT_OK) {
memzero(sig, sig_len);
return false;
diff --git a/core/site_scons/models/T3W1/emulator.py b/core/site_scons/models/T3W1/emulator.py
index 30ed57476..ac768f417 100644
--- a/core/site_scons/models/T3W1/emulator.py
+++ b/core/site_scons/models/T3W1/emulator.py
@@ -67,6 +67,7 @@ def configure(
"embed/sec/tropic/tropic.c",
"embed/sec/tropic/unix/tropic01.c",
"vendor/libtropic/src/libtropic.c",
+ "vendor/libtropic/src/lt_asn1_der.c",
"vendor/libtropic/src/lt_crc16.c",
"vendor/libtropic/src/lt_hkdf.c",
"vendor/libtropic/src/lt_l1.c",
@@ -74,9 +75,11 @@ def configure(
"vendor/libtropic/src/lt_l2.c",
"vendor/libtropic/src/lt_l2_frame_check.c",
"vendor/libtropic/src/lt_l3.c",
+ "vendor/libtropic/src/lt_l3_process.c",
"vendor/libtropic/src/lt_random.c",
"vendor/libtropic/hal/port/unix/lt_port_unix_tcp.c",
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_aesgcm.c",
+ "vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_ecdsa.c",
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_ed25519.c",
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_sha256.c",
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_x25519.c",
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revA.py b/core/site_scons/models/T3W1/trezor_t3w1_revA.py
index f136dba10..ea2998d46 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revA.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revA.py
@@ -186,17 +186,22 @@ def configure(
sources += ["embed/sec/tropic/tropic.c"]
sources += ["embed/sec/tropic/stm32/tropic01.c"]
sources += ["vendor/libtropic/src/libtropic.c"]
+ sources += ["vendor/libtropic/src/lt_asn1_der.c"]
sources += ["vendor/libtropic/src/lt_crc16.c"]
sources += ["vendor/libtropic/src/lt_l1_port_wrap.c"]
sources += ["vendor/libtropic/src/lt_l1.c"]
sources += ["vendor/libtropic/src/lt_l2.c"]
sources += ["vendor/libtropic/src/lt_l2_frame_check.c"]
sources += ["vendor/libtropic/src/lt_l3.c"]
+ sources += ["vendor/libtropic/src/lt_l3_process.c"]
sources += ["vendor/libtropic/src/lt_hkdf.c"]
sources += ["vendor/libtropic/src/lt_random.c"]
sources += [
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_aesgcm.c"
]
+ sources += [
+ "vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_ecdsa.c"
+ ]
sources += [
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_ed25519.c"
]
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revB.py b/core/site_scons/models/T3W1/trezor_t3w1_revB.py
index aed037913..4a4789aee 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revB.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revB.py
@@ -187,17 +187,22 @@ def configure(
sources += ["embed/sec/tropic/tropic.c"]
sources += ["embed/sec/tropic/stm32/tropic01.c"]
sources += ["vendor/libtropic/src/libtropic.c"]
+ sources += ["vendor/libtropic/src/lt_asn1_der.c"]
sources += ["vendor/libtropic/src/lt_crc16.c"]
sources += ["vendor/libtropic/src/lt_l1_port_wrap.c"]
sources += ["vendor/libtropic/src/lt_l1.c"]
sources += ["vendor/libtropic/src/lt_l2.c"]
sources += ["vendor/libtropic/src/lt_l2_frame_check.c"]
sources += ["vendor/libtropic/src/lt_l3.c"]
+ sources += ["vendor/libtropic/src/lt_l3_process.c"]
sources += ["vendor/libtropic/src/lt_hkdf.c"]
sources += ["vendor/libtropic/src/lt_random.c"]
sources += [
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_aesgcm.c"
]
+ sources += [
+ "vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_ecdsa.c"
+ ]
sources += [
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_ed25519.c"
]
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
index 9d2135b2f..fb40baef5 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
@@ -186,17 +186,22 @@ def configure(
sources += ["embed/sec/tropic/tropic.c"]
sources += ["embed/sec/tropic/stm32/tropic01.c"]
sources += ["vendor/libtropic/src/libtropic.c"]
+ sources += ["vendor/libtropic/src/lt_asn1_der.c"]
sources += ["vendor/libtropic/src/lt_crc16.c"]
sources += ["vendor/libtropic/src/lt_l1_port_wrap.c"]
sources += ["vendor/libtropic/src/lt_l1.c"]
sources += ["vendor/libtropic/src/lt_l2.c"]
sources += ["vendor/libtropic/src/lt_l2_frame_check.c"]
sources += ["vendor/libtropic/src/lt_l3.c"]
+ sources += ["vendor/libtropic/src/lt_l3_process.c"]
sources += ["vendor/libtropic/src/lt_hkdf.c"]
sources += ["vendor/libtropic/src/lt_random.c"]
sources += [
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_aesgcm.c"
]
+ sources += [
+ "vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_ecdsa.c"
+ ]
sources += [
"vendor/libtropic/hal/crypto/trezor_crypto/lt_crypto_trezor_ed25519.c"
]
Why this scored 17/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.