mirror of
https://github.com/refraction-networking/utls.git
synced 2025-04-01 19:17:36 +03:00
This makes three related changes that work particularly well together and would require significant extra work to do separately: it replaces X25519Kyber768Draft00 with X25519MLKEM768, it makes CurvePreferences ordering crypto/tls-selected, and applies a preference to PQ key exchange methods over key shares (to mitigate downgrades). TestHandshakeServerUnsupportedKeyShare was removed because we are not rejecting unsupported key shares anymore (nor do we select them, and rejecting them actively is a MAY). It would have been nice to keep the test to check we still continue successfully, but testClientHelloFailure is broken in the face of any server-side behavior which requires writing any other messages back to the client, or reading them. Updates #69985 Fixes #69393 Change-Id: I58de76f5b8742a9bd4543fd7907c48e038507b19 Reviewed-on: https://go-review.googlesource.com/c/go/+/630775 Reviewed-by: Roland Shoemaker <roland@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Auto-Submit: Filippo Valsorda <filippo@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
99 lines
2.9 KiB
Go
99 lines
2.9 KiB
Go
// Copyright 2018 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package tls
|
|
|
|
import (
|
|
"crypto/ecdh"
|
|
"crypto/hmac"
|
|
"crypto/internal/fips140/mlkem"
|
|
"crypto/internal/fips140/tls13"
|
|
"errors"
|
|
"hash"
|
|
"io"
|
|
)
|
|
|
|
// This file contains the functions necessary to compute the TLS 1.3 key
|
|
// schedule. See RFC 8446, Section 7.
|
|
|
|
// nextTrafficSecret generates the next traffic secret, given the current one,
|
|
// according to RFC 8446, Section 7.2.
|
|
func (c *cipherSuiteTLS13) nextTrafficSecret(trafficSecret []byte) []byte {
|
|
return tls13.ExpandLabel(c.hash.New, trafficSecret, "traffic upd", nil, c.hash.Size())
|
|
}
|
|
|
|
// trafficKey generates traffic keys according to RFC 8446, Section 7.3.
|
|
func (c *cipherSuiteTLS13) trafficKey(trafficSecret []byte) (key, iv []byte) {
|
|
key = tls13.ExpandLabel(c.hash.New, trafficSecret, "key", nil, c.keyLen)
|
|
iv = tls13.ExpandLabel(c.hash.New, trafficSecret, "iv", nil, aeadNonceLength)
|
|
return
|
|
}
|
|
|
|
// finishedHash generates the Finished verify_data or PskBinderEntry according
|
|
// to RFC 8446, Section 4.4.4. See sections 4.4 and 4.2.11.2 for the baseKey
|
|
// selection.
|
|
func (c *cipherSuiteTLS13) finishedHash(baseKey []byte, transcript hash.Hash) []byte {
|
|
finishedKey := tls13.ExpandLabel(c.hash.New, baseKey, "finished", nil, c.hash.Size())
|
|
verifyData := hmac.New(c.hash.New, finishedKey)
|
|
verifyData.Write(transcript.Sum(nil))
|
|
return verifyData.Sum(nil)
|
|
}
|
|
|
|
// exportKeyingMaterial implements RFC5705 exporters for TLS 1.3 according to
|
|
// RFC 8446, Section 7.5.
|
|
func (c *cipherSuiteTLS13) exportKeyingMaterial(s *tls13.MasterSecret, transcript hash.Hash) func(string, []byte, int) ([]byte, error) {
|
|
expMasterSecret := s.ExporterMasterSecret(transcript)
|
|
return func(label string, context []byte, length int) ([]byte, error) {
|
|
return expMasterSecret.Exporter(label, context, length), nil
|
|
}
|
|
}
|
|
|
|
type keySharePrivateKeys struct {
|
|
curveID CurveID
|
|
ecdhe *ecdh.PrivateKey
|
|
mlkem *mlkem.DecapsulationKey768
|
|
}
|
|
|
|
const x25519PublicKeySize = 32
|
|
|
|
// generateECDHEKey returns a PrivateKey that implements Diffie-Hellman
|
|
// according to RFC 8446, Section 4.2.8.2.
|
|
func generateECDHEKey(rand io.Reader, curveID CurveID) (*ecdh.PrivateKey, error) {
|
|
curve, ok := curveForCurveID(curveID)
|
|
if !ok {
|
|
return nil, errors.New("tls: internal error: unsupported curve")
|
|
}
|
|
|
|
return curve.GenerateKey(rand)
|
|
}
|
|
|
|
func curveForCurveID(id CurveID) (ecdh.Curve, bool) {
|
|
switch id {
|
|
case X25519:
|
|
return ecdh.X25519(), true
|
|
case CurveP256:
|
|
return ecdh.P256(), true
|
|
case CurveP384:
|
|
return ecdh.P384(), true
|
|
case CurveP521:
|
|
return ecdh.P521(), true
|
|
default:
|
|
return nil, false
|
|
}
|
|
}
|
|
|
|
func curveIDForCurve(curve ecdh.Curve) (CurveID, bool) {
|
|
switch curve {
|
|
case ecdh.X25519():
|
|
return X25519, true
|
|
case ecdh.P256():
|
|
return CurveP256, true
|
|
case ecdh.P384():
|
|
return CurveP384, true
|
|
case ecdh.P521():
|
|
return CurveP521, true
|
|
default:
|
|
return 0, false
|
|
}
|
|
}
|