feat(core/prodtest): introduce logging in `tropic_custom_session_start()`
What changed, and why it matters
This commit only adds extra diagnostic logging and changes a function signature so the logging can be routed to the production-test command-line interface. It does not change how cryptographic sessions are established or which keys are used. There is no indication this fixes or introduces a security vulnerability.
No security action required; treat as a normal logging/diagnostics improvement.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch modifies tropic_custom_session_start() to accept an optional cli_t* cli argument. Under TREZOR_PRODTEST builds it now emits cli_trace() messages when secret-key retrieval, public-key retrieval, or lt_session_start() fail. All non-prodtest callers pass NULL and behavior is unchanged. The retry macro also passes NULL because it has no CLI context. No cryptographic logic, access control, or session-management behavior is altered.
Changed components
core/embed/sec/tropic/tropic.ccore/embed/sec/tropic/inc/sec/tropic.hcore/embed/projects/prodtest/cmd/prodtest_tropic.ccore/embed/projects/prodtest/cmd/prodtest_secrets.cInspect captured patch +69 / −44
diff --git a/core/embed/projects/prodtest/cmd/prodtest_secrets.c b/core/embed/projects/prodtest/cmd/prodtest_secrets.c
index 02d6ee642..9e964005e 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_secrets.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_secrets.c
@@ -128,7 +128,8 @@ static void prodtest_secrets_init(cli_t* cli) {
// Ensure that a session with Tropic is established so that we can include
// randomness from the chip when generating the secrets. At this point in
// provisioning the factory pairing key should still be valid.
- if (tropic_custom_session_start(TROPIC_FACTORY_PAIRING_KEY_SLOT) != LT_OK) {
+ if (tropic_custom_session_start(cli, TROPIC_FACTORY_PAIRING_KEY_SLOT) !=
+ LT_OK) {
cli_error(cli, CLI_ERROR, "`tropic_custom_session_start()` failed.");
return;
}
diff --git a/core/embed/projects/prodtest/cmd/prodtest_tropic.c b/core/embed/projects/prodtest/cmd/prodtest_tropic.c
index 95a86bafb..97eb2910c 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_tropic.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_tropic.c
@@ -593,7 +593,7 @@ tropic_locked_status get_tropic_locked_status(cli_t* cli) {
return TROPIC_LOCKED_FALSE;
}
- ret = tropic_custom_session_start(TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
+ ret = tropic_custom_session_start(cli, TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
if (ret != LT_OK) {
if (ret == LT_L2_HSK_ERR) {
// The Tropic pairing process was initiated but probably failed midway.
@@ -669,7 +669,7 @@ static bool tropic_is_paired(cli_t* cli) {
lt_ret_t ret = LT_FAIL;
// Try to establish a session using the unprivileged key pair.
- ret = tropic_custom_session_start(TROPIC_UNPRIVILEGED_PAIRING_KEY_SLOT);
+ ret = tropic_custom_session_start(cli, TROPIC_UNPRIVILEGED_PAIRING_KEY_SLOT);
if (ret != LT_OK) {
if (cli != NULL) {
cli_error(
@@ -682,7 +682,7 @@ static bool tropic_is_paired(cli_t* cli) {
}
// Try to establish a session using the privileged key pair.
- ret = tropic_custom_session_start(TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
+ ret = tropic_custom_session_start(cli, TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
if (ret != LT_OK) {
if (cli != NULL) {
cli_error(cli, CLI_ERROR,
@@ -806,7 +806,8 @@ static void prodtest_tropic_pair(cli_t* cli) {
goto cleanup;
}
- if (tropic_custom_session_start(TROPIC_FACTORY_PAIRING_KEY_SLOT) == LT_OK) {
+ if (tropic_custom_session_start(cli, TROPIC_FACTORY_PAIRING_KEY_SLOT) ==
+ LT_OK) {
// Write the privileged pairing key to the tropic's pairing key slot if it
// has not been written yet.
lt_ret_t ret = pairing_key_write(
@@ -1160,7 +1161,7 @@ static void prodtest_tropic_lock(cli_t* cli) {
g_tropic_handshake_state = TROPIC_HANDSHAKE_STATE_0;
lt_ret_t ret = LT_FAIL;
- ret = tropic_custom_session_start(TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
+ ret = tropic_custom_session_start(cli, TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
if (ret != LT_OK) {
cli_error(cli, CLI_ERROR,
"`tropic_custom_session_start()` for privileged key failed with "
@@ -1362,7 +1363,7 @@ static void cert_write(cli_t* cli, uint16_t first_slot, uint16_t slots_count) {
g_tropic_handshake_state = TROPIC_HANDSHAKE_STATE_0;
lt_ret_t ret =
- tropic_custom_session_start(TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
+ tropic_custom_session_start(cli, TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
if (ret != LT_OK) {
cli_error(cli, CLI_ERROR,
"`tropic_custom_session_start()` for privileged key failed with "
@@ -1408,7 +1409,7 @@ static void cert_read(cli_t* cli, uint16_t first_slot, uint16_t slots_count) {
g_tropic_handshake_state = TROPIC_HANDSHAKE_STATE_0;
lt_ret_t ret = LT_FAIL;
- ret = tropic_custom_session_start(TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
+ ret = tropic_custom_session_start(cli, TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
if (ret != LT_OK) {
cli_error(cli, CLI_ERROR,
"`tropic_custom_session_start()` for privileged key failed with "
@@ -1455,7 +1456,7 @@ static void pubkey_read(cli_t* cli, lt_ecc_slot_t slot,
lt_ret_t ret = LT_FAIL;
- ret = tropic_custom_session_start(TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
+ ret = tropic_custom_session_start(cli, TROPIC_PRIVILEGED_PAIRING_KEY_SLOT);
if (ret != LT_OK) {
cli_error(cli, CLI_ERROR,
"`tropic_custom_session_start()` for privileged key failed with "
@@ -1655,7 +1656,7 @@ static void prodtest_tropic_stress_test(cli_t* cli) {
// Find an available pairing key
for (lt_pkey_index_t i = TROPIC_FACTORY_PAIRING_KEY_SLOT;
i <= TROPIC_PRIVILEGED_PAIRING_KEY_SLOT; i++) {
- res = tropic_custom_session_start(i);
+ res = tropic_custom_session_start(cli, i);
if (res == LT_OK) {
pairing_key_index = i;
break;
@@ -1686,7 +1687,7 @@ static void prodtest_tropic_stress_test(cli_t* cli) {
i + 1, lt_ret_verbose(res));
return;
}
- res = tropic_custom_session_start(pairing_key_index);
+ res = tropic_custom_session_start(cli, pairing_key_index);
if (res != LT_OK) {
cli_error(cli, CLI_ERROR,
"Call #%d of `tropic_custom_session_start()"
diff --git a/core/embed/sec/tropic/inc/sec/tropic.h b/core/embed/sec/tropic/inc/sec/tropic.h
index 709d44c9b..9aab1f8b6 100644
--- a/core/embed/sec/tropic/inc/sec/tropic.h
+++ b/core/embed/sec/tropic/inc/sec/tropic.h
@@ -22,6 +22,7 @@
#ifdef USE_STORAGE
#include <sec/storage.h>
#endif
+#include <rtl/cli.h>
#include <trezor_types.h>
#include "ed25519-donna/ed25519.h"
@@ -74,7 +75,8 @@ void tropic_deinit(void);
#include "libtropic.h"
lt_handle_t* tropic_get_handle(void);
-lt_ret_t tropic_custom_session_start(lt_pkey_index_t pairing_key_index);
+lt_ret_t tropic_custom_session_start(cli_t* cli,
+ lt_pkey_index_t pairing_key_index);
lt_ret_t tropic_session_invalidate(void);
diff --git a/core/embed/sec/tropic/tropic.c b/core/embed/sec/tropic/tropic.c
index 7dfbfa3df..9f02e0552 100644
--- a/core/embed/sec/tropic/tropic.c
+++ b/core/embed/sec/tropic/tropic.c
@@ -76,34 +76,34 @@ static bool is_retryable(lt_ret_t ret) {
// Statement expression, see
// https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
-#define TROPIC_RETRY_COMMAND(command) \
- ({ \
- bool TROPIC_RETRY_COMMAND_session_started = \
- g_tropic_driver.session_started; \
- lt_pkey_index_t TROPIC_RETRY_COMMAND_pairing_key_index = \
- g_tropic_driver.pairing_key_index; \
- lt_ret_t TROPIC_RETRY_COMMAND_res = command; \
- for (int TROPIC_RETRY_COMMAND_i = 0; \
- TROPIC_RETRY_COMMAND_i < TROPIC_MAX_RETRIES - 1; \
- TROPIC_RETRY_COMMAND_i++) { \
- if (!is_retryable(TROPIC_RETRY_COMMAND_res)) { \
- break; \
- } \
- if (TROPIC_RETRY_COMMAND_res == LT_L1_CHIP_ALARM_MODE) { \
- tropic01_reset(); \
- tropic_deinit(); \
- tropic_init(); \
- tropic_wait_for_ready(); \
- if (TROPIC_RETRY_COMMAND_session_started) { \
- if (tropic_custom_session_start( \
- TROPIC_RETRY_COMMAND_pairing_key_index) != LT_OK) { \
- continue; \
- } \
- } \
- } \
- TROPIC_RETRY_COMMAND_res = command; \
- } \
- TROPIC_RETRY_COMMAND_res; \
+#define TROPIC_RETRY_COMMAND(command) \
+ ({ \
+ bool TROPIC_RETRY_COMMAND_session_started = \
+ g_tropic_driver.session_started; \
+ lt_pkey_index_t TROPIC_RETRY_COMMAND_pairing_key_index = \
+ g_tropic_driver.pairing_key_index; \
+ lt_ret_t TROPIC_RETRY_COMMAND_res = command; \
+ for (int TROPIC_RETRY_COMMAND_i = 0; \
+ TROPIC_RETRY_COMMAND_i < TROPIC_MAX_RETRIES - 1; \
+ TROPIC_RETRY_COMMAND_i++) { \
+ if (!is_retryable(TROPIC_RETRY_COMMAND_res)) { \
+ break; \
+ } \
+ if (TROPIC_RETRY_COMMAND_res == LT_L1_CHIP_ALARM_MODE) { \
+ tropic01_reset(); \
+ tropic_deinit(); \
+ tropic_init(); \
+ tropic_wait_for_ready(); \
+ if (TROPIC_RETRY_COMMAND_session_started) { \
+ if (tropic_custom_session_start( \
+ NULL, TROPIC_RETRY_COMMAND_pairing_key_index) != LT_OK) { \
+ continue; \
+ } \
+ } \
+ } \
+ TROPIC_RETRY_COMMAND_res = command; \
+ } \
+ TROPIC_RETRY_COMMAND_res; \
})
#endif // TREZOR_EMULATOR
@@ -218,7 +218,9 @@ lt_ret_t tropic_session_invalidate(void) {
return LT_OK;
}
-lt_ret_t tropic_custom_session_start(lt_pkey_index_t pairing_key_index) {
+// If `TREZOR_PRODTEST` is not defined, the `cli` argument is ignored.
+lt_ret_t tropic_custom_session_start(cli_t *cli,
+ lt_pkey_index_t pairing_key_index) {
tropic_driver_t *drv = &g_tropic_driver;
if (!drv->initialized) {
@@ -238,11 +240,17 @@ lt_ret_t tropic_custom_session_start(lt_pkey_index_t pairing_key_index) {
break;
case TROPIC_PRIVILEGED_PAIRING_KEY_SLOT:
if (secret_key_tropic_pairing_privileged(trezor_private) != sectrue) {
+#ifdef TREZOR_PRODTEST
+ cli_trace(cli, "`secret_key_tropic_pairing_privileged()` failed");
+#endif
goto cleanup;
}
break;
case TROPIC_UNPRIVILEGED_PAIRING_KEY_SLOT:
if (secret_key_tropic_pairing_unprivileged(trezor_private) != sectrue) {
+#ifdef TREZOR_PRODTEST
+ cli_trace(cli, "`secret_key_tropic_pairing_unprivileged()` failed");
+#endif
goto cleanup;
}
break;
@@ -260,6 +268,10 @@ lt_ret_t tropic_custom_session_start(lt_pkey_index_t pairing_key_index) {
!tropic_get_pubkey(tropic_public))
#endif
{
+#ifdef TREZOR_PRODTEST
+ cli_trace(cli,
+ "`secret_key_tropic_public()` or `tropic_get_pubkey()` failed");
+#endif
goto cleanup;
}
}
@@ -269,6 +281,14 @@ lt_ret_t tropic_custom_session_start(lt_pkey_index_t pairing_key_index) {
ret = TROPIC_RETRY_COMMAND(lt_session_start(&drv->handle, tropic_public,
pairing_key_index, trezor_private,
trezor_public));
+#if TREZOR_PRODTEST
+ if (ret != LT_OK) {
+ cli_trace(cli,
+ "`lt_session_start()` failed for pairing key %d "
+ "with error '%s'",
+ pairing_key_index, lt_ret_verbose(ret));
+ }
+#endif
drv->session_started = (ret == LT_OK);
drv->pairing_key_index = pairing_key_index;
@@ -291,17 +311,18 @@ bool tropic_session_start(void) {
}
#ifndef TREZOR_EMULATOR
- if (tropic_custom_session_start(TROPIC_PRIVILEGED_PAIRING_KEY_SLOT) ==
+ if (tropic_custom_session_start(NULL, TROPIC_PRIVILEGED_PAIRING_KEY_SLOT) ==
LT_OK) {
return true;
}
- if (tropic_custom_session_start(TROPIC_UNPRIVILEGED_PAIRING_KEY_SLOT) ==
+ if (tropic_custom_session_start(NULL, TROPIC_UNPRIVILEGED_PAIRING_KEY_SLOT) ==
LT_OK) {
return true;
}
#endif
#if !PRODUCTION
- if (tropic_custom_session_start(TROPIC_FACTORY_PAIRING_KEY_SLOT) == LT_OK) {
+ if (tropic_custom_session_start(NULL, TROPIC_FACTORY_PAIRING_KEY_SLOT) ==
+ LT_OK) {
return true;
}
#endif
Why this scored 15/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.