Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reproducible builds #579

Open
xrviv opened this issue Sep 19, 2024 · 6 comments
Open

Reproducible builds #579

xrviv opened this issue Sep 19, 2024 · 6 comments
Labels
bug Something isn't working

Comments

@xrviv
Copy link

xrviv commented Sep 19, 2024

Describe the bug

  • Build is coming out as non-reproducible
    We successfully built version 3.9.0, using this bash script and this dockerfile.
Calculating checksums...
RESULTS==========================================
Built firmware hash:
4d84d17402d206bed1cbfddaeb08dc92dd3ce9be56add8da28a0963571989451  ./classic.3.9.0-Stable-0917-f3b0717.bin
Downloaded firmware hash:
a8d7051ea8b4a85038d032e4b86d5e8ee8f34870e3f861e59bf1a5578c36d176  downloaded-firmware.bin
=================================================
Build completed. Check the 'output' directory for results.

Firmware version and revision

Desktop/smartphone setup (please complete the following information):

  • Wallet software: n/a
  • OS: Ubuntu 22.04 / WalletScrutiny Debian Build Server
  • Browser: Firefox
  • Version: n/a

To Reproduce
Steps to reproduce the behavior:

  1. Using the above-mentioned bash script and dockerfile we built the firmware
  2. We then compared the hash of the built binary vs the downloaded binary
  3. We found this:
$ cat firmware_diff.txt 
--- built-firmware.hex	2024-09-17 13:21:42.261583273 +0000
+++ downloaded-firmware.hex	2024-09-17 13:22:02.354205676 +0000
@@ -16,8 +16,8 @@
 000000f0: e521 fc80 b931 89ea 3b32 99a2 536d be7c  .!...1..;2..Sm.|
 00000100: a3f1 5cb9 2dc7 c61f 07ed ec29 bdfc 1e53  ..\.-......)...S
 00000110: 15fa ecec c0cd 0a87 587b 9861 2c23 e7f0  ........X{.a,#..
-00000120: c21b d588 58bd e555 9f40 d9eb ea27 6395  ....X..U.@...'c.
-00000130: 520b 0d70 e29d ec8e 29e1 f5f9 d85b 0dc0  R..p....)....[..
+00000120: db58 e5b4 aa32 5c1b 6a66 1d2b 4e5d 351c  .X...2\.jf.+N]5.
+00000130: 3367 cd45 2fd7 b845 378b 5bf4 a3fd 4ec9  3g.E/..E7.[...N.
 00000140: 63b8 efba d27e 0bbd 7595 2426 8d8c d22c  c....~..u.$&...,
 00000150: cca3 61d3 7ab9 49c0 a623 e11a c436 f8df  ..a.z.I..#...6..
 00000160: 0b4a fa04 7fd6 98be 04f1 c4bd b53f 5f09  .J...........?_.
@@ -32,23 +32,23 @@
 000001f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000200: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000210: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000220: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000230: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000240: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000250: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000260: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000270: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000280: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000290: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-000002a0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-000002b0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-000002c0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-000002d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-000002e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-000002f0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000300: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000310: 0000 0000 0000 0000 0000 0000 0000 0000  ................
-00000320: 0000 0000 0000 0000 0000 0000 0000 0000  ................
+00000220: 01f3 b146 bc03 1287 f80d 9f74 5036 ba5c  ...F.......tP6.\
+00000230: f347 c55e 1170 71f2 b240 d595 cb9c 8629  .G.^.pq..@.....)
+00000240: 232e bc4f 0c19 a5f0 c2cf 6cd9 6676 a7cf  #..O......l.fv..
+00000250: a7b0 6bd8 dbe2 10d6 8d67 f28e 883f 29ca  ..k......g...?).
+00000260: ba4e 625a dc80 c429 ba29 a343 e3ce 8765  .NbZ...).).C...e
+00000270: 5a0b 9d00 1760 5ea0 0dd1 06ca 89fc 9b12  Z....`^.........
+00000280: 23b3 8730 71c5 3ffb df29 1f21 c5be b599  #..0q.?..).!....
+00000290: 061d 19d3 2810 8c20 5319 7e8e e6c7 8444  ....(.. S.~....D
+000002a0: bb79 ceb0 2f60 3f10 7259 e123 068f 5322  .y../`?.rY.#..S"
+000002b0: 29c8 1860 a3b0 cb80 3cb7 2f6f 9c94 1575  )..`....<./o...u
+000002c0: 4800 5be3 7f6d 6b82 3f66 f8d1 2fa2 19a9  H.[..mk.?f../...
+000002d0: ea5e 8543 cac0 5240 eac5 79ae 2bd4 c819  .^[email protected].+...
+000002e0: 169e 7329 401b b481 9371 b492 a124 c499  ..s)@....q...$..
+000002f0: 26b6 5400 d028 ac41 b168 4ab0 3e2c a8d3  &.T..(.A.hJ.>,..
+00000300: 73d8 31d7 f4d3 e59d 295b c4f8 3124 4e4c  s.1.....)[..1$NL
+00000310: 0594 4313 cd50 efff ac5d b0e4 f59d c1ff  ..C..P...]......
+00000320: 0103 0405 0000 0000 0000 0000 0000 0000  ................
 00000330: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000340: 0000 0000 0000 0000 0000 0000 0000 0000  ................
 00000350: 0000 0000 0000 0000 0000 0000 0000 0000  ................
@@ -35488,7 +35488,7 @@
 0008a9f0: b071 7d65 2c08 c79a 4b39 d06c 3c2b d9bc  .q}e,...K9.l<+..
 0008aa00: 5f17 b200 332e 392e 3000 636c 6173 7369  _...3.9.0.classi
 0008aa10: 632e 332e 392e 302d 5374 6162 6c65 2d30  c.3.9.0-Stable-0
-0008aa20: 3931 372d 6633 6230 3731 3700 556e 6578  917-f3b0717.Unex
+0008aa20: 3830 352d 6633 6230 3731 3700 556e 6578  805-f3b0717.Unex
 0008aa30: 7065 6374 6564 206d 6573 7361 6765 0041  pected message.A
 0008aa40: 6374 696f 6e20 6361 6e63 656c 6c65 6420  ction cancelled 
 0008aa50: 6279 2075 7365 7200 5049 4e20 6361 6e63  by user.PIN canc

One of the differences is the timestamp. The built firmware's value is 0917 - the date today. While the time stamp (or the short_release_date) on the downloaded firmware is 0805.

The second difference occurs between offsets 00000220 to 00000320. In the built firmware, we noticed that the values are comprised of zeroes. The corresponding offsets in the downloaded firmware is comprised of non-zeroes. This could indicate missing data in the built firmware.

We do not have enough data to determine the reason for the diffs here:

-00000120: c21b d588 58bd e555 9f40 d9eb ea27 6395
-00000130: 520b 0d70 e29d ec8e 29e1 f5f9 d85b 0dc0
+00000120: db58 e5b4 aa32 5c1b 6a66 1d2b 4e5d 351c
+00000130: 3367 cd45 2fd7 b845 378b 5bf4 a3fd 4ec9

**Expected behavior**
- The hash of the built artifact should match with the hash of the downloaded binary

**Screenshots**
n/a

**Additional context**
https://asciinema.org/a/676393
@xrviv xrviv added the bug Something isn't working label Sep 19, 2024
@424778940z
Copy link
Contributor

There are few errors in your process, I would suggest read our help center topic, or at least our CI task file, and get a basic understanding of which source to use, and how to verify it correctly.

First of all, you seems using the wrong branch, for Classic 1, it's built from bixin_dev branch (name did not change for history reasons). I did not see checkout bixin_dev branch in your script.

Second, firmware binary file contains a field for populating hash and signature, that's how firmware verification on device works. Our released firmware file have those field popluated by hashing and signing with our private key, which fill in those zero area you found different.

In your script, you did not skip the header part, thus the hash will be different for sure, and this is wrong

    wget -O downloaded-firmware.bin "https://github.com/OneKeyHQ/firmware/releases/download/${TYPE}%2Fv${VERSION}/${TYPE}.${VERSION}-Stable-${SHORT_RELEASE_DATE}-${SHORT_HASH}.signed.bin"

    # Calculate SHA-256 checksums
    echo "Calculating checksums..."
    sha256sum ./${TYPE}*Stable*.bin > built_firmware.sha256
    sha256sum downloaded-firmware.bin > downloaded_firmware.sha256

    # Display the results
    echo -e "\e[96mRESULTS=========================================="
    echo -e "Built firmware hash:"
    cat built_firmware.sha256
    echo -e "Downloaded firmware hash:"
    cat downloaded_firmware.sha256
    echo -e "=================================================\e[0m"
    '

The correct way of doing it is to skip the header

tail -c +1024 /path/to/(file path) | shasum -a 256

For firmware header, it's detailed in this file

@xrviv
Copy link
Author

xrviv commented Feb 18, 2025

Thanks.

Will read your new documentation, thanks for the heads up!

I will try to verify manually first and then create a script afterwards.

A few problems I encountered:

  1. Some of the GH Actions artifacts have already expired, thus I cannot download the pre-signed artifacts.

Possible solution: To build it myself.

@xrviv
Copy link
Author

xrviv commented Feb 19, 2025

Some progress:

The bash script: onekey.classic.sh

The dockerfile: onekey.classic.dockerfile


===== Begin Results =====

5db9faa8dbab83c0df4ab7c0295a5d5339f606f778d8bfd0c0131f7fc44c29b2 - built firmware hash (excluding header)

a8d7051ea8b4a85038d032e4b86d5e8ee8f34870e3f861e59bf1a5578c36d176 - downloaded firmware hash (including header) (from: github releases)

c1847cd787e33961e27e4f7dacd045fc495b5128e3aac98fb89a1a7393f9023d - downloaded firmware hash (excluding header) (from: github releases)

a8d7051ea8b4a85038d032e4b86d5e8ee8f34870e3f861e59bf1a5578c36d176 - downloaded firmware hash (including header) (from: OneKey CDN)

c1847cd787e33961e27e4f7dacd045fc495b5128e3aac98fb89a1a7393f9023d - downloaded firmware hash (excluding header) (from: OneKey CDN)
===== End Results =====


Image

@xrviv
Copy link
Author

xrviv commented Feb 19, 2025

With the changes suggested:

Image

Using tail

Image

With the built firmware not stripped

Image

@xrviv
Copy link
Author

xrviv commented Mar 13, 2025

tail -c +1024 /path/to/(file path) | shasum -a 256
For firmware header, it's detailed in this file

does this apply for the onekey mini as well? If so, we would appreciate the guidance on onekeymini_v3.9.0

Without this information, this is what resulted with the onekeymini build:

Initial Findings

We conducted a reproducibility test for OneKey Mini firmware v3.9.0 using a modified hardware-specific script. The test involved building the firmware from source code and comparing it with the official firmware downloaded from GitHub.

Build and Download Process

We successfully built the firmware from the OneKey GitHub repository using their provided build system. The build process completed without errors, producing a firmware file named mini.3.9.0-Stable-0313-a8b4519.bin (where 0313 represents the build date).

We then downloaded the official firmware from GitHub using the URL:

https://github.com/OneKeyHQ/firmware/releases/download/mini%2Fv3.9.0/mini.3.9.0-Stable-0807-a8b4519.signed.bin

Hash Comparison

We calculated SHA-256 hashes for both firmware files:

0ed8c4038c98cd351f3dcdeae1a6f159dc6084f4bd77cda891db60f0aae4899e  output/mini.3.9.0-Stable-0313-a8b4519.bin
70134b755f3246621b67029a11c5913c782e698ccf3a36aa736e8a73832f41f0  output/downloaded-firmware.bin

The hashes are different, which indicates that the built firmware is not bit-for-bit identical to the official firmware.

Binary Comparison

We performed a binary comparison using vbindiff and hexdump tools. Interestingly, the file sizes are identical (979,516 bytes), and the file headers and initial binary content are byte-for-byte identical. The first several hundred bytes, including the "MINI" identifier at the beginning, match perfectly between both files.

This is the result of the vbindiff:

output/mini.3.9.0-Stable-0313-a8b4519.bin                                       
00000 0000:  4D 49 4E 49 1F A4 01 08  00 00 00 00 3C EE 0E 00  MINI.... ....<...
00000 0010:  02 63 63 00 02 63 63 00  39 00 00 00 00 00 00 00  .cc..cc. 9.......
00000 0020:  31 44 0B 3E E1 87 34 39  3D 7E 32 76 75 65 12 BA  1D.>..49 =~2vue..
00000 0030:  5D F2 79 F1 DD A9 01 AA  CC 71 CD 97 95 84 52 43  ].y..... .q....RC
00000 0040:  81 C5 8C 4F 1C 96 68 FF  EA B4 32 63 06 F8 A9 42  ...O..h. ..2c...B
00000 0050:  7A 69 A4 D9 42 1A E1 D7  0B 91 9C 5E F8 13 85 7B  zi..B... ...^...{
00000 0060:  31 27 60 1B B6 1C 90 2B  47 36 07 8D 6D 0C 7D 05  1'`....+ G6..m.}.
00000 0070:  D8 C8 FE 37 E8 40 E5 21  AD 4C A2 36 7C 56 39 ED  ...7.@.! .L.6|V9.
00000 0080:  28 5B A3 87 05 7F 19 9C  6C F9 0B A5 83 CE 2D 85  ([...... l.....-.
00000 0090:  97 43 AB D3 3C DD 59 3D  63 92 12 F8 DD E5 CF CC  .C..<.Y= c.......
00000 00A0:  B2 2D CA 17 9C 2C 84 A7  68 FC A1 8D B7 3D 2B 57  .-...,.. h....=+W
00000 00B0:  63 2A 6A 5A 2F A8 88 87  6A 87 31 0A 9E 4F 8C 8F  c*jZ/... j.1..O..
output/downloaded-firmware.bin                                                  
00000 0000:  4D 49 4E 49 1F A4 01 08  00 00 00 00 3C EE 0E 00  MINI.... ....<...
00000 0010:  02 63 63 00 02 63 63 00  39 00 00 00 00 00 00 00  .cc..cc. 9.......
00000 0020:  31 44 0B 3E E1 87 34 39  3D 7E 32 76 75 65 12 BA  1D.>..49 =~2vue..
00000 0030:  5D F2 79 F1 DD A9 01 AA  CC 71 CD 97 95 84 52 43  ].y..... .q....RC
00000 0040:  81 C5 8C 4F 1C 96 68 FF  EA B4 32 63 06 F8 A9 42  ...O..h. ..2c...B
00000 0050:  7A 69 A4 D9 42 1A E1 D7  0B 91 9C 5E F8 13 85 7B  zi..B... ...^...{
00000 0060:  31 27 60 1B B6 1C 90 2B  47 36 07 8D 6D 0C 7D 05  1'`....+ G6..m.}.
00000 0070:  D8 C8 FE 37 E8 40 E5 21  AD 4C A2 36 7C 56 39 ED  ...7.@.! .L.6|V9.
00000 0080:  28 5B A3 87 05 7F 19 9C  6C F9 0B A5 83 CE 2D 85  ([...... l.....-.
00000 0090:  97 43 AB D3 3C DD 59 3D  63 92 12 F8 DD E5 CF CC  .C..<.Y= c.......
00000 00A0:  B2 2D CA 17 9C 2C 84 A7  68 FC A1 8D B7 3D 2B 57  .-...,.. h....=+W
00000 00B0:  63 2A 6A 5A 2F A8 88 87  6A 87 31 0A 9E 4F 8C 8F  c*jZ/... j.1..O..
┌──────────────────────────────────────────────────────────────────────────────┐
│Arrow keys move  F find  N next  RET next difference  ESC quit  T move top    │
│C  ASCII/EBCDIC  E edit  P prev  G   goto position    Q   quit  B move bottom │
└─────────────────────────────────────────────────────────────────────────────

$ hexdump -C -n 256 output/mini.3.9.0-Stable-0313-a8b4519.bin | head

$ hexdump -C -n 256 output/downloaded-firmware.bin | head

00000000  4d 49 4e 49 1f a4 01 08  00 00 00 00 3c ee 0e 00  |MINI........<...|
00000010  02 63 63 00 02 63 63 00  39 00 00 00 00 00 00 00  |.cc..cc.9.......|
00000020  31 44 0b 3e e1 87 34 39  3d 7e 32 76 75 65 12 ba  |1D.>..49=~2vue..|
00000030  5d f2 79 f1 dd a9 01 aa  cc 71 cd 97 95 84 52 43  |].y......q....RC|
00000040  81 c5 8c 4f 1c 96 68 ff  ea b4 32 63 06 f8 a9 42  |...O..h...2c...B|
00000050  7a 69 a4 d9 42 1a e1 d7  0b 91 9c 5e f8 13 85 7b  |zi..B......^...{|
00000060  31 27 60 1b b6 1c 90 2b  47 36 07 8d 6d 0c 7d 05  |1'`....+G6..m.}.|
00000070  d8 c8 fe 37 e8 40 e5 21  ad 4c a2 36 7c 56 39 ed  |...7.@.!.L.6|V9.|
00000080  28 5b a3 87 05 7f 19 9c  6c f9 0b a5 83 ce 2d 85  |([......l.....-.|
00000090  97 43 ab d3 3c dd 59 3d  63 92 12 f8 dd e5 cf cc  |.C..<.Y=c.......|
00000000  4d 49 4e 49 1f a4 01 08  00 00 00 00 3c ee 0e 00  |MINI........<...|
00000010  02 63 63 00 02 63 63 00  39 00 00 00 00 00 00 00  |.cc..cc.9.......|
00000020  31 44 0b 3e e1 87 34 39  3d 7e 32 76 75 65 12 ba  |1D.>..49=~2vue..|
00000030  5d f2 79 f1 dd a9 01 aa  cc 71 cd 97 95 84 52 43  |].y......q....RC|
00000040  81 c5 8c 4f 1c 96 68 ff  ea b4 32 63 06 f8 a9 42  |...O..h...2c...B|
00000050  7a 69 a4 d9 42 1a e1 d7  0b 91 9c 5e f8 13 85 7b  |zi..B......^...{|
00000060  31 27 60 1b b6 1c 90 2b  47 36 07 8d 6d 0c 7d 05  |1'`....+G6..m.}.|
00000070  d8 c8 fe 37 e8 40 e5 21  ad 4c a2 36 7c 56 39 ed  |...7.@.!.L.6|V9.|
00000080  28 5b a3 87 05 7f 19 9c  6c f9 0b a5 83 ce 2d 85  |([......l.....-.|
00000090  97 43 ab d3 3c dd 59 3d  63 92 12 f8 dd e5 cf cc  |.C..<.Y=c.......|

$ tail -c 1024 output/downloaded-firmware.bin | hexdump -C
00000000  5c 4c 00 20 00 00 00 00  00 00 00 00 89 64 0a 08  |\L. .........d..|
00000010  00 00 00 00 00 00 00 00  e0 4b 00 20 00 00 00 00  |.........K. ....|
00000020  00 00 00 00 f9 34 0a 08  00 00 00 00 00 00 00 00  |.....4..........|
00000030  0c 49 00 20 00 00 00 00  00 00 00 00 c5 50 0a 08  |.I. .........P..|
00000040  00 00 00 00 01 00 00 00  6d b4 01 08 00 00 00 00  |........m.......|
00000050  00 00 00 00 14 43 0a 08  00 00 00 00 01 00 00 00  |.....C..........|
00000060  61 bd 01 08 00 00 00 00  00 00 00 00 d5 63 0a 08  |a............c..|
00000070  00 00 00 00 01 00 00 00  b1 bc 01 08 00 00 00 00  |................|
00000080  00 00 00 00 f9 34 0a 08  00 00 00 00 01 00 00 00  |.....4..........|
00000090  f9 16 03 08 00 00 00 00  00 00 00 00 e8 66 0a 08  |.............f..|
000000a0  00 00 00 00 00 00 00 00  5c 4c 00 20 00 00 00 00  |........\L. ....|
000000b0  00 00 00 00 00 00 00 00  00 00 00 00 05 00 00 00  |................|
000000c0  00 00 00 00 01 00 00 00  00 4b 00 20 00 00 00 00  |.........K. ....|
000000d0  00 00 00 00 00 00 00 00  02 00 00 00 00 00 00 00  |................|
000000e0  00 00 00 00 b0 4b 00 20  e0 4b 00 20 70 31 0a 08  |.....K. .K. p1..|
000000f0  00 00 00 00 01 00 00 00  55 b9 01 08 00 00 00 00  |........U.......|
00000100  01 00 00 00 61 31 0a 08  00 00 00 00 01 00 00 00  |....a1..........|
00000110  55 b9 01 08 00 00 00 00  01 00 00 00 00 00 00 00  |U...............|
00000120  00 00 00 00 04 00 00 00  00 00 00 00 01 00 00 00  |................|
00000130  fc 4b 00 20 9c 4a 00 20  03 3c 0a 08 00 00 00 00  |.K. .J. .<......|
00000140  01 00 00 00 25 b9 01 08  00 00 00 00 00 00 00 00  |....%...........|
00000150  a5 62 0a 08 00 00 00 00  01 00 00 00 25 ba 01 08  |.b..........%...|
00000160  00 00 00 00 00 00 00 00  d7 4b 0a 08 00 00 00 00  |.........K......|
00000170  00 00 00 00 94 4b 00 20  ad ae 01 08 01 00 00 00  |.....K. ........|
00000180  1b 63 0a 08 00 00 00 00  01 00 00 00 35 b7 01 08  |.c..........5...|
00000190  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000001a0  03 00 00 00 00 00 00 00  01 00 00 00 78 4c 00 20  |............xL. |
000001b0  9c 4a 00 20 e0 53 0a 08  00 00 00 00 00 00 00 00  |.J. .S..........|
000001c0  50 4a 00 20 bd ad 01 08  00 00 00 00 d9 38 0a 08  |PJ. .........8..|
000001d0  00 00 00 00 00 00 00 00  58 49 00 20 11 ae 01 08  |........XI. ....|
000001e0  00 00 00 00 e0 3a 0a 08  00 00 00 00 00 00 00 00  |.....:..........|
000001f0  ec 49 00 20 41 ae 01 08  00 00 00 00 00 00 00 00  |.I. A...........|
00000200  00 00 00 00 02 00 00 00  57 6e 0a 08 00 00 00 00  |........Wn......|
00000210  dc 4c 00 20 0c 49 00 20  70 31 0a 08 00 00 00 00  |.L. .I. p1......|
00000220  01 00 00 00 1d bb 01 08  00 00 00 00 01 00 00 00  |................|
00000230  61 31 0a 08 00 00 00 00  01 00 00 00 1d bb 01 08  |a1..............|
00000240  00 00 00 00 01 00 00 00  ff ff ff ff 40 77 1b 00  |............@w..|
00000250  e0 93 04 00 f4 01 00 00  01 58 58 58 58 58 58 58  |.........XXXXXXX|
00000260  58 58 00 01 03 ab 00 20  44 ab 00 20 7f aa 00 20  |XX..... D.. ... |
00000270  a0 aa 00 20 c1 aa 00 20  e2 aa 00 20 01 00 00 00  |... ... ... ....|
00000280  c8 f6 0b 08 d8 ae 0c 08  04 53 01 20 19 53 01 20  |.........S. .S. |
00000290  2e 53 01 20 c8 d7 0c 08  9b e2 0c 08 0a 00 00 00  |.S. ............|
000002a0  88 00 fd 00 b7 01 27 02  8b 02 f5 02 41 03 81 03  |......'.....A...|
000002b0  b8 03 cc 03 e0 03 2c 04  95 04 be 04 f5 04 79 05  |......,.......y.|
000002c0  81 05 ed 05 e7 06 60 07  83 07 b1 07 f6 07 f6 07  |......`.........|
000002d0  fc 07 00 08 08 e4 0e 08  a6 56 0b 08 6c 08 01 01  |.........V..l...|
000002e0  a1 b3 01 20 00 00 00 00  00 00 00 00 00 00 00 00  |... ............|
000002f0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000300  00 00 00 00 00 00 00 00  00 00 00 00 3f c6 0f 08  |............?...|
00000310  28 00 00 00 00 01 04 00  01 00 00 00 00 00 00 00  |(...............|
00000320  00 01 57 49 4e 55 53 42  00 00 00 00 00 00 00 00  |..WINUSB........|
00000330  00 00 00 00 00 00 00 00  00 4e 00 20 00 00 00 00  |.........N. ....|
00000340  c8 d5 0f 08 e8 d5 0f 08  a8 d5 0f 08 00 00 00 00  |................|
00000350  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000390  00 00 00 00 00 00 00 00  00 00 00 00 30 d5 0f 08  |............0...|
000003a0  30 d5 0f 08 01 00 00 00  00 00 00 00 4a 00 00 00  |0...........J...|
000003b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
000003d0  00 00 00 00 4a 00 00 00  00 00 00 00 00 00 00 00  |....J...........|
000003e0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
000003f0  00 00 00 00 00 00 00 00  00 00 00 00 08 b6 01 20  |............... |
00000400

This suggests that while the core firmware code may be identical, there are differences in other parts of the firmware, likely related to build timestamps, signatures, or other metadata. These differences are sufficient to cause the hash verification to fail.

Steps to Locate Differences in the Firmware Files

We performed several analyses to locate the exact differences between the built and downloaded firmware files:

  1. First byte difference location using cmp:
$ cmp -l output/mini.3.9.0-Stable-0313-a8b4519.bin output/downloaded-firmware.bin | head
   321 234 165
   322  33 314
   323 202 250
   324 375  21
   325 352  66
   326 271  36
   327 311 372
   328 144 252
   329 376  20
   330 364  25

This shows that the first difference occurs at byte 321, which is very early in the firmware. This suggests that while the headers match, the actual code or data begins to differ quite early.

  1. Mid-section comparison (at offset 10000):
$ hexdump -C -s 10000 -n 100 output/mini.3.9.0-Stable-0313-a8b4519.bin > built_section.txt
$ hexdump -C -s 10000 -n 100 output/downloaded-firmware.bin > downloaded_section.txt
$ diff built_section.txt downloaded_section.txt

No differences were found at this specific section, indicating that some parts of the firmware remain identical despite the different build dates.

  1. String search for build dates:
$ strings output/mini.3.9.0-Stable-0313-a8b4519.bin | grep "0313"
$ strings output/downloaded-firmware.bin | grep "0807"
mini.3.9.0-Stable-0313-a8b4519
mini.3.9.0-Stable-0807-a8b4519

The build date strings are embedded in the firmware files, confirming that the build process includes the date in the binary.

  1. End section comparison (last 4KB):
$ hexdump -C -s $((979516-4096)) output/mini.3.9.0-Stable-0313-a8b4519.bin > built_end.txt
$ hexdump -C -s $((979516-4096)) output/downloaded-firmware.bin > downloaded_end.txt
$ diff built_end.txt downloaded_end.txt

Surprisingly, no differences were found in the last 4KB, suggesting that the signature block (if present) might not be at the very end of the file.

  1. Firmware structure analysis using binwalk:
$ binwalk output/downloaded-firmware.bin
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
15412         0x3C34          SHA256 hash constants, little endian
598268        0x920FC         SHA256 hash constants, little endian
777503        0xBDD1F         Base64 standard index table
910792        0xDE5C8         SHA256 hash constants, little endian

$ binwalk output/mini.3.9.0-Stable-0313-a8b4519.bin
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
15412         0x3C34          SHA256 hash constants, little endian
598268        0x920FC         SHA256 hash constants, little endian
777503        0xBDD1F         Base64 standard index table
910792        0xDE5C8         SHA256 hash constants, little endian

Both firmware files have identical binwalk signatures, showing the same cryptographic components in the same locations.

Interpretation and Next Steps

Our analysis reveals a complex picture: the firmware files differ starting from byte 321, yet have identical sections elsewhere, including the end of the file. The build date is embedded in the firmware, but the differences extend beyond just the date string. To make the firmware reproducible, we would need to:

  1. Identify the exact nature of the early differences (starting at byte 321)
  2. Determine if these are functional code differences or just build artifacts
  3. Modify the build process to use deterministic compilation settings
  4. Potentially separate the signature process from the build process

A more detailed approach would involve disassembling both firmware files and comparing the assembly code to identify if the differences are in the actual executable code or just in metadata. We could also examine the OneKey build scripts to see if there are any non-deterministic elements (like timestamps or random values) being included during compilation.

Conclusion

Based on our testing, the OneKey Mini firmware v3.9.0 is not verifiable in the strict sense, as we cannot produce a bit-for-bit identical copy of the official firmware. While many sections of the firmware appear to be identical, the differences that begin early in the file prevent full reproducibility. These differences are likely related to build environment specifics rather than intentional code changes.

Addendum

We ran another build with slightly different results, but feel that it could give a further insight on the build process. We posted this on a gist.

@xrviv
Copy link
Author

xrviv commented Mar 21, 2025

Initial Findings for OneKey Mini v3.9.0

We conducted a reproducibility test for OneKey Mini firmware v3.9.0 using a modified hardware-specific script. The test involved building the firmware from source code and comparing it with the official firmware downloaded from GitHub.

Build and Download Process

We successfully built the firmware from the OneKey GitHub repository using their provided build system. The build process completed without errors, producing a firmware file named mini.3.9.0-Stable-0321-a8b4519.bin (where 0321 represents the build date).

We then downloaded the official firmware from GitHub using the URL:

https://github.com/OneKeyHQ/firmware/releases/download/mini%2Fv3.9.0/mini.3.9.0-Stable-0807-a8b4519.signed.bin

Hash Comparison

We calculated SHA-256 hashes for both firmware files:

710186dec742eb0a27ff23a762d257a2cb60e565cc3f6fc8380a5e10f0d882b0  mini.3.9.0-Stable-0321-a8b4519.bin
70134b755f3246621b67029a11c5913c782e698ccf3a36aa736e8a73832f41f0  downloaded-firmware.bin

The hashes are different, which indicates that the built firmware is not bit-for-bit identical to the official firmware.

Following OneKey's documentation, we also calculated checksums excluding the first 1024 bytes (which contains the signature):

31ffa36ddf6221d02072245d9b7458dac908cc80f307100b2dad1f852c8d7cd0  mini.3.9.0-Stable-0321-a8b4519.bin (excluding signature)
5b506fe9c7ca702b6bf974ef1b386921b90e3825f9273dfbb98fcf0ffb053030  downloaded-firmware.bin (excluding signature)

Even after excluding the signature section, the hashes still differ, indicating that there are differences in the actual firmware content beyond just the signature.

Binary Comparison

We performed a binary comparison using cmp, hexdump, and other tools. Both firmware files have identical size (979,516 bytes). The file headers and initial binary content are identical for the first 320 bytes, with the first difference occurring at byte 321.

Here's a comparison of the first few bytes of both files:

00000000  4d 49 4e 49 1f a4 01 08  00 00 00 00 3c ee 0e 00  |MINI........<...|
00000010  02 63 63 00 02 63 63 00  39 00 00 00 00 00 00 00  |.cc..cc.9.......|

The "MINI" identifier at the beginning is present in both files, confirming they are for the same device type.

Analysis of the differences revealed:

  1. First difference at byte 321: This is within what OneKey documentation describes as the signature section (first 1024 bytes).

  2. Total differing bytes: 295 bytes out of 979,516 bytes differ between the two firmware files (approximately 0.03% of the total).

  3. Pattern of differences: The differences are concentrated in three main areas:

    • Early differences starting at byte 321 (likely signature-related)
    • A section around bytes 788-804 where the built firmware contains zeros
    • Later differences around byte 628694-628696
  4. Embedded version strings: Both firmware files contain their respective build date strings:

    mini.3.9.0-Stable-0807-a8b4519  (in downloaded firmware)
    mini.3.9.0-Stable-0321-a8b4519  (in built firmware)
    

Interpretation and Next Steps

Our analysis reveals that while the core firmware code appears largely identical, there are specific differences that prevent bit-for-bit verification. These differences are consistent with what we would expect from:

  1. Signature differences: The OneKey documentation explicitly mentions that a 1024-byte signature is added to the firmware, which is verified by the bootloader at device startup.

  2. Build-specific metadata: The build date is embedded in the firmware, causing differences between builds from different times.

  3. Potential non-deterministic build elements: Some elements of the build process may introduce non-deterministic outputs, such as timestamps or compiler-specific artifacts.

According to OneKey's documentation, the proper verification method is to compare the firmware content excluding the first 1024 bytes (signature section). However, our test shows that even with this approach, the hashes still differ.

To make the firmware fully reproducible, we would need to:

  1. Identify all sources of non-determinism in the build process
  2. Modify the build environment to use deterministic compilation settings
  3. Potentially separate the signature process from the build process
  4. Work with OneKey to understand any intentional differences between the public source code and the released firmware

Conclusion

Based on our testing, the OneKey Mini firmware v3.9.0 is not verifiable in the strict sense, as we cannot produce a bit-for-bit identical copy of the official firmware, even when following OneKey's recommended verification process of excluding the signature section.

While the differences are relatively small (295 bytes out of 979,516 bytes, or about 0.03%), they prevent complete verification. These differences are likely related to build environment specifics, timestamps, and the signature process rather than intentional code changes.

This finding is consistent with OneKey's documentation, which acknowledges that the firmware undergoes a signing process after compilation. However, the fact that differences persist even after excluding the signature section suggests additional non-deterministic elements in the build process that affect reproducibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants