Wallet Logo

Trezor Model T

latest release: 2.4.2 ( 8th September 2021 ) last analysed  16th October 2021 Reproducible when tested 
1st March 2018

Jump to verdict 

Older reviews (show 1 of 1 reproducible)

Help spread awareness for build reproducibility

Please follow Trezor Model T and thank them for being reproducible  via their Twitter!


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.2
Firmware size 45752 bytes
Firmware fingerprint: 6899cddc271a89fda4fc0666e9e3924f1d61ace891f4feb1aceb9a428fa731cb
Slot #1 is empty
Slot #2 is empty
Slot #3 is empty
make: Leaving directory '/tmp/trezor-firmware/legacy/intermediate_fw'
54ccf155510b5292bd17ed748409d0d135112e24e62eb74184639460beecb213 build/core/firmware/firmware.bin
60fee3c9775d8ccf71099f6f7d277463efd128414cfb9be45656b1a26eeb7301 build/core-bitcoinonly/firmware/firmware.bin
14438fe4727ddc3153fa3c1aff2ced8867322aa54a0eb0277800e54cda488f50 build/legacy/firmware/firmware.bin
02f112cc2dda68ed19c7dbd71780e8dc7e749c2cadd645be6398c4762a8adf0f 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.000129905 s, 500 kB/s
67946dee311e4606c468fe2e529530c363ee633c7f2ef965ddaa4688b6c31c4e  trezor-2.4.2.bin.zeroed
67946dee311e4606c468fe2e529530c363ee633c7f2ef965ddaa4688b6c31c4e  build/core/firmware/firmware.bin

Hash of the signed firmware:
1fa3d062251685dc8bebd0b15ed622441ca3778281a652d601548ed29287e29d  trezor-2.4.2.bin

This looks good. The compile 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  , 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:

  1. The device comes without firmware[1][2]
  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?)
  3. 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: [
    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
make: Leaving directory '/tmp/trezor-firmware/legacy/firmware'
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

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  , 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.


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 not, we tag it Reproducible 

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.