fix(core): embed the bitcoin-only vendor header in bitcoin-only builds
What changed, and why it matters
This commit fixes a build-time logic bug in Trezor firmware where the wrong vendor signature header could be embedded in Bitcoin-only firmware builds. The change makes the build system correctly detect Bitcoin-only mode by checking that the 'universal_fw' feature is absent, rather than relying on a 'bitcoin_only' feature flag that may not be set in all Bitcoin-only build configurations. Using the wrong vendor header could cause a device to present itself as a multi-coin/universal firmware or fail validation checks, but the effect is primarily at build/packaging time and would likely be caught by existing verification processes.
Treat as a build-hardening fix. Verify that all Bitcoin-only and universal firmware build variants now embed the expected vendor header, and add regression tests or assertions in CI that compare the embedded vendor header against the build configuration. Review whether the 'bitcoin_only' feature is still needed or should be deprecated to avoid future confusion.
Security signals we found
Build-system logic affecting signed firmware vendor header selection
Feature-flag mismatch between 'bitcoin_only' and absence of 'universal_fw'
Potential for incorrect vendor header embedding in firmware artifacts
No changelog entry provided
Evidence from the diff
In core/embed/xbuild/src/trezor.rs, get_firmware_vendor() selects which vendor header binary to embed. Previously it branched on has_feature(‘bitcoin_only’) to choose ‘trezor_btconly_signed_prod’. The patch introduces is_bitcoin_only() defined as !has_feature(‘universal_fw’) and uses that instead. This implies that Bitcoin-only builds were not necessarily setting the ‘bitcoin_only’ feature, so universal firmware builds could incorrectly fall into the bitcoin-only branch, or bitcoin-only builds could be misclassified. The vendor header is part of the signed firmware envelope used by the bootloader to verify firmware authenticity and identify the firmware variant.
Changed components
core/embed/xbuild/src/trezor.rsTrezor firmware build/packaging pipelineFirmware vendor header selection for Bitcoin-only and universal buildsInspect captured patch +5 / −1
diff --git a/core/embed/xbuild/src/trezor.rs b/core/embed/xbuild/src/trezor.rs
index 8c9e251e..3d316785 100644
--- a/core/embed/xbuild/src/trezor.rs
+++ b/core/embed/xbuild/src/trezor.rs
@@ -82,6 +82,10 @@ pub fn vendor_header_path(models_dir: impl AsRef<Path>, target: &str) -> Result<
.join(format!("vendorheader_{}.bin", vendor)))
}
+fn is_bitcoin_only() -> bool {
+ !has_feature("universal_fw")
+}
+
fn get_firmware_vendor() -> Result<&'static str> {
Ok(if has_feature("bootloader_devel") {
if has_feature("unsafe_fw") {
@@ -93,7 +97,7 @@ fn get_firmware_vendor() -> Result<&'static str> {
"unsafe_signed_prod"
} else if current_model_id()? == "T2T1" {
"satoshilabs_signed_prod"
- } else if has_feature("bitcoin_only") {
+ } else if is_bitcoin_only() {
"trezor_btconly_signed_prod"
} else {
"trezor_signed_prod"
Why this scored 45/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.