randombit / botan

Cryptography Toolkit
https://botan.randombit.net
BSD 2-Clause "Simplified" License
2.6k stars 570 forks source link

Enable the post-quantum x25519+ML-KEM-768 TLS 1.3 ciphersuite by default #4305

Open randombit opened 3 months ago

randombit commented 3 months ago

Tested with cloudflare.com, google.com and ourselves.

This adjusts the default logic for both which groups to offer and which group to select during negotiation.

For offering, we send the first pure ECC group in the preference list. This avoids sending large PQ shares to servers that don't support them. If the client for whatever reason does not have any pure ECC groups, then we send a share of whatever their top preference is.

On the server side, if the client indicated support for any mutually supported PQ algorithm, we always select it, even if the client sent some other type of keyshare. Previously we would always prefer to select a group that the client sent a share of, to reduce round trips.

coveralls commented 3 months ago

Coverage Status

coverage: 91.045% (-0.03%) from 91.072% when pulling 2ea709294c91694d5f879a0aa9e72a67c3e6a737 on jack/enable-pqc into bd045b1a02002b9a2f3f314da0ee55912aebb23f on master.

randombit commented 3 months ago

Something is wrong - I know I tested that our client connecting to our server would negotiate Kyber (highly relevant since Botan being on both sides of the connection is very common) but now this doesn't work ....

randombit commented 3 months ago

Oh I see. I tested us<->us in my initial attempt which put Kyber at the absolute top of the preference list. However I realized later this caused us to send a large keyshare that is ignored much of the time, which is non-optimal.

But it seems - unlike the stacks in google.com and cloudflare.com - we will, if we receive a keyshare for say x25519, we won't ignore it even if the top preference of both the client and the server are Kyber - we just negotiate x25519. So we won't negotiate Kyber with ourselves :sob:

randombit commented 3 months ago

OK I think we just need to adjust the logic in Policy::choose_key_exchange_group.

reneme commented 3 months ago

OK I think we just need to adjust the logic in Policy::choose_key_exchange_group.

... I was about to say that. Currently, the code there optimizes for round-trips and avoids sending a HelloRetryRequest whenever it can. I.e.: it will go for the non-PQ group if it is offered and fits with our supported groups.

randombit commented 3 months ago

I'll take a look at that BoringSSL and co do here. I expect it looks something like a 2-tier selection

reneme commented 3 months ago

I expect it looks something like a 2-tier selection

Sounds reasonable to me as a default policy. I was thinking to propose an additional policy setting like prefer_pqc_groups_when_possible(). But then again: if one is explicitly offering PQC support at this time, I guess they are also fine with using it anyway.

randombit commented 3 months ago

prefer_pqc_groups_when_possible() might be worth having as an easy to use toggle for those who are willing to use PQC but would like to save the round trip where possible.

randombit commented 3 months ago

OTOH we already have a lot of fucking policy toggles :sweat_smile: