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