Reproducible build

With docker you can build the firmware yourself in the same environment as we do, and verify that binaries in github releases have the same hash. This way you can be sure that firmware upgrades signed by our public keys are actually built from the code in this repository, no backdoors included.

Release builds (./build_firmware.sh) embed no clone-local provenance at all: the REPOSITORY, BRANCH and COMMIT values shown on the About screen are all unknown. This is what makes the build reproducible — the clone URL (HTTPS, SSH, or a fork remote), the checkout ref (branch or detached HEAD), the clone depth, and whether the source came from git at all or from a .git-less source archive all have no effect on the firmware binary. build_firmware.sh sets SPECTER_REPRODUCIBLE_BUILD=1 for this; plain make disco dev builds still embed the live commit SHA.

Historical note: this does not retroactively change the published v1.10.3 tag or its binaries, whose hash still depends on the git metadata embedded when that release was built.

From the root of the repository:

  1. Set up bootloader to use production keys:
cp bootloader/keys/production/pubkeys.c bootloader/keys/selfsigned/
  1. Build a docker container:
docker build -t diy .
  1. Run the container in interactive mode:
docker run -ti -v `pwd`:/app -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) diy

The container runs ./build_firmware.sh, which now also drops release/disco-nobootloader.{bin,hex} alongside the signed artifacts. The disco-nobootloader.bin image matches the standard nix build output and can be flashed directly to a development board when you want to skip the secure bootloader during testing.

At the end of the build you will be presented with a base32 encoded hash of the firmware upgrade file that should be signed and asked to provide signatures.

Get signatures from the description of the github release and enter one by one in the same order as provided in the release.

After adding signatures binaries in the release folder should be exactly the same as in github release. Hashes of the binaries will be saved to release/sha256.txt.

Note: You can also run specifics tasks directly. For example:

docker run -ti -v `pwd`:/app -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) diy ./build_firmware.sh nobootloader ownership

Apple M1 users

For Apple M1 add a platform flag to the docker commands:

docker build -t diy . --platform linux/x86_64
docker run --platform linux/amd64 -ti -v `pwd`:/app -e HOST_UID=$(id -u) -e HOST_GID=$(id -g) diy