crypto/internal/fips/tls13: implement TLS 1.3 KDF

The new implementation encodes the key schedule into the type system,
which is actually nicer than what we had before.

For #69536

Change-Id: Iddab62c2aae40bc2425a155443576bb9b7aafe03
Reviewed-on: https://go-review.googlesource.com/c/go/+/626836
Reviewed-by: Russ Cox <rsc@golang.org>
Reviewed-by: Roland Shoemaker <roland@golang.org>
Commit-Queue: Roland Shoemaker <roland@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Filippo Valsorda <filippo@golang.org>
Reviewed-by: Daniel McCarney <daniel@binaryparadox.net>
This commit is contained in:
Filippo Valsorda 2024-11-09 16:23:22 +01:00 committed by Gopher Robot
parent b06b8816fa
commit 80b8ff4aa9
5 changed files with 114 additions and 248 deletions

View file

@ -9,6 +9,7 @@ import (
"context"
"crypto"
"crypto/hmac"
"crypto/internal/fips/tls13"
"crypto/internal/mlkem768"
"crypto/rsa"
"errors"
@ -35,10 +36,10 @@ type serverHandshakeStateTLS13 struct {
suite *cipherSuiteTLS13
cert *Certificate
sigAlg SignatureScheme
earlySecret []byte
earlySecret *tls13.EarlySecret
sharedKey []byte
handshakeSecret []byte
masterSecret []byte
handshakeSecret *tls13.HandshakeSecret
masterSecret *tls13.MasterSecret
trafficSecret []byte // client_application_traffic_secret_0
transcript hash.Hash
clientFinished []byte
@ -382,8 +383,8 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
}
}
hs.earlySecret = hs.suite.extract(sessionState.secret, nil)
binderKey := hs.suite.deriveSecret(hs.earlySecret, resumptionBinderLabel, nil)
hs.earlySecret = tls13.NewEarlySecret(hs.suite.hash.New, sessionState.secret)
binderKey := hs.earlySecret.ResumptionBinderKey()
// Clone the transcript in case a HelloRetryRequest was recorded.
transcript := cloneHash(hs.transcript, hs.suite.hash)
if transcript == nil {
@ -411,7 +412,7 @@ func (hs *serverHandshakeStateTLS13) checkForResumption() error {
if err := transcriptMsg(hs.clientHello, transcript); err != nil {
return err
}
earlyTrafficSecret := hs.suite.deriveSecret(hs.earlySecret, clientEarlyTrafficLabel, transcript)
earlyTrafficSecret := hs.earlySecret.ClientEarlyTrafficSecret(transcript)
c.quicSetReadSecret(QUICEncryptionLevelEarly, hs.suite.id, earlyTrafficSecret)
}
@ -649,16 +650,13 @@ func (hs *serverHandshakeStateTLS13) sendServerParameters() error {
earlySecret := hs.earlySecret
if earlySecret == nil {
earlySecret = hs.suite.extract(nil, nil)
earlySecret = tls13.NewEarlySecret(hs.suite.hash.New, nil)
}
hs.handshakeSecret = hs.suite.extract(hs.sharedKey,
hs.suite.deriveSecret(earlySecret, "derived", nil))
hs.handshakeSecret = earlySecret.HandshakeSecret(hs.sharedKey)
clientSecret := hs.suite.deriveSecret(hs.handshakeSecret,
clientHandshakeTrafficLabel, hs.transcript)
clientSecret := hs.handshakeSecret.ClientHandshakeTrafficSecret(hs.transcript)
c.in.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, clientSecret)
serverSecret := hs.suite.deriveSecret(hs.handshakeSecret,
serverHandshakeTrafficLabel, hs.transcript)
serverSecret := hs.handshakeSecret.ServerHandshakeTrafficSecret(hs.transcript)
c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelHandshake, serverSecret)
if c.quic != nil {
@ -783,13 +781,10 @@ func (hs *serverHandshakeStateTLS13) sendServerFinished() error {
// Derive secrets that take context through the server Finished.
hs.masterSecret = hs.suite.extract(nil,
hs.suite.deriveSecret(hs.handshakeSecret, "derived", nil))
hs.masterSecret = hs.handshakeSecret.MasterSecret()
hs.trafficSecret = hs.suite.deriveSecret(hs.masterSecret,
clientApplicationTrafficLabel, hs.transcript)
serverSecret := hs.suite.deriveSecret(hs.masterSecret,
serverApplicationTrafficLabel, hs.transcript)
hs.trafficSecret = hs.masterSecret.ClientApplicationTrafficSecret(hs.transcript)
serverSecret := hs.masterSecret.ServerApplicationTrafficSecret(hs.transcript)
c.out.setTrafficSecret(hs.suite, QUICEncryptionLevelApplication, serverSecret)
if c.quic != nil {
@ -855,8 +850,7 @@ func (hs *serverHandshakeStateTLS13) sendSessionTickets() error {
return err
}
c.resumptionSecret = hs.suite.deriveSecret(hs.masterSecret,
resumptionLabel, hs.transcript)
c.resumptionSecret = hs.masterSecret.ResumptionMasterSecret(hs.transcript)
if !hs.shouldSendSessionTickets() {
return nil
@ -871,7 +865,7 @@ func (c *Conn) sendSessionTicket(earlyData bool, extra [][]byte) error {
}
// ticket_nonce, which must be unique per connection, is always left at
// zero because we only ever send one ticket per connection.
psk := suite.expandLabel(c.resumptionSecret, "resumption",
psk := tls13.ExpandLabel(suite.hash.New, c.resumptionSecret, "resumption",
nil, suite.hash.Size())
m := new(newSessionTicketMsgTLS13)