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

> Learn to use custom crypto providers in iroh. Inject any rustls-compatible provider into your endpoint builder for enhanced security and flexibility. Complete guide.

- Repository: [number zero/iroh](https://github.com/n0-computer/iroh)
- Tags: how-to-guide
- Published: 2026-07-10

---

**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`](https://github.com/n0-computer/iroh/blob/main/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`:

```rust
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`](https://github.com/n0-computer/iroh/blob/main/iroh/src/endpoint/presets.rs) (lines 58‑78):

```rust
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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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`](https://github.com/n0-computer/iroh/blob/main/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.