package handshake
import (
"encoding/binary"
"github.com/tmc/go-iroh/internal/qng/internal/protocol"
)
const pathPacketNumberLow62 = (uint64 (1 ) << 62 ) - 1
func putPathNonce(buf []byte , pid protocol .PathID , pn protocol .PacketNumber ) []byte {
if pid == protocol .PathIDZero {
nonce := buf [len (buf )-8 :]
binary .BigEndian .PutUint64 (nonce , uint64 (pn ))
return nonce
}
nonce := buf [len (buf )-12 :]
binary .BigEndian .PutUint32 (nonce [:4 ], uint32 (pid ))
binary .BigEndian .PutUint64 (nonce [4 :], uint64 (pn )&pathPacketNumberLow62 )
return nonce
}
func createAEAD(suite cipherSuite , trafficSecret []byte , v protocol .Version ) *xorNonceAEAD {
keyLabel := hkdfLabelKeyV1
ivLabel := hkdfLabelIVV1
if v == protocol .Version2 {
keyLabel = hkdfLabelKeyV2
ivLabel = hkdfLabelIVV2
}
key := hkdfExpandLabel (suite .Hash , trafficSecret , []byte {}, keyLabel , suite .KeyLen )
iv := hkdfExpandLabel (suite .Hash , trafficSecret , []byte {}, ivLabel , suite .IVLen ())
return suite .AEAD (key , iv )
}
type longHeaderSealer struct {
aead *xorNonceAEAD
headerProtector headerProtector
nonceBuf [12 ]byte
}
var _ LongHeaderSealer = &longHeaderSealer {}
func newLongHeaderSealer(aead *xorNonceAEAD , headerProtector headerProtector ) LongHeaderSealer {
if aead .NonceSize () != 8 {
panic ("unexpected nonce size" )
}
return &longHeaderSealer {
aead : aead ,
headerProtector : headerProtector ,
}
}
func (s *longHeaderSealer ) Seal (dst , src []byte , pid protocol .PathID , pn protocol .PacketNumber , ad []byte ) []byte {
return s .aead .Seal (dst , putPathNonce (s .nonceBuf [:], pid , pn ), src , ad )
}
func (s *longHeaderSealer ) EncryptHeader (sample []byte , firstByte *byte , pnBytes []byte ) {
s .headerProtector .EncryptHeader (sample , firstByte , pnBytes )
}
func (s *longHeaderSealer ) Overhead () int {
return s .aead .Overhead ()
}
type longHeaderOpener struct {
aead *xorNonceAEAD
headerProtector headerProtector
highestRcvdPN protocol .PacketNumber
nonceBuf [12 ]byte
}
var _ LongHeaderOpener = &longHeaderOpener {}
func newLongHeaderOpener(aead *xorNonceAEAD , headerProtector headerProtector ) LongHeaderOpener {
if aead .NonceSize () != 8 {
panic ("unexpected nonce size" )
}
return &longHeaderOpener {
aead : aead ,
headerProtector : headerProtector ,
}
}
func (o *longHeaderOpener ) DecodePacketNumber (_ protocol .PathID , wirePN protocol .PacketNumber , wirePNLen protocol .PacketNumberLen ) protocol .PacketNumber {
return protocol .DecodePacketNumber (wirePNLen , o .highestRcvdPN , wirePN )
}
func (o *longHeaderOpener ) Open (dst , src []byte , pid protocol .PathID , pn protocol .PacketNumber , ad []byte ) ([]byte , error ) {
dec , err := o .aead .Open (dst , putPathNonce (o .nonceBuf [:], pid , pn ), src , ad )
if err == nil {
o .highestRcvdPN = max (o .highestRcvdPN , pn )
} else {
err = ErrDecryptionFailed
}
return dec , err
}
func (o *longHeaderOpener ) DecryptHeader (sample []byte , firstByte *byte , pnBytes []byte ) {
o .headerProtector .DecryptHeader (sample , firstByte , pnBytes )
}
The pages are generated with Golds v0.8.4 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .