Thanks to visit codestin.com
Credit goes to github.com

Skip to content

crypto/tls: X25519MLKEM768 not enabled by default #75453

@jmayclin

Description

@jmayclin

Go version

go version go1.25.1 linux/arm64

Output of go env in your module/workspace:

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2947797469=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='arm64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/root/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_arm64'
GOVCS=''
GOVERSION='go1.25.1'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

I did a TLS handshake between a go client and a go server using library defaults and Go 1.25.

A reproducer is available here: https://github.com/jmayclin/go-default-kx-group

To reproducer is significantly trimmed down, but you can see the decrypted handshake here: https://github.com/jmayclin/wire/blob/main/brass-aphid-wire/resources/traces/go_go1.25.1.log

What did you see happen?

I saw that x25519 was negotiated.

=== RUN   TestServerAuth
go1.25.1
2025/09/13 01:12:21 &[]
Negotiated CurveID: X25519
2025/09/13 01:12:21 server handshake finished
--- PASS: TestServerAuth (0.00s)
PASS
ok      tls-transcript  0.004s

What did you expect to see?

I expected to see X25519MLKEM768 negotiated. I expected this because the following github issue is closed: #69985

This is also mentioned in the Go 1.24 release notes

The new post-quantum X25519MLKEM768 key exchange mechanism is now supported and is enabled by default when Config.CurvePreferences is nil. GODEBUG setting tlsmlkem=0 reverts the default.
https://tip.golang.org/doc/go1.24#cryptotlspkgcryptotls

I confirmed in my reproducer that when I explicitly enable GODEBUG=tlsmlkem=1, then X2519MLKEM768 is negotiated

Running the test with GODEBUG=tlsmlkem=1\n

=== RUN   TestServerAuth
go1.25.1
2025/09/13 01:06:28 &[]
Negotiated CurveID: X25519MLKEM768
2025/09/13 01:06:28 server handshake finished
--- PASS: TestServerAuth (0.00s)
PASS
ok      tls-transcript  0.005s

Note that this is one of several default behaviors that I was confused by. The 1.25 client also offered

  • rsa key exchange
  • 3des ciphers
  • SHA1 signatures

This is unexpected because of the following items in the 1.25 go defaults table

	{Name: "tls3des", Package: "crypto/tls", Changed: 23, Old: "1"}, // implies 3des now 0/off by default
	{Name: "tlsmaxrsasize", Package: "crypto/tls"},
	{Name: "tlsmlkem", Package: "crypto/tls", Changed: 24, Old: "0", Opaque: true},
	{Name: "tlsrsakex", Package: "crypto/tls", Changed: 22, Old: "1"}, //implies rsakx now 0/off by default
	{Name: "tlssha1", Package: "crypto/tls", Changed: 25, Old: "1"}, //implies SHA1 sig now 0/off by default

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions