github.com/sagernet/quic-go@v0.43.1-beta.1/internal/handshake/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  }