Skip to content

feat: add aws-lc-rs feature as alternative crypto backend (ring stays default)#134

Merged
spongebob888 merged 1 commit into
spongebob888:mainfrom
ibigbug:feat/aws-lc-rs
May 12, 2026
Merged

feat: add aws-lc-rs feature as alternative crypto backend (ring stays default)#134
spongebob888 merged 1 commit into
spongebob888:mainfrom
ibigbug:feat/aws-lc-rs

Conversation

@ibigbug

@ibigbug ibigbug commented May 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Add a new aws-lc-rs Cargo feature that lets downstream users swap the Ring crypto backend for AWS-LC. Ring remains the default — no breaking change.

Motivation

Projects like clash-rs use aws-lc-rs as their primary crypto provider across the whole binary. Without this feature, shadowquic unconditionally pulls in ring as an additional crypto library, duplicating ~500KB–1MB of crypto code (AES, curve25519, P-256 assembly) in the final binary even though those primitives are already provided by aws-lc-rs.

Changes

shadowquic/Cargo.toml

  • Make ring dep optional, gated by the new ring feature (included in default)
  • Add aws-lc-rs as an optional dep
  • Add ring and aws-lc-rs feature flags that propagate the backend choice to all sub-crates: quinn-jls, quinn-proto-jls, rustls-jls, iroh-quinn, iroh-quinn-proto, rustls, rcgen
  • Remove hardcoded rustls-ring / ring from dep features lists

Source files — replace ring:: with a feature-gated crypto_provider alias:

  • src/shadowquic/quinn_wrapper/wrapper.rs — cipher suite selection + provider init
  • src/sunnyquic/iroh_wrapper/wrapper.rs — same
  • src/sunnyquic/dynamic_cert.rssign::any_supported_type
  • src/sunnyquic/mod.rs — SHA256 hash via ring::digest / aws_lc_rs::digest

Usage

# Keep ring (default, unchanged behaviour)
shadowquic = { version = "0.3" }

# Opt into aws-lc-rs
shadowquic = { version = "0.3", default-features = false, features = ["shadowquic-quinn", "sunnyquic-iroh-quinn", "aws-lc-rs"] }

Verification

# default (ring) still builds
cargo check -p shadowquic

# aws-lc-rs path builds and ring dep is absent
cargo check -p shadowquic --no-default-features -F shadowquic-quinn,sunnyquic-iroh-quinn,aws-lc-rs
cargo tree  -p shadowquic --no-default-features -F shadowquic-quinn,sunnyquic-iroh-quinn,aws-lc-rs -i ring
# → empty (ring completely removed)

Add a new `aws-lc-rs` feature flag that allows users to opt-in to the
AWS-LC crypto backend instead of ring. Ring remains the default via the
`ring` feature in the default feature set.

Changes:
- Make `ring` dep optional, gated behind the new `ring` feature
- Add `aws-lc-rs` optional dep
- Add `ring` and `aws-lc-rs` features that propagate the backend
  choice to all sub-crates (quinn-jls, quinn-proto-jls, rustls-jls,
  iroh-quinn, iroh-quinn-proto, rustls, rcgen)
- Replace hardcoded `ring::crypto` references in source with a
  feature-gated `crypto_provider` alias
- Replace direct `ring::digest` SHA256 usage with feature-gated
  equivalent using `aws_lc_rs::digest` when aws-lc-rs is active

This allows downstream crates (e.g. clash-rs) using aws-lc-rs as their
primary crypto provider to avoid pulling in ring as a duplicate
dependency, reducing binary size.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ibigbug added a commit to Watfaq/clash-rs that referenced this pull request May 11, 2026
When aws-lc-rs is the active crypto backend, ring was still being
pulled in as a duplicate dependency by three paths:

1. quinn (v0.11) - used feature = "rustls" which aliases to
   "rustls-ring". Removed "rustls" from static features; now routes
   via aws-lc-rs feature (quinn/rustls-aws-lc-rs) or ring feature
   (quinn/rustls-ring).

2. rcgen - used default features which include ring backend. Switched
   to default-features = false; crypto backend now selected via
   aws-lc-rs/ring features (rcgen/aws_lc_rs or rcgen/ring).

3. shadowquic - hardcoded ring throughout. Switched to the fork
   ibigbug/shadowquic@a6f3fde which adds an aws-lc-rs feature flag
   (see spongebob888/shadowquic#134).
   Added default-features = false on the dep and explicit feature
   routing in aws-lc-rs/ring clash-lib features.

Result: cargo tree -p clash-lib -F aws-lc-rs,shadowquic -i ring
returns empty — ring is completely absent from the aws-lc-rs path.
Estimated binary size reduction: ~500KB-1MB stripped release.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
ibigbug added a commit to Watfaq/clash-rs that referenced this pull request May 12, 2026
…#1397)

* fix: remove ring from aws-lc-rs code path

When aws-lc-rs is the active crypto backend, ring was still being
pulled in as a duplicate dependency by three paths:

1. quinn (v0.11) - used feature = "rustls" which aliases to
   "rustls-ring". Removed "rustls" from static features; now routes
   via aws-lc-rs feature (quinn/rustls-aws-lc-rs) or ring feature
   (quinn/rustls-ring).

2. rcgen - used default features which include ring backend. Switched
   to default-features = false; crypto backend now selected via
   aws-lc-rs/ring features (rcgen/aws_lc_rs or rcgen/ring).

3. shadowquic - hardcoded ring throughout. Switched to the fork
   ibigbug/shadowquic@a6f3fde which adds an aws-lc-rs feature flag
   (see spongebob888/shadowquic#134).
   Added default-features = false on the dep and explicit feature
   routing in aws-lc-rs/ring clash-lib features.

Result: cargo tree -p clash-lib -F aws-lc-rs,shadowquic -i ring
returns empty — ring is completely absent from the aws-lc-rs path.
Estimated binary size reduction: ~500KB-1MB stripped release.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: remove unused imports in watfaq-dns handler test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* fix: use ClashInstance RAII in anytls integration tests

The anytls tests were using std::thread::spawn + start_clash without
any cleanup mechanism. Threads kept running after each test completed,
leaving ports 8902/9092 and 8998/9095 bound. The subsequent
integration_test_anytls_udp test would then fail to bind port 8902
with 'Address already in use'.

Replace both anytls tests with ClashInstance, which cancels the
shutdown token on drop and waits for all ports to be released before
returning — matching the pattern used throughout api_tests.rs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@spongebob888 spongebob888 merged commit 0f0842d into spongebob888:main May 12, 2026
32 checks passed
@ibigbug ibigbug deleted the feat/aws-lc-rs branch May 12, 2026 15:37
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.

2 participants