Skip to content

[Feature request] Detect PQ Cipher X25519Kyber512Draft00 and X25519Kyber768Draft00 #2280

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
drwetter opened this issue Nov 25, 2022 · 31 comments
Labels
3.2 upcoming release

Comments

@drwetter
Copy link
Collaborator

drwetter commented Nov 25, 2022

Which version are you referring to
3.2rcx .

Please check this repo whether this is a known feature request
no

Describe your feature request (if it's a technical feature)
Cloudflare has published a blog post at https://blog.cloudflare.com/post-quantum-for-all/ about one of their servers (https://pq.cloudflareresearch.com/) supporting the post quantum ciphers X25519Kyber512Draft00 / X25519Kyber768Draft00.

Not much surprisingly it didn't work to add just the cipher in the handshake or try the undocumented debug switch DEBUG=3 ./testssl.sh --devel 04 "fe,30, fe,31" pq.cloudflareresearch.com .

As an educated guess I suppose the KEM (Key Encapsulation Mechanism) is what doesn't work, see paragraph "on the wired" in their blog post.

@dcooper16
Copy link
Collaborator

Hi Dirk,

I saw this too and was thinking about trying to add support for it. I just tried using the --devel option and had some success, but I had to make a change to the code. The issue is that ""fe,30" and "fe,31" are not cipher suites, they are for identifiers in the supported_groups extension. Unfortunately, with the --devel option, the TLS version and list of cipher suites can be specified at the command line, but extensions can not.

So, I created a modified version of testssl.sh in which I changed line 23742 to:

tls_sockets "$TLS_LOW_BYTE" "$HEX_CIPHER" "ephemeralkey" "00,0a, 00, 06, 00, 04, fe,30, fe,31"

and then I called testssl.sh as:

./testssl.sh --debug 4 --devel "04" "13,01, 13,02, 13,03, 13,04, 13,05" pq.cloudflareresearch.com

The result is that the server sends a HelloRetryRequest specifying the use of group "fe, 30" and then testssl.sh fails since it does not have a key share for that group.

So, the first (and biggest) step in adding support for detecting these key types is to add key shares to TLS13_PUBLIC_KEY_SHARES (defined in etc/tls_data.txt) for X25519Kyber512 and X25519Kyber768, which means finding a way to generate Kyber key pairs. Then, after coming up with short names for these key types, they can be added to prepare_tls_clienthello(), run_fs(), pr_ecdh_curve_quality(), parse_tls_serverhello(), etc.

@drwetter
Copy link
Collaborator Author

Ah, ok, thanks for the heads up!

I had a quick look here: https://pq.cloudflareresearch.com/ and I found not so much yet, besides references like this: https://github.com/cloudflare/boringssl-pq/search?q=KYBER768_generate_key .

@dcooper16
Copy link
Collaborator

I was able to compile the reference implementation for Kyber from https://github.com/pq-crystals/kyber and used it to generate public keys for Kyber512 and Kyber768. I added public keys for 0xFE30 and 0xFE31 to etc/tls_data.txt in the https://github.com/dcooper16/testssl.sh/tree/TLS_ECDHE_HSS_WITH_AES_256_GCM_SHA384 branch. Using that version of etc/tls_data.txt and modifying line 23742 of testssl.sh as above results in the --devel command working:

./testssl.sh --debug 4 --devel "04" "13,01, 13,02, 13,03, 13,04, 13,05" pq.cloudflareresearch.com

Next step is to assign string names to these groups (X25519+Kyber512 and X25519+Kyber768 are too long to print in the KeyExch. column output by neat_list()) and then modify parse_tls_clienthello() to recognize these named groups.

@drwetter
Copy link
Collaborator Author

very cool!

@dcooper16
Copy link
Collaborator

The run_fs() function in https://github.com/dcooper16/testssl.sh/tree/TLS_ECDHE_HSS_WITH_AES_256_GCM_SHA384 will now detect if a server supports X25519+Kyber512 and/or X25519+Kyber768 (as long as the server also supports at least one "standard" ECDH or FFDH group). Other than the check for "Elliptic curves offered," everything else in https://github.com/dcooper16/testssl.sh/tree/TLS_ECDHE_HSS_WITH_AES_256_GCM_SHA384 only tests for "standard" elliptic curves (or FFDH groups).

@ju916
Copy link

ju916 commented Nov 26, 2022

That’s super cool !
Thank‘s a lot for your continued efforts.

@drwetter
Copy link
Collaborator Author

drwetter commented Nov 27, 2022

For "others convenience" this is a diff (wrong order of files) of the output:

image

@dcooper16
Copy link
Collaborator

@amran28
Copy link

amran28 commented Apr 25, 2024

The run_fs() function in https://github.com/dcooper16/testssl.sh/tree/TLS_ECDHE_HSS_WITH_AES_256_GCM_SHA384 will now detect if a server supports X25519+Kyber512 and/or X25519+Kyber768 (as long as the server also supports at least one "standard" ECDH or FFDH group). Other than the check for "Elliptic curves offered," everything else in https://github.com/dcooper16/testssl.sh/tree/TLS_ECDHE_HSS_WITH_AES_256_GCM_SHA384 only tests for "standard" elliptic curves (or FFDH groups).

Thank you for the effort, very interesting. I quickly tested your commit against the cloudflare websites and it works, however, it doesn't show the support for X25519+Kyber when testing via ./testssl.sh -f www.google.com, although the google website communicates with that key exchange when using PQC-enabled Firefox or Chrome. Just to understand: Is that because of the way the script only tests via the "Elliptic curves offered" check?

@dcooper16
Copy link
Collaborator

Hello @amran28,

At the moment, any support for options such as X25519+Kyber is just experimental, as the standards are not yet complete. So, if the google website does support X25519+Kyber, then I would need more information to understand why https://github.com/dcooper16/testssl.sh/tree/TLS_ECDHE_HSS_WITH_AES_256_GCM_SHA384 is not detecting it. I don't think it is because the script only tests via the "Elliptic curves offered" check, as the mechanism for negotiating elliptic curves is just being extended to allow allow for negotiating post-quantum algorithms.

I do have one guess. When I connect to google.com, Wireshake shows some TLS packets, but a lot of QUIC packets. testssl.sh only tests TLS, not QUIC. So, if X25519+Kyber is being negotiated in QUIC, then testssl.sh would not see it.

@amran28
Copy link

amran28 commented Apr 25, 2024

Ah, that would indeed explain it; I just looked at all packets over TCP without differentiating between TLS and QUIC.
Thanks again, @dcooper16.

@okoeroo
Copy link

okoeroo commented Jul 28, 2024

Is there any way to help on this issue?

@drwetter
Copy link
Collaborator Author

drwetter commented Sep 8, 2024

Hi @dcooper16 ,

at a certain point (few weeks) I'd like to release the 3.2 once the remaining problems are squashed . I ´d love to see the work you've done included. Last but not least as you know the first 3 PQ encryption standards were finalized.

Do you think you can help here with a PR?

@drwetter drwetter added the 3.2 upcoming release label Sep 8, 2024
@dcooper16
Copy link
Collaborator

Hi @drwetter,

I don't think the work that I've done on this should be included in 3.2. First, it is very incomplete. More importantly, I don't think it will be of much use. Cloudflare has indicated that in the coming weeks they will be disabling support for the two code points that https://github.com/dcooper16/testssl.sh/tree/TLS_ECDHE_HSS_WITH_AES_256_GCM_SHA384 detects. They will also more generally be phasing out the use of code points that are based on the draft versions of Kyber. My guess is that others will be doing the same.

I was hoping to find some time to work on detecting use of post-quantum key exchange once implementations were in place based on the final versions of the standards. I see that draft-kwiatkowski-tls-ecdhe-mlkem defines two code points for use of ML-KEM in hybrid mode (Cloudflare mentions that they are planning to support one of them). However, I haven't been following the IETF TLS WG closely, so I can't say whether it is too early to know if these code points will be among the set of "final" code points for post-quantum key exchange.

Maybe once the situation is more settled, any necessary changes could be backported for the 3.2 branch, so that they could be included in a point release.

@ghen2
Copy link
Contributor

ghen2 commented Sep 13, 2024

Maybe it's also interesting to add a Chrome 124+ handshake simulation that uses this key exchange (0x6399 currently, or 0x11ec soon).

@ghen2
Copy link
Contributor

ghen2 commented Sep 23, 2024

FWIW Google servers are now supporting both 0x6399 x25519_kyber768 (draft) and 0x11ec x25519_mlkem768 (final).
Firefox nightly switched from the former to the latter, Chrome too will switch soon.

@ghen2
Copy link
Contributor

ghen2 commented Jan 3, 2025

Hi @drwetter, @dcooper16,
This is become more and more relevant, any plans to proceed with this?

@drwetter
Copy link
Collaborator Author

drwetter commented Jan 3, 2025

I would like rather to wait for @dcooper16 who is afk these days.

@dcooper16
Copy link
Collaborator

Hi Dirk,

I have created a branch that checks for the three groups in draft-kwiatkowski-tls-ecdhe-mlkem: https://github.com/dcooper16/testssl.sh/tree/draft-kwiatkowski-tls-ecdhe-mlkem. I think this branch is in better shape than what is in https://github.com/dcooper16/testssl.sh/tree/TLS_ECDHE_HSS_WITH_AES_256_GCM_SHA384. I have tested it against a couple of servers that support X25519MLKEM768. However it is my impression that no servers currently support the other two groups, so they have not been tested.

I feel more comfortable with submitting this as a PR, since I think it is more complete and it is based on groups that use the standard (ML-KEM, FIPS 203) rather than the pre-standardized version of Kyber. It would be nice if standardization of PQC groups were further along in the IETF, but I can go ahead and submit a PR.

@ghen2
Copy link
Contributor

ghen2 commented Jan 17, 2025

However it is my impression that no servers currently support the other two groups, so they have not been tested.

You can test against https://geert.hendrickx.be/. Your branch correctly detects all three KEM's there.

@ghen2
Copy link
Contributor

ghen2 commented Jan 17, 2025

It would also be interesting to add a handshake simulation for recent Chrome or Firefox with X25519MLKEM768 enabled.

@dcooper16
Copy link
Collaborator

You can test against https://geert.hendrickx.be/. Your branch correctly detects all three KEM's there.

Thanks for the pointer. It definitely helps to verify that it can detect all three groups.

It would also be interesting to add a handshake simulation for recent Chrome or Firefox with X25519MLKEM768 enabled.

I did try copying the ClientHello from Firefox 134 and adding it to etc/client-simulation.txt, just to make sure that code was working. But, I just copied the entry for "Firefox 100 (Win 10)" and replaced the handshakebytes with the capture I got for Firefox 134 using Wireshark. More work would be needed to correctly fill in all of the other fields.

@ghen2
Copy link
Contributor

ghen2 commented Jan 17, 2025

I feel more comfortable with submitting this as a PR, since I think it is more complete and it is based on groups that use the standard (ML-KEM, FIPS 203) rather than the pre-standardized version of Kyber. It would be nice if standardization of PQC groups were further along in the IETF, but I can go ahead and submit a PR.

Wouldn't you add the Kyber hybrid draft (0x6399) as well? It's deployed by at least Google and Cloudflare, so useful to check for.
I think we should care more about what is actually deployed, than about IETF status? As long as they have IANA code points...

@dcooper16
Copy link
Collaborator

Wouldn't you add the Kyber hybrid draft (0x6399) as well? It's deployed by at least Google and Cloudflare, so useful to check for.
I think we should care more about what is actually deployed, than about IETF status? As long as they have IANA code points...

The issue isn't so much about IETF status. I was just under the impression that these code points were just being used temporarily for testing purposes, and that they wouldn't be used long term. I don't have code at the moment for testing 0x6399, but the IANA registry labels it as obsolete, and it was my understanding that Googe and Cloudflare were replacing 0x6399 with 0x11ec, rather than supporting both.

@ghen2
Copy link
Contributor

ghen2 commented Jan 17, 2025

No, they are supporting both, expecting clients to shift from X25519Kyber768Draft00 to X25519MLKEM768 over time. They will remove server-side support for Kyber when usage approaches zero.

@dcooper16
Copy link
Collaborator

Okay, I went ahead and adding a second commit to check for 0x6399. When I test against Cloudflare I am seeing both groups. With Google I am only seeing X25519MLKEM768.

@ghen2
Copy link
Contributor

ghen2 commented Jan 17, 2025

Strange, I can still connect to google.com with x25519_kyber768 though (using openssl+oqsprovider).

@dcooper16
Copy link
Collaborator

Strange, I can still connect to google.com with x25519_kyber768 though (using openssl+oqsprovider).

I see there was an question about Google in April 2024. Is it is possible that the connection to google.com is over QUIC rather than TLS?

Why do you mark [X25519Kyber768Draft00] as 128 bits, but the MLKEM768 equivalent as 192 bits? It's virtually the same algorithm.

I don't think it actually matters, as I don't think that information is being used at the moment, and if it were used, then anything 128 bits or above would be considered good. But, I just choose treat X25519Kyber768Draft00 as if Kyber768 doesn't add security. It's true that I don't have any reason to think there is a significant security difference between round 3 Kyber768 and ML-KEM 768, but I prefer to give more credit for use of the final version.

@ghen2
Copy link
Contributor

ghen2 commented Jan 17, 2025

I see there was an question about Google in April 2024. Is it is possible that the connection to google.com is over QUIC rather than TLS?

I tested with plain curl --curves x25519_kyber768 www.google.com (curl using openssl with oqs-provider), not using QUIC.
I also just now checked with Chrome (which can toggle between Kyber and MLKEM hybrids through feature flags), which does use QUIC. Both can connect with either variant.

So it's strange that your check can't detect 0x6399 with google, but does detect it with Cloudflare (who use boringssl just like google).

@drwetter
Copy link
Collaborator Author

With the PR #2622 merged, I am closing this.

Not sure about the status of the handshakes of the browsers using TCP? Using https://pq.cloudflareresearch.com I only see X25519MLKEM768 and X25519Kyber768Draft00 using QUIC.

@drwetter
Copy link
Collaborator Author

drwetter commented Apr 9, 2025

preliminary result from #2731 (sorry, @ghen2 using it as an example ;-) )

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.2 upcoming release
Projects
None yet
Development

No branches or pull requests

6 participants