Skip to content

Latest commit

 

History

History
61 lines (45 loc) · 2.6 KB

File metadata and controls

61 lines (45 loc) · 2.6 KB

Post-quantum transport (pqc feature)

Vault can negotiate a post-quantum-secure TLS 1.3 handshake with the Bitwarden / Vaultwarden server using the hybrid X25519MLKEM768 key-exchange group. It is off by default and enabled with the pqc cargo feature.

# build the agent with PQC preferred on its HTTPS client
cargo build -p vault-agent --features pqc
# (vault-api exposes the underlying feature: `--features vault-api/pqc`)

When enabled, the client offers X25519MLKEM768 first and the classical groups (X25519, P-256, P-384) as fallback. If the server doesn't support PQC — most don't yet — the handshake silently falls back to a classical group, so enabling the feature is safe. PQC is TLS 1.3 only.

Why we hand-roll it (and don't use aws-lc-rs)

rustls only ships X25519MLKEM768 through its aws-lc-rs provider. aws-lc-rs bundles AWS-LC, whose license tree includes OpenSSL-licensed code — which is GPL-incompatible. Vault is GPL-3.0-or-later (Standard §4), so aws-lc-rs is not an option, and our deny.toml allow-list would reject it.

Instead, crates/vault-api/src/pqc.rs builds the hybrid group from GPL-compatible parts:

  • classical half — ring's audited X25519 (rustls::crypto::ring::kx_group::X25519), reused as-is;
  • post-quantum half — RustCrypto's ml-kem (MlKem768), Apache-2.0/MIT.

The two are composed into a rustls::crypto::SupportedKxGroup and injected via reqwest's use_preconfigured_tls. Only the client role is implemented.

Wire construction

Per draft-ietf-tls-ecdhe-mlkem (X25519MLKEM768), the post-quantum element comes first in every share and in the derived secret:

bytes layout
client share 1216 ek_ML-KEM-768 (1184) ‖ x25519_pub (32)
server share 1120 ct (1088) ‖ x25519_pub (32)
shared secret 64 ss_ML-KEM (32) ‖ ss_X25519 (32)

The client generates an ML-KEM keypair (keeping the decapsulation key) plus an X25519 ephemeral, sends ek ‖ x25519_pub, then on the server's reply X25519-DHs the classical part, decapsulates the ML-KEM ciphertext, and concatenates the two secrets (PQ first). This mirrors rustls's own (crate-private) aws_lc_rs::pq::hybrid layout.

Status (PRD §12 M7)

This satisfies the M7 "PQC transport feature flag" item. Still pending for the v0.1 tag: making PQC a tested live handshake against a PQC-enabled server, the ≥ 24 h EncString fuzz soak (docs/fuzzing.md), the broader hardening pass, and the §11.2 two-week daily-driver attestation.