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