webrtc-extensions icon indicating copy to clipboard operation
webrtc-extensions copied to clipboard

Post-Quantum Crypto (PQC) support in WebRTC

Open aboba opened this issue 1 year ago • 21 comments

We are now seeing PQC support added to TLS implementations: https://docs.aws.amazon.com/kms/latest/developerguide/pqtls.html

In the announcement, s2n-tls was modified to add support for Kyber, NIST's first post-quantum key agreement standard.

The question is whether any changes are needed for WebRTC to support PQC algorithms such as Kyber:

  • In SDP Offer/Answer.
  • In the WebRTC-PC API.

aboba avatar May 24 '24 16:05 aboba

The only things I know about PQC at the moment is that 1) it's implemented in TLS for Chrome, and 2) the keys are awfully big and 3) it requires TLS 1.3 In order to use PQC with WebRTC, we need DTLS 1.3 support. Once that's in place, the big worry is the size of the handshake - if it's now taking many more UDP packets, it will fail more often.

alvestrand avatar May 24 '24 17:05 alvestrand

I would love to have it supported too, and have hybrid key exchanges (preferably with different cryptographic problems rather than algorithms from the same problem set (e.g. LWE)). I know it is beyond the scope of WebRTC, but DTLS1.3 should have at least some basic PQ resistance and should work for us!

ris-work avatar Sep 15 '24 11:09 ris-work

Hi any updates here? Is anyone tried to add pqc to webrtc?

maciejkra avatar Nov 03 '24 20:11 maciejkra

There's work underway to implement DTLS 1.3 in boringssl. That's a precondition to adding the PQ cryptosuites in libwebrtc. The tracking bug is https://issues.chromium.org/issues/42290594 Usage should be straightforward - "just" pass the necessary parameters to the generateCertificate method. But I think we can't mandate support for this until we have gathered some experience, so there should be no need to update the standards at this time.

alvestrand avatar Nov 03 '24 22:11 alvestrand

Thanks! I just stared the mentioned ticket!

maciejkra avatar Nov 03 '24 22:11 maciejkra

The only things I know about PQC at the moment is that 1) it's implemented in TLS for Chrome, and 2) the keys are awfully big and 3) it requires TLS 1.3 In order to use PQC with WebRTC, we need DTLS 1.3 support. Once that's in place, the big worry is the size of the handshake - if it's now taking many more UDP packets, it will fail more often.

Hi, we (Firefox) currently support ssl_grp_kem_mlkem768x25519 in WebRTC in Nightly. My approach was to enable ssl_grp_kem_mlkem768x25519 in the list of supported groups, but not to generate a key share, such that the message does not get fragmented

Frosne avatar Nov 22 '24 09:11 Frosne

From trying to experimentally enable PQC in Chromium/WebRTC it looks like we might want to expose the TLS group id as defined in https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-8 in webrtc stats similar to https://w3c.github.io/webrtc-stats/#dom-rtctransportstats-dtlscipher (which is a string)? The numeric id, e.g. 4588 for X25519MLKEM768 should be sufficient, resolving that to the IANA string seems a bit of a hassle. @Frosne would that work from the NSS side too?

How to opt in remains a good question, by default boringssl generated a key share which has impact on the size of the handshake which is going to be a headache.

fippo avatar Mar 26 '25 18:03 fippo

Hi, If I understood the question correctly:

We do use the id (like for the mentioned X25519MLKEM768 we use only the id - see here: https://searchfox.org/mozilla-central/source/security/nss/lib/ssl/sslt.h#263) for TLS/DTLS

Frosne avatar Apr 07 '25 08:04 Frosne

Seems like exposing the ID of the DTLS cipher to stats seems like the right choice here, given that the IANA strings are not universally used across the industry. What would be the result for traditional ciphers like EC and RSA?

alvestrand avatar Apr 07 '25 11:04 alvestrand

OpenSSL (and BoringSSL) have a "human-friendly" SSL_CIPHER_standard_name which takes the result of SSL_get_current_cipher and turns it into the standard name that we use for dtlsCipher (this seems to be "recent", I found vestiges of a libWebRTC trying to do a mapping to standard names). Currently you get something like TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 which is the translated equivalent of 0xC0,0x2B from the registry. We could add dtlsCipherId and deprecate dtlsCipher but we know we have no way to actually remove stats (looking at you, mediaType aka kind).

fippo avatar Apr 07 '25 18:04 fippo

Current 🤔:

const pc = new RTCPeerConnection({cryptoOptions:{
  dtls: {
    groups: ["X25519MLKEM768"],
  }
}});

with a list of MTI IANA group names. cryptoOptions maps nicely to an existing implementation and can be extended to give more control over SRTP ciphers as requested in #113.

Combined with RTCTransportStats dtlsGroup that gives the algorithm identifier as integer because of this and I'd rather not have a reverse mapping of group names.

fippo avatar Jul 25 '25 14:07 fippo

@fippo Er, are you proposing that we add an API to not only report the selected group but also control the parameters? That's a much, much larger ask and not consistent with anything we've ever exposed on the web platform. (D)TLS configuration is complex and shouldn't be left to individual webpages. That will make it impossible for us to evolve protocol in the future.

davidben avatar Aug 25 '25 15:08 davidben

@davidben since PQC is larger it needs to be opt-in (or as Chrome does it use a policy) at least for transition. Exposing a boolean might be simpler and more flexible

fippo avatar Aug 27 '25 13:08 fippo

Chrome's policy is a temporary compatibility measure and not limited to opt-in. We've had it on by default in HTTPS for some time now. That's our usual process; on by default with a temporary enterprise opt-out, then simply always on after a short while.

davidben avatar Aug 27 '25 14:08 davidben

on by default with a temporary enterprise opt-out, then simply always on after a short while.

That works for changes without a regression in a metric folks care about. Given that PQC makes the client hello go from one to two packets I'd expect reliability issues which negatively affect the "call setup time" (DTLS 1.3 will be a win). Services and servers not having another option but to not negotiate PQC might be a blocker for adoption.

We've seen that before and it is the reason why SRTP in Chrome is still the AES_CM_128_HMAC_SHA1_80 ciphersuites instead of the GCM ones.

fippo avatar Aug 28 '25 13:08 fippo

That works for changes without a regression in a metric folks care about. Given that PQC makes the client hello go from one to two packets I'd expect reliability issues which negatively affect the "call setup time" (DTLS 1.3 will be a win).

That is not quite how (D)TLS 1.3 works. Offering and predicting PQC makes the ClientHello go to two packets. There are clear reasons to want to predict PQC given we intend for traffic to migrate to it. But if mispredicting PQC against non-PQC peers is too much a transitionary performance problem, those are things we can explore to refine that behavior. On the HTTPS side, there's a DNS hint at TLSWG to adjust the predicted set (but not the supported set).

However, thus far, I'm not aware of problems with the current launch strategy. (@alvestrand, do you know how we are looking on that so far?) If problems develop, we can figure that out. But given that the performance baseline was a 2-RTT DTLS 1.2 handshake, it's not obvious to me that 1-RTT with two-packet ClientHello will be worse.

Services and servers not having another option but to not negotiate PQC might be a blocker for adoption.

That is not how (D)TLS works. The client and server both support multiple options. Adding PQ does not remove the classical options when speaking to legacy servers.

We've seen that before and it is the reason why SRTP in Chrome is still the AES_CM_128_HMAC_SHA1_80 ciphersuites instead of the GCM ones.

This also does not make any sense. I have not been involved with Chrome WebRTC's use of SRTP, but there's an entire TLS extension jammed in there so that the TLS handshake can negotiate an SRTP profile. It should have been possible to do a smooth transition where the client offers both old + new and then servers support both old + new.

@alvestrand do you know what's up with this?

davidben avatar Aug 28 '25 13:08 davidben

The SHA1_80 ciphersuites (if I remember correctly) are because of overhead on audio packets. Completely different discussion - bandwidth usage, not negotiation cycles.

I'm happy with "measure first, then decide if we have a problem". The metrics are sensitive enough that they eventually caught the 2-lost-packets regression that jonas just fixed; from what davidben is saying, we have multiple dimensions that may cause metrics to move, and not all of them in a negative direction.

On Thu, Aug 28, 2025 at 3:42 PM David Benjamin @.***> wrote:

davidben left a comment (w3c/webrtc-extensions#207) https://github.com/w3c/webrtc-extensions/issues/207#issuecomment-3233558154

That works for changes without a regression in a metric folks care about. Given that PQC makes the client hello go from one to two packets I'd expect reliability issues which negatively affect the "call setup time" (DTLS 1.3 will be a win).

That is not quite how (D)TLS 1.3 works. Offering and predicting PQC makes the ClientHello go to two packets. There are clear reasons to want to predict PQC given we intend for traffic to migrate to it. But if mispredicting PQC against non-PQC peers is too much a transitionary performance problem, those are things we can explore to refine that behavior. On the HTTPS side, there's a DNS hint at TLSWG to adjust the predicted set (but not the supported set).

However, thus far, I'm not aware of problems with the current launch strategy. @.*** https://github.com/alvestrand, do you know how we are looking on that so far?) If problems develop, we can figure that out. But given that the performance baseline was a 2-RTT DTLS 1.2 handshake, it's not obvious to me that 1-RTT with two-packet ClientHello will be worse.

Services and servers not having another option but to not negotiate PQC might be a blocker for adoption.

That is not how (D)TLS works. The client and server both support multiple options. Adding PQ does not remove the classical options when speaking to legacy servers.

We've seen that before and it is the reason why SRTP in Chrome is still the AES_CM_128_HMAC_SHA1_80 ciphersuites instead of the GCM ones.

This also does not make any sense. I have not been involved with Chrome WebRTC's use of SRTP, but there's an entire TLS extension jammed in there so that the TLS handshake can negotiate an SRTP profile. It should have been possible to do a smooth transition where the client offers both old + new and then servers support both old + new.

@alvestrand https://github.com/alvestrand do you know what's up with this?

— Reply to this email directly, view it on GitHub https://github.com/w3c/webrtc-extensions/issues/207#issuecomment-3233558154, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADVM7LOZ677RLJH3LIQNGL3P4BMRAVCNFSM6AAAAABIH3NTCSVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZTEMZTGU2TQMJVGQ . You are receiving this because you were mentioned.Message ID: @.***>

alvestrand avatar Aug 28 '25 13:08 alvestrand

Ah yeah, polynomial MACs are nice and fast, but they're much less tolerant of truncation than HMAC. :-/

davidben avatar Aug 28 '25 14:08 davidben

The client and server both support multiple options. Adding PQ does not remove the classical options when speaking to legacy servers.

This also means that the server do not really have the option to not take "the hit" (unknown size) unless they act as DTLS client during the negotiation which should be worse than "the hit".

So we're down to "browsers rollout" but can we still have the stats? This allows services to measure "grouped by dtlsGroup we see much higher setup latency".

See #113 and the good old chrome bug for GCM

fippo avatar Aug 28 '25 14:08 fippo