refactor(core): do not use PYOPT in syscall/smcalls
What changed, and why it matters
This commit is a code cleanup that changes how a special testing-only feature is enabled in Trezor firmware. Previously, the feature was enabled whenever Python optimization was disabled (PYOPT == 0). Now it is enabled through a dedicated flag called USE_OPTIGA_TESTING. The feature itself—raising the Optiga security event counter to maximum—remains a debug/testing capability and is not intended for production. The change does not remove the feature; it only changes the build condition that turns it on. There is no direct evidence in the commit that this fixes an active security vulnerability.
Treat as a routine refactor rather than a security patch. Verify that production/release builds continue to define neither PYOPT='0' nor USE_OPTIGA_TESTING, so the Optiga test hook remains unavailable. Review whether any CI or debug artifact accidentally ships with USE_OPTIGA_TESTING enabled.
Security signals we found
Refactoring of debug-only security hardware test hook
Decoupling of PYOPT from USE_OPTIGA_TESTING build flag
No removal of the underlying test-only syscall/smcall
No changelog entry provided by vendor
Evidence from the diff
The commit refactors conditional compilation for the Optiga ‘set_sec_max’ testing function. It replaces the preprocessor guard PYOPT == 0 with USE_OPTIGA_TESTING in smcall/syscall dispatch and stub files and in the MicroPython module binding. The build scripts (SConscript.firmware, SConscript.kernel, SConscript.secmon, SConscript.unix) are updated so that USE_OPTIGA_TESTING=1 is defined whenever PYOPT == '0' (debug builds). The functional behavior is preserved: the testing-only Optiga security counter reset remains available only in debug builds. The change reduces coupling between Python optimization level and hardware security module test hooks.
Changed components
core/SConscript.firmwarecore/SConscript.kernelcore/SConscript.secmoncore/SConscript.unixcore/embed/sys/smcall/stm32/smcall_dispatch.ccore/embed/sys/smcall/stm32/smcall_stubs.ccore/embed/sys/syscall/stm32/syscall_dispatch.ccore/embed/sys/syscall/stm32/syscall_stubs.ccore/embed/upymod/modtrezorcrypto/modtrezorcrypto-optiga.hInspect captured patch +20 / −10
diff --git a/core/SConscript.firmware b/core/SConscript.firmware
index cd2f15f1..c24241d2 100644
--- a/core/SConscript.firmware
+++ b/core/SConscript.firmware
@@ -461,7 +461,7 @@ ui.init_ui(TREZOR_MODEL, "firmware", RUST_UI_FEATURES)
SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_MICROPYTHON_SPEED
if PYOPT == '0':
- DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=1 -DSTATIC="
+ DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=1 -DSTATIC= -DUSE_OPTIGA_TESTING=1"
else:
DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=0"
diff --git a/core/SConscript.kernel b/core/SConscript.kernel
index 0d089a11..3225d304 100644
--- a/core/SConscript.kernel
+++ b/core/SConscript.kernel
@@ -263,9 +263,14 @@ if THP:
if STORAGE_INSECURE_TESTING_MODE:
CPPDEFINES_MOD += ['STORAGE_INSECURE_TESTING_MODE']
+if PYOPT == '0':
+ DEBUG_FLAGS = "-DUSE_OPTIGA_TESTING=1"
+else:
+ DEBUG_FLAGS = ""
+
env = Environment(
ENV=os.environ,
- CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY} -USCM_REVISION_INIT",
+ CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY} -USCM_REVISION_INIT {DEBUG_FLAGS}",
CPPDEFINES_IMPLICIT=[],
CPPDEFPREFIX="-D'",
CPPDEFSUFFIX="'",
diff --git a/core/SConscript.secmon b/core/SConscript.secmon
index 124d8dc4..653cf469 100644
--- a/core/SConscript.secmon
+++ b/core/SConscript.secmon
@@ -72,11 +72,16 @@ PATH_HAL = []
if DBG_CONSOLE != "":
FEATURES_WANTED += ["dbg_console"]
+if PYOPT == '0':
+ DEBUG_FLAGS = "-DUSE_OPTIGA_TESTING=1"
+else:
+ DEBUG_FLAGS = ""
+
FROZEN = True
env = Environment(
ENV=os.environ,
- CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY} -USCM_REVISION_INIT",
+ CFLAGS=f"{ARGUMENTS.get('CFLAGS', '')} -DPRODUCTION={int(PRODUCTION)} -DPYOPT={PYOPT} -DBOOTLOADER_QA={int(BOOTLOADER_QA)} -DBITCOIN_ONLY={BITCOIN_ONLY} -USCM_REVISION_INIT {DEBUG_FLAGS}",
CPPDEFINES_IMPLICIT=[],
CPPDEFPREFIX="-D'",
CPPDEFSUFFIX="'",
diff --git a/core/SConscript.unix b/core/SConscript.unix
index 453b6c01..11f322e2 100644
--- a/core/SConscript.unix
+++ b/core/SConscript.unix
@@ -457,7 +457,7 @@ ui.init_ui(TREZOR_MODEL, "firmware", RUST_UI_FEATURES)
SOURCE_QSTR = SOURCE_MOD + SOURCE_MICROPYTHON + SOURCE_UNIX
if PYOPT == '0' or not FROZEN:
- DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=1 -DSTATIC="
+ DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=1 -DSTATIC= -DUSE_OPTIGA_TESTING=1"
else:
DEBUG_FLAGS = "-DMICROPY_OOM_CALLBACK=0"
diff --git a/core/embed/sys/smcall/stm32/smcall_dispatch.c b/core/embed/sys/smcall/stm32/smcall_dispatch.c
index 8536463c..5614b806 100644
--- a/core/embed/sys/smcall/stm32/smcall_dispatch.c
+++ b/core/embed/sys/smcall/stm32/smcall_dispatch.c
@@ -213,7 +213,7 @@ __attribute((no_stack_protector)) void smcall_handler(uint32_t *args,
optiga_init_and_configure();
} break;
-#if PYOPT == 0
+#if USE_OPTIGA_TESTING
case SMCALL_OPTIGA_SET_SEC_MAX: {
optiga_set_sec_max();
} break;
diff --git a/core/embed/sys/smcall/stm32/smcall_stubs.c b/core/embed/sys/smcall/stm32/smcall_stubs.c
index b2d777c5..cfc63be7 100644
--- a/core/embed/sys/smcall/stm32/smcall_stubs.c
+++ b/core/embed/sys/smcall/stm32/smcall_stubs.c
@@ -201,7 +201,7 @@ void optiga_init_and_configure(void) {
smcall_invoke0(SMCALL_OPTIGA_INIT_AND_CONFIGURE);
}
-#if PYOPT == 0
+#if USE_OPTIGA_TESTING
void optiga_set_sec_max(void) { smcall_invoke0(SMCALL_OPTIGA_SET_SEC_MAX); }
#endif
diff --git a/core/embed/sys/syscall/stm32/syscall_dispatch.c b/core/embed/sys/syscall/stm32/syscall_dispatch.c
index ceede694..6fcb289f 100644
--- a/core/embed/sys/syscall/stm32/syscall_dispatch.c
+++ b/core/embed/sys/syscall/stm32/syscall_dispatch.c
@@ -492,7 +492,7 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args,
args[0] = optiga_read_sec__verified(sec);
} break;
-#if PYOPT == 0
+#if USE_OPTIGA_TESTING
case SYSCALL_OPTIGA_SET_SEC_MAX: {
optiga_set_sec_max();
} break;
diff --git a/core/embed/sys/syscall/stm32/syscall_stubs.c b/core/embed/sys/syscall/stm32/syscall_stubs.c
index d6561f71..83d6d3a3 100644
--- a/core/embed/sys/syscall/stm32/syscall_stubs.c
+++ b/core/embed/sys/syscall/stm32/syscall_stubs.c
@@ -474,7 +474,7 @@ bool optiga_read_sec(uint8_t *sec) {
return (bool)syscall_invoke1((uint32_t)sec, SYSCALL_OPTIGA_READ_SEC);
}
-#if PYOPT == 0
+#if USE_OPTIGA_TESTING
void optiga_set_sec_max(void) { syscall_invoke0(SYSCALL_OPTIGA_SET_SEC_MAX); }
#endif
diff --git a/core/embed/upymod/modtrezorcrypto/modtrezorcrypto-optiga.h b/core/embed/upymod/modtrezorcrypto/modtrezorcrypto-optiga.h
index f7462b11..3dccf6c6 100644
--- a/core/embed/upymod/modtrezorcrypto/modtrezorcrypto-optiga.h
+++ b/core/embed/upymod/modtrezorcrypto/modtrezorcrypto-optiga.h
@@ -123,7 +123,7 @@ STATIC mp_obj_t mod_trezorcrypto_optiga_get_sec() {
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_trezorcrypto_optiga_get_sec_obj,
mod_trezorcrypto_optiga_get_sec);
-#if PYOPT == 0
+#if USE_OPTIGA_TESTING
/// def set_sec_max() -> None:
/// """
/// Set Optiga's security event counter to maximum.
@@ -146,7 +146,7 @@ STATIC const mp_rom_map_elem_t mod_trezorcrypto_optiga_globals_table[] = {
{MP_ROM_QSTR(MP_QSTR_sign), MP_ROM_PTR(&mod_trezorcrypto_optiga_sign_obj)},
{MP_ROM_QSTR(MP_QSTR_get_sec),
MP_ROM_PTR(&mod_trezorcrypto_optiga_get_sec_obj)},
-#if PYOPT == 0
+#if USE_OPTIGA_TESTING
{MP_ROM_QSTR(MP_QSTR_set_sec_max),
MP_ROM_PTR(&mod_trezorcrypto_optiga_set_sec_max_obj)},
#endif
Why this scored 26/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.