build(core): support DISABLE_TROPIC for HW tests
What changed, and why it matters
This commit adds a new build option, DISABLE_TROPIC, that lets developers compile Trezor firmware test builds without the Tropic secure-element feature. It mirrors the existing DISABLE_OPTIGA flag and is blocked from production builds. There is no indication this is a security fix or vulnerability patch; it is a build-system convenience for hardware testing.
No security action required. Treat as routine build-system maintenance. If reviewing broader Tropic integration, verify that production builds cannot accidentally disable the feature and that secure-element-dependent code paths handle its absence gracefully in test builds only.
Security signals we found
Adds build-time feature flag only
Explicitly prevents use in production builds
Tied to insecure testing mode which already disables other security features
No changelog entry (routine build change)
Evidence from the diff
The change introduces DISABLE_TROPIC handling across three SCons build scripts (SConscript.firmware, SConscript.kernel, SConscript.secmon). When set, it removes the ‘tropic’ feature from FEATURES_WANTED. The flag is automatically enabled alongside DISABLE_OPTIGA when STORAGE_INSECURE_TESTING_MODE is active, and explicitly rejected in PRODUCTION builds with a RuntimeError. No runtime code, cryptographic logic, or device behavior is modified.
Changed components
core/SConscript.firmwarecore/SConscript.kernelcore/SConscript.secmonInspect captured patch +21 / −0
diff --git a/core/SConscript.firmware b/core/SConscript.firmware
index 696c1852..79d0c9f6 100644
--- a/core/SConscript.firmware
+++ b/core/SConscript.firmware
@@ -16,6 +16,7 @@ TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T2T1')
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
PYOPT = ARGUMENTS.get('PYOPT', '1')
DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1'
+DISABLE_TROPIC = ARGUMENTS.get('DISABLE_TROPIC', '0') == '1'
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
SCM_REVISION = ARGUMENTS.get('SCM_REVISION', None)
THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol
@@ -32,6 +33,7 @@ if STORAGE_INSECURE_TESTING_MODE and PRODUCTION:
raise RuntimeError("STORAGE_INSECURE_TESTING_MODE cannot be used in production")
if STORAGE_INSECURE_TESTING_MODE:
DISABLE_OPTIGA = True
+ DISABLE_TROPIC = True
PYOPT = "0"
if BENCHMARK and PYOPT != '0':
@@ -74,6 +76,11 @@ if DISABLE_OPTIGA:
raise RuntimeError("DISABLE_OPTIGA requires PYOPT=0")
FEATURES_WANTED.remove("optiga")
+if DISABLE_TROPIC:
+ if PRODUCTION:
+ raise RuntimeError("DISABLE_TROPIC requires non-production build")
+ FEATURES_WANTED.remove("tropic")
+
if PYOPT == '0':
DBG_CONSOLE = DBG_CONSOLE or "VCP"
FEATURES_WANTED += ["usb_iface_debug"]
diff --git a/core/SConscript.kernel b/core/SConscript.kernel
index 0622ec6d..7a107ab2 100644
--- a/core/SConscript.kernel
+++ b/core/SConscript.kernel
@@ -14,6 +14,7 @@ TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T2T1')
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
PYOPT = ARGUMENTS.get('PYOPT', '1')
DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1'
+DISABLE_TROPIC = ARGUMENTS.get('DISABLE_TROPIC', '0') == '1'
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol
DBG_CONSOLE = ARGUMENTS.get('DBG_CONSOLE', '')
@@ -23,6 +24,7 @@ if STORAGE_INSECURE_TESTING_MODE and PRODUCTION:
raise RuntimeError("STORAGE_INSECURE_TESTING_MODE cannot be used in production")
if STORAGE_INSECURE_TESTING_MODE:
DISABLE_OPTIGA = True
+ DISABLE_TROPIC = True
PYOPT = "0"
CCFLAGS_MOD = ''
@@ -84,6 +86,11 @@ if DISABLE_OPTIGA:
raise RuntimeError("DISABLE_OPTIGA requires non-production build")
FEATURES_WANTED.remove("optiga")
+if DISABLE_TROPIC:
+ if PRODUCTION:
+ raise RuntimeError("DISABLE_TROPIC requires non-production build")
+ FEATURES_WANTED.remove("tropic")
+
FROZEN = True
# modtrezorcrypto
diff --git a/core/SConscript.secmon b/core/SConscript.secmon
index 244460e5..fe64d567 100644
--- a/core/SConscript.secmon
+++ b/core/SConscript.secmon
@@ -14,6 +14,7 @@ TREZOR_MODEL = ARGUMENTS.get('TREZOR_MODEL', 'T2T1')
CMAKELISTS = int(ARGUMENTS.get('CMAKELISTS', 0))
PYOPT = ARGUMENTS.get('PYOPT', '1')
DISABLE_OPTIGA = ARGUMENTS.get('DISABLE_OPTIGA', '0') == '1'
+DISABLE_TROPIC = ARGUMENTS.get('DISABLE_TROPIC', '0') == '1'
HW_REVISION = ARGUMENTS.get('HW_REVISION', None)
THP = ARGUMENTS.get('THP', '0') == '1' # Trezor-Host Protocol
DBG_CONSOLE = ARGUMENTS.get('DBG_CONSOLE', '')
@@ -23,6 +24,7 @@ if STORAGE_INSECURE_TESTING_MODE and PRODUCTION:
raise RuntimeError("STORAGE_INSECURE_TESTING_MODE cannot be used in production")
if STORAGE_INSECURE_TESTING_MODE:
DISABLE_OPTIGA = True
+ DISABLE_TROPIC = True
PYOPT = "0"
FEATURE_FLAGS = {
@@ -51,6 +53,11 @@ if DISABLE_OPTIGA:
raise RuntimeError("DISABLE_OPTIGA requires non-production build")
FEATURES_WANTED.remove("optiga")
+if DISABLE_TROPIC:
+ if PRODUCTION:
+ raise RuntimeError("DISABLE_TROPIC requires non-production build")
+ FEATURES_WANTED.remove("tropic")
+
CCFLAGS_MOD = ''
CPPPATH_MOD = []
CPPDEFINES_MOD = []
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.