Don’t trust, verify! – Jeder Bitcoiner versteht diese Philosophie und viele setzen sie auch in die Tat um. Genau das machen wir heute auch!
Dieses Tutorial richtet sich an diejenigen die mit Linux (oder macOS) bereits ein bisschen was anfangen können aber so etwas konkret noch nie gemacht haben. Das dürfte zwar eine eher kleine Zielgruppe sein, aber ich hatte halt Lust drauf… :D
Auch wenn das reproduzieren der Firmware eher etwas für’s gute Gewissen ist als eine wirklich relevante Sicherheitsmaßnahme, macht es sicherlich Sinn (und Spaß) es einfach mal gemacht zu haben. :)
Hinweis
Wir verifizieren hier nicht die Qualität der Inhalte sondern die Integrität, also ob die Open-Source Firmware auf GitHub dieselbe ist, die von Shift Crypto veröffentlicht und auf unserer BitBox02 installiert wird.
Falls ihr mehr zur Sicherheit der BitBox02 lesen wollt, hier entlang:
Warum reproduzieren?
Die Firmware der BitBox02 ist vollständig quelloffen und reproduzierbar. Wie können wir aber wissen ob die auf der BitBox02 installierte Firmware auch tatsächlich dem Release auf GitHub entspricht?
Dafür reproduzieren wir die Firmware einfach selbst und vergleichen die Prüfsummen mit denen des offiziellen Releases von Shift Crypto. Wir können die Checksumme unseres reproduzierten Releases dann auch mit dem Firmware Hash auf der BitBox02 abgleichen.
Es geht hier also eigentlich nur darum sicher zu stellen dass der öffentlich einsehbare Quellcode tatsächlich auch im kompilierten Release steckt. Nicht mehr, und nicht weniger.
Legen wir los!
Zunächst stellen wir sicher dass Docker auf eurem System installiert (und gestartet) ist.
sudo docker info
Falls nein, installiert Docker mit einem Package Manager eurer Wahl.
Eine ausführliche Dokumentation zum Installieren von Docker finder ihr hier.
Ausreichen sollte aber:
sudo apt-get install docker docker.io
Anschließend (nach einem Reboot) starten wir Docker mit:
sudo systemctl start docker
systemctl status docker
… müsste jetzt ein grünes Lämpchen zurück liefern. :)
macOS: Docker Desktop hier installieren und starten
Wenn ihr im Folgenden die Dateien nicht auf eurem System behalten wollt, wechselt in einen temporären Ordner:
cd /tmp
Jetzt holen wir uns eine lokale Kopie vom GitHub Repository der BitBox02 Firmware:
git clone https://github.com/BitBoxSwiss/bitbox02-firmware.git
cd bitbox02-firmware/
Mit ls -la
müsstet ihr jetzt alle Dateien sehen die auch auf der Startseite des Repositories aufzufinden sind.
Wir wechseln in den Ordner releases
. Um es möglichst einfach zu halten werden wir in diesem Ordner bleiben.
cd releases
Jetzt überlegen wir uns welche Firmware wir reproduzieren wollen. In der Regel ist das die Version die auch auf unserer BitBox02 installiert ist, wir können aber auch ältere Versionen reproduzieren, falls wir das möchten.
Wir speichern uns die neuste Version in einer Variable (die folgenden Befehle funktionieren daher auch in Zukunft – ihr könnt aber auch einfach manuell die gewünschte Version einfügen):
VERSION=$(git tag -l 'firmware*' | sort --version-sort | tail -n 1 | egrep -o 'v[0-9.]+')
Wichtig ist auch die Unterscheidung zur Bitcoin-only Edition, die natürlich eine eigene Firmware Version hat.
Im folgenden werden wir beispielhaft die Multi-Edition v9.16.0 verifizieren. Wer die Bitcoin-only Edition reproduziert, muss nachfolgend entsprechend die Dateipfade und Links leicht anpassen.
# Bitcoin-only:
sudo ./build.sh firmware-btc-only/$VERSION "make firmware-btc"
# Multi:
sudo ./build.sh firmware/$VERSION "make firmware"
Wichtiger Hinweis für Macs mit Apple Silicon
Es ist ein Krampf. Ich habe es nicht geschafft mit meinem Rechner lokal zu verifizieren, die Docker Emulation ist einfach zu langsam und ich laufe auch immer in einen Segfault. Allzu viel Zeit wollte ich dann auch nicht investieren, wäre also dankbar falls jemand eine elegante Lösung gefunden hat.
Nutzt also entweder einen anderen Rechner, holt euch irgendwo einen stündlich abrechnenden Server (dann zahlt man ca. 0,01€) oder lasst es bleiben…
Das kann jetzt einige Zeit dauern, holt euch einen Kaffee und schubst ein paar Sats. Es kann gut sein dass euch der Build irgendwann abbricht, schaut euch dann die Fehlermeldung an und versucht herauszufinden woran et jelegen hat.
Sobald der Build fertig ist, sind wir fast schon am Ziel. Die Datei firmware-btc.bin
bzw. firmware.bin
liegt jetzt in einem neu angelegten Unterordner. Wir werden jetzt SHA-256 auf diese Datei anwenden und schauen ob wir die richtige Hashsumme erhalten.
# Bitcoin-only:
sha256sum temp/build/bin/firmware-btc.bin
# Multi:
sha256sum temp/build/bin/firmware.bin
Auf macOS shasum -a 256
statt sha256sum
verwenden.
Wir haben jetzt unsere Prüfsumme und wollen diese vergleichen. Dafür schauen wir in die assertion.txt
Datei des entsprechenden Relase-Ordners rein:
cat firmware-$VERSION/assertion.txt
Prüfsumme identisch mit eurem Build? Geschafft! Wir haben die BitBox02 Firmware erfolgreich reproduziert.
Das ist allerdings „nur“ der Hash der unsignierten Binary, der noch nicht mit dem Firmware Hash auf der BitBox02 übereinstimmt…
Firmware Hash im BitBox02 Bootloader
Auch das, also ob die signierte Binary die von uns reproduzierte Binary enthält, können wir noch selbst überprüfen, zunächst müssen wir dafür die BitBox02 Python Bibliothek installieren:
pip install -r ../py/requirements.txt
Wir laden uns die signierte Binary runter (geht hier auch manuell).
(URL entsprechend der Edition anpassen)
wget https://github.com/BitBoxSwiss/bitbox02-firmware/releases/download/firmware%2F$VERSION/firmware.$VERSION.signed.bin
Jetzt lassen wir das Python Skript describe_signed_firmware.py
auf die signierte Binary los.
(Dateiname entsprechend der Edition anpassen)
./describe_signed_firmware.py firmware-btc.$VERSION.signed.bin
Wir wissen jetzt dass unsere reproduzierte Binary in der signierten enthalten ist (erste Prüfsumme stimmt mit unserer überein). Dem veröffentlichten Firmware Hash können wir jetzt also vertrauen.
In der BitBox App klicken wir auf Gehe zu den Starteinstellungen und bestätigen dies auf der BitBox02. Wir landen jetzt im Bootloader und können in der App auf Erweiterte Einstellungen klicken und den Haken für den Firmware Hash setzen.
Beim Start wird uns jetzt jedes mal der Firmware Hash präsentiert, der mit dem Hash oben übereinstimmen sollte.
Theoretisch könnte man diese komplette Prozedur bei jedem Release wiederholen, für die allermeisten wird es ausreichen das einfach mal gemacht zu haben. :)
Signaturen verifizieren
Stattdessen könnt ihr auch einfach die Signaturen der assertion.txt
Datei von den Entwicklern (und anderen aus der Community) überprüfen und habt damit auch indirekt verifiziert dass alles seine Richtigkeit hat.
Natürlich ist hier wieder Vertrauen im Spiel, da ihr erstens die Unterschreiber nicht kennt und diese ihre Signatur natürlich auch setzen können ohne selbst reproduziert zu haben, aber da es dafür absolut keinen Anreiz gibt könnt ihr hier relativ zuversichtlich sein.
Hier ein Beispiel zum Verifizieren, wir sind immer noch im releases
Ordner. Zunächst importieren wir erstmal alle verfügbaren öffentlichen Schlüssel aus dem pubkeys
Ordner.
gpg --import pubkeys/*.asc
Jetzt können wir eine beliebige Signatur (oder auch alle) im jeweiligen Releaseordner einfach verifizieren. Hier als Beispiel einfach mal meine Signatur für die Multi-Edition:
cd firmware-$VERSION
gpg --verify assertion-sutterseba.sig assertion.txt
Hinweis: Nicht wundern wenn ihr hier diese Warnung bekommt:
WARNING: This key is not certified with a trusted signature!
Das liegt daran, dass ihr dem öffentlichen Schlüssel nicht vertraut, da ihr die Person z.B. nicht kennt bzw. nicht verifizieren könnt, ob es sich wirklich um diese Person handelt. Die Signatur ist aber gültig, sobald ihr „Good Signature“ zurückbekommt (vs. „BAD Signature“ im Falle einer ungültigen Signatur).
Um direkt alle Signaturen vom jeweiligen Release zu überprüfen (vorher müssen wie oben alle Public Keys importiert sein):
for sig in *.sig ; do gpg --verify $sig assertion.txt ; done
Für die Zukunft
Um Änderungen im Repository, z.B. nach einem neuen Firmware Release, auch lokal zu übernehmen nutzt ihr:
git pull
Wenn ihr einfach nur den Firmware Hash auf der BitBox02 mit den Angaben auf GitHub abgleichen wollt, ohne diese explizit selbst zu verifizieren, dann findet ihr immer zu jedem Release direkt den zugehörigen Firmware Hash aufgelistet:
Veröffentlicht eure Signatur!
Wer sich mit GitHub und GPG etwas auskennt, sollte die sich im Ordner der jeweiligen Firmware (die man gerade reproduziert hat) befindende assertion.txt
Datei signieren und eine PR mit der Signatur und seinem Public Key öffnen.
Eure Signatur ist danach für andere zur Verifizierung sichtbar, und ihr könnt von euch behaupten, dass ihr einen kleinen Beitrag zur BitBox02 Firmware beigetragen habt!
Beachtet bitte die Anleitungen im Repository sorgfältig!
Solltet ihr irgendwo Probleme haben und nicht weiter kommen, dann meldet euch hier im Thread!
Ich hoffe es war hilfreich und das Vertrauen in eure Hardware Wallet ist etwas gestärkt! :)