How to Use Custom Crypto Providers in iroh: A Complete Guide

You can inject any rustls-compatible CryptoProvider into iroh by calling the crypto_provider() method on the endpoint Builder, passing an Arc-wrapped provider that implements the rustls trait.

iroh's TLS layer is built on rustls, which abstracts cryptographic implementations behind the CryptoProvider trait. By default, the library ships with preset providers (ring and aws‑lc‑rs) that are selected automatically when Cargo features tls‑ring or tls‑aws‑lc‑rs are enabled. When you need a different provider—whether a custom-built implementation or a third-party crate—you can inject it directly into the endpoint builder to control the cryptographic primitives used for all TLS and QUIC communication.

Understanding iroh's Crypto Provider Architecture

iroh delegates all cryptographic operations to rustls, which defines the CryptoProvider trait as the interface for cipher suites, signature schemes, and key‑exchange algorithms. The library selects a default provider based on feature flags:

  • tls‑ring: Enables the ring crate provider
  • tls‑aws‑lc‑rs: Enables the AWS Libcrypto provider

These presets are wired into the build configuration, but the Builder API allows you to override this selection at runtime with any compatible implementation.

Setting a Custom Crypto Provider on the Endpoint Builder

The Builder::crypto_provider method in iroh/src/endpoint.rs (lines 47‑64) accepts an Arc<CryptoProvider> and stores it for all subsequent TLS operations, including QUIC connections, HTTPS calls to relays, and PKARR publishing.

Using a Built‑in Provider Explicitly

To use one of the built‑in rustls providers directly, obtain it via default_provider() and wrap it in Arc:

use std::sync::Arc;
use rustls::crypto::{CryptoProvider, ring};
use iroh::endpoint::Builder;

// Obtain the ring provider
let provider = Arc::new(ring::default_provider());

// Inject into the builder
let endpoint = Builder::empty()
    .crypto_provider(provider)  // ← custom crypto provider injection
    .bind()
    .await?;

Overriding Preset Configurations

Presets like Minimal or N0 configure default providers based on feature flags, but you can override them after instantiation. The preset logic resides in iroh/src/endpoint/presets.rs (lines 58‑78):

use iroh::endpoint::{Builder, presets};
use rustls::crypto::aws_lc_rs;

// Start with a preset that includes relay and address lookup
let endpoint = Builder::new(presets::N0)
    .crypto_provider(Arc::new(aws_lc_rs::default_provider()))  // override provider
    .bind()
    .await?;

Implementing a Fully Custom Crypto Provider

For custom implementations—whether your own code or third‑party crates—you must implement the full rustls::crypto::CryptoProvider trait. The provider must support the cipher suites required by QUIC, specifically TLS 1.3 AES 128‑GCM‑SHA256.

iroh validates this requirement at runtime. If your provider lacks the necessary cipher suite, the library emits an error from iroh/src/tls.rs:


The configured crypto provider is missing support for TLS13_AES_128_GCM_SHA256

Ensure your implementation includes:

  • TLS 1.3 cipher suites (mandatory: AES 128‑GCM‑SHA256)
  • Supported signature schemes
  • Key‑exchange algorithms compatible with QUIC

Summary

  • iroh uses rustls's CryptoProvider trait to abstract cryptographic implementations, with default providers selected via tls‑ring or tls‑aws‑lc‑rs features.
  • Call Builder::crypto_provider() with an Arc-wrapped provider to inject custom crypto providers in iroh, overriding any preset defaults.
  • The method is implemented in iroh/src/endpoint.rs (lines 47‑64) and affects all TLS operations including QUIC and HTTPS.
  • Presets can be customized by chaining crypto_provider() after instantiating the preset, as shown in iroh/src/endpoint/presets.rs (lines 58‑78).
  • Custom providers must implement the full rustls trait and support TLS 1.3 AES 128‑GCM‑SHA256; missing support triggers an error from iroh/src/tls.rs.

Frequently Asked Questions

What is a CryptoProvider in iroh?

A CryptoProvider is a rustls trait implementation that supplies cryptographic primitives—including cipher suites, signature schemes, and key‑exchange algorithms—to iroh's TLS and QUIC stack. iroh uses this abstraction to allow swapping between different cryptographic libraries (like ring or aws‑lc‑rs) or custom implementations without changing the application code.

Can I use a custom crypto provider with iroh's built‑in presets?

Yes. Presets like N0 or Minimal configure default providers based on Cargo features, but you can override them by calling crypto_provider() on the builder after instantiating the preset. This allows you to keep the preset's relay and discovery configuration while substituting your own cryptographic implementation.

What happens if my custom provider doesn't support the required cipher suites?

iroh validates that the provided CryptoProvider supports TLS 1.3 AES 128‑GCM‑SHA256, which is required for QUIC. If your provider lacks this support, the library will return an error stating "The configured crypto provider is missing support for TLS13_AES_128_GCM_SHA256" from the validation logic in iroh/src/tls.rs.

Do I need to enable a Cargo feature to use custom crypto providers?

No. The tls‑ring and tls‑aws‑lc‑rs features only control the default providers included in the build. To use a custom crypto provider, you simply pass it to Builder::crypto_provider() at runtime, regardless of which default features are enabled. However, you must ensure your custom provider is compatible with the rustls version used by iroh.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →