mirror of
https://github.com/cloudflare/cloudflared.git
synced 2025-07-30 11:00:11 +00:00
RTG-1339 Support post-quantum hybrid key exchange
Func spec: https://wiki.cfops.it/x/ZcBKHw
This commit is contained in:

committed by
Devin Carr

parent
3e0ff3a771
commit
11cbff4ff7
71
vendor/github.com/marten-seemann/qtls-go1-19/handshake_client_tls13.go
generated
vendored
71
vendor/github.com/marten-seemann/qtls-go1-19/handshake_client_tls13.go
generated
vendored
@@ -12,10 +12,12 @@ import (
|
||||
"crypto/rsa"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
circlKem "github.com/cloudflare/circl/kem"
|
||||
"golang.org/x/crypto/cryptobyte"
|
||||
)
|
||||
|
||||
@@ -24,7 +26,8 @@ type clientHandshakeStateTLS13 struct {
|
||||
ctx context.Context
|
||||
serverHello *serverHelloMsg
|
||||
hello *clientHelloMsg
|
||||
ecdheParams ecdheParameters
|
||||
|
||||
keySharePrivate clientKeySharePrivate
|
||||
|
||||
session *clientSessionState
|
||||
earlySecret []byte
|
||||
@@ -44,6 +47,8 @@ type clientHandshakeStateTLS13 struct {
|
||||
func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||
c := hs.c
|
||||
|
||||
startTime := time.Now()
|
||||
|
||||
if needFIPS() {
|
||||
return errors.New("tls: internal error: TLS 1.3 reached in FIPS mode")
|
||||
}
|
||||
@@ -56,7 +61,7 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||
}
|
||||
|
||||
// Consistency check on the presence of a keyShare and its parameters.
|
||||
if hs.ecdheParams == nil || len(hs.hello.keyShares) != 1 {
|
||||
if hs.keySharePrivate == nil || len(hs.hello.keyShares) != 1 {
|
||||
return c.sendAlert(alertInternalError)
|
||||
}
|
||||
|
||||
@@ -107,6 +112,12 @@ func (hs *clientHandshakeStateTLS13) handshake() error {
|
||||
return err
|
||||
}
|
||||
|
||||
raiseCFEvent(&cfEventHandshake{
|
||||
serverSide: false,
|
||||
duration: time.Since(startTime),
|
||||
kex: hs.serverHello.serverShare.group,
|
||||
})
|
||||
|
||||
atomic.StoreUint32(&c.handshakeStatus, 1)
|
||||
|
||||
return nil
|
||||
@@ -184,6 +195,8 @@ func (hs *clientHandshakeStateTLS13) sendDummyChangeCipherSpec() error {
|
||||
func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
||||
c := hs.c
|
||||
|
||||
raiseCFEvent(&cfEventHRR{serverSide: false})
|
||||
|
||||
// The first ClientHello gets double-hashed into the transcript upon a
|
||||
// HelloRetryRequest. (The idea is that the server might offload transcript
|
||||
// storage to the client in the cookie.) See RFC 8446, Section 4.4.1.
|
||||
@@ -225,21 +238,38 @@ func (hs *clientHandshakeStateTLS13) processHelloRetryRequest() error {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return errors.New("tls: server selected unsupported group")
|
||||
}
|
||||
if hs.ecdheParams.CurveID() == curveID {
|
||||
if clientKeySharePrivateCurveID(hs.keySharePrivate) == curveID {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return errors.New("tls: server sent an unnecessary HelloRetryRequest key_share")
|
||||
}
|
||||
if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
|
||||
c.sendAlert(alertInternalError)
|
||||
return errors.New("tls: CurvePreferences includes unsupported curve")
|
||||
if scheme := curveIdToCirclScheme(curveID); scheme != nil {
|
||||
pk, sk, err := generateKemKeyPair(scheme, c.config.rand())
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return fmt.Errorf("HRR generateKeyPair %s: %w",
|
||||
scheme.Name(), err)
|
||||
}
|
||||
packedPk, err := pk.MarshalBinary()
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return fmt.Errorf("HRR pack circl public key %s: %w",
|
||||
scheme.Name(), err)
|
||||
}
|
||||
hs.keySharePrivate = sk
|
||||
hs.hello.keyShares = []keyShare{{group: curveID, data: packedPk}}
|
||||
} else {
|
||||
if _, ok := curveForCurveID(curveID); curveID != X25519 && !ok {
|
||||
c.sendAlert(alertInternalError)
|
||||
return errors.New("tls: CurvePreferences includes unsupported curve")
|
||||
}
|
||||
params, err := generateECDHEParameters(c.config.rand(), curveID)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
hs.keySharePrivate = params
|
||||
hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
|
||||
}
|
||||
params, err := generateECDHEParameters(c.config.rand(), curveID)
|
||||
if err != nil {
|
||||
c.sendAlert(alertInternalError)
|
||||
return err
|
||||
}
|
||||
hs.ecdheParams = params
|
||||
hs.hello.keyShares = []keyShare{{group: curveID, data: params.PublicKey()}}
|
||||
}
|
||||
|
||||
hs.hello.raw = nil
|
||||
@@ -318,7 +348,7 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return errors.New("tls: server did not send a key share")
|
||||
}
|
||||
if hs.serverHello.serverShare.group != hs.ecdheParams.CurveID() {
|
||||
if hs.serverHello.serverShare.group != clientKeySharePrivateCurveID(hs.keySharePrivate) {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return errors.New("tls: server selected unsupported group")
|
||||
}
|
||||
@@ -356,7 +386,18 @@ func (hs *clientHandshakeStateTLS13) processServerHello() error {
|
||||
func (hs *clientHandshakeStateTLS13) establishHandshakeKeys() error {
|
||||
c := hs.c
|
||||
|
||||
sharedKey := hs.ecdheParams.SharedKey(hs.serverHello.serverShare.data)
|
||||
var sharedKey []byte
|
||||
if params, ok := hs.keySharePrivate.(ecdheParameters); ok {
|
||||
sharedKey = params.SharedKey(hs.serverHello.serverShare.data)
|
||||
} else if sk, ok := hs.keySharePrivate.(circlKem.PrivateKey); ok {
|
||||
var err error
|
||||
sharedKey, err = sk.Scheme().Decapsulate(sk, hs.serverHello.serverShare.data)
|
||||
if err != nil {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return fmt.Errorf("%s decaps: %w", sk.Scheme().Name(), err)
|
||||
}
|
||||
}
|
||||
|
||||
if sharedKey == nil {
|
||||
c.sendAlert(alertIllegalParameter)
|
||||
return errors.New("tls: invalid server key share")
|
||||
|
Reference in New Issue
Block a user