Skip to content

fix(deps): replace unmaintained rust-crypto with bitcoin::hashes::sha256, bump vulnerable deps#208

Open
EddieHouston wants to merge 2 commits intoBlockstream:new-indexfrom
EddieHouston:fix/cargo-audit-vulnerabilities
Open

fix(deps): replace unmaintained rust-crypto with bitcoin::hashes::sha256, bump vulnerable deps#208
EddieHouston wants to merge 2 commits intoBlockstream:new-indexfrom
EddieHouston:fix/cargo-audit-vulnerabilities

Conversation

@EddieHouston
Copy link
Copy Markdown
Collaborator

@EddieHouston EddieHouston commented Apr 16, 2026

Summary

  • Replace rust-crypto with bitcoin::hashes::sha256 for hardware-accelerated SHA-256 (SHA-NI on x86_64, ARMv8 crypto on aarch64)
  • Bump tokio 1.49→1.52 and tar 0.4.44→0.4.45 to resolve known vulnerabilities
  • Add unit tests for SHA-256 correctness (NIST test vectors + P2PKH script hash)
  • Resolves 11 of 18 cargo audit findings; remaining 7 are pinned by upstream crates (electrum-client, electrumd, minreq)

Motivation

cargo audit flagged 18 vulnerabilities and 15 warnings. The most actionable was rust-crypto, a direct dependency used only for SHA-256 hashing in three places:

  • compute_script_hash in src/new_index/schema.rs and src/new_index/precache.rs
  • get_status_hash and hash_ip_with_salt in src/electrum/server.rs

rust-crypto is unmaintained (last release 2016) and has a known AES miscomputation advisory (RUSTSEC-2022-0011). Its transitive dependency rustc-serialize has a stack overflow advisory (RUSTSEC-2022-0004) and is also unmaintained.

Migrated to bitcoin::hashes::sha256 (re-exported from the bitcoin crate, already a direct dependency) per reviewer feedback. This avoids adding a new top-level dependency and keeps hashing consistent with the rest of the codebase, which already uses bitcoin::hashes for sha256d, Midstate, etc.

Benchmark

Independent micro-benchmark (GitHub Actions ubuntu-latest, CPU with SHA-NI) comparing the pre-PR implementation against two modern alternatives. Workload: N strings of the form <txid>:<height>: fed into a single SHA-256 hasher, matching
the get_status_hash shape.

N rust-crypto (pre-PR) sha2 bitcoin_hashes
10 2.81 µs 559 ns 570 ns
100 27.3 µs 5.46 µs 5.41 µs
1000 273.8 µs 54.2 µs 53.9 µs

Both modern implementations are ~5× faster than rust-crypto and within noise of each other on SHA-NI hardware. Benchmark source is on branch bench/sha256-comparison for reproducibility.

Changes

File Change
Cargo.toml Remove rust-crypto = "0.2"; no new direct SHA-256 dep (uses bitcoin::hashes::sha256 already in-tree)
src/new_index/schema.rs Use bitcoin::hashes::sha256 API
src/new_index/precache.rs Use bitcoin::hashes::sha256 API
src/electrum/server.rs Use bitcoin::hashes::sha256 API
Cargo.lock Remove rust-crypto/rustc-serialize tree, bump tokio and tar

Advisories resolved

Crate Advisory Fix
rust-crypto RUSTSEC-2022-0011 (AES miscomputation) Replaced with bitcoin::hashes::sha256
rustc-serialize RUSTSEC-2022-0004 (stack overflow) Removed (transitive of rust-crypto)
bytes RUSTSEC-2026-0007 (integer overflow) Resolved in lockfile
crossbeam-channel RUSTSEC-2025-0024 (double free) Resolved in lockfile
h2 RUSTSEC-2024-0332 (CONTINUATION flood) Resolved in lockfile
hyper-util RUSTSEC-2025-0002 (incomplete requests) Resolved in lockfile
protobuf RUSTSEC-2024-0437 (uncontrolled recursion) Resolved in lockfile
rocksdb RUSTSEC-2024-0433 (miscompilation) Resolved in lockfile
url RUSTSEC-2024-0438 (hostname confusion) Resolved in lockfile
tokio RUSTSEC-2025-0023 (broadcast unsoundness) Bumped 1.49→1.52
tar RUSTSEC-2026-0068 (PAX header bypass) Bumped 0.4.44→0.4.45

Remaining (upstream-blocked)

The 7 remaining advisories cannot be resolved without upstream releases. Most are in dev-only dependencies that do not ship in the production binary; electrum-client is the exception — it ships when the electrum-discovery feature is
enabled.

Crate Advisory Dep chain Production?
ring 0.16.20 RUSTSEC-2025-0009 electrum-client, electrumd Yes (via electrum-discovery)
rustls 0.16.0 RUSTSEC-2024-0336 electrum-client Yes (via electrum-discovery)
webpki 0.21.4 RUSTSEC-2023-0052 electrum-client Yes (via electrum-discovery)
rustls 0.19.1 RUSTSEC-2024-0336 electrumdureq No (dev-dep)
idna 0.2.3 RUSTSEC-2024-0421 electrumdureq No (dev-dep)
rustls-webpki 0.101.7 RUSTSEC-2026-0098, 0099 minreqcorepc-node No (dev-dep)

Test plan

  • cargo check passes (default features)
  • cargo check --features liquid passes
  • cargo test new_index::schema::tests — 3 unit tests pass:
    • test_sha256_empty_input — NIST test vector for SHA-256("")
    • test_sha256_abc — NIST test vector for SHA-256("abc")
    • test_p2pkh_script_hash — real P2PKH scriptPubKey verified against independent SHA-256 computation
  • rest of tests also pass: cargo test -p electrs

@EddieHouston EddieHouston force-pushed the fix/cargo-audit-vulnerabilities branch from 566076b to 45e3daa Compare April 16, 2026 13:48
@shesek
Copy link
Copy Markdown
Collaborator

shesek commented Apr 17, 2026

Have you considered using bitcoin_hashes::sha256 instead of the sha2 crate? (already available through the bitcoin::hashes re-export)

@EddieHouston
Copy link
Copy Markdown
Collaborator Author

EddieHouston commented Apr 20, 2026

Have you considered using bitcoin_hashes::sha256 instead of the sha2 crate? (already available through the bitcoin::hashes re-export)

Looking into it to see if we get the same hardware acceleration 👍 , looks like it may depend on the version.

@EddieHouston
Copy link
Copy Markdown
Collaborator Author

Have you considered using bitcoin_hashes::sha256 instead of the sha2 crate? (already available through the bitcoin::hashes re-export)

Looking into it to see if we get the same hardware acceleration 👍 , looks like it may depend on the version.

Running some benches on a branch on my fork: https://github.com/EddieHouston/electrs/actions/runs/24655997795

Looks like the version of bitcoin_hashes::sha256 is equivalent to sha2 (and both are 5x faster than what we havd in rust-crypto).

Will update to use bitcoin_hashes::sha256. Thanks!

@EddieHouston EddieHouston changed the title fix(deps): replace unmaintained rust-crypto with sha2, bump vulnerabl… fix(deps): replace unmaintained rust-crypto with bitcoin::hashes::sha256, bump vulnerable deps Apr 20, 2026
EddieHouston added a commit to EddieHouston/electrs that referenced this pull request Apr 20, 2026
  Per reviewer feedback on PR Blockstream#208: bitcoin_hashes::sha256 is already
  available via the bitcoin crate re-export and provides equivalent
  SHA-NI hardware acceleration. Drops the direct sha2 dependency.

  Bench (ubuntu-latest w/ SHA-NI, 1000 tx status hashes):
    rust-crypto     273.8 µs
    sha2             54.2 µs
    bitcoin_hashes   53.9 µs
@EddieHouston EddieHouston force-pushed the fix/cargo-audit-vulnerabilities branch from 6f607e9 to 8559ab3 Compare April 20, 2026 09:13
philippem
philippem previously approved these changes Apr 20, 2026
Randy808
Randy808 previously approved these changes Apr 20, 2026
shesek
shesek previously approved these changes Apr 21, 2026
RCasatta
RCasatta previously approved these changes Apr 21, 2026
Copy link
Copy Markdown
Collaborator

@RCasatta RCasatta left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 8559ab3 code review

would have been great to introduce unit tests with hardcoded values of hash_ip_with_salt and compute_script_hash in a separate commit before any other change, so that it's confirmed the following commit with the dep change doesn't change behaviour

…ded expected values

  Add test_compute_script_hash_p2pkh (calls compute_script_hash directly, asserts
  hardcoded FullHash bytes for a P2PKH scriptPubKey) and test_hash_ip_with_salt
  (extracts hash_ip_with_salt to a free function, tests known salt+ip → hex).

  These tests establish the behavioral contract before the rust-crypto dep swap,
  so the following commit can prove the new implementation is bit-for-bit identical.
@EddieHouston
Copy link
Copy Markdown
Collaborator Author

EddieHouston commented Apr 21, 2026

utACK 8559ab3 code review

would have been great to introduce unit tests with hardcoded values of hash_ip_with_salt and compute_script_hash in a separate commit before any other change, so that it's confirmed the following commit with the dep change doesn't change behaviour

Yep, good call for extra safety. Will redo the commits to incorporate this.

…256, bump vulnerable deps

  rust-crypto 0.2 is unmaintained (last release 2016) and has a known AES
  miscomputation advisory (RUSTSEC-2022-0011). Its transitive dependency
  rustc-serialize has a stack overflow advisory (RUSTSEC-2022-0004) and is
  also unmaintained.

  Replace the three SHA-256 call sites (compute_script_hash in schema.rs
  and precache.rs, get_status_hash and hash_ip_with_salt in server.rs)
  with bitcoin::hashes::sha256, already re-exported from the bitcoin
  crate — avoids adding a new top-level dependency and keeps hashing
  consistent with the rest of the codebase.

  Also bumps tokio (1.49->1.52, RUSTSEC-2025-0023) and tar (0.4.44->0.4.45,
  RUSTSEC-2026-0068). Resolves 11 of 18 cargo-audit findings; the
  remaining 7 are pinned by upstream deps (electrum-client, electrumd,
  minreq) and require upstream releases.

  Adds NIST SHA-256 test vectors (empty, 'abc') verifying the new
  implementation against known-good values.
@EddieHouston EddieHouston dismissed stale reviews from RCasatta, shesek, Randy808, and philippem via b095dfc April 21, 2026 15:44
@EddieHouston EddieHouston force-pushed the fix/cargo-audit-vulnerabilities branch from 8559ab3 to b095dfc Compare April 21, 2026 15:44
@EddieHouston
Copy link
Copy Markdown
Collaborator Author

utACK 8559ab3 code review
would have been great to introduce unit tests with hardcoded values of hash_ip_with_salt and compute_script_hash in a separate commit before any other change, so that it's confirmed the following commit with the dep change doesn't change behaviour

Yep, good call for extra safety. Will redo the commits to incorporate this.

Completed commit changes.

@EddieHouston EddieHouston requested a review from RCasatta April 21, 2026 15:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants