[Feature Request] Add detached signature for firmware manifests

Open
#336 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
48/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active

Research direction

Start with FWUPDATE.md and the three published index.json manifests, then trace how firmware metadata is released. Confirm the signing-key, publication, and documentation requirements; done means each manifest has a verifiable detached signature and the key fingerprint and verification steps are documented.

Written by the indexing model from the issue text.

Description

[Feature Request] Add detached signature for firmware manifests

Summary

It would be useful to provide a detached cryptographic signature for the firmware metadata manifests published at:

  • https://jadefw.blockstream.com/bin/jade/index.json
  • https://jadefw.blockstream.com/bin/jade1.1/index.json
  • https://jadefw.blockstream.com/bin/jade2.0/index.json

For example:

index.json
index.json.asc

signed by a documented Blockstream/Jade firmware release key.

I think signing the manifest is probably simpler and more scalable than providing a separate PGP signature for every firmware binary, because index.json already contains the hashes needed to verify the individual firmware files.

Current verification

I recently manually verified Jade 2.0 firmware downloaded from:

https://jadefw.blockstream.com/upgrade/download.html

For example, for firmware 1.0.41 the ZIP contains:

1.0.41_ble_1445888_fw.bin
1.0.41_ble_1445888_fw.bin.hash

1.0.41_noradio_1183744_fw.bin
1.0.41_noradio_1183744_fw.bin.hash

The downloaded compressed binary can be checked directly against the cmphash from index.json:

BIN_FILE="1.0.41_ble_1445888_fw.bin"
sha256sum "$BIN_FILE"

The final uncompressed firmware can also be checked against the published fwhash and the accompanying .hash file:

BIN_FILE="1.0.41_ble_1445888_fw.bin"
cp "$BIN_FILE" tmp.fw.gz
pigz -z -d tmp.fw.gz
sha256sum tmp.fw
rm tmp.fw
cat "$BIN_FILE".hash

In my case both the BLE and no-radio builds matched the values published in:

https://jadefw.blockstream.com/bin/jade2.0/index.json

So the existing hash verification works well.

Motivation

The hashes provide a good way to verify that the firmware downloaded by the user is exactly the firmware represented by the metadata.

However, the firmware binaries and their expected hashes are obtained from the same Blockstream firmware infrastructure.

For example, a user currently effectively verifies:

downloaded .bin
      │
      ├── SHA256 ──> cmphash in index.json
      │
      └── decompress
              │
              └── SHA256 ──> fwhash in index.json / .hash

A detached signature over index.json would add another verification layer:

Trusted Jade release public key
              │
              │ signature verification
              ▼
          index.json
          /        \
     cmphash       fwhash
        │             │
        ▼             ▼
 compressed       uncompressed
 firmware          firmware

A user could first authenticate the manifest:

gpg --verify index.json.asc index.json

and then use the authenticated cmphash / fwhash values to verify the downloaded firmware.

Why sign the manifest instead of every .bin?

Signing index.json seems like the smallest change because the manifest already contains:

filename
version
config
fwsize
cmphash
fwhash

One detached signature would therefore authenticate the hashes and metadata for all firmware entries in that manifest.

It would avoid needing files such as:

1.0.41_ble_1445888_fw.bin.asc
1.0.41_noradio_1183744_fw.bin.asc
...

for every build.

The existing firmware download format would not need to change.

Something like this could simply be added alongside each manifest:

/bin/jade/index.json
/bin/jade/index.json.asc

/bin/jade1.1/index.json
/bin/jade1.1/index.json.asc

/bin/jade2.0/index.json
/bin/jade2.0/index.json.asc

Public key distribution

For this to provide meaningful independent authentication, the signing key fingerprint should also be documented somewhere outside the firmware server itself.

For example:

  • Jade GitHub repository
  • FWUPDATE.md
  • Blockstream Jade documentation
  • other official Blockstream channels

Ideally this would be a dedicated release-signing key rather than requiring the private key used internally by Jade to authenticate firmware on official devices.

Relationship with Jade's existing firmware signature

I understand that official Blockstream Jade units already verify that firmware has been signed by Blockstream before accepting/running it.

This proposal is not intended to replace that mechanism.

The existing firmware signature provides authentication at the device level:

Jade → verifies firmware

The proposed detached manifest signature would additionally allow:

User → verifies firmware release metadata

before uploading the firmware to Jade.

This would complement the existing firmware signing and reproducible-build verification.

Proposed minimal implementation

  1. Create/use a documented Jade firmware release-signing OpenPGP key.
  2. Generate a detached signature whenever an index.json manifest is updated:
gpg --armor --detach-sign index.json
  1. Publish index.json.asc next to each existing index.json.
  2. Publish and document the signing-key fingerprint in the Jade repository and documentation.
  3. Add a short optional verification example to FWUPDATE.md:
gpg --verify index.json.asc index.json
sha256sum <firmware.bin>

The second result can then be compared with the now-authenticated cmphash.

This seems like a relatively small addition while giving users who manually verify firmware an additional independent authenticity check.

Dominant language
C
Stars
497
Forks
131
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Blockstream/Jade

All issues in Blockstream/Jade

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.