package handshake import ( "crypto/cipher" "encoding/binary" "github.com/quic-go/quic-go/internal/protocol" "github.com/quic-go/quic-go/internal/utils" ) func createAEAD(suite *cipherSuite, trafficSecret []byte, v protocol.VersionNumber) cipher.AEAD { keyLabel := hkdfLabelKeyV1 ivLabel := hkdfLabelIVV1 if v == protocol.Version2 { keyLabel = hkdfLabelKeyV2 ivLabel = hkdfLabelIVV2 } key := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, keyLabel, suite.KeyLen) iv := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, ivLabel, suite.IVLen()) return suite.AEAD(key, iv) } type longHeaderSealer struct { aead cipher.AEAD headerProtector headerProtector // use a single slice to avoid allocations nonceBuf []byte } var _ LongHeaderSealer = &longHeaderSealer{} func newLongHeaderSealer(aead cipher.AEAD, headerProtector headerProtector) LongHeaderSealer { return &longHeaderSealer{ aead: aead, headerProtector: headerProtector, nonceBuf: make([]byte, aead.NonceSize()), } } func (s *longHeaderSealer) Seal(dst, src []byte, pn protocol.PacketNumber, ad []byte) []byte { binary.BigEndian.PutUint64(s.nonceBuf[len(s.nonceBuf)-8:], uint64(pn)) // The AEAD we're using here will be the qtls.aeadAESGCM13. // It uses the nonce provided here and XOR it with the IV. return s.aead.Seal(dst, s.nonceBuf, src, ad) } func (s *longHeaderSealer) EncryptHeader(sample []byte, firstByte *byte, pnBytes []byte) { s.headerProtector.EncryptHeader(sample, firstByte, pnBytes) } func (s *longHeaderSealer) Overhead() int { return s.aead.Overhead() } type longHeaderOpener struct { aead cipher.AEAD headerProtector headerProtector highestRcvdPN protocol.PacketNumber // highest packet number received (which could be successfully unprotected) // use a single slice to avoid allocations nonceBuf []byte } var _ LongHeaderOpener = &longHeaderOpener{} func newLongHeaderOpener(aead cipher.AEAD, headerProtector headerProtector) LongHeaderOpener { return &longHeaderOpener{ aead: aead, headerProtector: headerProtector, nonceBuf: make([]byte, aead.NonceSize()), } } func (o *longHeaderOpener) DecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber { return protocol.DecodePacketNumber(wirePNLen, o.highestRcvdPN, wirePN) } func (o *longHeaderOpener) Open(dst, src []byte, pn protocol.PacketNumber, ad []byte) ([]byte, error) { binary.BigEndian.PutUint64(o.nonceBuf[len(o.nonceBuf)-8:], uint64(pn)) // The AEAD we're using here will be the qtls.aeadAESGCM13. // It uses the nonce provided here and XOR it with the IV. dec, err := o.aead.Open(dst, o.nonceBuf, src, ad) if err == nil { o.highestRcvdPN = utils.Max(o.highestRcvdPN, pn) } else { err = ErrDecryptionFailed } return dec, err } func (o *longHeaderOpener) DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) { o.headerProtector.DecryptHeader(sample, firstByte, pnBytes) }