Skip to content
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

Post-quantum key agreement X25519Kyber768 disabled in Go 1.23 #6540

Closed
bwesterb opened this issue Aug 26, 2024 · 8 comments
Closed

Post-quantum key agreement X25519Kyber768 disabled in Go 1.23 #6540

bwesterb opened this issue Aug 26, 2024 · 8 comments
Labels
discussion 💬 The right solution needs to be found feature ⚙️ New feature or request

Comments

@bwesterb
Copy link
Contributor

bwesterb commented Aug 26, 2024

Go 1.23 adds support for and enables post-quantum key agreement:

The experimental post-quantum key exchange mechanism X25519Kyber768Draft00 is now enabled by default when Config.CurvePreferences is nil. The default can be reverted by adding tlskyber=0 to the GODEBUG environment variable.

Go 1.23 doesn't expose a CurveID, so setting CurvePreferences (as Caddy does) disables Kyber.

(The reason for not exposing the CurveID, is that X25519Kyber768 is a preliminary key agreement that doesn't use ML-KEM, the final version of Kyber, that wasn't out when X25519Kyber768 was proposed. X25519Kyber768 will be phased out, but that will takes months if not more than a year.)

I see two options.

  1. Ignore X25519Kyber768.
  2. Modify Caddy to not set CurvePreferences when the user doesn't specify any curves.

I prefer the second and am happy to write a PR.

cc @sam-bee @FiloSottile

@caddyserver caddyserver deleted a comment Aug 26, 2024
@sam-bee
Copy link

sam-bee commented Aug 26, 2024

I agree that it would be good if Caddy could offer post-quantum cryptography support. Ignoring X25519Kyber768 is also not my preferred option.

For the benefit of anyone joining the conversation, here is some background information:

There is a blog post here explaining why this issue is important, why PQC is being adopted now, and emphasising that adoption is increasingly widespread.

Compiling Caddy with Cloudflare's fork of Go results in working PQC, as demonstrated in this walkthrough. This is a result of @bwesterb's PR to Caddy last year. As mentioned at Gophercon UK, it seems that Caddy compiled with Go 1.23 provides no way of accessing the X25519Kyber768 functionality, because it is unexported in the Go runtime. As noted in this issue above, however, it is the default 'curve' for Go 1.23, so allowing a user of Caddy use Go's defaults would give out-of-the-box access to PQC.

It seems from looking at the Go source code in 1.22.6 that the Go defaults would be X25519, CurveP256, CurveP384, CurveP521, and in 1.23.0 they are x25519Kyber768Draft00, X25519, CurveP256, CurveP384, CurveP521. At present Caddy's default curves are X25519 and CurveP256. Using Go's defaults instead would therefore result in adding PQC where Caddy is compiled with Go 1.23.

I'm afraid I'm not sure at present what behaviour we should prefer where TLS 1.2 has been specified. Should Caddy's default curves depend on the TLS version in future? In the current implementation the two are not interdependent, but I'm unsure whether that would need to change.

@mholt
Copy link
Member

mholt commented Aug 26, 2024

Thanks for opening this discussion!

Modify Caddy to not set CurvePreferences when the user doesn't specify any curves.

This sounds logical to me. We currently have a hard-coded default of those which are "fast by design (e.g. X25519) and those for which an optimized assembly implementation exists (e.g. P256)" (so those are the 2 defaults).

I think post-quantum key agreements are worth the tradeoff though, especially since it sounds like it will be a temporary restriction where we can't set CurvePreferences to get it.

@mholt mholt added the discussion 💬 The right solution needs to be found label Aug 26, 2024
@bwesterb
Copy link
Contributor Author

bwesterb commented Aug 26, 2024

Yeah, I assume X25519MLKEM768 when it lands in either 1.24 or 1.25 it'll have a CurveID. I think the current Caddy default is great. P-521 is very much overkill and much slower. But it's not that slow it's a huge DoS vector. I'll fashion a PR.

bwesterb added a commit to bwesterb/caddy that referenced this issue Aug 26, 2024
By default Go 1.23 enables X25519Kyber768, a post-quantum key agreement
method that is enabled by default on Chrome. Go 1.23 does not expose
the CurveID, so we cannot add it by specifying it in CurvePreferences.
The reason is that X25519Kyber768 is a preliminary key agreement that
will be supplanted by X25519MLKEM768. For the moment there is value
in enabling it.

A consequence of this is that by default Caddy will enable support
for P-384 and P-521.

Cf caddyserver#6540
bwesterb added a commit to bwesterb/caddy that referenced this issue Aug 26, 2024
By default Go 1.23 enables X25519Kyber768, a post-quantum key agreement
method that is enabled by default on Chrome. Go 1.23 does not expose
the CurveID, so we cannot add it by specifying it in CurvePreferences.
The reason is that X25519Kyber768 is a preliminary key agreement that
will be supplanted by X25519MLKEM768. For the moment there is value
in enabling it.

A consequence of this is that by default Caddy will enable support
for P-384 and P-521.

This PR also removes the special code to add support for X25519Kyber768
via the Cloudflare Go branch.

Cf caddyserver#6540
bwesterb added a commit to bwesterb/caddy that referenced this issue Aug 26, 2024
By default Go 1.23 enables X25519Kyber768, a post-quantum key agreement
method that is enabled by default on Chrome. Go 1.23 does not expose
the CurveID, so we cannot add it by specifying it in CurvePreferences.
The reason is that X25519Kyber768 is a preliminary key agreement that
will be supplanted by X25519MLKEM768. For the moment there is value
in enabling it.

A consequence of this is that by default Caddy will enable support
for P-384 and P-521.

This PR also removes the special code to add support for X25519Kyber768
via the Cloudflare Go branch.

Cf caddyserver#6540
bwesterb added a commit to bwesterb/caddy that referenced this issue Aug 27, 2024
By default Go 1.23 enables X25519Kyber768, a post-quantum key agreement
method that is enabled by default on Chrome. Go 1.23 does not expose
the CurveID, so we cannot add it by specifying it in CurvePreferences.
The reason is that X25519Kyber768 is a preliminary key agreement that
will be supplanted by X25519MLKEM768. For the moment there is value
in enabling it.

A consequence of this is that by default Caddy will enable support
for P-384 and P-521.

This PR also removes the special code to add support for X25519Kyber768
via the Cloudflare Go branch.

Cf caddyserver#6540
@bwesterb
Copy link
Contributor Author

Unfortunately Go 1.23 only enables Kyber if the go directive is 1.23 or higher. This is at odds with #6318

@francislavoie
Copy link
Member

We prefer to keep two Go versions supported in Caddy to ease the transition for plugins and users, otherwise users may suddenly be stuck having to upgrade Go before they're otherwise ready to. So I think this should be shelved until 1.24 is out when we can bump Caddy's minimum to 1.23 (i.e. roughly 6 months from now). You can bump it in a fork to 1.23 if you need it though, pretty easy to do and you can still use xcaddy to build.

@FiloSottile
Copy link

Unfortunately Go 1.23 only enables Kyber if the go directive is 1.23 or higher. This is at odds with #6318

You can force it on with

//go:debug tlskyber=1

The go.mod version just sets the defaults of the GODEBUGs.

See https://go.dev/doc/godebug.

@mholt
Copy link
Member

mholt commented Aug 27, 2024

Oh nice, if that ^ works, maybe we can accept this change sooner than 1.24.

bwesterb added a commit to bwesterb/caddy that referenced this issue Aug 27, 2024
By default Go 1.23 enables X25519Kyber768, a post-quantum key agreement
method that is enabled by default on Chrome. Go 1.23 does not expose
the CurveID, so we cannot add it by specifying it in CurvePreferences.
The reason is that X25519Kyber768 is a preliminary key agreement that
will be supplanted by X25519MLKEM768. For the moment there is value
in enabling it.

A consequence of this is that by default Caddy will enable support
for P-384 and P-521.

This PR also removes the special code to add support for X25519Kyber768
via the Cloudflare Go branch.

Cf caddyserver#6540
bwesterb added a commit to bwesterb/caddy that referenced this issue Aug 27, 2024
By default Go 1.23 enables X25519Kyber768, a post-quantum key agreement
method that is enabled by default on Chrome. Go 1.23 does not expose
the CurveID, so we cannot add it by specifying it in CurvePreferences.
The reason is that X25519Kyber768 is a preliminary key agreement that
will be supplanted by X25519MLKEM768. For the moment there is value
in enabling it.

A consequence of this is that by default Caddy will enable support
for P-384 and P-521.

This PR also removes the special code to add support for X25519Kyber768
via the Cloudflare Go branch.

Cf caddyserver#6540
@bwesterb
Copy link
Contributor Author

Seems to work. Thanks @FiloSottile.

mholt pushed a commit that referenced this issue Aug 27, 2024
By default Go 1.23 enables X25519Kyber768, a post-quantum key agreement
method that is enabled by default on Chrome. Go 1.23 does not expose
the CurveID, so we cannot add it by specifying it in CurvePreferences.
The reason is that X25519Kyber768 is a preliminary key agreement that
will be supplanted by X25519MLKEM768. For the moment there is value
in enabling it.

A consequence of this is that by default Caddy will enable support
for P-384 and P-521.

This PR also removes the special code to add support for X25519Kyber768
via the Cloudflare Go branch.

Cf #6540
@mholt mholt closed this as completed Aug 27, 2024
@mholt mholt added the feature ⚙️ New feature or request label Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion 💬 The right solution needs to be found feature ⚙️ New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants