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  }