-
Notifications
You must be signed in to change notification settings - Fork 52
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
Comments
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 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 |
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:
Possible solution: To build it myself. |
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) |
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 FindingsWe 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 ProcessWe 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 We then downloaded the official firmware from GitHub using the URL:
Hash ComparisonWe calculated SHA-256 hashes for both firmware files:
The hashes are different, which indicates that the built firmware is not bit-for-bit identical to the official firmware. Binary ComparisonWe performed a binary comparison using This is the result of the vbindiff:
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 FilesWe performed several analyses to locate the exact differences between the built and downloaded firmware files:
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.
No differences were found at this specific section, indicating that some parts of the firmware remain identical despite the different build dates.
The build date strings are embedded in the firmware files, confirming that the build process includes the date in the binary.
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.
Both firmware files have identical Interpretation and Next StepsOur 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:
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. ConclusionBased 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. AddendumWe 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. |
Initial Findings for OneKey Mini v3.9.0We 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 ProcessWe 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 We then downloaded the official firmware from GitHub using the URL:
Hash ComparisonWe calculated SHA-256 hashes for both firmware files:
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):
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 ComparisonWe performed a binary comparison using Here's a comparison of the first few bytes of both files:
The "MINI" identifier at the beginning is present in both files, confirming they are for the same device type. Analysis of the differences revealed:
Interpretation and Next StepsOur 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:
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:
ConclusionBased 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. |
Describe the bug
We successfully built version 3.9.0, using this bash script and this dockerfile.
Firmware version and revision
Desktop/smartphone setup (please complete the following information):
To Reproduce
Steps to reproduce the behavior:
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
to00000320
. 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:
The text was updated successfully, but these errors were encountered: