Open matty279 opened 10 months ago
./jade_ota.py
is really more of an internal script used during automated testing than a script intended for users - you may find ./update_jade_fw.py
more user-friendly - it looks at the plugged jade to determine the 'hw_target' (uploading the wrong 'target' to hw is not recommended - it should be harmless and produce an 'INVALID_FW' error, but it's not something we test (all possible combinations of) on a regular basis!).
Of course you are free to use jade_ota.py
as you show above (* see below). I suppose it has the upper hand if you decidedly don't want to plug the jade in to an internet-connected machine, but yes, it may make some assumptions as it was written to run as part of the automated CI process.
That said, I'll take your suggestion on board and tweak it to create the build dir if not present, thanks.
NOTE: (*) again because of its history/intended use, the script assumes it should upload the fw to jade by default. If you also pass '--skipserial --skipble' it will just save the fw locally and not try to upload/update jade.
Ok, to answer your actual question ;-) :
1.0.27_noradio_1118208_fw.bin 1.0.27_noradio_1118208_fw.bin.hash
The former is a compressed 'full' firmware image binary - ie. the entirety of the '1.0.27 noradio' fw. The latter contains the hash of the uncompressed final firmware image - ie. the hash of the '1.0.27 noradio' fw that jade will boot/run. ( NOTE: We also offer 'from fwA to fwB' delta/diff patches - in this case the .hash file would have the hash of the final fw jade will run - so eg. 'anything-to-1.0.27-noradio' would all have the same .hash file - the hash of the '1.0.27 noradio' fw that jade will boot/run after the diff has been applied to existing/running fw.)
Should you run the jade_ota.py
script again to upload the firmware to Jade (./jade_ota.py --fwfile build/1.0.27_noradio_1118208_fw.bin
) the script will read that .hash file and pass the hash to Jade before it uploads any firmware - you should see it on screen when confirming the upgrade.
If you go ahead, the compressed firmware (or delta patch) is uploaded to Jade. When complete, Jade checks the hash of the final firmware image it now has ready to boot matches that uploaded/inspected/confirmed by you (if mismatch, the fw is discarded and not finalised for booting).
If you have downloaded a full firmware image, such as you have above, you can uncompress it and check the hash matches that in the file (ofc this doesn't work for deltas, which need to be applied to a base as well as being uncompressed). eg:
cp build/1.0.27_noradio_1118208_fw.bin ./1.0.27_noradio_fw_image.gz
pigz -z -d ./1.0.27_noradio_fw_image.gz
sha256sum ./1.0.27_noradio_fw_image
(because of the compression used, I don't think normal 'gzip -d' works ... although pigz wants the file suffixed .gz ... odd ... might depend on your version of gzip, might need additional arguments, not sure ...)
At that point the sha should match (and uncomp[ressed file size should be that in the original filename - in this case 1118208).
We (Blockstream) really ought to provide a signed file of fw hashes, or secure web page with them listed, or something similar. This is something we are aware of.
NOTE: a firmware image won't update/boot/run on an official Jade device unless it has been signed by Blockstream.
Also, if you want to go the whole hog, and verify that the fw image you have download indeed corresponds to the source code in this repo at the 1.0.27 tag - see REPRODUCIBLE.md
Thanks Jamie that was very helpful. I had difficulties executing these scripts on Windows but they ran successfully on Mac OS and I was able to download the firmware upgrade files and verify the hash.
I executed the following command to upgrade the firmware :
python3 ./jade_ota.py --fwfile build/1.0.27_noradio_1118208_fw.bin
However, the following exception was thrown:
File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/subprocess.py", line 1026, in init self._execute_child(args, executable, preexec_fn, close_fds, File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/subprocess.py", line 1950, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename) FileNotFoundError: [Errno 2] No such file or directory: '/usr/bin/bt-agent'
I tried to manually create the directory '/usr/bin/bt-agent' in the root of the cloned repository and execute the script again but this was unsuccessful.
Also, can you please confirm whether the Jade must be unlocked to execute a firmware upgrade?
I inadvertently closed the ticket...
Ahh sorry, try: ./jade_ota.py --no-ble --fwfile build/1.0.27_noradio_1118208_fw.bin
An uninitialised Jade does not need to be unlocked - ota upgrade can just run.
If the jade is initialised with a PIN-protected wallet, it will need to be unlocked with pin first - but the jade_ota.py script should handle that ...
I executed the following script:
./jade_ota.py --no-ble --fwfile build/1.0.27_noradio_1118208_fw.bin
The following exception was thrown:
jade_ota.py: error: unrecognized arguments: --no-ble
--skipble
- third time lucky ... :crossed_fingers:
NOTE: ./jade_ota.py --help
to get all the options/arguments etc.
I disconnected my Mac from the network, connected the Jade and executed the following script:
./jade_ota.py --skipble --fwfile build/1.0.27_noradio_1118208_fw.bin
This invoked the Jade which displayed the following screen:
I entered the PIN and the following displayed:
Clicking on "Yes" just looped back to the same error.
I then entered QR mode, performed a blind oracle PIN unlock and then executed the script again and the same sequence repeated with the following displaying on the Jade:
As you previously indicated:
"If the jade is initialised with a PIN-protected wallet, it will need to be unlocked with pin first - but the jade_ota.py script should handle that ..."
Unlocking the Jade before executing the script did not resolve the issue.
What is the process of the script unlocking the Jade?
As it says, that first error suggests networking errors - ie. it cannot reach the blind oracle to unlock the wallet. If you have a Jade with a PIN-protected wallet, you must usually unlock it to use it - this involves a network roundtrip. I assume this usually works ?
If you have a Jade with a PIN-protected wallet, you cannot update the firmware without first entering the PIN and unlocking the wallet (otherwise an attacker could temporarily take your jade, upload malicious firmware, and put it back where they found it ...).
If you unlock Jade using QR codes this is only unlocked for 'QR - mode' - ie you cannot send it data over USB. (Similarly, if you unlock using USB, you (or an attacker) can't start sending it messages over Bluetooth.) So if you unlock with QRs, then try to send firmware over USB, it will still be asking you to unlock over USB (again, to verify it is you sending those messages/trying to upload fw).
tl;dr:
Jade can operate in a 'connected' fashion, where it encrypts your wallet data in flash, and needs a PIN (and a handshake with a remote blind oracle server (*)) to unlock, or it can operate in a totally stateless/disconnected fashion where you scan a QR code you keep (containing the wallet seed data) every time you want to use it. (Different people view the security risks of each model differently/have different perspectives on the tradeoffs/prefer one or the other ...)
However, while you can 'mix and match' to some degree, once you've opted for PIN-protection several features will require the PIN to be entered correctly before they are allowed to run. Specifically, in the PIN-protected model you must unlock with PIN before you can update the firmware.
NOTE (*): by default Jade will use a blind oracle server hosted by Blockstream, but you can if you prefer run your own server - see https://help.blockstream.com/hc/en-us/articles/12800132096793-Set-up-a-personal-blind-oracle
I have only used the QR PIN unlock method to date so I am unfamiliar with other mechanisms of unlocking the Jade. If "Unlock Jade" is selected, a message displays "Connect via USB/BLE to a companion app and select your Jade to unlock with your PIN".
Can any of the companion apps listed in the following article be used to unlock the Jade with its PIN or does this require the Blockstream Green app?
https://help.blockstream.com/hc/en-us/articles/9601453403801-Download-a-companion-app-for-Jade
Ah ok, so you usually use QR unlock - cool beans. Aside: You'll be pleased to know that in the next release we plan to improve that to only being one QR scan each way (rather than the existing two-each-way) - ie webapp scans jade, jade scans webapp, done. And the QR codes will be fewer frames each, so all in all should be much easier/quicker than it is today.
Ok, the ota script will handle the pin-unlocking of Jade - I don't understand why you are getting these network errors - I assume you could reach the network in order to download the firmware in the first place ?
Have you deliberately disconnected the machine from the internet ?
Can you ping jadefw.blockstream.com
? That's the site that hosts the firmware images. What about ping jadepin.blockstream.com
? That's the pin blind oracle server. Or are you already using a bespoke server ?
While any Green app (or Sparrow, Specter, Electrum, HWI ...) can unlock Jade, they will all need access to the internet and be able to reach the blind oracle. But you don't need them, the ota script should be able to do it itself.
Or try ./jade_auth.py
... or ./update_jade_fw.py
(even if you abandon any update).
In any case, if you disconnect Jade from the USB, it will lock itself again (again, to prevent an attacker grabbing it from your machine and plugging it into their own and using it). So you need to unlock jade on the same machine you are going to use to upgrade it.
The issue here is those network errors when you try to unlock.
Thanks for the update on QR unlock. That is a good improvement.
I have deliberately disconnected the machine from the internet. What I am trying to achieve is to upgrade Jade's firmware without connecting it to an internet connected device. I have succeeded to download an offline copy of the latest firmware. The next challenge is how to unlock the Jade and install the offline firmware onto it without connecting the machine to the internet and without factory resetting the Jade.
It is not possible to unlock a PIN-protected Jade wallet without connecting to the blind oracle server - in theory you could run your own server and plug Jade physically into that machine (or at least into the same LAN) to do the fw upgrade (telling jade it's blind oracle was at a 'localhost' url). [ But this would involve resetting the wallet on Jade, as you can't move from one blind oracle server to another without re-creating the wallet (so it persists the oracle secret to the new oracle). ]
(and ofc your blind oracle server needs to be reachable from wherever you plan to use Jade - eg if you ran your oracle at home without any bridge/nat/routes from the outside, your Jade would only be 'unlockable' from your house/LAN ...)
If you do not want Jade connected to the machine at the same time that the machine is connected to the internet, but at the same time use a PIN-(and hence remote-server)-protected wallet ... you're a bit stuck re: fw updates atm I'm afraid. You need the internet to unlock the Jade, but you don't want the internet connected (as you view it as a security risk?)
In a future version of the hw, we plan to to able to use SD-cards and other USB storage devices for fw updates (and psbt signing etc), which should satisfy your use-case. But I'm afraid that won't be workable on the existing hw.
(We have also considered transferring the fw via QRs - but it will take a very long time to transfer across and it has yet to be decided whether it's practically viable).
In the interim, you could: Connect the machine to the internet
jade_auth.py
)Disconnect the machine from the internet
jade_ota.py
or update_jade_fw.py
OR (assuming you have an easily-scanned qr code backup of your seed data, or don't mind typing the words again...)
I know, both of these options are what you would rather avoid ...
Atm we deliberately disallow unlocking with QRs and then going ahead and accepting messages over USB, as (most?) QR users want to be reassured that if they unlock via QR, the only way to meaningfully interact with Jade is via QRs.
The absolute best (air-gapped) practice is for the hardware wallet to never connect to an internet connected device. Coldcard supports this using a micro SD card and a verifiable firmware update file downloaded from their website. I think this is the best way to achieve air-gapped firmware updates. With updating Jade's firmware, I might need to either just connect to an internet connected device, perform a factory reset or wait for future developments. Another workaround might be to block all internet traffic but allow access to required sites while the Jade is connected for the firmware update.
Is it just jadefw.blockstream.com and jadepin.blockstream.com for which access is required for unlocking and updating firmware via the Blockstream Green app?
Thank you for the detailed information. It has been very helpful and is appreciated.
Agree with you re: 'best practice' and as I say we are looking at the usb-storage (eg. micro-sd reader) for the next iteration of the hw. atm the only way to acheive what you are after is to use jade in totally stateless 'QR mode' where the seed info is not kept in jade flash but on a paper or metal sheet (eg in the form of a CompactSeedQR) which is entered/scanned every time you want to use the hww. (But ofc has the disadvantage that you then have your [unencrypted] seed on a bit of paper ...). But yes, we are aware of these challenges.
Is it just jadefw.blockstream.com and jadepin.blockstream.com for which access is required for unlocking and updating firmware via the Blockstream Green app?
jadefw.blockstream.com - firmware images hosted here jadepin.blockstream.com - the default Blockstream-hosted blind oracle
These should be all that is required.
NOTE: the reason we use a remote blind oracle to assist in decrypting the wallet, is that jade has no 'secure element' hw on board. The reason jade has no 'secure element' on board, is that these use 'closed source' software, and we are committed to keeping jade based on open source libraries. It's all about the tradeoffs .. :upside_down_face:
In the end I decided to factory reset my Jades, upgrade firmware using Blockstream Green and restore.
I understand the importance of supporting open source Bitcoin only projects. I found out about Jade from the following YouTube channel that promotes Jade and Coldcard as the premier (Bitcoin) hardware wallets:
https://www.youtube.com/@Bitcoin_University
I'll be happy to upgrade my Jade hardware as new features such as support for SD cards is released. Keep up the good work.
Many thanks for your comments and the useful discussion! :rocket:
I downloaded the latest Jade firmware update using the following Python script:
./jade_ota.py --download-firmware --hw-target jade1.1 --release stable --write-compressed
I managed to download the following files:
1.0.27_noradio_1118208_fw.bin 1.0.27_noradio_1118208_fw.bin.hash
Note that the download fails unless the “build” directory exists. I would suggest that the script create the “build” directory.
The SHA256 hash of “1.0.27_noradio_1118208_fw.bin” doesn’t match the contents of “1.0.27_noradio_1118208_fw.bin.hash”:
b2b67f5943ca4c1ae0c7fc3733352dbb4b644add5a174111547e5bd7f77d7171
Can you please clarify how to verify “1.0.27_noradio_1118208_fw.bin” and whether the hash itself can be separately verified?