feat(core): add telemetry response in unix.
What changed, and why it matters
This commit reorganizes where the device's internal battery/telemetry tracking code lives and adds a fake fixed-response version for the desktop emulator. It does not fix any security bug, introduce a new attack path, or change how real hardware protects data. It is a build/structure-only change.
No security action required. Treat as normal feature/build maintenance.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The change moves telemetry.c from core/embed/sec/telemetry/ to core/embed/sec/telemetry/stm32u5/ and adds a new unix/telemetry.c stub that returns hard-coded telemetry values (20 °C min, 35 °C max, zero battery errors, 30.0 cycles). The SCons build files are updated to select the stm32u5 implementation for hardware builds and the unix stub for the T3W1 emulator. The real hardware implementation is unchanged in behavior; only its path changed. No security boundary, cryptographic operation, authentication, or secret handling is modified.
Changed components
core/embed/sec/telemetry/stm32u5/telemetry.ccore/embed/sec/telemetry/unix/telemetry.ccore/site_scons/models/T3W1/emulator.pycore/site_scons/models/T3W1/trezor_t3w1_revB.pycore/site_scons/models/T3W1/trezor_t3w1_revC.pyInspect captured patch +177 / −133
diff --git a/core/embed/sec/telemetry/stm32u5/telemetry.c b/core/embed/sec/telemetry/stm32u5/telemetry.c
new file mode 100644
index 000000000..102ec702f
--- /dev/null
+++ b/core/embed/sec/telemetry/stm32u5/telemetry.c
@@ -0,0 +1,132 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef SECURE_MODE
+
+#include <trezor_types.h>
+
+#include <sec/backup_ram.h>
+#include <sec/telemetry.h>
+
+// Versioning for persisted telemetry structure
+#define TELEMETRY_DATA_VERSION 0x0001
+
+typedef struct {
+ uint16_t version;
+ uint8_t initialized; // 0 = not set, 1 = valid data present
+ uint8_t reserved; // alignment/padding
+ telemetry_data_t data;
+} telemetry_t;
+
+static bool telemetry_read(telemetry_t* out) {
+ size_t size = 0;
+ if (!backup_ram_read(BACKUP_RAM_KEY_TELEMETRY, out, sizeof(*out), &size)) {
+ return false;
+ }
+ if (size != sizeof(*out)) {
+ return false;
+ }
+ if (out->version != TELEMETRY_DATA_VERSION) {
+ return false;
+ }
+ return true;
+}
+
+static bool telemetry_write(const telemetry_t* data) {
+ return backup_ram_write(BACKUP_RAM_KEY_TELEMETRY, BACKUP_RAM_ITEM_PUBLIC,
+ data, sizeof(*data));
+}
+
+static void telemetry_init_record(void) {
+ telemetry_t telemetry;
+ telemetry.version = TELEMETRY_DATA_VERSION;
+ telemetry.initialized = 1;
+ telemetry.reserved = 0;
+ telemetry.data.min_temp_c = 500.0f;
+ telemetry.data.max_temp_c = -500.0f;
+ telemetry.data.battery_errors.all = 0;
+ telemetry.data.battery_cycles = 0.0f;
+ telemetry_write(&telemetry);
+}
+
+void telemetry_update_battery_temp(float temp_c) {
+ telemetry_t telemetry;
+ bool have = telemetry_read(&telemetry) && telemetry.initialized == 1;
+
+ if (!have) {
+ telemetry_init_record();
+ }
+
+ bool changed = false;
+ if (temp_c < telemetry.data.min_temp_c) {
+ telemetry.data.min_temp_c = temp_c; // min can only decrease
+ changed = true;
+ }
+ if (temp_c > telemetry.data.max_temp_c) {
+ telemetry.data.max_temp_c = temp_c; // max can only increase
+ changed = true;
+ }
+
+ if (changed) {
+ telemetry_write(&telemetry);
+ }
+}
+
+void telemetry_update_battery_errors(telemetry_batt_errors_t errors) {
+ telemetry_t telemetry;
+ bool have = telemetry_read(&telemetry) && telemetry.initialized == 1;
+
+ if (!have) {
+ telemetry_init_record();
+ }
+
+ // Only update and write if some of OUR flags are set
+ if (errors.all != 0 &&
+ ((telemetry.data.battery_errors.all & errors.all) != errors.all)) {
+ telemetry.data.battery_errors.all |= errors.all;
+ telemetry_write(&telemetry);
+ }
+}
+
+void telemetry_update_battery_cycles(float battery_cycles_inc) {
+ telemetry_t telemetry;
+ bool have = telemetry_read(&telemetry) && telemetry.initialized == 1;
+
+ if (!have) {
+ telemetry_init_record();
+ }
+
+ if (battery_cycles_inc > 0.0f) {
+ telemetry.data.battery_cycles += battery_cycles_inc;
+ telemetry_write(&telemetry);
+ }
+}
+
+bool telemetry_get(telemetry_data_t* out) {
+ telemetry_t telemetry;
+ if (!telemetry_read(&telemetry) || telemetry.initialized != 1) {
+ return false;
+ }
+ if (out != NULL) {
+ *out = telemetry.data;
+ }
+ return true;
+}
+
+#endif
diff --git a/core/embed/sec/telemetry/telemetry.c b/core/embed/sec/telemetry/telemetry.c
deleted file mode 100644
index 102ec702f..000000000
--- a/core/embed/sec/telemetry/telemetry.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * This file is part of the Trezor project, https://trezor.io/
- *
- * Copyright (c) SatoshiLabs
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifdef SECURE_MODE
-
-#include <trezor_types.h>
-
-#include <sec/backup_ram.h>
-#include <sec/telemetry.h>
-
-// Versioning for persisted telemetry structure
-#define TELEMETRY_DATA_VERSION 0x0001
-
-typedef struct {
- uint16_t version;
- uint8_t initialized; // 0 = not set, 1 = valid data present
- uint8_t reserved; // alignment/padding
- telemetry_data_t data;
-} telemetry_t;
-
-static bool telemetry_read(telemetry_t* out) {
- size_t size = 0;
- if (!backup_ram_read(BACKUP_RAM_KEY_TELEMETRY, out, sizeof(*out), &size)) {
- return false;
- }
- if (size != sizeof(*out)) {
- return false;
- }
- if (out->version != TELEMETRY_DATA_VERSION) {
- return false;
- }
- return true;
-}
-
-static bool telemetry_write(const telemetry_t* data) {
- return backup_ram_write(BACKUP_RAM_KEY_TELEMETRY, BACKUP_RAM_ITEM_PUBLIC,
- data, sizeof(*data));
-}
-
-static void telemetry_init_record(void) {
- telemetry_t telemetry;
- telemetry.version = TELEMETRY_DATA_VERSION;
- telemetry.initialized = 1;
- telemetry.reserved = 0;
- telemetry.data.min_temp_c = 500.0f;
- telemetry.data.max_temp_c = -500.0f;
- telemetry.data.battery_errors.all = 0;
- telemetry.data.battery_cycles = 0.0f;
- telemetry_write(&telemetry);
-}
-
-void telemetry_update_battery_temp(float temp_c) {
- telemetry_t telemetry;
- bool have = telemetry_read(&telemetry) && telemetry.initialized == 1;
-
- if (!have) {
- telemetry_init_record();
- }
-
- bool changed = false;
- if (temp_c < telemetry.data.min_temp_c) {
- telemetry.data.min_temp_c = temp_c; // min can only decrease
- changed = true;
- }
- if (temp_c > telemetry.data.max_temp_c) {
- telemetry.data.max_temp_c = temp_c; // max can only increase
- changed = true;
- }
-
- if (changed) {
- telemetry_write(&telemetry);
- }
-}
-
-void telemetry_update_battery_errors(telemetry_batt_errors_t errors) {
- telemetry_t telemetry;
- bool have = telemetry_read(&telemetry) && telemetry.initialized == 1;
-
- if (!have) {
- telemetry_init_record();
- }
-
- // Only update and write if some of OUR flags are set
- if (errors.all != 0 &&
- ((telemetry.data.battery_errors.all & errors.all) != errors.all)) {
- telemetry.data.battery_errors.all |= errors.all;
- telemetry_write(&telemetry);
- }
-}
-
-void telemetry_update_battery_cycles(float battery_cycles_inc) {
- telemetry_t telemetry;
- bool have = telemetry_read(&telemetry) && telemetry.initialized == 1;
-
- if (!have) {
- telemetry_init_record();
- }
-
- if (battery_cycles_inc > 0.0f) {
- telemetry.data.battery_cycles += battery_cycles_inc;
- telemetry_write(&telemetry);
- }
-}
-
-bool telemetry_get(telemetry_data_t* out) {
- telemetry_t telemetry;
- if (!telemetry_read(&telemetry) || telemetry.initialized != 1) {
- return false;
- }
- if (out != NULL) {
- *out = telemetry.data;
- }
- return true;
-}
-
-#endif
diff --git a/core/embed/sec/telemetry/unix/telemetry.c b/core/embed/sec/telemetry/unix/telemetry.c
new file mode 100644
index 000000000..57621fb79
--- /dev/null
+++ b/core/embed/sec/telemetry/unix/telemetry.c
@@ -0,0 +1,33 @@
+/*
+ * This file is part of the Trezor project, https://trezor.io/
+ *
+ * Copyright (c) SatoshiLabs
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef SECURE_MODE
+
+#include <sec/telemetry.h>
+#include <trezor_types.h>
+
+bool telemetry_get(telemetry_data_t* out) {
+ out->min_temp_c = 20.0f;
+ out->max_temp_c = 35.0f;
+ out->battery_errors.all = 0;
+ out->battery_cycles = 30.00f;
+ return true;
+}
+
+#endif
diff --git a/core/site_scons/models/T3W1/emulator.py b/core/site_scons/models/T3W1/emulator.py
index eb3c8c0e3..8d68feb9d 100644
--- a/core/site_scons/models/T3W1/emulator.py
+++ b/core/site_scons/models/T3W1/emulator.py
@@ -125,6 +125,11 @@ def configure(
paths += ["embed/io/power_manager/inc"]
features_available.append("power_manager")
+ sources += ["embed/sec/telemetry/unix/telemetry.c"]
+ paths += ["embed/sec/telemetry/inc"]
+ defines += [("USE_TELEMETRY", "1")]
+ features_available.append("telemetry")
+
paths += ["embed/io/suspend/inc"]
features_available.append("backlight")
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revB.py b/core/site_scons/models/T3W1/trezor_t3w1_revB.py
index 78de3c3d7..c35a48ec2 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revB.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revB.py
@@ -239,6 +239,12 @@ def configure(
paths += ["embed/sec/hw_revision/inc"]
sources += ["embed/sec/hw_revision/stm32/hw_revision.c"]
+ if "telemetry" in features_wanted:
+ sources += ["embed/sec/telemetry/stm32u5/telemetry.c"]
+ paths += ["embed/sec/telemetry/inc"]
+ defines += [("USE_TELEMETRY", "1")]
+ features_available.append("telemetry")
+
defines += [
"FRAMEBUFFER",
"DISPLAY_RGBA8888",
diff --git a/core/site_scons/models/T3W1/trezor_t3w1_revC.py b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
index b559fd60a..579502e5d 100644
--- a/core/site_scons/models/T3W1/trezor_t3w1_revC.py
+++ b/core/site_scons/models/T3W1/trezor_t3w1_revC.py
@@ -238,7 +238,7 @@ def configure(
sources += ["embed/sec/hw_revision/stm32/hw_revision.c"]
if "telemetry" in features_wanted:
- sources += ["embed/sec/telemetry/telemetry.c"]
+ sources += ["embed/sec/telemetry/stm32u5/telemetry.c"]
paths += ["embed/sec/telemetry/inc"]
defines += [("USE_TELEMETRY", "1")]
features_available.append("telemetry")
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.