github.com/apernet/quic-go@v0.43.1-0.20240515053213-5e9e635fd9f0/internal/handshake/aead.go (about) 1 package handshake 2 3 import ( 4 "encoding/binary" 5 6 "github.com/apernet/quic-go/internal/protocol" 7 ) 8 9 func createAEAD(suite *cipherSuite, trafficSecret []byte, v protocol.Version) *xorNonceAEAD { 10 keyLabel := hkdfLabelKeyV1 11 ivLabel := hkdfLabelIVV1 12 if v == protocol.Version2 { 13 keyLabel = hkdfLabelKeyV2 14 ivLabel = hkdfLabelIVV2 15 } 16 key := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, keyLabel, suite.KeyLen) 17 iv := hkdfExpandLabel(suite.Hash, trafficSecret, []byte{}, ivLabel, suite.IVLen()) 18 return suite.AEAD(key, iv) 19 } 20 21 type longHeaderSealer struct { 22 aead *xorNonceAEAD 23 headerProtector headerProtector 24 nonceBuf [8]byte 25 } 26 27 var _ LongHeaderSealer = &longHeaderSealer{} 28 29 func newLongHeaderSealer(aead *xorNonceAEAD, headerProtector headerProtector) LongHeaderSealer { 30 if aead.NonceSize() != 8 { 31 panic("unexpected nonce size") 32 } 33 return &longHeaderSealer{ 34 aead: aead, 35 headerProtector: headerProtector, 36 } 37 } 38 39 func (s *longHeaderSealer) Seal(dst, src []byte, pn protocol.PacketNumber, ad []byte) []byte { 40 binary.BigEndian.PutUint64(s.nonceBuf[:], uint64(pn)) 41 return s.aead.Seal(dst, s.nonceBuf[:], src, ad) 42 } 43 44 func (s *longHeaderSealer) EncryptHeader(sample []byte, firstByte *byte, pnBytes []byte) { 45 s.headerProtector.EncryptHeader(sample, firstByte, pnBytes) 46 } 47 48 func (s *longHeaderSealer) Overhead() int { 49 return s.aead.Overhead() 50 } 51 52 type longHeaderOpener struct { 53 aead *xorNonceAEAD 54 headerProtector headerProtector 55 highestRcvdPN protocol.PacketNumber // highest packet number received (which could be successfully unprotected) 56 57 // use a single array to avoid allocations 58 nonceBuf [8]byte 59 } 60 61 var _ LongHeaderOpener = &longHeaderOpener{} 62 63 func newLongHeaderOpener(aead *xorNonceAEAD, headerProtector headerProtector) LongHeaderOpener { 64 if aead.NonceSize() != 8 { 65 panic("unexpected nonce size") 66 } 67 return &longHeaderOpener{ 68 aead: aead, 69 headerProtector: headerProtector, 70 } 71 } 72 73 func (o *longHeaderOpener) DecodePacketNumber(wirePN protocol.PacketNumber, wirePNLen protocol.PacketNumberLen) protocol.PacketNumber { 74 return protocol.DecodePacketNumber(wirePNLen, o.highestRcvdPN, wirePN) 75 } 76 77 func (o *longHeaderOpener) Open(dst, src []byte, pn protocol.PacketNumber, ad []byte) ([]byte, error) { 78 binary.BigEndian.PutUint64(o.nonceBuf[:], uint64(pn)) 79 dec, err := o.aead.Open(dst, o.nonceBuf[:], src, ad) 80 if err == nil { 81 o.highestRcvdPN = max(o.highestRcvdPN, pn) 82 } else { 83 err = ErrDecryptionFailed 84 } 85 return dec, err 86 } 87 88 func (o *longHeaderOpener) DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) { 89 o.headerProtector.DecryptHeader(sample, firstByte, pnBytes) 90 }