tris: add new key schedule implementation
In order to reduce repetitive complexity (extract handshake context, pass the right secrets around to calculate a secret and build a cipher), create a new type that tracks the hash type, the handshake context and intermediate secrets. Advantages: facilitates reuse between client and server code, makes it easier to update labels for draft-19, makes it easier to add central KeyLogWriter functionality.
This commit is contained in:
vanhempi
079992e500
commit
9f9f06de80
78
13.go
78
13.go
@ -28,6 +28,84 @@ import (
|
||||
// server sends to a TLS 1.3 client, who will use each only once.
|
||||
const numSessionTickets = 2
|
||||
|
||||
type secretLabel int
|
||||
|
||||
const (
|
||||
secretResumptionPskBinder secretLabel = iota
|
||||
secretEarlyClient
|
||||
secretHandshakeClient
|
||||
secretHandshakeServer
|
||||
secretApplicationClient
|
||||
secretApplicationServer
|
||||
secretResumption
|
||||
)
|
||||
|
||||
type keySchedule13 struct {
|
||||
suite *cipherSuite
|
||||
transcriptHash hash.Hash // uses the cipher suite hash algo
|
||||
secret []byte // Current secret as used for Derive-Secret
|
||||
handshakeCtx []byte // cached handshake context, invalidated on updates.
|
||||
}
|
||||
|
||||
func newKeySchedule13(suite *cipherSuite) *keySchedule13 {
|
||||
return &keySchedule13{
|
||||
suite: suite,
|
||||
transcriptHash: hashForSuite(suite).New(),
|
||||
}
|
||||
}
|
||||
|
||||
// setSecret sets the early/handshake/master secret based on the given secret
|
||||
// (IKM). The salt is based on previous secrets (nil for the early secret).
|
||||
func (ks *keySchedule13) setSecret(secret []byte) {
|
||||
hash := hashForSuite(ks.suite)
|
||||
salt := ks.secret
|
||||
ks.secret = hkdfExtract(hash, secret, salt)
|
||||
}
|
||||
|
||||
// write appends the data to the transcript hash context.
|
||||
func (ks *keySchedule13) write(data []byte) {
|
||||
ks.handshakeCtx = nil
|
||||
ks.transcriptHash.Write(data)
|
||||
}
|
||||
|
||||
func (ks *keySchedule13) getLabel(secretLabel secretLabel) (label string) {
|
||||
switch secretLabel {
|
||||
case secretResumptionPskBinder:
|
||||
label = "resumption psk binder key"
|
||||
case secretEarlyClient:
|
||||
label = "client early traffic secret"
|
||||
case secretHandshakeClient:
|
||||
label = "client handshake traffic secret"
|
||||
case secretHandshakeServer:
|
||||
label = "server handshake traffic secret"
|
||||
case secretApplicationClient:
|
||||
label = "client application traffic secret"
|
||||
case secretApplicationServer:
|
||||
label = "server application traffic secret"
|
||||
case secretResumption:
|
||||
label = "resumption master secret"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// deriveSecret returns the secret derived from the handshake context and label.
|
||||
func (ks *keySchedule13) deriveSecret(secretLabel secretLabel) []byte {
|
||||
label := ks.getLabel(secretLabel)
|
||||
if ks.handshakeCtx == nil {
|
||||
ks.handshakeCtx = ks.transcriptHash.Sum(nil)
|
||||
}
|
||||
hash := hashForSuite(ks.suite)
|
||||
return hkdfExpandLabel(hash, ks.secret, ks.handshakeCtx, label, hash.Size())
|
||||
}
|
||||
|
||||
func (ks *keySchedule13) prepareCipher(secretLabel secretLabel) (interface{}, []byte) {
|
||||
trafficSecret := ks.deriveSecret(secretLabel)
|
||||
hash := hashForSuite(ks.suite)
|
||||
key := hkdfExpandLabel(hash, trafficSecret, nil, "key", ks.suite.keyLen)
|
||||
iv := hkdfExpandLabel(hash, trafficSecret, nil, "iv", 12)
|
||||
return ks.suite.aead(key, iv), trafficSecret
|
||||
}
|
||||
|
||||
func (hs *serverHandshakeState) doTLS13Handshake() error {
|
||||
config := hs.c.config
|
||||
c := hs.c
|
||||
|
Ladataan…
Viittaa uudesa ongelmassa
Block a user