Trezor Model T
Latest release: 2.5.1 ( 18th May 2022 ) 🔍 Last analysed 7th August 2022 . Reproducible when tested Review might be outdatedOlder reviews (show 2 of 2 reproducible)
Help spread awareness for build reproducibility
Please follow Trezor Model T and thank them for being reproducible via their Twitter!
Disclaimer
The following Analysis is not a full code review! We plan to make code reviews available in the future but even then it will never be a stamp of approval but rather a list of incidents and questionable coding practice. Nasa sends probes to space that crash due to software bugs despite a huge budget and stringent scrutiny.
Do your own research!
Try out searching for "lost bitcoins", "stole my money" or "scammers" together with the wallet's name, even if you think the wallet is generally trustworthy. For all the bigger wallets you will find accusations. Make sure you understand why they were made and if you are comfortable with the provider's reaction.
If you find something we should include, you can create an issue or edit this analysis yourself and create a merge request for your changes.
The Analysis ¶
After manually testing prior versions, we now wrote a test script (?).
Here is it’s condensed output:
$ ./scripts/test/hardware/trezorT.sh 2.4.3
...
Fingerprints:
a07f69d8d2065006a79c6b5636bd046496dbcb3820b41f1d604d8a4605ca4056 build/core/firmware/firmware.bin
1744efccabd479526392b281b7e0fc7aa2b4ecb454007dff7ca8c1f8171fad90 build/core-bitcoinonly/firmware/firmware.bin
3eaf589c54180dce1f8f3726b02d5384de356118bb710519e6137bcb32f52b4c build/legacy/firmware/firmware.bin
21542bba6cdc419460f87e6edbac3af0a19c6a51da46223bfdf7dc7350950e63 build/legacy-bitcoinonly/firmware/firmware.bin
Hash of non-signature parts downloaded/compiled:
65+0 records in
65+0 records out
65 bytes copied, 0.000151876 s, 428 kB/s
f75eb91587be7b99ae94ee95cefadcda8f5149cabdc485f165f1086f0ad918cc trezor-2.4.3.bin.zeroed
f75eb91587be7b99ae94ee95cefadcda8f5149cabdc485f165f1086f0ad918cc build/core/firmware/firmware.bin
Hash of the signed firmware:
4279e8fbf0bf85b6412c1ab1e1fe16844b42d83d2d8a45aaf6cf68dfb7afabbc trezor-2.4.3.bin
This looks good. The compiled version only differs in 64 bytes - the signature - from the downloaded version. This firmware is reproducible.
Original Analysis with discussion of details
After reviewing their Trezor One Reproducible Review Outdated! , this model should be mostly the same but with lessons learned …
The claims made are straight the same:
On the provider’s page on security we read:
Protected bootloader.
The bootloader is write protected and the JTAG is disabled, so an attacker cannot replace it.
The bootloader is a tiny but critical part of any computer. Without one, no higher functionality could be loaded. The device would have no way of knowing it had a screen and buttons and storage …
Firmware verification.
The bootloader always verifies the firmware signature. The firmware is only run if correctly signed by SatoshiLabs. Otherwise, a warning is shown.
So in this case, the bootloader is tiny but knows about cryptography as it has to verify the signature of the firmware and compare its signing key to the provider’s public keys that should be hard-coded into the bootloader.
Secure update procedure.
The bootloader erases the device memory if the firmware signature is invalid. Downgrade to a vulnerable version also wipes the memory.
The above properties ensure that only software which has been approved by the provider can be run on this device. It doesn’t guarantee that this software is not stealing your keys.
To our surprise, the wallet’s main page does not show or link to claims about the product being open source.
We asked on Reddit but somehow there really is no authoritative claim from the provider that the device they sell follows this protocol:
- The device comes without firmware[1][2]
- The firmware can be downloaded, verified to match the source code and then deployed to your device on an air-gapped computer (?can it?)
- The firmware checks the boot-loader for tampering. If you are sure to run a certain firmware (layout changed …) you can be relatively sure that a rogue boot-loader would have been detected.
While the lack of a comprehensive “Security protocol for your Trezor Model T” is a surprise, all the relevant information can be found and we can check the firmware.
Please be aware that we only look at the software and the advertised properties
of the hardware. The hardware aspect makes it hard to make any claims about the
specific device you might be getting in your mail, which makes it hard to
eliminate the need for some level of trust. But let’s see if we can reproduce
the current firmware version 2.3.6
:
$ git clone https://github.com/trezor/trezor-firmware.git
$ cd trezor-firmware/
$ git checkout core/v2.3.6
$ bash build-docker.sh core/v2.3.6
… thousands of lines of compiler output. This block calls our attention. It looks related to the instructions on how to verify the build later:
Vendor Header for SatoshiLabs version 0.0 (4608 bytes)
âś” Signature is VALID
Firmware Header {
magic: HeaderType.FIRMWARE
header_len: 1024
expiry: 0
code_length: 1598976
version: 2.3.6 build 0
fix_version: 2.2.0 build 0
hashes: [
âś” f4c8bcebb02f088c9e7a9df21b5b66f83d1209a7c3702db8643448717cf58593
âś” 9847b75d23ad100e9da871771e6592858450918d3f6a1d182edac7da7a012c63
âś” 7beaf165a8030dc682f4b43ad3b5b042b1fab16ac933e1f6af8cad8af1ecc705
âś” 5e4d8df865bb08bdbb44dd1c7e191ee20f12127ef5605259c0ac13f9a94948a9
âś” ced651b53ad164d6211c6ac76bc70a060cf27b62061009d729b48ddab39cbcff
âś” 64e03f153d5496d7d8271cce5107d05de46e6d735a0c25d4a8410339a141b17e
âś” 6a935d490188ede773871d73fa14e0480fdc34e343a6974d55d3e00d14fa476e
âś” a0980b638dd49f9ac53afcd8431917dcf934b70cd29a3e710355b916cdeb36db
âś” 986a1f5859a619588ab40abe901bce876173777a9f93e17e67ea2bca48db7f19
âś” c598ffda50a78b227e7b5b40018dfe9f301677f7dbf068dddb82e92f28a565d5
âś” 743180fd252895aae2b1879b771605a12fb7ee30e67e20155a73bbd2ce84d834
âś” 23f392eda648fd9bf80919a10c787fd9ebf9bb8d2a7dba439a221cca5167fdc6
âś” e2ee2ca1296e4ea18f248b7ac32ac483712f902df1b699c9752728b12ca378df
âś” 0000000000000000000000000000000000000000000000000000000000000000
âś” 0000000000000000000000000000000000000000000000000000000000000000
âś” 0000000000000000000000000000000000000000000000000000000000000000
]
sigmask: 0
signature: 64 bytes 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
}
Fingerprint: 0efa3ba6135caea7693d145d60441eeb46283fe0b8b1fd59a04af33a638ad237
❌ Signature is MISSING, hashes are VALID
dd if=build/firmware/firmware.bin of=build/firmware/firmware.bin.p1 skip=0 bs=128k count=6
As we can’t sign, missing signatures are expected.
python ../bootloader/firmware_sign.py -f trezor.bin
Firmware size 418700 bytes
Firmware fingerprint: 94103013539c0d1e067d6da77dd20f46eae19a449d48e732cd9f6a99cc62560e
Slot #1 is empty
Slot #2 is empty
Slot #3 is empty
HASHES OK
make: Leaving directory '/tmp/trezor-firmware/legacy/firmware'
Fingerprints:
0efa3ba6135caea7693d145d60441eeb46283fe0b8b1fd59a04af33a638ad237 build/core/firmware/firmware.bin
e2cab40bb4c6ae65417b80ad564b905796038a0f5e6d0f50cead257fdd3a9c2d build/core-bitcoinonly/firmware/firmware.bin
8fe15b61de0cf547bfb9f3e5b251bab6ccca3780a44b6048d61e3aa6ffc8a9c3 build/legacy/firmware/firmware.bin
94103013539c0d1e067d6da77dd20f46eae19a449d48e732cd9f6a99cc62560e build/legacy-bitcoinonly/firmware/firmware.bin
$ wget https://data.trezor.io/firmware/2/trezor-2.3.6.bin
$ cmp build/core/firmware/firmware.bin trezor-2.3.6.bin --verbose
5568 0 3
5569 0 41
5570 0 311
5571 0 73
5572 0 105
5573 0 53
5574 0 77
5575 0 141
5576 0 142
5577 0 171
5578 0 253
5579 0 104
5580 0 163
5581 0 65
5582 0 336
5583 0 207
5584 0 275
5585 0 57
5586 0 66
5587 0 21
5588 0 52
5589 0 245
5590 0 2
5591 0 314
5592 0 154
5593 0 276
5594 0 104
5595 0 60
5596 0 220
5597 0 54
5598 0 335
5599 0 357
5600 0 377
5601 0 365
5602 0 146
5603 0 230
5604 0 6
5605 0 251
5606 0 210
5607 0 211
5608 0 20
5609 0 317
5610 0 236
5611 0 211
5612 0 352
5613 0 60
5614 0 241
5615 0 313
5616 0 74
5617 0 73
5618 0 44
5619 0 377
5620 0 335
5621 0 156
5622 0 325
5623 0 30
5624 0 212
5625 0 230
5626 0 225
5627 0 64
5628 0 53
5629 0 352
5630 0 353
5631 0 134
$ cmp build/core/firmware/firmware.bin trezor-2.3.6.bin --verbose | wc -l
64
so yes, the diff is 64 bytes. One signature, as expected.
The recommended way of checking the firmware for a match is to zero out the signature in the original file, too and to then hash both:
$ dd if=/dev/zero of=trezor-2.3.6.bin bs=1 seek=5567 count=65 conv=notrunc
65+0 records in
65+0 records out
65 bytes copied, 0.000168417 s, 386 kB/s
$ sha256sum build/core/firmware/firmware.bin trezor-2.3.6.bin
c239e48c2088082155a48f4b47573a57aab59639d62e2f90ad69546b5e088181 build/core/firmware/firmware.bin
c239e48c2088082155a48f4b47573a57aab59639d62e2f90ad69546b5e088181 trezor-2.3.6.bin
and that is a match. The Trezor Model T firmware 2.3.6
is reproducible.
This review is quite a bit shorter than the one of the older model Trezor One Reproducible Review Outdated! , which is both to the newer model not using some legacy format that caused many more bytes to be questionable there but also because we directly jumped to trusting tools from their repository as we do not do code reviews. Our assurance is that a passed code review of their repository has relevance for the binary and that necessarily implies that if there was a problem with the tools we used to check the binary, it would be in the open, to be found in a review. The reproducible verdict does not replace a code review.
(lw)
Verdict Explained
The binary provided was reproducible from the code provided.
As part of our Methodology, we ask:
Does the binary we built differ from what we downloaded?
If the answer is "no", we mark it as "Reproducible when tested".If we can reproduce the binary we downloaded from the public source code, with all bytes accounted for, we call the product reproducible. This does not mean we audited the code but it’s the precondition to make sure the public code has relevance for the provided binary.
If the provider puts your funds at risk on purpose or by accident, security researchers can see this if they care to look. It also means that inside the company, engineers can verify that the release manager is releasing the product based on code known to all engineers on the team. A scammer would have to work under the potential eyes of security researchers. He would have to take more effort in hiding any exploit.
“Reproducible” does not mean “verified”. There is good reason to believe that security researchers as of today would not detect very blatant backdoors in the public source code before it gets exploited, much less if the attacker takes moderate efforts to hide it. This is especially true for less popular projects.
But we also ask:
Does our review and verdict apply to their latest release?
If the answer is "no", we mark it as "Review might be outdated".Verdicts apply to very specific releases of products and never to the product as a whole. A new release of a product can change the product completely and thus also the verdict. This product remains listed according to its latest verdict but readers are advised to do their own research as this product might have changed for the better or worse.
This meta verdict is applied manually in cases of reviews that we identify as requiring an update.
This meta verdict applies to all products with verdict “reproducible” as soon as a new version is released until we test that new version, too. It also applies in cases where issues we opened are marked as resolved by the provider.
If we had more resources, we would update reviews more timely instead of assigning this meta verdict ;)
Share on
Twitter Facebook LinkedInOr embed a widget in your website
<iframe
src="https://walletscrutiny.com/widget/#appId=hardware/trezorT&theme=auto&style=short" name="_ts"
style="min-width:180px;border:0;border-radius:10px;max-width:280px;min-height:30px;">
</iframe>
and
<iframe
src="https://walletscrutiny.com/widget/#appId=hardware/trezorT&theme=auto&style=long"
style="max-width:100%;width:342px;border:0;border-radius:10px;min-height:290px;">
</iframe>