Blockstream / Blockstream/Jade

[Feature Request] Add detached signature for firmware manifests

Open
#336 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
496
Forks
127
PR merge metrics
No merged PRs in 30d

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:

```text
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:

```text
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`:

```bash
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:

```bash
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:

```text
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:

```text
Trusted Jade release public key

│ signature verification

index.json
/ \
cmphash fwhash
│ │
▼ ▼
compressed uncompressed
firmware firmware
```

A user could first authenticate the manifest:

```bash
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:

```text
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:

```text
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:

```text
/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:

```text
Jade → verifies firmware
```

The proposed detached manifest signature would additionally allow:

```text
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:

```bash
gpg --armor --detach-sign index.json
```

3. Publish `index.json.asc` next to each existing `index.json`.
4. Publish and document the signing-key fingerprint in the Jade repository and documentation.
5. Add a short optional verification example to `FWUPDATE.md`:

```bash
gpg --verify index.json.asc index.json
sha256sum
```

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.

Contributor guide

No contributing guide indexed for this repository

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.

Assessment

Domain
documentation, embedded-iot, release, security
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.