feat(core/prodtest): add rgb_led effect commands to prodtest.
What changed, and why it matters
This commit adds two new factory-testing commands for controlling the RGB LED on Trezor devices during production testing. It is a feature addition to the prodtest (manufacturing diagnostic) firmware, not a fix for a security issue. There is no indication it addresses a vulnerability or was disclosed as security-relevant.
No security action required. Treat as a normal feature addition to production-test firmware. If reviewing for defense in depth, verify that `rgb_led_effect_start`/`rgb_led_effect_stop` cannot be triggered from the main firmware or bootloader and that prodtest interface access is appropriately restricted in production devices.
Security signals we found
New prodtest CLI commands for RGB LED effects
Argument validation present (uint32 bounds, arg count, positive cycle check)
Disables automatic RGB LED control before starting/stopping effects
No changelog entry (marked [no changelog])
No security-relevant description in commit or references
Evidence from the diff
The patch introduces rgbled-effect-start and rgbled-effect-stop CLI commands in core/embed/projects/prodtest/cmd/prodtest_rgbled.c, plus documentation in the prodtest README. The commands validate arguments (effect number bounds, positive requested cycles, argument count), disable automatic RGB LED control in the prodtest main loop, and call rgb_led_effect_start() / rgb_led_effect_stop(). The code appears to perform standard input validation and does not expose obvious unsafe behavior beyond the intended prodtest interface.
Changed components
core/embed/projects/prodtest/cmd/prodtest_rgbled.ccore/embed/projects/prodtest/README.mdInspect captured patch +93 / −0
diff --git a/core/embed/projects/prodtest/README.md b/core/embed/projects/prodtest/README.md
index 4f091fc7e..0cb195ba9 100644
--- a/core/embed/projects/prodtest/README.md
+++ b/core/embed/projects/prodtest/README.md
@@ -541,6 +541,28 @@ rgbled-set 255 0 0
OK
```
+### rgbled-effect-start
+Start the rgb effect from the predifined list. Command takes two arguments, first argument define a number of the rgbled effect, second argument then define number of requested cycles for which the effect should run. `requested_cycles` argument is optional, calling the command without it will run effect indefinitly.
+
+`rgbled-effect-start <effect_num> <requested_cycles>`
+
+Example:
+```
+rgbled-effect-start 0 2
+# Start RGB LED effect #0 for 2 cycles
+OK
+```
+
+### rgbled-effect-stop
+stop the ongoing rgbled effect.
+
+Examples:
+```
+rgbled-effect-stop
+# Stop ongoing RGB LED effect
+OK
+```
+
### otp-batch-read
Retrieves the batch string from the device's OTP memory. The batch string identifies the model and production batch of the device.
diff --git a/core/embed/projects/prodtest/cmd/prodtest_rgbled.c b/core/embed/projects/prodtest/cmd/prodtest_rgbled.c
index 63b575619..d2603a551 100644
--- a/core/embed/projects/prodtest/cmd/prodtest_rgbled.c
+++ b/core/embed/projects/prodtest/cmd/prodtest_rgbled.c
@@ -63,6 +63,62 @@ static void prodtest_rgbled_set(cli_t* cli) {
cli_ok(cli, "");
}
+static void prodtest_rgbled_effect_start(cli_t* cli) {
+ uint32_t effect_num;
+ uint32_t requested_cycles = 0;
+
+ if (!cli_arg_uint32(cli, "effect_num", &effect_num) ||
+ effect_num >= RGB_LED_NUM_OF_EFFECTS) {
+ cli_error_arg(cli, "Expecting effect number in range 0-%d.",
+ (RGB_LED_NUM_OF_EFFECTS - 1));
+ return;
+ }
+
+ if (cli_has_arg(cli, "requested_cycles")) {
+ if (!cli_arg_uint32(cli, "requested_cycles", &requested_cycles) ||
+ requested_cycles == 0) {
+ cli_error_arg(cli,
+ "Expecting requested_cycles to be a positive integer.");
+ return;
+ }
+ }
+
+ if (cli_arg_count(cli) > 2) {
+ cli_error_arg_count(cli);
+ return;
+ }
+
+ if (requested_cycles == 0) {
+ cli_trace(cli, "Start RGB LED effect #%d for infinite cycles", effect_num);
+ } else {
+ cli_trace(cli, "Start RGB LED effect #%d for %d cycles", effect_num,
+ requested_cycles);
+ }
+
+ // Disable automatic control of RGB LED in prodtest main loop
+ prodtest_disable_rgbled_control();
+
+ rgb_led_effect_start((rgb_led_effect_type_t)effect_num, requested_cycles);
+
+ cli_ok(cli, "");
+}
+
+static void prodtest_rgbled_effect_stop(cli_t* cli) {
+ if (cli_arg_count(cli) > 0) {
+ cli_error_arg_count(cli);
+ return;
+ }
+
+ cli_trace(cli, "Stop ongoing RGB LED effect");
+
+ // Disable automatic control of RGB LED in prodtest main loop
+ prodtest_disable_rgbled_control();
+
+ rgb_led_effect_stop();
+
+ cli_ok(cli, "");
+}
+
// clang-format off
PRODTEST_CLI_CMD(
@@ -72,4 +128,19 @@ PRODTEST_CLI_CMD(
.args = "<r> <g> <b>"
);
+PRODTEST_CLI_CMD(
+ .name = "rgbled-effect-start",
+ .func = prodtest_rgbled_effect_start,
+ .info = "Start rgbled effect",
+ .args = "<effect_num> <requested_cycles>"
+);
+
+PRODTEST_CLI_CMD(
+ .name = "rgbled-effect-stop",
+ .func = prodtest_rgbled_effect_stop,
+ .info = "Stop rgbled effect",
+ .args = ""
+);
+
+
#endif // USE_RGB_LED
Why this scored 21/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.