drwetter / testssl.sh

Testing TLS/SSL encryption anywhere on any port
https://testssl.sh
GNU General Public License v2.0
7.91k stars 1.02k forks source link

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

Open drwetter opened 1 year ago

drwetter commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

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 commented 1 year ago

very cool!

dcooper16 commented 1 year ago

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 commented 1 year ago

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

drwetter commented 1 year ago

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

image
dcooper16 commented 1 year ago

I haven't had a chance to look into this in detail, but I found another source for information on experimenting with post-quantum cryptography in TLS:

https://www.wolfssl.com/documentation/manuals/wolfssl/appendix07.html https://test.openquantumsafe.org/ https://github.com/open-quantum-safe/openssl/blob/OQS-OpenSSL_1_1_1-stable/oqs-template/oqs-kem-info.md https://github.com/open-quantum-safe/openssl/blob/OQS-OpenSSL_1_1_1-stable/oqs-template/oqs-sig-info.md

amran28 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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

okoeroo commented 2 months ago

Is there any way to help on this issue?

drwetter commented 3 weeks ago

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?

dcooper16 commented 3 weeks ago

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 commented 2 weeks ago

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

ghen2 commented 1 week ago

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.