feat: build-docker.sh: add translations root to fingerprints when core firmware is built
What changed, and why it matters
This change updates Trezor's build script so that when core firmware is built, a 'translations Merkle root' is added to the reproducible-build fingerprints file. It also adds a command-line option to skip that step. The change is about build reproducibility and verification, not about fixing a vulnerability in the device firmware itself.
No security action required. Treat as a normal build/CI improvement. Reviewers may verify that the translations root is correctly computed and that --skip-translations behaves as documented.
Security signals we found
Build reproducibility / attestation change
Adds optional translations Merkle root to fingerprint file
No runtime firmware code changed
No cryptographic primitive or memory-safety change in firmware
Evidence from the diff
The commit modifies build-docker.sh to: (1) track whether any core firmware target was built via CORE_FIRMWARE_BUILT, (2) append a translations Merkle root (computed by core/translations/cli.py merkle-root) to the fingerprints file when core firmware is built and –skip-translations is not set, and (3) compute the master fingerprint after the append. This affects the reproducible-build attestation pipeline, not runtime firmware behavior.
Changed components
build-docker.shreproducible-build fingerprint generation pipelineInspect captured patch +24 / −3
diff --git a/build-docker.sh b/build-docker.sh
index 0895f62e..98f9953e 100755
--- a/build-docker.sh
+++ b/build-docker.sh
@@ -50,6 +50,7 @@ function help_and_die() {
echo "Options:"
echo " --skip-bitcoinonly - do not build bitcoin-only firmwares"
echo " --skip-normal - do not build regular firmwares"
+ echo " --skip-translations - do not add the translations Merkle root to the fingerprints file"
echo " --repository path/to/repo - checkout the repository from the given path/url"
echo " --no-init - do not recreate docker environments"
echo " --init-only - set up the docker environment and exit without building"
@@ -68,6 +69,7 @@ function help_and_die() {
OPT_BUILD_NORMAL=1
OPT_BUILD_BITCOINONLY=1
OPT_BUILD_NRF=0
+OPT_ADD_TRANSLATIONS=1
INIT=1
INIT_ONLY=0
MODELS=(T1B1 T2B1 T2T1 T3T1 T3W1)
@@ -88,6 +90,10 @@ while true; do
OPT_BUILD_NORMAL=0
shift
;;
+ --skip-translations)
+ OPT_ADD_TRANSLATIONS=0
+ shift
+ ;;
--repository)
REPOSITORY="$2"
shift 2
@@ -304,6 +310,8 @@ DIR=$(pwd)
# build core
+CORE_FIRMWARE_BUILT=0
+
for TREZOR_MODEL in ${MODELS[@]}; do
if [ "$TREZOR_MODEL" = "T1B1" ]; then
continue
@@ -331,6 +339,10 @@ for TREZOR_MODEL in ${MODELS[@]}; do
continue
fi
+ if [[ "$MAKE_TARGETS" == *build_firmware* ]]; then
+ CORE_FIRMWARE_BUILT=1
+ fi
+
SCRIPT_NAME=".build_core_${TREZOR_MODEL}_${BITCOIN_ONLY}.sh"
cat <<EOF > "build/$SCRIPT_NAME"
# DO NOT MODIFY!
@@ -561,9 +573,8 @@ echo
FINGERPRINTS_FILE="build/${COMMIT_HASH}.fingerprints"
MASTER_FILE="build/${COMMIT_HASH}.master"
if [ -f "$FINGERPRINTS_FILE" ]; then
- echo "Fingerprints ($FINGERPRINTS_FILE):"
- echo
- cat "$FINGERPRINTS_FILE"
+ # Append the translations root if a firmware that consumes them was built and
+ # compute the master fingerprint.
$DOCKER run \
--network=host \
--rm \
@@ -572,10 +583,20 @@ if [ -f "$FINGERPRINTS_FILE" ]; then
"$SNAPSHOT_NAME" \
/nix/var/nix/profiles/default/bin/nix-shell --run \
"cd /reproducible-build/trezor-firmware \
+ && if [ $OPT_ADD_TRANSLATIONS -eq 1 ] && [ $CORE_FIRMWARE_BUILT -eq 1 ] \
+ && ! grep -q '^translations:' /local/$FINGERPRINTS_FILE; then \
+ translations_root=\$(uv run core/translations/cli.py merkle-root) \
+ && { echo '# core/translations'; \
+ echo \"translations: \$translations_root\"; \
+ echo; } >> /local/$FINGERPRINTS_FILE; \
+ fi \
&& uv run python/tools/master-fingerprint.py /local/$FINGERPRINTS_FILE \
> /local/$MASTER_FILE \
&& chown $USER:$GROUP /local/$MASTER_FILE" \
|| { rm -f "$MASTER_FILE"; exit 1; }
+ echo "Fingerprints ($FINGERPRINTS_FILE):"
+ echo
+ cat "$FINGERPRINTS_FILE"
cat "$MASTER_FILE"
else
echo "(no core/legacy firmware images built)"
Why this scored 18/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.