github.com/amazechain/amc@v0.1.3/internal/p2p/discover/v5wire/encoding.go (about)

     1  // Copyright 2020 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package v5wire
    18  
    19  import (
    20  	"bytes"
    21  	"crypto/aes"
    22  	"crypto/cipher"
    23  	"crypto/ecdsa"
    24  	crand "crypto/rand"
    25  	"crypto/sha256"
    26  	"encoding/binary"
    27  	"errors"
    28  	"fmt"
    29  	"github.com/amazechain/amc/common/mclock"
    30  	"github.com/amazechain/amc/internal/avm/rlp"
    31  	"github.com/amazechain/amc/internal/p2p/enode"
    32  	"github.com/amazechain/amc/internal/p2p/enr"
    33  	"hash"
    34  )
    35  
    36  // TODO concurrent WHOAREYOU tie-breaker
    37  // TODO rehandshake after X packets
    38  
    39  // Header represents a packet header.
    40  type Header struct {
    41  	IV [sizeofMaskingIV]byte
    42  	StaticHeader
    43  	AuthData []byte
    44  
    45  	src enode.ID // used by decoder
    46  }
    47  
    48  // StaticHeader contains the static fields of a packet header.
    49  type StaticHeader struct {
    50  	ProtocolID [6]byte
    51  	Version    uint16
    52  	Flag       byte
    53  	Nonce      Nonce
    54  	AuthSize   uint16
    55  }
    56  
    57  // Authdata layouts.
    58  type (
    59  	whoareyouAuthData struct {
    60  		IDNonce   [16]byte // ID proof data
    61  		RecordSeq uint64   // highest known ENR sequence of requester
    62  	}
    63  
    64  	handshakeAuthData struct {
    65  		h struct {
    66  			SrcID      enode.ID
    67  			SigSize    byte // signature data
    68  			PubkeySize byte // offset of
    69  		}
    70  		// Trailing variable-size data.
    71  		signature, pubkey, record []byte
    72  	}
    73  
    74  	messageAuthData struct {
    75  		SrcID enode.ID
    76  	}
    77  )
    78  
    79  // Packet header flag values.
    80  const (
    81  	flagMessage = iota
    82  	flagWhoareyou
    83  	flagHandshake
    84  )
    85  
    86  // Protocol constants.
    87  const (
    88  	version         = 1
    89  	minVersion      = 1
    90  	sizeofMaskingIV = 16
    91  
    92  	// The minimum size of any Discovery v5 packet is 63 bytes.
    93  	// Should reject packets smaller than minPacketSize.
    94  	minPacketSize = 63
    95  
    96  	maxPacketSize = 1280
    97  
    98  	minMessageSize      = 48 // this refers to data after static headers
    99  	randomPacketMsgSize = 20
   100  )
   101  
   102  var DefaultProtocolID = [6]byte{'d', 'i', 's', 'c', 'v', '5'}
   103  
   104  // Errors.
   105  var (
   106  	errTooShort            = errors.New("packet too short")
   107  	errInvalidHeader       = errors.New("invalid packet header")
   108  	errInvalidFlag         = errors.New("invalid flag value in header")
   109  	errMinVersion          = errors.New("version of packet header below minimum")
   110  	errMsgTooShort         = errors.New("message/handshake packet below minimum size")
   111  	errAuthSize            = errors.New("declared auth size is beyond packet length")
   112  	errUnexpectedHandshake = errors.New("unexpected auth response, not in handshake")
   113  	errInvalidAuthKey      = errors.New("invalid ephemeral pubkey")
   114  	errNoRecord            = errors.New("expected ENR in handshake but none sent")
   115  	errInvalidNonceSig     = errors.New("invalid ID nonce signature")
   116  	errMessageTooShort     = errors.New("message contains no data")
   117  	errMessageDecrypt      = errors.New("cannot decrypt message")
   118  )
   119  
   120  // Public errors.
   121  var (
   122  	// ErrInvalidReqID represents error when the ID is invalid.
   123  	ErrInvalidReqID = errors.New("request ID larger than 8 bytes")
   124  )
   125  
   126  // IsInvalidHeader reports whether 'err' is related to an invalid packet header. When it
   127  // returns false, it is pretty certain that the packet causing the error does not belong
   128  // to discv5.
   129  func IsInvalidHeader(err error) bool {
   130  	return err == errTooShort || err == errInvalidHeader || err == errMsgTooShort
   131  }
   132  
   133  // Packet sizes.
   134  var (
   135  	sizeofStaticHeader      = binary.Size(StaticHeader{})
   136  	sizeofWhoareyouAuthData = binary.Size(whoareyouAuthData{})
   137  	sizeofHandshakeAuthData = binary.Size(handshakeAuthData{}.h)
   138  	sizeofMessageAuthData   = binary.Size(messageAuthData{})
   139  	sizeofStaticPacketData  = sizeofMaskingIV + sizeofStaticHeader
   140  )
   141  
   142  // Codec encodes and decodes Discovery v5 packets.
   143  // This type is not safe for concurrent use.
   144  type Codec struct {
   145  	sha256     hash.Hash
   146  	localnode  *enode.LocalNode
   147  	privkey    *ecdsa.PrivateKey
   148  	sc         *SessionCache
   149  	protocolID [6]byte
   150  
   151  	// encoder buffers
   152  	buf      bytes.Buffer // whole packet
   153  	headbuf  bytes.Buffer // packet header
   154  	msgbuf   bytes.Buffer // message RLP plaintext
   155  	msgctbuf []byte       // message data ciphertext
   156  
   157  	// decoder buffer
   158  	decbuf []byte
   159  	reader bytes.Reader
   160  }
   161  
   162  // NewCodec creates a wire codec.
   163  func NewCodec(ln *enode.LocalNode, key *ecdsa.PrivateKey, clock mclock.Clock, protocolID *[6]byte) *Codec {
   164  	c := &Codec{
   165  		sha256:     sha256.New(),
   166  		localnode:  ln,
   167  		privkey:    key,
   168  		sc:         NewSessionCache(1024, clock),
   169  		protocolID: DefaultProtocolID,
   170  		decbuf:     make([]byte, maxPacketSize),
   171  	}
   172  	if protocolID != nil {
   173  		c.protocolID = *protocolID
   174  	}
   175  	return c
   176  }
   177  
   178  // Encode encodes a packet to a node. 'id' and 'addr' specify the destination node. The
   179  // 'challenge' parameter should be the most recently received WHOAREYOU packet from that
   180  // node.
   181  func (c *Codec) Encode(id enode.ID, addr string, packet Packet, challenge *Whoareyou) ([]byte, Nonce, error) {
   182  	// Create the packet header.
   183  	var (
   184  		head    Header
   185  		session *session
   186  		msgData []byte
   187  		err     error
   188  	)
   189  	switch {
   190  	case packet.Kind() == WhoareyouPacket:
   191  		head, err = c.encodeWhoareyou(id, packet.(*Whoareyou))
   192  	case challenge != nil:
   193  		// We have an unanswered challenge, send handshake.
   194  		head, session, err = c.encodeHandshakeHeader(id, addr, challenge)
   195  	default:
   196  		session = c.sc.session(id, addr)
   197  		if session != nil {
   198  			// There is a session, use it.
   199  			head, err = c.encodeMessageHeader(id, session)
   200  		} else {
   201  			// No keys, send random data to kick off the handshake.
   202  			head, msgData, err = c.encodeRandom(id)
   203  		}
   204  	}
   205  	if err != nil {
   206  		return nil, Nonce{}, err
   207  	}
   208  
   209  	// Generate masking IV.
   210  	if err := c.sc.maskingIVGen(head.IV[:]); err != nil {
   211  		return nil, Nonce{}, fmt.Errorf("can't generate masking IV: %v", err)
   212  	}
   213  
   214  	// Encode header data.
   215  	c.writeHeaders(&head)
   216  
   217  	// Store sent WHOAREYOU challenges.
   218  	if challenge, ok := packet.(*Whoareyou); ok {
   219  		challenge.ChallengeData = bytesCopy(&c.buf)
   220  		c.sc.storeSentHandshake(id, addr, challenge)
   221  	} else if msgData == nil {
   222  		headerData := c.buf.Bytes()
   223  		msgData, err = c.encryptMessage(session, packet, &head, headerData)
   224  		if err != nil {
   225  			return nil, Nonce{}, err
   226  		}
   227  	}
   228  
   229  	enc, err := c.EncodeRaw(id, head, msgData)
   230  	return enc, head.Nonce, err
   231  }
   232  
   233  // EncodeRaw encodes a packet with the given header.
   234  func (c *Codec) EncodeRaw(id enode.ID, head Header, msgdata []byte) ([]byte, error) {
   235  	c.writeHeaders(&head)
   236  
   237  	// Apply masking.
   238  	masked := c.buf.Bytes()[sizeofMaskingIV:]
   239  	mask := head.mask(id)
   240  	mask.XORKeyStream(masked[:], masked[:])
   241  
   242  	// Write message data.
   243  	c.buf.Write(msgdata)
   244  	return c.buf.Bytes(), nil
   245  }
   246  
   247  func (c *Codec) writeHeaders(head *Header) {
   248  	c.buf.Reset()
   249  	c.buf.Write(head.IV[:])
   250  	binary.Write(&c.buf, binary.BigEndian, &head.StaticHeader)
   251  	c.buf.Write(head.AuthData)
   252  }
   253  
   254  // makeHeader creates a packet header.
   255  func (c *Codec) makeHeader(toID enode.ID, flag byte, authsizeExtra int) Header {
   256  	var authsize int
   257  	switch flag {
   258  	case flagMessage:
   259  		authsize = sizeofMessageAuthData
   260  	case flagWhoareyou:
   261  		authsize = sizeofWhoareyouAuthData
   262  	case flagHandshake:
   263  		authsize = sizeofHandshakeAuthData
   264  	default:
   265  		panic(fmt.Errorf("BUG: invalid packet header flag %x", flag))
   266  	}
   267  	authsize += authsizeExtra
   268  	if authsize > int(^uint16(0)) {
   269  		panic(fmt.Errorf("BUG: auth size %d overflows uint16", authsize))
   270  	}
   271  	return Header{
   272  		StaticHeader: StaticHeader{
   273  			ProtocolID: c.protocolID,
   274  			Version:    version,
   275  			Flag:       flag,
   276  			AuthSize:   uint16(authsize),
   277  		},
   278  	}
   279  }
   280  
   281  // encodeRandom encodes a packet with random content.
   282  func (c *Codec) encodeRandom(toID enode.ID) (Header, []byte, error) {
   283  	head := c.makeHeader(toID, flagMessage, 0)
   284  
   285  	// Encode auth data.
   286  	auth := messageAuthData{SrcID: c.localnode.ID()}
   287  	if _, err := crand.Read(head.Nonce[:]); err != nil {
   288  		return head, nil, fmt.Errorf("can't get random data: %v", err)
   289  	}
   290  	c.headbuf.Reset()
   291  	binary.Write(&c.headbuf, binary.BigEndian, auth)
   292  	head.AuthData = c.headbuf.Bytes()
   293  
   294  	// Fill message ciphertext buffer with random bytes.
   295  	c.msgctbuf = append(c.msgctbuf[:0], make([]byte, randomPacketMsgSize)...)
   296  	crand.Read(c.msgctbuf)
   297  	return head, c.msgctbuf, nil
   298  }
   299  
   300  // encodeWhoareyou encodes a WHOAREYOU packet.
   301  func (c *Codec) encodeWhoareyou(toID enode.ID, packet *Whoareyou) (Header, error) {
   302  	// Sanity check node field to catch misbehaving callers.
   303  	if packet.RecordSeq > 0 && packet.Node == nil {
   304  		panic("BUG: missing node in whoareyou with non-zero seq")
   305  	}
   306  
   307  	// Create header.
   308  	head := c.makeHeader(toID, flagWhoareyou, 0)
   309  	head.AuthData = bytesCopy(&c.buf)
   310  	head.Nonce = packet.Nonce
   311  
   312  	// Encode auth data.
   313  	auth := &whoareyouAuthData{
   314  		IDNonce:   packet.IDNonce,
   315  		RecordSeq: packet.RecordSeq,
   316  	}
   317  	c.headbuf.Reset()
   318  	binary.Write(&c.headbuf, binary.BigEndian, auth)
   319  	head.AuthData = c.headbuf.Bytes()
   320  	return head, nil
   321  }
   322  
   323  // encodeHandshakeHeader encodes the handshake message packet header.
   324  func (c *Codec) encodeHandshakeHeader(toID enode.ID, addr string, challenge *Whoareyou) (Header, *session, error) {
   325  	// Ensure calling code sets challenge.node.
   326  	if challenge.Node == nil {
   327  		panic("BUG: missing challenge.Node in encode")
   328  	}
   329  
   330  	// Generate new secrets.
   331  	auth, session, err := c.makeHandshakeAuth(toID, addr, challenge)
   332  	if err != nil {
   333  		return Header{}, nil, err
   334  	}
   335  
   336  	// Generate nonce for message.
   337  	nonce, err := c.sc.nextNonce(session)
   338  	if err != nil {
   339  		return Header{}, nil, fmt.Errorf("can't generate nonce: %v", err)
   340  	}
   341  
   342  	// TODO: this should happen when the first authenticated message is received
   343  	c.sc.storeNewSession(toID, addr, session)
   344  
   345  	// Encode the auth header.
   346  	var (
   347  		authsizeExtra = len(auth.pubkey) + len(auth.signature) + len(auth.record)
   348  		head          = c.makeHeader(toID, flagHandshake, authsizeExtra)
   349  	)
   350  	c.headbuf.Reset()
   351  	binary.Write(&c.headbuf, binary.BigEndian, &auth.h)
   352  	c.headbuf.Write(auth.signature)
   353  	c.headbuf.Write(auth.pubkey)
   354  	c.headbuf.Write(auth.record)
   355  	head.AuthData = c.headbuf.Bytes()
   356  	head.Nonce = nonce
   357  	return head, session, err
   358  }
   359  
   360  // makeHandshakeAuth creates the auth header on a request packet following WHOAREYOU.
   361  func (c *Codec) makeHandshakeAuth(toID enode.ID, addr string, challenge *Whoareyou) (*handshakeAuthData, *session, error) {
   362  	auth := new(handshakeAuthData)
   363  	auth.h.SrcID = c.localnode.ID()
   364  
   365  	// Create the ephemeral key. This needs to be first because the
   366  	// key is part of the ID nonce signature.
   367  	var remotePubkey = new(ecdsa.PublicKey)
   368  	if err := challenge.Node.Load((*enode.Secp256k1)(remotePubkey)); err != nil {
   369  		return nil, nil, fmt.Errorf("can't find secp256k1 key for recipient")
   370  	}
   371  	ephkey, err := c.sc.ephemeralKeyGen()
   372  	if err != nil {
   373  		return nil, nil, fmt.Errorf("can't generate ephemeral key")
   374  	}
   375  	ephpubkey := EncodePubkey(&ephkey.PublicKey)
   376  	auth.pubkey = ephpubkey[:]
   377  	auth.h.PubkeySize = byte(len(auth.pubkey))
   378  
   379  	// Add ID nonce signature to response.
   380  	cdata := challenge.ChallengeData
   381  	idsig, err := makeIDSignature(c.sha256, c.privkey, cdata, ephpubkey[:], toID)
   382  	if err != nil {
   383  		return nil, nil, fmt.Errorf("can't sign: %v", err)
   384  	}
   385  	auth.signature = idsig
   386  	auth.h.SigSize = byte(len(auth.signature))
   387  
   388  	// Add our record to response if it's newer than what remote side has.
   389  	ln := c.localnode.Node()
   390  	if challenge.RecordSeq < ln.Seq() {
   391  		auth.record, _ = rlp.EncodeToBytes(ln.Record())
   392  	}
   393  
   394  	// Create session keys.
   395  	sec := deriveKeys(sha256.New, ephkey, remotePubkey, c.localnode.ID(), challenge.Node.ID(), cdata)
   396  	if sec == nil {
   397  		return nil, nil, fmt.Errorf("key derivation failed")
   398  	}
   399  	return auth, sec, err
   400  }
   401  
   402  // encodeMessageHeader encodes an encrypted message packet.
   403  func (c *Codec) encodeMessageHeader(toID enode.ID, s *session) (Header, error) {
   404  	head := c.makeHeader(toID, flagMessage, 0)
   405  
   406  	// Create the header.
   407  	nonce, err := c.sc.nextNonce(s)
   408  	if err != nil {
   409  		return Header{}, fmt.Errorf("can't generate nonce: %v", err)
   410  	}
   411  	auth := messageAuthData{SrcID: c.localnode.ID()}
   412  	c.buf.Reset()
   413  	binary.Write(&c.buf, binary.BigEndian, &auth)
   414  	head.AuthData = bytesCopy(&c.buf)
   415  	head.Nonce = nonce
   416  	return head, err
   417  }
   418  
   419  func (c *Codec) encryptMessage(s *session, p Packet, head *Header, headerData []byte) ([]byte, error) {
   420  	// Encode message plaintext.
   421  	c.msgbuf.Reset()
   422  	c.msgbuf.WriteByte(p.Kind())
   423  	if err := rlp.Encode(&c.msgbuf, p); err != nil {
   424  		return nil, err
   425  	}
   426  	messagePT := c.msgbuf.Bytes()
   427  
   428  	// Encrypt into message ciphertext buffer.
   429  	messageCT, err := encryptGCM(c.msgctbuf[:0], s.writeKey, head.Nonce[:], messagePT, headerData)
   430  	if err == nil {
   431  		c.msgctbuf = messageCT
   432  	}
   433  	return messageCT, err
   434  }
   435  
   436  // Decode decodes a discovery packet.
   437  func (c *Codec) Decode(inputData []byte, addr string) (src enode.ID, n *enode.Node, p Packet, err error) {
   438  	if len(inputData) < minPacketSize {
   439  		return enode.ID{}, nil, nil, errTooShort
   440  	}
   441  	// Copy the packet to a tmp buffer to avoid modifying it.
   442  	c.decbuf = append(c.decbuf[:0], inputData...)
   443  	input := c.decbuf
   444  	// Unmask the static header.
   445  	var head Header
   446  	copy(head.IV[:], input[:sizeofMaskingIV])
   447  	mask := head.mask(c.localnode.ID())
   448  	staticHeader := input[sizeofMaskingIV:sizeofStaticPacketData]
   449  	mask.XORKeyStream(staticHeader, staticHeader)
   450  
   451  	// Decode and verify the static header.
   452  	c.reader.Reset(staticHeader)
   453  	binary.Read(&c.reader, binary.BigEndian, &head.StaticHeader)
   454  	remainingInput := len(input) - sizeofStaticPacketData
   455  	if err := head.checkValid(remainingInput, c.protocolID); err != nil {
   456  		return enode.ID{}, nil, nil, err
   457  	}
   458  
   459  	// Unmask auth data.
   460  	authDataEnd := sizeofStaticPacketData + int(head.AuthSize)
   461  	authData := input[sizeofStaticPacketData:authDataEnd]
   462  	mask.XORKeyStream(authData, authData)
   463  	head.AuthData = authData
   464  
   465  	// Delete timed-out handshakes. This must happen before decoding to avoid
   466  	// processing the same handshake twice.
   467  	c.sc.handshakeGC()
   468  
   469  	// Decode auth part and message.
   470  	headerData := input[:authDataEnd]
   471  	msgData := input[authDataEnd:]
   472  	switch head.Flag {
   473  	case flagWhoareyou:
   474  		p, err = c.decodeWhoareyou(&head, headerData)
   475  	case flagHandshake:
   476  		n, p, err = c.decodeHandshakeMessage(addr, &head, headerData, msgData)
   477  	case flagMessage:
   478  		p, err = c.decodeMessage(addr, &head, headerData, msgData)
   479  	default:
   480  		err = errInvalidFlag
   481  	}
   482  	return head.src, n, p, err
   483  }
   484  
   485  // decodeWhoareyou reads packet data after the header as a WHOAREYOU packet.
   486  func (c *Codec) decodeWhoareyou(head *Header, headerData []byte) (Packet, error) {
   487  	if len(head.AuthData) != sizeofWhoareyouAuthData {
   488  		return nil, fmt.Errorf("invalid auth size %d for WHOAREYOU", len(head.AuthData))
   489  	}
   490  	var auth whoareyouAuthData
   491  	c.reader.Reset(head.AuthData)
   492  	binary.Read(&c.reader, binary.BigEndian, &auth)
   493  	p := &Whoareyou{
   494  		Nonce:         head.Nonce,
   495  		IDNonce:       auth.IDNonce,
   496  		RecordSeq:     auth.RecordSeq,
   497  		ChallengeData: make([]byte, len(headerData)),
   498  	}
   499  	copy(p.ChallengeData, headerData)
   500  	return p, nil
   501  }
   502  
   503  func (c *Codec) decodeHandshakeMessage(fromAddr string, head *Header, headerData, msgData []byte) (n *enode.Node, p Packet, err error) {
   504  	node, auth, session, err := c.decodeHandshake(fromAddr, head)
   505  	if err != nil {
   506  		c.sc.deleteHandshake(auth.h.SrcID, fromAddr)
   507  		return nil, nil, err
   508  	}
   509  
   510  	// Decrypt the message using the new session keys.
   511  	msg, err := c.decryptMessage(msgData, head.Nonce[:], headerData, session.readKey)
   512  	if err != nil {
   513  		c.sc.deleteHandshake(auth.h.SrcID, fromAddr)
   514  		return node, msg, err
   515  	}
   516  
   517  	// Handshake OK, drop the challenge and store the new session keys.
   518  	c.sc.storeNewSession(auth.h.SrcID, fromAddr, session)
   519  	c.sc.deleteHandshake(auth.h.SrcID, fromAddr)
   520  	return node, msg, nil
   521  }
   522  
   523  func (c *Codec) decodeHandshake(fromAddr string, head *Header) (n *enode.Node, auth handshakeAuthData, s *session, err error) {
   524  	if auth, err = c.decodeHandshakeAuthData(head); err != nil {
   525  		return nil, auth, nil, err
   526  	}
   527  
   528  	// Verify against our last WHOAREYOU.
   529  	challenge := c.sc.getHandshake(auth.h.SrcID, fromAddr)
   530  	if challenge == nil {
   531  		return nil, auth, nil, errUnexpectedHandshake
   532  	}
   533  	// Get node record.
   534  	n, err = c.decodeHandshakeRecord(challenge.Node, auth.h.SrcID, auth.record)
   535  	if err != nil {
   536  		return nil, auth, nil, err
   537  	}
   538  	// Verify ID nonce signature.
   539  	sig := auth.signature
   540  	cdata := challenge.ChallengeData
   541  	err = verifyIDSignature(c.sha256, sig, n, cdata, auth.pubkey, c.localnode.ID())
   542  	if err != nil {
   543  		return nil, auth, nil, err
   544  	}
   545  	// Verify ephemeral key is on curve.
   546  	ephkey, err := DecodePubkey(c.privkey.Curve, auth.pubkey)
   547  	if err != nil {
   548  		return nil, auth, nil, errInvalidAuthKey
   549  	}
   550  	// Derive session keys.
   551  	session := deriveKeys(sha256.New, c.privkey, ephkey, auth.h.SrcID, c.localnode.ID(), cdata)
   552  	session = session.keysFlipped()
   553  	return n, auth, session, nil
   554  }
   555  
   556  // decodeHandshakeAuthData reads the authdata section of a handshake packet.
   557  func (c *Codec) decodeHandshakeAuthData(head *Header) (auth handshakeAuthData, err error) {
   558  	// Decode fixed size part.
   559  	if len(head.AuthData) < sizeofHandshakeAuthData {
   560  		return auth, fmt.Errorf("header authsize %d too low for handshake", head.AuthSize)
   561  	}
   562  	c.reader.Reset(head.AuthData)
   563  	binary.Read(&c.reader, binary.BigEndian, &auth.h)
   564  	head.src = auth.h.SrcID
   565  
   566  	// Decode variable-size part.
   567  	var (
   568  		vardata       = head.AuthData[sizeofHandshakeAuthData:]
   569  		sigAndKeySize = int(auth.h.SigSize) + int(auth.h.PubkeySize)
   570  		keyOffset     = int(auth.h.SigSize)
   571  		recOffset     = keyOffset + int(auth.h.PubkeySize)
   572  	)
   573  	if len(vardata) < sigAndKeySize {
   574  		return auth, errTooShort
   575  	}
   576  	auth.signature = vardata[:keyOffset]
   577  	auth.pubkey = vardata[keyOffset:recOffset]
   578  	auth.record = vardata[recOffset:]
   579  	return auth, nil
   580  }
   581  
   582  // decodeHandshakeRecord verifies the node record contained in a handshake packet. The
   583  // remote node should include the record if we don't have one or if ours is older than the
   584  // latest sequence number.
   585  func (c *Codec) decodeHandshakeRecord(local *enode.Node, wantID enode.ID, remote []byte) (*enode.Node, error) {
   586  	node := local
   587  	if len(remote) > 0 {
   588  		var record enr.Record
   589  		if err := rlp.DecodeBytes(remote, &record); err != nil {
   590  			return nil, err
   591  		}
   592  		if local == nil || local.Seq() < record.Seq() {
   593  			n, err := enode.New(enode.ValidSchemes, &record)
   594  			if err != nil {
   595  				return nil, fmt.Errorf("invalid node record: %v", err)
   596  			}
   597  			if n.ID() != wantID {
   598  				return nil, fmt.Errorf("record in handshake has wrong ID: %v", n.ID())
   599  			}
   600  			node = n
   601  		}
   602  	}
   603  	if node == nil {
   604  		return nil, errNoRecord
   605  	}
   606  	return node, nil
   607  }
   608  
   609  // decodeMessage reads packet data following the header as an ordinary message packet.
   610  func (c *Codec) decodeMessage(fromAddr string, head *Header, headerData, msgData []byte) (Packet, error) {
   611  	if len(head.AuthData) != sizeofMessageAuthData {
   612  		return nil, fmt.Errorf("invalid auth size %d for message packet", len(head.AuthData))
   613  	}
   614  	var auth messageAuthData
   615  	c.reader.Reset(head.AuthData)
   616  	binary.Read(&c.reader, binary.BigEndian, &auth)
   617  	head.src = auth.SrcID
   618  
   619  	// Try decrypting the message.
   620  	key := c.sc.readKey(auth.SrcID, fromAddr)
   621  	msg, err := c.decryptMessage(msgData, head.Nonce[:], headerData, key)
   622  	if errors.Is(err, errMessageDecrypt) {
   623  		// It didn't work. Start the handshake since this is an ordinary message packet.
   624  		return &Unknown{Nonce: head.Nonce}, nil
   625  	}
   626  	return msg, err
   627  }
   628  
   629  func (c *Codec) decryptMessage(input, nonce, headerData, readKey []byte) (Packet, error) {
   630  	msgdata, err := decryptGCM(readKey, nonce, input, headerData)
   631  	if err != nil {
   632  		return nil, errMessageDecrypt
   633  	}
   634  	if len(msgdata) == 0 {
   635  		return nil, errMessageTooShort
   636  	}
   637  	return DecodeMessage(msgdata[0], msgdata[1:])
   638  }
   639  
   640  // checkValid performs some basic validity checks on the header.
   641  // The packetLen here is the length remaining after the static header.
   642  func (h *StaticHeader) checkValid(packetLen int, protocolID [6]byte) error {
   643  	if h.ProtocolID != protocolID {
   644  		return errInvalidHeader
   645  	}
   646  	if h.Version < minVersion {
   647  		return errMinVersion
   648  	}
   649  	if h.Flag != flagWhoareyou && packetLen < minMessageSize {
   650  		return errMsgTooShort
   651  	}
   652  	if int(h.AuthSize) > packetLen {
   653  		return errAuthSize
   654  	}
   655  	return nil
   656  }
   657  
   658  // mask returns a cipher for 'masking' / 'unmasking' packet headers.
   659  func (h *Header) mask(destID enode.ID) cipher.Stream {
   660  	block, err := aes.NewCipher(destID[:16])
   661  	if err != nil {
   662  		panic("can't create cipher")
   663  	}
   664  	return cipher.NewCTR(block, h.IV[:])
   665  }
   666  
   667  func bytesCopy(r *bytes.Buffer) []byte {
   668  	b := make([]byte, r.Len())
   669  	copy(b, r.Bytes())
   670  	return b
   671  }