Skip to content

chore: enforce hybrid PQ key exchange in mTLS handshakes - #922

Open
mkmks wants to merge 1 commit into
mainfrom
chore/pq-tls-handshake
Open

mkmks wants to merge 1 commit into
mainfrom
chore/pq-tls-handshake

Conversation

@mkmks

@mkmks mkmks commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Description

While rustls already supported PQ key change for a while, and we had enabled in mTLS between parties, we don't forbid explicitly classical key exchange which might lead to a downgrade by a malicious operator. This PR only permits hybrid PQ exchanges, preventing potential downgrades.

PR Checklist

Tick all that apply — by ticking I attest the item holds; justify any deviation in the description above.

  • Title follows conventional commits (e.g. chore: ...).
  • Tests added for every new pub item and test coverage has not decreased.
  • Public APIs and non-obvious logic documented; unfinished work marked TODO(#issue).
  • unwrap/expect/panic only in tests or for invariant bugs (documented if present).
  • No dependency version changes OR (if changed) only minimal required fixes.
  • No architectural protocol changes OR linked spec PR/issue provided.
  • No breaking deployment config / Helm chart / telemetry changes OR devops label + infra notified + review requested.
  • No breaking gRPC / serialized data changes OR commit marked with ! and affected teams notified.
  • No modifications to existing versionized structs OR backward compatibility tests updated.
  • No critical business logic / crypto changes OR ≥2 reviewers assigned.
  • No new sensitive data fields OR Zeroize + ZeroizeOnDrop implemented.
  • No new public storage data OR data is verifiable (signature / digest).
  • No unsafe; if unavoidable: minimal, justified, documented, and test/fuzz covered.
  • Strongly typed boundaries: typed inputs validated at the edge; no untyped values or errors cross modules.
  • Self-review completed.

@mkmks
mkmks requested a review from a team as a code owner October 5, 2026 10:34
@cla-bot cla-bot Bot added the cla-signed The CLA has been signed. label Oct 5, 2026

@titouantanguy titouantanguy left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Changes do LGTM, but maybe others also have an opinion on what we want to support for the key exchange and cipher suite ?
cc @jot2re @dd23 @kc1212

Comment on lines +1076 to +1089
let error = server_result.unwrap_err();
assert!(
matches!(
error
.get_ref()
.and_then(|error| error.downcast_ref::<Error>()),
Some(Error::PeerIncompatible(
PeerIncompatible::NoKxGroupsInCommon
))
),
"unexpected rejection for {:?}: {error}",
group.name(),
);
assert!(client_result.is_err(), "client accepted {:?}", group.name());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit, why an assert on the client's error but an unwrap on the server's one ?


/// Constructs mutually authenticated P2P TLS configurations with hybrid-only key exchange.
///
/// Both endpoints require TLS 1.3 and prefer [`kx_group::X25519MLKEM768`] over [`kx_group::SECP256R1MLKEM768`].

@titouantanguy titouantanguy Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any reason why we support both ? and in that order ?
I reckon compliance frameworks might enforce SECP256R1MLKEM768 as that's what NIST suggests ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The reason was that rustls supports both, and whatever is the default came out first. Will pin the NIST recommendation, unless someone objects.

where
R: ResolvesServerCert + ResolvesClientCert + 'static,
{
let mut provider = default_provider();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This PR talks about handshake only, but I'm wondering do we want to force AES 256 as well ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, will restrict session ciphers too.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cla-signed The CLA has been signed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants