Files
quic-go/crypto/key_derivation.go
Lucas Clemente 86b4ffdaaf use chacha20poly1305 instead of AES and include cert in key derivation
Unfortunately QUIC uses non-standard tag sizes with both AES-GCM and
Poly1305. Adopting AES-GCM seems much harder, so I changed it to
Chacha20Poly1305 and only made some slight changes to an existing algo.
This should probably be double-checked at some point.
2016-04-14 23:44:31 +02:00

45 lines
1.1 KiB
Go

package crypto
import (
"bytes"
"crypto/sha256"
"io"
"github.com/lucas-clemente/quic-go/protocol"
"github.com/lucas-clemente/quic-go/utils"
"golang.org/x/crypto/hkdf"
)
// DeriveKeysChacha20 derives the client and server keys and creates a matching chacha20poly1305 instance
func DeriveKeysChacha20(sharedSecret, nonces []byte, connID protocol.ConnectionID, chlo []byte, scfg []byte, cert []byte) (AEAD, error) {
var info bytes.Buffer
info.Write([]byte("QUIC key expansion\x00"))
utils.WriteUint64(&info, uint64(connID))
info.Write(chlo)
info.Write(scfg)
info.Write(cert)
r := hkdf.New(sha256.New, sharedSecret, nonces, info.Bytes())
otherKey := make([]byte, 32)
myKey := make([]byte, 32)
otherIV := make([]byte, 4)
myIV := make([]byte, 4)
if _, err := io.ReadFull(r, otherKey); err != nil {
return nil, err
}
if _, err := io.ReadFull(r, myKey); err != nil {
return nil, err
}
if _, err := io.ReadFull(r, otherIV); err != nil {
return nil, err
}
if _, err := io.ReadFull(r, myIV); err != nil {
return nil, err
}
return NewAEADChacha20Poly1305(otherKey, myKey, otherIV, myIV)
}