github.com/TugasAkhir-QUIC/quic-go@v0.0.2-0.20240215011318-d20e25a9054c/internal/handshake/aead.go (about) 1 package handshake 2 3 import ( 4 "crypto/cipher" 5 "encoding/binary" 6 7 "github.com/TugasAkhir-QUIC/quic-go/internal/protocol" 8 ) 9 10 func createAEAD(suite *cipherSuite, trafficSecret []byte, v protocol.Version) cipher.AEAD { 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 cipher.AEAD 24 headerProtector headerProtector 25 26 // use a single slice to avoid allocations 27 nonceBuf []byte 28 } 29 30 var _ LongHeaderSealer = &longHeaderSealer{} 31 32 func newLongHeaderSealer(aead cipher.AEAD, headerProtector headerProtector) LongHeaderSealer { 33 return &longHeaderSealer{ 34 aead: aead, 35 headerProtector: headerProtector, 36 nonceBuf: make([]byte, aead.NonceSize()), 37 } 38 } 39 40 func (s *longHeaderSealer) Seal(dst, src []byte, pn protocol.PacketNumber, ad []byte) []byte { 41 binary.BigEndian.PutUint64(s.nonceBuf[len(s.nonceBuf)-8:], uint64(pn)) 42 // The AEAD we're using here will be the qtls.aeadAESGCM13. 43 // It uses the nonce provided here and XOR it with the IV. 44 return s.aead.Seal(dst, s.nonceBuf, src, ad) 45 } 46 47 func (s *longHeaderSealer) EncryptHeader(sample []byte, firstByte *byte, pnBytes []byte) { 48 s.headerProtector.EncryptHeader(sample, firstByte, pnBytes) 49 } 50 51 func (s *longHeaderSealer) Overhead() int { 52 return s.aead.Overhead() 53 } 54 55 type longHeaderOpener struct { 56 aead cipher.AEAD 57 headerProtector headerProtector 58 highestRcvdPN protocol.PacketNumber // highest packet number received (which could be successfully unprotected) 59 60 // use a single slice to avoid allocations 61 nonceBuf []byte 62 } 63 64 var _ LongHeaderOpener = &longHeaderOpener{} 65 66 func newLongHeaderOpener(aead cipher.AEAD, headerProtector headerProtector) LongHeaderOpener { 67 return &longHeaderOpener{ 68 aead: aead, 69 headerProtector: headerProtector, 70 nonceBuf: make([]byte, aead.NonceSize()), 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[len(o.nonceBuf)-8:], uint64(pn)) 80 // The AEAD we're using here will be the qtls.aeadAESGCM13. 81 // It uses the nonce provided here and XOR it with the IV. 82 dec, err := o.aead.Open(dst, o.nonceBuf, src, ad) 83 if err == nil { 84 o.highestRcvdPN = max(o.highestRcvdPN, pn) 85 } else { 86 err = ErrDecryptionFailed 87 } 88 return dec, err 89 } 90 91 func (o *longHeaderOpener) DecryptHeader(sample []byte, firstByte *byte, pnBytes []byte) { 92 o.headerProtector.DecryptHeader(sample, firstByte, pnBytes) 93 }