TUN-8855: Update PQ curve preferences

## Summary

Nowadays, Cloudflared only supports X25519Kyber768Draft00 (0x6399,25497) but older versions may use different preferences.

For FIPS compliance we are required to use P256Kyber768Draft00 (0xfe32,65074) which is supported in our internal fork of [Go-Boring-1.22.10](https://bitbucket.cfdata.org/projects/PLAT/repos/goboring/browse?at=refs/heads/go-boring/1.22.10 "Follow link").

In the near future, Go will support by default the X25519MLKEM768 (0x11ec,4588) given this we may drop the usage of our public fork of GO.

To summarise:

* Cloudflared FIPS: QUIC_CURVE_PREFERENCES=65074
* Cloudflared non-FIPS: QUIC_CURVE_PREFERENCES=4588

Closes TUN-8855
This commit is contained in:
Luis Neto
2025-01-30 05:02:47 -08:00
committed by João "Pisco" Fernandes
parent bfdb0c76dc
commit 31a870b291
11 changed files with 150 additions and 41 deletions

View File

@@ -7,30 +7,53 @@ import (
"github.com/cloudflare/cloudflared/features"
)
// When experimental post-quantum tunnels are enabled, and we're hitting an
// issue creating the tunnel, we'll report the first error
// to https://pqtunnels.cloudflareresearch.com.
const (
PQKex = tls.CurveID(0x6399) // X25519Kyber768Draft00
PQKexName = "X25519Kyber768Draft00"
X25519Kyber768Draft00PQKex = tls.CurveID(0x6399) // X25519Kyber768Draft00
X25519Kyber768Draft00PQKexName = "X25519Kyber768Draft00"
P256Kyber768Draft00PQKex = tls.CurveID(0xfe32) // P256Kyber768Draft00
P256Kyber768Draft00PQKexName = "P256Kyber768Draft00"
X25519MLKEM768PQKex = tls.CurveID(0x11ec) // X25519MLKEM768
X25519MLKEM768PQKexName = "X25519MLKEM768"
)
func curvePreference(pqMode features.PostQuantumMode, currentCurve []tls.CurveID) ([]tls.CurveID, error) {
var (
nonFipsPostQuantumStrictPKex []tls.CurveID = []tls.CurveID{X25519MLKEM768PQKex, X25519Kyber768Draft00PQKex}
nonFipsPostQuantumPreferPKex []tls.CurveID = []tls.CurveID{X25519MLKEM768PQKex, X25519Kyber768Draft00PQKex}
fipsPostQuantumStrictPKex []tls.CurveID = []tls.CurveID{P256Kyber768Draft00PQKex}
fipsPostQuantumPreferPKex []tls.CurveID = []tls.CurveID{P256Kyber768Draft00PQKex, tls.CurveP256}
)
func removeDuplicates(curves []tls.CurveID) []tls.CurveID {
bucket := make(map[tls.CurveID]bool)
var result []tls.CurveID
for _, curve := range curves {
if _, ok := bucket[curve]; !ok {
bucket[curve] = true
result = append(result, curve)
}
}
return result
}
func curvePreference(pqMode features.PostQuantumMode, fipsEnabled bool, currentCurve []tls.CurveID) ([]tls.CurveID, error) {
switch pqMode {
case features.PostQuantumStrict:
// If the user passes the -post-quantum flag, we override
// CurvePreferences to only support hybrid post-quantum key agreements.
return []tls.CurveID{PQKex}, nil
if fipsEnabled {
return fipsPostQuantumStrictPKex, nil
}
return nonFipsPostQuantumStrictPKex, nil
case features.PostQuantumPrefer:
if len(currentCurve) == 0 {
return []tls.CurveID{PQKex}, nil
if fipsEnabled {
// Ensure that all curves returned are FIPS compliant.
// Moreover the first curves are post-quantum and then the
// non post-quantum.
return fipsPostQuantumPreferPKex, nil
}
if currentCurve[0] != PQKex {
return append([]tls.CurveID{PQKex}, currentCurve...), nil
}
return currentCurve, nil
curves := append(nonFipsPostQuantumPreferPKex, currentCurve...)
curves = removeDuplicates(curves)
return curves, nil
default:
return nil, fmt.Errorf("Unexpected post quantum mode")
}